first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace External\PompoBundle\View;
use Query\Operator;
class BonusProgramExchangeView extends \KupShop\BonusProgramBundle\View\Exchange\BonusProgramExchangeView
{
protected function getExchangeList(): array
{
$data = parent::getExchangeList();
// Odfiltruju partnerske slevy, ktere uz nemaji dostupne zadne kupony
foreach ($data as $key => $item) {
if (($item['partner'] ?? 'N') === 'Y') {
if (!$this->hasAvailablePartnerCoupons((int) $item['id_discount'])) {
unset($data[$key]);
}
}
}
return $data;
}
private function hasAvailablePartnerCoupons(int $discountId): bool
{
$count = sqlQueryBuilder()
->select('COUNT(*)')
->from('discounts_coupons')
->andWhere(Operator::equals(['id_discount' => $discountId]))
->andWhere('id_user IS NULL AND id_order_purchased IS NULL AND id_order_used IS NULL')
->andWhere(Operator::equals(['used' => 'N']))
->andWhere('date_from <= NOW() OR date_from IS NULL')
->andWhere('date_to >= NOW() OR date_to IS NULL')
->execute()->fetchOne();
if ($count > 0) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace External\PompoBundle\View;
use External\PompoBundle\Util\Configuration;
use KupShop\CatalogBundle\Section\SectionTree;
use KupShop\KupShopBundle\Exception\PermanentRedirectException;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\SellerBundle\Context\SellerContext;
use Query\QueryBuilder;
class CategoryView extends \KupShop\CatalogBundle\View\CategoryView
{
/** @required */
public Configuration $configuration;
/** @required */
public SectionTree $sectionTree;
public function render(): string
{
if ($this->configuration->isPompo() && $this->producerId == 34) {
if ($section = $this->sectionTree->getSectionById(202)) {
throw new PermanentRedirectException('/'.$section->getUrl());
}
}
return parent::render();
}
protected function defaultOrderStart($productAlias, $query)
{
$query = parent::defaultOrderStart($productAlias, $query);
$dbcfg = \Settings::getDefault();
$defaultOrderByPosition = 'COALESCE(psp.position - '.POSITION_STANDARD.', p.position, '.POSITION_STANDARD.')';
if (($this->getCategory()['data']['enable_sort_by_product_position'] ?? 'Y') === 'N') {
$defaultOrderByPosition = 'COALESCE(psp.position - '.POSITION_STANDARD.', '.POSITION_STANDARD.')';
}
// customizace kvuli razeni podel skladovosti - nechceme radit podle celkoveho poctu kusu skladem. Na prvnich mistech maji byt
// produkty, ktere jsou skladem na hlavnim skladu, za nima potom produkty, co jsou skladem na moji prodejne
if ($dbcfg->prod_subtract_from_store) {
if (($this->getCategory()['data']['enable_sort_by_in_store'] ?? $dbcfg->sort_in_cat_by_in_store) === 'Y') {
$storeId = null;
if (findModule(\Modules::SELLERS)) {
$sellerContext = Contexts::get(SellerContext::class);
$storeId = $sellerContext->getActive()['id_store'] ?? null;
}
// skladovost na hlavnim skladu
$mainQuantitySubQuery = '(SELECT SUM(si_sort.quantity) FROM stores_items si_sort WHERE si_sort.id_product = p.id AND si_sort.id_store ='.$this->configuration->getMainStoreId().')';
// skladovost na vybrane prodejne
if ($storeId) {
$activeSellerQuantitySubQuery = '(SELECT SUM(si_sort.quantity) FROM stores_items si_sort WHERE si_sort.id_product = p.id AND si_sort.id_store = '.$storeId.' AND si_sort.quantity >= 0)';
$otherSellerQuantitySubQuery = '(SELECT SUM(si_sort_other.quantity) FROM stores_items si_sort_other WHERE si_sort_other.id_product = p.id AND si_sort_other.id_store NOT IN ('.$storeId.', '.$this->configuration->getMainStoreId().') AND si_sort_other.quantity >= 0)';
} else {
$activeSellerQuantitySubQuery = '(0)';
$otherSellerQuantitySubQuery = '(SELECT SUM(si_sort_other.quantity) FROM stores_items si_sort_other WHERE si_sort_other.id_product = p.id AND si_sort_other.id_store != '.$this->configuration->getMainStoreId().' AND si_sort_other.quantity >= 0)';
}
// skladovost u dodavatele
$supplierQuantitySubQuery = 'SUM(pos.in_store)';
$this->productList->andSpec(function (QueryBuilder $qb) {
$qb->joinProductsOfSuppliers();
});
// razeni podle skladovosti
// 1. skladem na centrale a moji prodejne
// 2. skladem na centrale
// 3. skladem na vybrane prodejne
// 4. skladem u dodavatele
// 5. skladem na jine prodejne
// .. zbytek
$query['order_start'] = "(
CASE
WHEN {$mainQuantitySubQuery} > 0 AND {$activeSellerQuantitySubQuery} > 0 THEN {$defaultOrderByPosition}
WHEN {$mainQuantitySubQuery} > 0 THEN {$defaultOrderByPosition} + 500
WHEN {$activeSellerQuantitySubQuery} > 0 THEN {$defaultOrderByPosition} + 1000
WHEN {$supplierQuantitySubQuery} > 0 THEN {$defaultOrderByPosition} + 5000
WHEN {$otherSellerQuantitySubQuery} > 0 THEN {$defaultOrderByPosition} + 9000
ELSE {$defaultOrderByPosition} + 10000
END
)";
}
}
return $query;
}
}

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace External\PompoBundle\View;
use KupShop\KupShopBundle\Exception\RedirectException;
use Symfony\Component\HttpFoundation\RequestStack;
class PageView extends \KupShop\ContentBundle\View\PageView
{
/** @required */
public RequestStack $requestStack;
public function getBodyVariables()
{
$vars = parent::getBodyVariables();
$passwordRequired = false;
if (!empty($this->getPage()->getData()['password'])) {
if ($request = $this->requestStack->getCurrentRequest()) {
if ($request->isMethod('POST')) {
$this->authenticatePage(
$request->get('password')
);
}
if (!($hash = $request->get('hash'))) {
$hash = $request->getSession()->get(
$this->getPageHashSessionKey()
);
}
if (!$hash || (md5($this->getPage()->getData()['password']) !== $hash)) {
$passwordRequired = true;
}
}
}
$vars['passwordRequired'] = $passwordRequired;
return $vars;
}
private function authenticatePage(?string $password): void
{
if (mb_strtolower($this->getPage()->getData()['password']) === mb_strtolower($password)) {
$this->requestStack->getSession()->set(
$this->getPageHashSessionKey(),
md5($this->getPage()->getData()['password'])
);
throw new RedirectException('/'.$this->getPage()->getUrl());
}
}
private function getPageHashSessionKey(): string
{
return 'pageHash_'.$this->getPage()->getId();
}
}

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace External\PompoBundle\View;
use External\PompoBundle\Util\ProductUtil;
use Symfony\Contracts\Service\Attribute\Required;
class ProductView extends \KupShop\ContentBundle\View\ProductView
{
#[Required]
public ProductUtil $productUtil;
public function getProduct()
{
$product = parent::getProduct();
if ($product && $this->productCollection) {
$product->_pompoProductCollection = $this->productCollection;
$this->productUtil->fetchAdditionalPrices($this->productCollection);
}
return $product;
}
}

View File

@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace External\PompoBundle\View;
use External\PompoBundle\Util\User\UserCardUtil;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Views\View;
use Query\Operator;
class UserCardsView extends View
{
protected $template = 'user/user.cards.tpl';
private UserCardUtil $userCardUtil;
public function __construct(UserCardUtil $userCardUtil)
{
$this->userCardUtil = $userCardUtil;
}
public function getTitle()
{
return translate('userCardsTitle', 'pompo');
}
public function getBodyVariables()
{
$vars = parent::getBodyVariables();
$vars['cards'] = $this->userCardUtil->getUserCards(
$this->getUserId()
);
$vars['children'] = $this->getUserChildren();
return $vars;
}
public function getUserChildren(): string
{
$qb = sqlQueryBuilder()
->select('name')
->from('users_family')
->where(Operator::equals(['id_user' => $this->getUserId()]));
$result = [];
foreach ($qb->execute() as $item) {
$result[] = $item['name'];
}
return implode(', ', array_filter($result));
}
public function getUserId(): int
{
return (int) Contexts::get(UserContext::class)->getActiveId();
}
}

View File

@@ -0,0 +1,204 @@
<?php
declare(strict_types=1);
namespace External\PompoBundle\View;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use External\PompoBundle\DRS\Util\DRSApi;
use KupShop\KupShopBundle\Exception\RedirectException;
use KupShop\KupShopBundle\Util\StringUtil;
use Query\Operator;
class UserView extends \KupShop\UserBundle\View\UserView
{
/** @required */
public DRSApi $api;
public function getBodyVariables()
{
$vars = parent::getBodyVariables();
if ($this->newUser() && $this->request->get('customer')) {
foreach ($this->getDRSCustomerData() as $key => $value) {
$vars['input'][$key] = ['value' => $value];
}
}
return $vars;
}
protected function handleSubmit(): void
{
$customerId = $this->request->get('customerId');
// Byl odeslan formular s cislem zakaznika a cislem karty
if ($this->request->get('Submit') === 'login-using-customer-id') {
$cardCode = $this->request->get('customerCardCode');
// Obe pole musi byt vyplneny
if (empty($customerId) || empty($cardCode)) {
$this->returnError(
translate('regFieldsEmpty', 'pompo')
);
}
// Najdu zakaznika v DRSu
try {
$customer = $this->api->getUserById((int) $customerId);
} catch (\Throwable $e) {
$customer = null;
}
if (!$customer) {
$this->returnError(
translate('regCustomerNotFound', 'pompo')
);
}
// Kontroluju, ze zakaznik uz neni registrovany na shopu
if (!$this->isRegistrationAllowed((int) $customerId)) {
$this->returnError(
translate('regRegisteredAlready', 'pompo')
);
}
$cardFound = false;
// Kontroluju, ze existuje karta, kterou zadal
foreach ($customer['customercard'] ?? [] as $card) {
if (trim($card['@attributes']['number']) == trim($cardCode)) {
$cardFound = true;
break;
}
}
// Pokud karta neexistuje, tak vyhazuju chybu
if (!$cardFound) {
$this->returnError(
translate('regCustomerNotFound', 'pompo')
);
}
$this->addSuccessMessage(
translate('regCustomerFound', 'pompo')
);
// Pokud je vse OK, tak redirectuju na registraci s GET parametrem customerId - diky tomu prednactu formular podle DRSu
throw new RedirectException(
path('register', ['customer' => base64_encode((string) $customerId)]).'#user-register-form'
);
}
if ($customerId = $this->getRegisteredCustomerId()) {
$email = getVal('email');
try {
// musim udelat update na email uzivatele, aby pak zafungovalo naparovani na uz existujici ucet, ktery se vytvoril z DRSu
if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
sqlQueryBuilder()
->update('users', 'u')
->join('u', 'drs_users', 'du', 'du.id_user = u.id')
->set('u.email', ':email')
->set('u.figure', ':figure')
->where('du.id_drs = :customerId AND u.passw = ""')
->addParameters(
[
'email' => $email,
'figure' => 'N',
'customerId' => $customerId,
]
)
->execute();
}
// Pokud je volan handleSubmit a mam cislo uzivatele z DRSu, tak nasetuju custom data, ktere reknou, ze se po registraci maji
// sesynchronizovat karty uzivatele
$this->user->setCustomData('forceUserSynchronization', $customerId);
} catch (UniqueConstraintViolationException $e) {
}
}
// handle klasicke registrace
parent::handleSubmit();
}
public function getDRSCustomerData(): array
{
// Nacteni DRS dat do registracniho formulare
if ($customerId = $this->getRegisteredCustomerId()) {
// zkontroluju, ze uzivatel uz neni registrovany a timpadem se muze registrovat pres DRS
if (!$this->isRegistrationAllowed($customerId)) {
$this->returnError(translate('regRegisteredAlready', 'pompo'));
}
if ($customer = $this->api->getUserById($customerId)) {
if (StringUtil::startsWith($customer['@attributes']['firstName'] ?? '', 'DEL_')) {
$this->returnError(translate('registrationInvalidLink', 'pompo'));
}
$email = $customer['@attributes']['email'] ?? '';
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$email = '';
}
$result = [
'email' => $email,
'name' => $customer['@attributes']['firstName'] ?? '',
'surname' => $customer['@attributes']['lastName'] ?? '',
];
foreach ($customer['address'] ?? [] as $address) {
$prefix = '';
if ($address['@attributes']['addressType'] != 1) {
continue;
}
$result[$prefix.'name'] = $address['@attributes']['firstName'] ?? '';
$result[$prefix.'surname'] = $address['@attributes']['lastName'] ?? '';
$result[$prefix.'city'] = $address['@attributes']['city'] ?? '';
$result[$prefix.'street'] = $address['@attributes']['street'] ?? '';
$result[$prefix.'zip'] = $address['@attributes']['zipCode'] ?? '';
$result[$prefix.'country'] = $address['@attributes']['country'] ?? 'CZ';
$result[$prefix.'firm'] = $address['@attributes']['company'] ?? '';
}
return $result;
}
}
return [];
}
private function isRegistrationAllowed(int $customerId): bool
{
$user = sqlQueryBuilder()
->select('u.id, u.passw')
->from('users', 'u')
->join('u', 'drs_users', 'du', 'du.id_user = u.id')
->andWhere(Operator::equals(['du.id_drs' => $customerId]))
->execute()->fetchAssociative();
if ($user && !empty($user['passw'])) {
return false;
}
return true;
}
private function getRegisteredCustomerId(): ?int
{
if ($customerId = $this->request->get('customer')) {
// cislo zakaznika je po submitu v GET datech, ale je base encodnuty
return (int) base64_decode($customerId);
}
return null;
}
private function returnError(string $message): void
{
$this->addErrorMessage($message);
throw new RedirectException(
path('register')
);
}
}