388 lines
14 KiB
PHP
388 lines
14 KiB
PHP
<?php
|
|
|
|
namespace KupShop\ReclamationsBundle\Util;
|
|
|
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
|
use KupShop\KupShopBundle\Context\LanguageContext;
|
|
use KupShop\ReclamationsBundle\Email\ReclamationCreateAdminEmail;
|
|
use KupShop\ReclamationsBundle\Entity\ReclamationEntity;
|
|
use KupShop\ReclamationsBundle\Event\ReclamationsEvent;
|
|
use KupShop\ReturnsBundle\Util\ReturnsReclamations;
|
|
use Query\Operator;
|
|
use Query\QueryBuilder;
|
|
|
|
class ReclamationsUtil extends ReturnsReclamations
|
|
{
|
|
public const DEFAULT_GUARANTEE = 24;
|
|
public const STATUS_NEW = 0;
|
|
public const STATUS_ACCEPTED = 1;
|
|
public const STATUS_HANDLED = 2;
|
|
|
|
protected static $tableName = 'reclamations';
|
|
|
|
private $languageContext;
|
|
|
|
public function __construct(LanguageContext $languageContext)
|
|
{
|
|
$this->languageContext = $languageContext;
|
|
}
|
|
|
|
public function createReclamation(int $itemId, int $itemPieces, array $delivery, $bankAccount, $preferred_handle_type, $userNote = null, $sendMail = true, ?array $user_content = null)
|
|
{
|
|
$entity = sqlGetConnection()->transactional(function () use ($itemId, $itemPieces, $delivery, $bankAccount, $preferred_handle_type, $userNote, $sendMail, $user_content) {
|
|
$order_id = sqlQueryBuilder()
|
|
->select('oi.id_order')
|
|
->from('order_items', 'oi')
|
|
->where(Operator::equals(['oi.id' => $itemId]))
|
|
->execute()->fetchColumn();
|
|
|
|
$order = new \Order($order_id);
|
|
$order->createFromDB($order_id);
|
|
|
|
$insert = [
|
|
'date_created' => new \DateTime(),
|
|
'status' => 0,
|
|
'id_item' => $itemId,
|
|
'pieces' => $itemPieces,
|
|
'bank_account' => $bankAccount,
|
|
'preferred_handle_type' => $preferred_handle_type,
|
|
'user_note' => $userNote,
|
|
] + $delivery;
|
|
|
|
$data = json_decode($insert['data'] ?? '', true) ?? [];
|
|
|
|
if (!empty($user_content)) {
|
|
$data['userContent'] = $user_content;
|
|
}
|
|
|
|
$deliveryData = $order->getDeliveryType()->getDelivery()->data;
|
|
if (!empty($deliveryData)) {
|
|
$data['delivery_data'] = $deliveryData;
|
|
}
|
|
|
|
if (!empty($data)) {
|
|
$insert['data'] = json_encode($data);
|
|
}
|
|
|
|
sqlQueryBuilder()->insert('reclamations')
|
|
->directValues($insert, ['date_created' => 'datetime'])
|
|
->execute();
|
|
|
|
$reclamationId = sqlInsertId();
|
|
|
|
$code = $this->getCode($reclamationId);
|
|
|
|
sqlQueryBuilder()->update('reclamations')
|
|
->directValues(['code' => $code])
|
|
->where(Operator::equals(['id' => $reclamationId]))
|
|
->execute();
|
|
|
|
$this->logHistory($reclamationId, empty($userNote) ? '' : $userNote, $sendMail);
|
|
|
|
$entity = $this->getReclamation($reclamationId);
|
|
|
|
$order->logHistory(translate('order_history', 'Reclamations', false, true)." <a href=\"javascript:nw('Reclamations', {$reclamationId})\">{$code}</a>");
|
|
|
|
$entity->setOrderNumber($order->order_no);
|
|
$event = new ReclamationsEvent($entity, self::STATUS_NEW);
|
|
$this->dispatcher->dispatch($event, ReclamationsEvent::RECLAMATION_CREATED);
|
|
|
|
return $entity;
|
|
});
|
|
|
|
if ($sendMail) {
|
|
$this->contextManager->activateContexts([
|
|
LanguageContext::class => $entity->getIdLanguage(),
|
|
CurrencyContext::class => $entity->getIdCurrency(),
|
|
],
|
|
function () use ($entity) {
|
|
$this->sendEmail($entity, $this->getEmailsInStatuses()[self::STATUS_NEW]);
|
|
}
|
|
);
|
|
}
|
|
|
|
$dbcfg = \Settings::getDefault();
|
|
// Shopkeeper notification
|
|
$shopkeeperEmail = !empty($dbcfg->reclamations['shopkeeper_email']) ? $dbcfg->reclamations['shopkeeper_email'] : $dbcfg->order_shopkeeper_mail;
|
|
if (!empty($shopkeeperEmail)) {
|
|
$this->sendNotificationToOwner(
|
|
$entity,
|
|
$shopkeeperEmail
|
|
);
|
|
}
|
|
|
|
return $entity->getId();
|
|
}
|
|
|
|
public function getCode($reclamationId)
|
|
{
|
|
return 'R'.sprintf('%03d', $reclamationId);
|
|
}
|
|
|
|
public function setData(int $reclamationId, $key, $value)
|
|
{
|
|
$data = $this->getData($reclamationId);
|
|
|
|
$data[$key] = $value;
|
|
|
|
sqlQueryBuilder()->update('reclamations')
|
|
->directValues(['data' => json_encode($data)])
|
|
->where(Operator::equals(['id' => $reclamationId]))
|
|
->execute();
|
|
|
|
return true;
|
|
}
|
|
|
|
public function getData(int $reclamationId, $key = null)
|
|
{
|
|
$data = sqlQueryBuilder()
|
|
->select('data')
|
|
->from('reclamations')
|
|
->where(Operator::equals(['id' => $reclamationId]))
|
|
->execute()->fetchColumn();
|
|
|
|
$data = json_decode($data ?? '', true) ?? [];
|
|
|
|
if ($key) {
|
|
return $data[$key] ?? null;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
public function getReclamation(int $reclamationId, bool $ordersSpecs = false)
|
|
{
|
|
$reclamation_qb = sqlQueryBuilder()->select('r.*, o.id as id_order, o.order_no, o.invoice_email as email')
|
|
->from('reclamations', 'r')
|
|
->leftJoin('r', 'order_items', 'oi', 'oi.id = r.id_item')
|
|
->leftJoin('oi', 'orders', 'o', 'o.id = oi.id_order')
|
|
->where(Operator::equals(['r.id' => $reclamationId]));
|
|
|
|
if ($ordersSpecs && !getAdminUser()) {
|
|
$reclamation_qb->andWhere($this->getOrdersSpec());
|
|
}
|
|
|
|
if ($reclamation = $reclamation_qb->execute()->fetch()) {
|
|
$reclamationEntity = new ReclamationEntity();
|
|
|
|
$delivery = [];
|
|
foreach ($reclamation as $key => $value) {
|
|
if (in_array($key, $this->getAddressFields())) {
|
|
$delivery[$key] = $value;
|
|
}
|
|
}
|
|
|
|
$order = new \Order();
|
|
$order->createFromDB($reclamation['id_order']);
|
|
|
|
$reclamationEntity->setId($reclamationId)
|
|
->setIdLanguage($order->getLanguage())
|
|
->setIdCurrency($order->getCurrency())
|
|
->setCode($reclamation['code'])
|
|
->setDateCreated($reclamation['date_created'])
|
|
->setDateAccepted($reclamation['date_accepted'])
|
|
->setDateHandle($reclamation['date_handle'])
|
|
->setStatus($reclamation['status'])
|
|
->setStatusName(
|
|
$this->getStatuses()[$reclamation['status']] ?? ''
|
|
)
|
|
->setHandleType($reclamation['handle_type'])
|
|
->setHandleTypeName(
|
|
$this->getHandleTypes()[$reclamation['handle_type']] ?? ''
|
|
)
|
|
->setPrefHandleType($reclamation['preferred_handle_type'])
|
|
->setPrefHandleTypeName(
|
|
$this->getPrefHandleTypes()[$reclamation['preferred_handle_type']] ?? ''
|
|
)
|
|
->setBankAccount($reclamation['bank_account'])
|
|
->setDescr($reclamation['descr'])
|
|
->setUserNote($reclamation['user_note'])
|
|
->setHistory(
|
|
$this->getHistory($reclamationId)
|
|
)
|
|
->setEmail($reclamation['email'])
|
|
->setAddress($delivery)
|
|
->setIdItem($reclamation['id_item'])
|
|
->setItem(
|
|
$this->getReclamationItem($reclamationId)
|
|
)
|
|
->setPieces($reclamation['pieces'])
|
|
->setIdOrder($reclamation['id_order'])
|
|
->setOrderNumber($reclamation['order_no'])
|
|
->setPackageId($reclamation['package_id'])
|
|
->setIdBalikonos($reclamation['id_balikonos'] ?? null)
|
|
->setData(
|
|
$this->getData($reclamationId)
|
|
);
|
|
|
|
return $reclamationEntity;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function getAddressFields(bool $requiresDeliveryAddress = true)
|
|
{
|
|
return array_merge(['name', 'surname', 'phone'],
|
|
$requiresDeliveryAddress
|
|
? ['street', 'city', 'zip', 'country']
|
|
: []
|
|
);
|
|
}
|
|
|
|
public function getReclamationItem(int $reclamationId)
|
|
{
|
|
$qb = sqlQueryBuilder()->select('oi.*, p.code, COALESCE(pv.ean, p.ean) AS ean, r.pieces, oi.piece_price*r.pieces as total_price')
|
|
->from('order_items', 'oi')
|
|
->leftJoin('oi', 'reclamations', 'r', 'r.id_item = oi.id')
|
|
->leftJoin('oi', 'products', 'p', 'p.id = oi.id_product')
|
|
->joinVariationsOnProducts()
|
|
->andWhere(Operator::equals(['r.id' => $reclamationId]))
|
|
->andWhere(Operator::equalsToOrNullable('oi.id_variation', 'pv.id'));
|
|
if (findModule('products_variations', 'variationCode')) {
|
|
$qb->addSelect('COALESCE(pv.code, p.code) AS `code`');
|
|
}
|
|
|
|
if (findModule(\Modules::PRODUCTS, \Modules::SUB_WEIGHT) && findModule(\Modules::PRODUCTS_VARIATIONS)) {
|
|
$qb->addSelect('COALESCE(pv.weight, p.weight) as weight');
|
|
} elseif (findModule(\Modules::PRODUCTS, \Modules::SUB_WEIGHT) && !findModule(\Modules::PRODUCTS_VARIATIONS)) {
|
|
$qb->addSelect('p.weight as weight');
|
|
}
|
|
|
|
$item = $qb->execute()->fetch();
|
|
|
|
return $item;
|
|
}
|
|
|
|
public function getStatuses(): array
|
|
{
|
|
return [
|
|
0 => translate_shop('status_0', 'reclamations'),
|
|
1 => translate_shop('status_1', 'reclamations'),
|
|
2 => translate_shop('status_2', 'reclamations'),
|
|
];
|
|
}
|
|
|
|
public function getHandleTypes(): array
|
|
{
|
|
return [
|
|
1 => translate_shop('handle_type_1', 'reclamations'),
|
|
0 => translate_shop('handle_type_0', 'reclamations'),
|
|
2 => translate_shop('handle_type_2', 'reclamations'),
|
|
3 => translate_shop('handle_type_3', 'reclamations'),
|
|
4 => translate_shop('handle_type_4', 'reclamations'),
|
|
];
|
|
}
|
|
|
|
public function getPrefHandleTypes(): array
|
|
{
|
|
return [
|
|
1 => translate_shop('handle_1', 'reclamations'),
|
|
2 => translate_shop('handle_2', 'reclamations'),
|
|
3 => translate_shop('handle_3', 'reclamations'),
|
|
4 => translate_shop('handle_4', 'reclamations'),
|
|
];
|
|
}
|
|
|
|
public function getEmailsInStatuses($entity = null): array
|
|
{
|
|
$handleEmail = 'RECLAMATION_HANDLE_EXCHANGE_EMAIL';
|
|
/** @var ReclamationEntity $entity */
|
|
if ($entity) {
|
|
switch ($entity->getHandleType()) {
|
|
case 0:
|
|
$handleEmail = 'RECLAMATION_HANDLE_EXCHANGE_EMAIL';
|
|
break;
|
|
case 1:
|
|
$handleEmail = 'RECLAMATION_HANDLE_FIX_EMAIL';
|
|
break;
|
|
case 2:
|
|
$handleEmail = 'RECLAMATION_HANDLE_RETURN_EMAIL';
|
|
break;
|
|
case 3:
|
|
$handleEmail = 'RECLAMATION_HANDLE_CANCEL_EMAIL';
|
|
break;
|
|
case 4:
|
|
$handleEmail = 'RECLAMATION_HANDLE_CONVERT_TO_RETURN_EMAIL';
|
|
break;
|
|
default:
|
|
throw new \RuntimeException('Invalid handle_type');
|
|
}
|
|
}
|
|
|
|
return [
|
|
self::STATUS_NEW => 'RECLAMATION_CREATE_EMAIL',
|
|
self::STATUS_ACCEPTED => 'RECLAMATION_ACCEPT_EMAIL',
|
|
self::STATUS_HANDLED => $handleEmail,
|
|
self::STATUS_HANDLED.'-0' => 'RECLAMATION_HANDLE_EXCHANGE_EMAIL',
|
|
self::STATUS_HANDLED.'-1' => 'RECLAMATION_HANDLE_FIX_EMAIL',
|
|
self::STATUS_HANDLED.'-2' => 'RECLAMATION_HANDLE_RETURN_EMAIL',
|
|
self::STATUS_HANDLED.'-3' => 'RECLAMATION_HANDLE_CANCEL_EMAIL',
|
|
self::STATUS_HANDLED.'-4' => 'RECLAMATION_HANDLE_CONVERT_TO_RETURN_EMAIL',
|
|
];
|
|
}
|
|
|
|
public function sendNotificationToOwner(ReclamationEntity $reclamation, string $email): void
|
|
{
|
|
$reclamationEmail = $reclamation->getEmail();
|
|
// Override reclamation email that is used as "to"
|
|
$reclamation->setEmail($email);
|
|
// Send email
|
|
$this->sendEmail($reclamation, ReclamationCreateAdminEmail::getType());
|
|
// Set original email back
|
|
$reclamation->setEmail($reclamationEmail);
|
|
}
|
|
|
|
public function getAcceptedStatuses(): array
|
|
{
|
|
return [self::STATUS_ACCEPTED];
|
|
}
|
|
|
|
public function getHandleStatuses(): array
|
|
{
|
|
return [self::STATUS_HANDLED];
|
|
}
|
|
|
|
public function getAuthCode(int $reclamationId)
|
|
{
|
|
if (!findModule(\Modules::RETURNS, \Modules::SUB_CP_AUTH_CODES)) {
|
|
return false;
|
|
}
|
|
|
|
$auth_code = $this->getData($reclamationId, 'auth_code');
|
|
|
|
if ($auth_code) {
|
|
return $auth_code;
|
|
}
|
|
|
|
if ($auth_code = $this->getNextAuthCode()) {
|
|
$this->setData($reclamationId, 'auth_code', $auth_code);
|
|
}
|
|
|
|
return $auth_code;
|
|
}
|
|
|
|
public function getSecurityCode(int $reclamationId)
|
|
{
|
|
$reclamationArr = sqlFetchAssoc(sqlQuery('SELECT
|
|
id, code, date_created
|
|
FROM '.getTableName('reclamations')."
|
|
WHERE id='{$reclamationId}'
|
|
LIMIT 1"));
|
|
|
|
$code = $reclamationArr['id'].'*'.$reclamationArr['code'].'*'.$reclamationArr['date_created'];
|
|
|
|
return md5($code);
|
|
}
|
|
|
|
public function getExpiredItemsSpec()
|
|
{
|
|
return function (QueryBuilder $qb) {
|
|
$dbcfg = \Settings::getDefault();
|
|
$qb->addSelect('COALESCE(o.date_delivered, o.date_handle, o.date_created) + INTERVAL COALESCE(NULLIF(p.guarantee, 0), :defaultGuarantee) MONTH + INTERVAL :dayGuarantee DAY < NOW() as expired')
|
|
->setParameter('dayGuarantee', $dbcfg->reclamations['days'] == '' ? 0 : $dbcfg->reclamations['days'])
|
|
->setParameter('defaultGuarantee', self::DEFAULT_GUARANTEE);
|
|
};
|
|
}
|
|
}
|