Files
kupshop/bundles/External/FlexiBeeBundle/Synchronizers/UserSynchronizer.php
2025-08-02 16:30:27 +02:00

208 lines
7.1 KiB
PHP

<?php
declare(strict_types=1);
namespace External\FlexiBeeBundle\Synchronizers;
use AbraFlexi\RO;
use Query\Operator;
class UserSynchronizer extends BaseSynchronizer
{
protected static string $type = 'user';
protected function process(?int $lastSyncTime = null): void
{
$this->processToFlexiBee($lastSyncTime);
}
protected function processItem(array $item): void
{
}
protected function getItems(?int $lastSyncTime = null): iterable
{
return [];
}
private function processToFlexiBee(?int $lastSyncTime): void
{
if (isLocalDevelopment()) {
return;
}
$qb = sqlQueryBuilder()
->select('u.id, u.email, fu.id_flexi')
->from('users', 'u')
->leftJoin('u', 'flexi_users', 'fu', 'u.id = fu.id_user')
->where(Operator::equals(['u.figure' => 'Y']));
$specs[] = 'fu.id_flexi IS NULL';
if ($this->mode === self::MODE_NORMAL && $lastSyncTime) {
$dateTime = $this->createDateTime($lastSyncTime);
$specs[] = 'u.date_updated > :lastSyncTime';
$qb->setParameter('lastSyncTime', $dateTime->format('Y-m-d H:i:s'));
}
$qb->andWhere(Operator::orX($specs));
foreach ($qb->execute() as $item) {
$user = \User::createFromId($item['id']);
$user->fetchAddresses();
try {
$flexiId = $item['id_flexi'] ? (int) $item['id_flexi'] : null;
// pokud ho eshop jeste nezapsal do Flexi, tak ho zkusim ve Flexi najit
if (!$flexiId) {
$flexiId = $this->flexiBeeApi->getUserIdByEmail($item['email']);
}
// provedu zalozeni nebo aktualizaci uzivatele ve Flexi
$flexiId = $this->processUserToFlexiBee(
$this->getUserData($user, $flexiId)
);
// pokud uzivatel jeste nema mapping, tak ho vytvorim
if ($flexiId && !$item['id_flexi']) {
$this->flexiBeeUtil->createMapping(UserSynchronizer::getType(), $flexiId, (int) $user->id);
}
} catch (\Throwable $e) {
$this->logger->exception($e, '[FlexiBee] Během synchronizace uživatele se vyskytla chyba!', [
'email' => $user->email,
]);
}
}
}
public function processUserToFlexiBee(array $userData): ?int
{
try {
if ($flexiId = $this->flexiBeeApi->createOrUpdateUser($userData)) {
return $flexiId;
}
} catch (\Throwable $e) {
$this->logger->exception($e, '[FlexiBee] Během synchronizace uživatele se vyskytla chyba!', [
'email' => $userData['email'],
]);
}
return null;
}
public function getUserData(\User $user, ?int $flexiId = null): array
{
$invoiceName = $this->getUserName($user);
if (empty($invoiceName)) {
// invoice name cannot be empty
$invoiceName = $user->email;
}
$item = [
'typVztahuK' => 'typVztahu.odberatel',
'email' => $user->email,
'canceled' => $user->figure == 'N',
'nazev' => $invoiceName,
'ulice' => $user->invoice['street'],
'mesto' => $user->invoice['city'],
'psc' => $user->invoice['zip'],
'ic' => $user->invoice['ico'],
'dic' => $user->invoice['dic'],
'stat' => $user->invoice['country'] ? 'code:'.$user->invoice['country'] : '',
'postovniShodna' => $this->isUserDeliveryAddressSame($user),
'faNazev' => $this->getUserName($user, 'delivery'),
'faUlice' => $user->delivery['street'],
'faMesto' => $user->delivery['city'],
'faPsc' => $user->delivery['zip'],
'faStat' => $user->delivery['country'] ? 'code:'.$user->delivery['country'] : '',
];
if ($user->id_pricelist && ($flexiPriceListId = $this->flexiBeeUtil->getFlexiId('pricelist', $user->id_pricelist))) {
$item['skupCen'] = $flexiPriceListId;
}
if ($flexiId) {
// pokud uzivatel uz existuje, tak vyplnim id, aby se provedl jeho update
$item['id'] = $flexiId;
} else {
// pokud uzivatel jeste neexistuje, tak vyplnim jen kod, abychom ho zalozili s nejakym identifikatorem
if ($user->id === null && !empty($user->orderId)) {
// kvuli uzivatelum v objednavkach bez registrace
$item['kod'] = 'WPJ-ORDER'.$user->orderId;
} else {
// standartni uzivatel
$item['kod'] = 'WPJ'.$user->id;
}
}
$dateTime = !empty($user->date_reg) ? \DateTime::createFromFormat('Y-m-d H:i:s', $user->date_reg) : new \DateTime();
if ($dateTime && $dateTime->format('Y-m-d H:i:s') !== '0000-00-00 00:00:00') {
$item['datZaloz'] = RO::dateToFlexiDate($dateTime);
}
return $item;
}
/** Vytvorim dummy uzivatele pro objednavku bez uzivatele */
public function getOrderUserData(\Order $order): array
{
$user = new \User();
$user->id = null;
$user->orderId = (int) $order->id;
$user->email = $order->invoice_email;
$user->figure = 'Y';
$user->invoice = [
'name' => $order->invoice_name,
'surname' => $order->invoice_surname,
'firm' => $order->invoice_firm,
'street' => $order->invoice_street,
'city' => $order->invoice_city,
'zip' => $order->invoice_zip,
'ico' => $order->invoice_ico,
'dic' => $order->invoice_dic,
'country' => $order->invoice_country,
];
$user->delivery = [
'name' => $order->delivery_name,
'surname' => $order->delivery_surname,
'firm' => $order->delivery_firm,
'street' => $order->delivery_street,
'city' => $order->delivery_city,
'zip' => $order->delivery_zip,
'country' => $order->delivery_country,
];
return $this->getUserData($user);
}
private function getUserName(\User $user, string $type = 'invoice'): string
{
$parts = [];
if (!empty($user->{$type}['firm'])) {
$parts[] = $user->{$type}['firm'];
}
$parts[] = $user->{$type}['name'].' '.$user->{$type}['surname'];
return trim(implode(', ', array_filter($parts)));
}
private function isUserDeliveryAddressSame(\User $user): bool
{
$invoice = [$user->invoice['firm'], $user->invoice['name'], $user->invoice['country'], $user->invoice['street'], $user->invoice['city'], $user->invoice['zip']];
$delivery = array_filter([$user->delivery['firm'], $user->delivery['name'], $user->delivery['country'], $user->delivery['street'], $user->delivery['city'], $user->delivery['zip']]);
if (empty($delivery) || count($delivery) == 1) {
return true;
}
return $invoice === $delivery;
}
}