373 lines
14 KiB
PHP
373 lines
14 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace External\HannahBundle\Controller;
|
|
|
|
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
|
use External\HannahBundle\Email\OCPartnerRegistrationEmail;
|
|
use External\HannahBundle\Email\OCProfiPartnerRegistrationEmail;
|
|
use External\HannahBundle\Email\OCRegistrationEmail;
|
|
use External\HannahBundle\Email\OCSellerRegistrationEmail;
|
|
use External\HannahBundle\SAP\Exception\SAPException;
|
|
use External\HannahBundle\SAP\Synchronizer\UserSynchronizer;
|
|
use External\HannahBundle\SAP\Util\SAPClient;
|
|
use External\HannahBundle\Util\Product\ProductRelatedVariationsUtil;
|
|
use External\HannahBundle\Util\User\UserCardGenerator;
|
|
use KupShop\AdminBundle\Util\LegacyAdminCredentials;
|
|
use KupShop\ContentBundle\View\Exception\ValidationException;
|
|
use KupShop\KupShopBundle\Context\ContextManager;
|
|
use KupShop\KupShopBundle\Context\DomainContext;
|
|
use KupShop\KupShopBundle\Context\LanguageContext;
|
|
use KupShop\KupShopBundle\Context\UserContext;
|
|
use KupShop\KupShopBundle\Exception\RedirectException;
|
|
use KupShop\KupShopBundle\Util\Database\QueryHint;
|
|
use KupShop\KupShopBundle\Util\Mail\EmailCheck;
|
|
use KupShop\KupShopBundle\Views\View;
|
|
use KupShop\SellerBundle\Utils\SellerUtil;
|
|
use Query\Operator;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
use Symfony\Component\Routing\Attribute\Route;
|
|
use Symfony\Contracts\Service\Attribute\Required;
|
|
|
|
class OCController extends AbstractController
|
|
{
|
|
#[Required]
|
|
public ContextManager $contextManager;
|
|
|
|
#[Required]
|
|
public SellerUtil $sellerUtil;
|
|
|
|
#[Required]
|
|
public OCSellerRegistrationEmail $sellerRegistrationEmail;
|
|
#[Required]
|
|
public OCPartnerRegistrationEmail $partnerRegistrationEmail;
|
|
#[Required]
|
|
public OCProfiPartnerRegistrationEmail $profiPartnerRegistrationEmail;
|
|
|
|
#[Required]
|
|
public EmailCheck $emailCheck;
|
|
|
|
#[Required]
|
|
public SAPClient $sapClient;
|
|
|
|
#[Required]
|
|
public UserCardGenerator $userCardGenerator;
|
|
|
|
#[Route('/_oc/product-collection/{productId}/related-variation-ids/{variationId}/', requirements: ['productId' => '\d+', 'variationId' => '\d+'])]
|
|
public function getProductCollectionsRelatedVariationIds(ProductRelatedVariationsUtil $productRelatedVariationsUtil, int $productId, int $variationId): JsonResponse
|
|
{
|
|
$product = new \Product();
|
|
$product->createFromDB($productId);
|
|
|
|
$productRelatedVariationsUtil->fetchForProduct($product, $variationId);
|
|
|
|
$result = [];
|
|
foreach ($product->fetchCollections() as $item) {
|
|
if (empty($item)) {
|
|
continue;
|
|
}
|
|
|
|
$result[$item->id] = $item->relatedVariationId ?? null;
|
|
}
|
|
|
|
return new JsonResponse(array_filter($result));
|
|
}
|
|
|
|
/**
|
|
* Registrace uzivatele na prodejne.
|
|
*/
|
|
#[Route('/registrace-na-prodejne/{token}/{sellerId}/', requirements: ['sellerId' => '\d+'])]
|
|
#[Route('/registrace-na-prodejne/{token}/')]
|
|
public function sellerRegistration(Request $request, LegacyAdminCredentials $credentials, UserSynchronizer $userSynchronizer, string $token, ?int $sellerId = null): Response
|
|
{
|
|
if (!$credentials->loginByHash($token)) {
|
|
throw new NotFoundHttpException('Token is not valid');
|
|
}
|
|
|
|
if ($request->isMethod('POST') && $request->get('Submit')) {
|
|
try {
|
|
if ([$user, $cardNumber] = $this->handleSellerRegistration($request)) {
|
|
addUserMessage('Uživatel byl úspěšně zaregistrován.', 'success');
|
|
|
|
// zkusim uzivatele rovnou zapsat do SAPu, aby na pokladne nemuseli cekat
|
|
try {
|
|
QueryHint::withRouteToMaster(fn () => $userSynchronizer->updateUserToSAP(['id' => $user->id, 'id_sap' => null]));
|
|
addUserMessage('Uživatel byl úspěšně zapsán do SAPu.', 'success');
|
|
} catch (\Throwable $e) {
|
|
}
|
|
}
|
|
|
|
throw new RedirectException(
|
|
path('external_hannah_oc_sellerregistration', [
|
|
'token' => $token,
|
|
'sellerId' => $request->get('seller'),
|
|
'success' => 1,
|
|
'userId' => $user->id,
|
|
'cardNumber' => $cardNumber,
|
|
])
|
|
);
|
|
} catch (ValidationException $e) {
|
|
addUserMessage($e->getMessage());
|
|
}
|
|
}
|
|
|
|
$view = new class extends View {
|
|
protected $template = 'seller/seller.registration.tpl';
|
|
|
|
public function getTitle()
|
|
{
|
|
return 'Registrace na prodejně';
|
|
}
|
|
};
|
|
|
|
return $view
|
|
->addBodyVariables([
|
|
'token' => $token,
|
|
'invoice' => $request->get('invoice', []),
|
|
'delivery' => $request->get('delivery', []),
|
|
'sellerId' => $sellerId ?: $request->get('seller'),
|
|
'card_number' => $request->get('customer_card')['number'] ?? '',
|
|
])
|
|
->getResponse();
|
|
}
|
|
|
|
/**
|
|
* Registrace partnera, viz. #15748.
|
|
*/
|
|
#[Route('/registrace-partnera/')]
|
|
public function partnerRegistration(Request $request, LegacyAdminCredentials $legacyAdminCredentials, UserSynchronizer $userSynchronizer, View $view): Response
|
|
{
|
|
// musi byz prihlaseny jako admin, aby byla URL pristupna
|
|
if (!$legacyAdminCredentials->isLogged()) {
|
|
return new RedirectResponse(
|
|
path('kupshop_admin_admin_index', ['url' => $request->getPathInfo()])
|
|
);
|
|
}
|
|
|
|
if ($request->isMethod('POST') && $request->get('Submit')) {
|
|
try {
|
|
if ([$user, $cardNumber] = $this->handlePartnerRegistration($request)) {
|
|
addUserMessage('Uživatel byl úspěšně zaregistrován.', 'success');
|
|
|
|
// zkusim uzivatele rovnou zapsat do SAPu, aby na pokladne nemuseli cekat
|
|
try {
|
|
QueryHint::withRouteToMaster(fn () => $userSynchronizer->updateUserToSAP(['id' => $user->id, 'id_sap' => null]));
|
|
addUserMessage('Uživatel byl úspěšně zapsán do SAPu.', 'success');
|
|
} catch (\Throwable $e) {
|
|
}
|
|
}
|
|
|
|
throw new RedirectException(
|
|
path('external_hannah_oc_partnerregistration', [
|
|
'success' => 1,
|
|
'userId' => $user->id,
|
|
'cardNumber' => $cardNumber,
|
|
])
|
|
);
|
|
} catch (ValidationException $e) {
|
|
addUserMessage($e->getMessage());
|
|
}
|
|
}
|
|
|
|
return $view
|
|
->setTemplate('oc/oc.partner-registration.tpl')
|
|
->addBodyVariables([
|
|
'invoice' => $request->get('invoice', []),
|
|
'delivery' => $request->get('delivery', []),
|
|
'generate' => $request->get('customer_card')['generate'] ?? '',
|
|
'card_number' => $request->get('customer_card')['number'] ?? '',
|
|
])
|
|
->getResponse();
|
|
}
|
|
|
|
#[Route('/uzivatel/{userId}/zakaznicka-karta/', requirements: ['userId' => '\d+'])]
|
|
public function userCardPDF(UserCardGenerator $userCardGenerator, int $userId, #[MapQueryParameter] $cardNumber = null): Response
|
|
{
|
|
if (!($pdf = $userCardGenerator->generateUserCardPDF($userId, $cardNumber))) {
|
|
throw new NotFoundHttpException();
|
|
}
|
|
|
|
return new Response($pdf, headers: ['Content-Type' => 'application/pdf']);
|
|
}
|
|
|
|
private function handlePartnerRegistration(Request $request): array
|
|
{
|
|
[$user, $userCardNumber] = $this->handleRegistration($request, null);
|
|
|
|
$email = match ($request->get('customer_card')['generate'] ?? null) {
|
|
'9997' => $this->profiPartnerRegistrationEmail,
|
|
'9996' => $this->partnerRegistrationEmail,
|
|
default => null,
|
|
};
|
|
|
|
if ($email) {
|
|
$this->sendRegistrationEmail($email, $user);
|
|
}
|
|
|
|
return [$user, $userCardNumber];
|
|
}
|
|
|
|
/**
|
|
* Registrace uzivatele na prodejne.
|
|
*/
|
|
private function handleSellerRegistration(Request $request): array
|
|
{
|
|
if (!($sellerId = $request->get('seller'))) {
|
|
throw new ValidationException('Není vybrána prodejna!');
|
|
}
|
|
|
|
[$user, $userCardNumber] = $this->handleRegistration($request);
|
|
|
|
// nastavim uzivateli skupinu podle prodejny
|
|
$this->setUserGroupBySellerId((int) $user->id, (int) $sellerId);
|
|
// odeslu uzivateli email s nastavenim hesla
|
|
$this->sendRegistrationEmail(
|
|
$this->sellerRegistrationEmail,
|
|
$user
|
|
);
|
|
|
|
return [$user, $userCardNumber];
|
|
}
|
|
|
|
/**
|
|
* Vytvoreni uzivatele.
|
|
*/
|
|
private function handleRegistration(Request $request, ?int $cardEanFourthPositionDigit = UserCardGenerator::EAN_FOURTH_POSITION_DIGIT): array
|
|
{
|
|
$user = new \User();
|
|
|
|
// nactu si data
|
|
$invoice = $request->get('invoice');
|
|
$delivery = $request->get('delivery');
|
|
|
|
$customerCard = $request->get('customer_card');
|
|
// pokud se jedna o elektronickou kartu, tak ji chceme vygenerovat
|
|
if (($customerCard['type'] ?? null) === 'electronic') {
|
|
$prefixes = explode(',', $customerCard['generate'] ?? '');
|
|
|
|
$customerCardNumber = $this->userCardGenerator->generateCustomerCardEAN(
|
|
(string) $prefixes[array_rand($prefixes)],
|
|
$cardEanFourthPositionDigit
|
|
);
|
|
} else {
|
|
$customerCardNumber = $customerCard['number'] ?? null;
|
|
}
|
|
|
|
$customData = [];
|
|
if ($customerCardNumber) {
|
|
$customData = [
|
|
'sap' => [
|
|
'cards' => [$customerCardNumber],
|
|
],
|
|
];
|
|
}
|
|
|
|
foreach ($customData as $key => $value) {
|
|
$user->setCustomData($key, $value);
|
|
}
|
|
|
|
// zvaliduju email
|
|
if (!$this->emailCheck->isEmailDomainValid($invoice['email'])) {
|
|
throw new ValidationException('Zadaný e-mail není validní!');
|
|
}
|
|
|
|
try {
|
|
$result = $this->sapClient->customerValidate($invoice['email'], '');
|
|
if (!empty($result->CustomerData->CustomerId)) {
|
|
throw new ValidationException('Uživatel se zadaným e-mailem už existuje!');
|
|
}
|
|
} catch (SAPException $e) {
|
|
}
|
|
|
|
// ignorujeme chyby
|
|
try {
|
|
$user->updateAddresses($invoice, $delivery);
|
|
} catch (ValidationException $e) {
|
|
}
|
|
|
|
try {
|
|
// zkusim vytvorit uzivatele
|
|
$userId = $this->contextManager->activateContexts([UserContext::class => ContextManager::FORCE_EMPTY], function () use ($user) {
|
|
return sqlGetConnection()->transactional(function () use ($user) {
|
|
return $user->update();
|
|
});
|
|
});
|
|
} catch (UniqueConstraintViolationException $e) {
|
|
throw new ValidationException('Uživatel se zadaným e-mailem už existuje!');
|
|
}
|
|
|
|
if (!$userId) {
|
|
throw new ValidationException('Uživatele se nepodařilo vytvořit.');
|
|
}
|
|
|
|
// nactu si uzivatele
|
|
$user = sqlGetConnection()->transactional(function () use ($userId) {
|
|
return \User::createFromId($userId);
|
|
});
|
|
|
|
return [$user, $customerCardNumber];
|
|
}
|
|
|
|
private function sendRegistrationEmail(OCRegistrationEmail $email, \User $user): void
|
|
{
|
|
$message = $this->contextManager->activateContexts(
|
|
[
|
|
LanguageContext::class => $user->id_language ?? null,
|
|
DomainContext::class => $this->contextManager->getDomainFromLanguage($user->id_language ?? null),
|
|
],
|
|
function () use ($email, $user) {
|
|
$email->setUser($user);
|
|
|
|
return $email->getEmail();
|
|
}
|
|
);
|
|
$message['to'] = $user['email'];
|
|
|
|
$email->sendEmail($message);
|
|
}
|
|
|
|
private function setUserGroupBySellerId(int $userId, int $sellerId): void
|
|
{
|
|
if (!($seller = $this->sellerUtil->getSeller($sellerId))) {
|
|
return;
|
|
}
|
|
|
|
$userGroupId = sqlQueryBuilder()
|
|
->select('id')
|
|
->from('users_groups')
|
|
->where(Operator::equals(['descr' => $sellerId]))
|
|
->execute()->fetchOne();
|
|
|
|
if (!$userGroupId) {
|
|
$userGroupId = sqlGetConnection()->transactional(function () use ($seller) {
|
|
sqlQueryBuilder()
|
|
->insert('users_groups')
|
|
->directValues(
|
|
[
|
|
'name' => 'Prodejna: '.$seller['title'],
|
|
'descr' => $seller['id'],
|
|
]
|
|
)->execute();
|
|
|
|
return (int) sqlInsertId();
|
|
});
|
|
}
|
|
|
|
sqlQueryBuilder()
|
|
->insert('users_groups_relations')
|
|
->directValues(
|
|
[
|
|
'id_user' => $userId,
|
|
'id_group' => $userGroupId,
|
|
]
|
|
)->execute();
|
|
}
|
|
}
|