541 lines
20 KiB
PHP
541 lines
20 KiB
PHP
<?php
|
|
|
|
namespace KupShop\ReclamationsBundle\Admin;
|
|
|
|
use KupShop\AdminBundle\Admin\UserMessagesAdminInterface;
|
|
use KupShop\BalikonosBundle\Balikobot;
|
|
use KupShop\BalikonosBundle\Exception\BalikonosException;
|
|
use KupShop\KupShopBundle\Context\ContextManager;
|
|
use KupShop\KupShopBundle\Email\UserMessagesInterface;
|
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
|
use KupShop\OrderingBundle\Util\Order\QRPayment;
|
|
use KupShop\ReclamationsBundle\Attachment\ReclamationPDFAttachment;
|
|
use KupShop\ReclamationsBundle\Email\ReclamationMessageEmail;
|
|
use KupShop\ReclamationsBundle\Util\ReclamationsUtil;
|
|
use KupShop\ReclamationsSuppliersBundle\Util\ReclamationsSuppliersUtil;
|
|
use Query\Operator;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
|
|
class Reclamations extends \Window implements UserMessagesAdminInterface
|
|
{
|
|
protected $template = 'window/reclamations.tpl';
|
|
|
|
protected $nameField = 'code';
|
|
protected $tableName = 'reclamations';
|
|
|
|
/** @var ReclamationsUtil */
|
|
public $reclamations;
|
|
|
|
private $reclamation;
|
|
public $contextManager;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->reclamations = ServiceContainer::getService(ReclamationsUtil::class);
|
|
$this->contextManager = ServiceContainer::getService(ContextManager::class);
|
|
}
|
|
|
|
public function createSQLFields($tablename)
|
|
{
|
|
parent::createSQLFields($tablename);
|
|
|
|
foreach ($this->fields as $key => $field) {
|
|
if ($field == 'status') {
|
|
unset($this->fields[$key]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function get_vars()
|
|
{
|
|
if (empty($this->getID())) {
|
|
$this->action = 'add';
|
|
}
|
|
|
|
$vars = parent::get_vars();
|
|
|
|
if ($this->getAction() == 'edit') {
|
|
$order = $this->prepareOrder($vars['body']['data']['id_order']);
|
|
|
|
$diff = 0;
|
|
if ($order->date_handle) {
|
|
$diff = $order->date_handle->diff(new \DateTime());
|
|
$diff = abs($diff->days);
|
|
}
|
|
|
|
$vars['body']['order_date_diff'] = $diff;
|
|
$vars['body']['order'] = $order;
|
|
|
|
$this->contextManager->activateOrder($order, function () use (&$vars) {
|
|
$vars['body']['emails'] = $this->reclamations->getEmails($this->getReclamation());
|
|
$vars['body']['emailsInStatuses'] = $this->reclamations->getEmailsInStatuses($this->getReclamation());
|
|
});
|
|
|
|
$vars['body']['exchangeOrder'] = $this->getExchangeOrder();
|
|
$vars['body']['returnPrice'] = toDecimal($this->getReclamation()->getItem()['total_price'])->addVat($this->getReclamation()->getItem()['tax']);
|
|
$vars['body']['selected_delivery'] = $this->getDeliveryId();
|
|
|
|
$delivery = $this->getDelivery();
|
|
if ($delivery && isset($vars['body']['data']['data']['delivery_data'])) {
|
|
$delivery->loadDeliveryInfo($vars['body']['data']['data']['delivery_data']);
|
|
}
|
|
|
|
$vars['body']['delivery'] = $delivery;
|
|
|
|
if (findModule(\Modules::RECLAMATIONS_SUPPLIERS)) {
|
|
$vars['body']['supplierReclamation'] = sqlQueryBuilder()
|
|
->select('rs.id, rs.code, rs.id_supplier, rs.status, rs.date_created, rs.date_accepted, rs.date_handle')
|
|
->from('reclamations_suppliers_items', 'rsi')
|
|
->where(Operator::equals([
|
|
'id_reclamation' => $this->getID(),
|
|
]))->join('rsi', 'reclamations_suppliers', 'rs', 'rs.id = rsi.id_reclamation_supplier')
|
|
->execute()->fetchAssociative();
|
|
|
|
if (findModule(\Modules::PRODUCTS_SERIAL_NUMBERS)) {
|
|
$vars['body']['serialNumberSuppliers'] = sqlQueryBuilder()->select('si.id_supplier')->from('products_serial_numbers',
|
|
'psn')
|
|
->innerJoin('psn', 'stock_in', 'si', 'psn.id_stock_in = si.id')
|
|
->where(Operator::equals(['psn.id_order_item' => $vars['body']['data']['id_item']]))
|
|
->execute()->fetchFirstColumn();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($this->getAction() == 'add') {
|
|
$vars['body']['data']['id_order'] = getVal('id_order', null, '');
|
|
}
|
|
|
|
$vars['body']['statuses'] = $this->reclamations->getStatuses();
|
|
$vars['body']['handle_statuses'] = $this->reclamations->getHandleStatuses();
|
|
$vars['body']['handle_types'] = $this->reclamations->getHandleTypes();
|
|
$vars['body']['preferred_handle_types'] = $this->reclamations->getPrefHandleTypes();
|
|
$vars['body']['address_fields'] = $this->reclamations->getAddressFields();
|
|
|
|
$vars['body']['deliveries'] = \Delivery::getAll();
|
|
|
|
$fakeOrder = new \Order();
|
|
if (isset($vars['body']['data']['data']['delivery_data'])) {
|
|
$fakeOrder->note_admin = json_encode(['delivery_data' => $vars['body']['data']['data']['delivery_data']]);
|
|
}
|
|
|
|
$vars['body']['fakeOrder'] = $fakeOrder;
|
|
|
|
if (findModule(\Modules::PRODUCTS_SUPPLIERS) && $this->getAction() != 'add') {
|
|
$item = $this->getReclamation()->getItem();
|
|
$suppliersCodes = sqlQueryBuilder()->select('s.id, s.name, pos.code')
|
|
->from('products_of_suppliers', 'pos')
|
|
->leftJoin('pos', 'suppliers', 's', 's.id = pos.id_supplier')
|
|
->where(\Query\Operator::equalsNullable(['id_product' => $item['id_product'], 'id_variation' => $item['id_variation']]))
|
|
->execute()->fetchAll();
|
|
|
|
$vars['body']['suppliers_codes'] = $suppliersCodes;
|
|
}
|
|
|
|
return $vars;
|
|
}
|
|
|
|
public function getExchangeOrder()
|
|
{
|
|
$id = $this->getReclamation() === false
|
|
? null
|
|
: $this->getReclamation()->getData()['exchange_order'] ?? null;
|
|
|
|
if ($id) {
|
|
$order = $this->prepareOrder($id);
|
|
|
|
return $order;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function sendToBalikobot()
|
|
{
|
|
if (!findModule(\Modules::BALIKONOS)) {
|
|
return;
|
|
}
|
|
|
|
$balikobot = ServiceContainer::getService(Balikobot::class);
|
|
|
|
if ($this->getReclamation()->getIdBalikonos()) {
|
|
return;
|
|
}
|
|
|
|
$address = $this->getReclamation()->getAddress();
|
|
$deliveryId = $this->getDeliveryId();
|
|
$deliveries = \Delivery::getAll();
|
|
|
|
$delivery = $deliveries[$deliveryId] ?? null;
|
|
|
|
// do not send to balikobot if in person
|
|
if ($delivery && $delivery->isInPerson()) {
|
|
return;
|
|
}
|
|
|
|
$orderCls = new \Order();
|
|
$orderCls->currency = $this->getReclamation()->getIdCurrency();
|
|
$orderCls->note_admin = json_encode(['delivery_data' => $this->getReclamation()->getData()['delivery_data'] ?? []]);
|
|
|
|
$balikobot->setIDs([
|
|
0 => [
|
|
'type' => Balikobot::TYPE_RECLAMATION,
|
|
'invoice_email' => $this->getReclamation()->getEmail(),
|
|
'invoice_name' => $address['name'],
|
|
'invoice_surname' => $address['surname'],
|
|
'invoice_street' => $address['street'],
|
|
'invoice_city' => $address['city'],
|
|
'invoice_zip' => $address['zip'],
|
|
'invoice_country' => !empty($address['country']) ? $address['country'] : 'CZ',
|
|
'invoice_phone' => $address['phone'],
|
|
'total_price' => $this->getReclamation()->getItem()['total_price'],
|
|
'id_delivery' => $deliveryId,
|
|
'cod_price' => 0,
|
|
'order_id' => $this->getReclamation()->getCode(),
|
|
'order' => $orderCls,
|
|
'weight' => $this->getReclamation()->getItem()['weight'],
|
|
],
|
|
]);
|
|
|
|
$balikobot->sendDeliveries();
|
|
|
|
$result = $balikobot->getResult();
|
|
$result = reset($result);
|
|
|
|
if (!empty($result['error_message']) && $result['error_message'] != 'OK') {
|
|
$this->returnError('Chyba při odesílání do balíkobotu: '.$result['error_message']);
|
|
}
|
|
|
|
$this->updateSQL('reclamations', ['package_id' => $result['package_id'] ?? null, 'id_balikonos' => $result['id_balikonos'] ?? null], ['id' => $this->getID()]);
|
|
}
|
|
|
|
protected function getDeliveryId()
|
|
{
|
|
$dbcfg = \Settings::getDefault();
|
|
|
|
if ($this->getReclamation()) {
|
|
$delivery = $this->reclamations->getData($this->getReclamation()->getId(), 'delivery');
|
|
if (!empty($delivery)) {
|
|
return $delivery;
|
|
}
|
|
|
|
$order = $this->prepareOrder($this->getReclamation()->getIdOrder());
|
|
if ($order->getDeliveryType() && $order->getDeliveryType()->id_delivery != null) {
|
|
return $order->getDeliveryType()->id_delivery;
|
|
}
|
|
}
|
|
|
|
return $dbcfg->reclamations['delivery'] ?? null;
|
|
}
|
|
|
|
private function deleteFromBalikobot($package_id)
|
|
{
|
|
if (!findModule(\Modules::BALIKONOS)) {
|
|
return;
|
|
}
|
|
|
|
$balikobot = ServiceContainer::getService(Balikobot::class);
|
|
try {
|
|
$balikobot->deletePackage($package_id);
|
|
} catch (BalikonosException $e) {
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function getQRPayment()
|
|
{
|
|
$dbcfg = \Settings::getDefault();
|
|
|
|
$returnPrice = toDecimal($this->getReclamation()->getItem()['total_price'])->addVat($this->getReclamation()->getItem()['tax']);
|
|
|
|
$parameters = [
|
|
'amount' => $returnPrice->asFloat(),
|
|
'currency' => 'CZK',
|
|
'vs' => $this->getReclamation()->getCode(),
|
|
'message' => $dbcfg->shop_firm_name.' Reklamace '.$this->getReclamation()->getCode(),
|
|
];
|
|
|
|
/** @var QRPayment $QRPayment */
|
|
$QRPayment = ServiceContainer::getService(QRPayment::class);
|
|
|
|
$accountNumberParameters = $QRPayment->parseAccountNumber($this->getReclamation()->getBankAccount());
|
|
|
|
$parameters = array_merge($parameters, $accountNumberParameters);
|
|
|
|
return $QRPayment->getQRCodeImageUrl(
|
|
$this->prepareOrder($this->getReclamation()->getIdOrder()), 200, $parameters
|
|
);
|
|
}
|
|
|
|
public function handlePrintLabel()
|
|
{
|
|
if (!findModule(\Modules::BALIKONOS)) {
|
|
return;
|
|
}
|
|
|
|
$balikobot = ServiceContainer::getService(Balikobot::class);
|
|
|
|
if (empty($this->getReclamation()->getIdBalikonos())) {
|
|
$this->returnError('Štítek nelze vytisknout, protože reklamace není v balíkobotu! Zkuste reklamaci odeslat do balíkobotu znovu tím, že na detailu reklamace kliknete na tlačítko "OK"');
|
|
}
|
|
|
|
try {
|
|
$balikobot->printTickets(null, 1, 'default', [], false, [$this->getReclamation()->getIdBalikonos()]);
|
|
} catch (\KupShop\BalikonosBundle\Exception\BalikonosException $e) {
|
|
$this->returnError($e->getMessage());
|
|
}
|
|
}
|
|
|
|
public function handlePrintReclamation()
|
|
{
|
|
/** @var ReclamationPDFAttachment $reclamationAttachment */
|
|
$reclamationAttachment = ServiceContainer::getService(ReclamationPDFAttachment::class);
|
|
$reclamationAttachment->setReclamation($this->getReclamation());
|
|
$this->contextManager->activateContexts([\KupShop\KupShopBundle\Context\LanguageContext::class => $reclamationAttachment->getReclamation()['id_language']], function () use ($reclamationAttachment) {
|
|
header('Content-type: application/pdf');
|
|
header('Content-Disposition: inline; filename="'.$reclamationAttachment->getFilename().'"');
|
|
|
|
echo $reclamationAttachment->getContent();
|
|
});
|
|
}
|
|
|
|
public function handleSupplierReclamation()
|
|
{
|
|
/**
|
|
* @var $reclamationsSuppliersUtil ReclamationsSuppliersUtil
|
|
*/
|
|
$reclamationsSuppliersUtil = ServiceContainer::getService(ReclamationsSuppliersUtil::class);
|
|
|
|
$supplierId = getVal('supplierId');
|
|
$reclamation = $this->getReclamation();
|
|
|
|
$reclamationsSuppliersUtil->addItemFromReclamation($supplierId, $reclamation);
|
|
|
|
$this->returnOK('Produkt přidán do reklamace k dodavateli', false, ['supplierId' => null]);
|
|
}
|
|
|
|
public function handleUpdate()
|
|
{
|
|
$data = $this->getData();
|
|
|
|
if ($this->getAction() == 'add') {
|
|
$delivery = [];
|
|
foreach ($this->reclamations->getAddressFields() as $field) {
|
|
$delivery[$field] = getVal($field, $data);
|
|
}
|
|
|
|
if (empty($data['id_item'])) {
|
|
$this->returnError('Nevybrali jste položku!');
|
|
}
|
|
|
|
// todo: set pieces in admin
|
|
if (empty($data['pieces'])) {
|
|
$data['pieces'] = 1;
|
|
}
|
|
|
|
if ($id = $this->reclamations->createReclamation($data['id_item'], $data['pieces'], $delivery, $data['bank_account'], null, null, false)) {
|
|
$this->setID($id);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
} elseif ($this->getAction() == 'edit') {
|
|
if ($delivery = $this->getDelivery()) {
|
|
$data['data']['delivery_data'] = $delivery->storeDeliveryInfo($data['delivery_data'] ?? []);
|
|
|
|
// Update address from delivery
|
|
$delivery->applyToOrder($delivery_data, new \Order());
|
|
if ($delivery_data) {
|
|
foreach ($delivery_data as $field => $value) {
|
|
$this->processedData[str_replace('delivery_', '', $field)] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
$return = parent::handleUpdate();
|
|
|
|
// save data before sendToBalikobot call
|
|
if (!empty($data['data']) && is_array($data['data'])) {
|
|
foreach ($data['data'] as $key => $value) {
|
|
$this->reclamations->setData($this->getID(), $key, $value);
|
|
}
|
|
// Potřebuju dál pro balíkobota aktuální data, getReclamation vracelo zacachovanou verzi před updatem
|
|
$this->reclamation = $this->reclamations->getReclamation($this->getID());
|
|
}
|
|
|
|
$reclamation = $this->getReclamation();
|
|
if (!is_null($data['handle_type']) && in_array($data['handle_type'], $this->getPrintLabelHandleTypes())) {
|
|
$this->sendToBalikobot();
|
|
} elseif (!empty($reclamation->getIdBalikonos()) && $reclamation['status'] != 2) {
|
|
$this->deleteFromBalikobot($this->getReclamation()->getIdBalikonos());
|
|
}
|
|
|
|
$userContent = ServiceContainer::getService(\KupShop\OrderingBundle\Util\UserContent\UserContent::class);
|
|
if (($user_content = $userContent->getData('reclamation')) && $reclamation) {
|
|
$this->reclamations->setData($this->getID(), 'userContent',
|
|
array_merge($reclamation->getData()['userContent'] ?? [], $user_content)
|
|
);
|
|
$userContent->clearData('reclamation');
|
|
}
|
|
|
|
$sendEmail = (!isset($data['doNotNotify'])) ? null : false;
|
|
if (!empty($data['comment']) && !isset($data['doNotNotify'])) {
|
|
$sendEmail = true;
|
|
}
|
|
|
|
if ($data['handle_type'] != null) {
|
|
$data['status'] = ReclamationsUtil::STATUS_HANDLED;
|
|
}
|
|
|
|
if (isset($data['status'])) {
|
|
$this->reclamations->changeStatus($this->getID(), $data['status'], $data['comment'], $sendEmail, $data['user_message']);
|
|
}
|
|
|
|
if ($data['handle_type'] == '0' || $data['handle_type'] == '2' || $data['handle_type'] == '4') {
|
|
$this->handleConvertToReturn($data['comment'], $data['handle_type'] != '4');
|
|
}
|
|
|
|
return $return;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function getPrintLabelHandleTypes()
|
|
{
|
|
return [1, 3];
|
|
}
|
|
|
|
public function handleReopen()
|
|
{
|
|
$data = $this->getData();
|
|
if (empty($data['comment'])) {
|
|
$data['comment'] = null;
|
|
}
|
|
|
|
$this->reclamations->changeStatus($this->getID(), 1, 'Reklamace byla znovu otevřena', false);
|
|
$this->updateSQL('reclamations', [
|
|
'handle_type' => null,
|
|
'date_handle' => null,
|
|
'package_id' => null,
|
|
'id_balikonos' => null,
|
|
], ['id' => $this->getID()]);
|
|
|
|
$this->returnOK('Reklamace byla znovu otevřena');
|
|
}
|
|
|
|
public function handleConvertToReturn($comment, bool $isReclamation = true)
|
|
{
|
|
/** @var \KupShop\ReturnsBundle\Util\ReturnsUtil $returnsUtil */
|
|
$returnsUtil = ServiceContainer::getService(\KupShop\ReturnsBundle\Util\ReturnsUtil::class);
|
|
|
|
$reasons = array_keys($returnsUtil->getReasons());
|
|
$reasonId = end($reasons);
|
|
$item = ['pieces' => $this->getReclamation()->getPieces(), 'return_reason' => $reasonId];
|
|
|
|
$returnId = $returnsUtil->createReturn(
|
|
$this->getReclamation()->getBankAccount() ?: '',
|
|
[$this->getReclamation()->getIdItem() => $item],
|
|
[],
|
|
null,
|
|
false
|
|
);
|
|
|
|
$return = $returnsUtil->getReturn($returnId);
|
|
|
|
$returnMessage = 'Vratka byla vytvořena pro vyřízení reklamace č.';
|
|
if (!$isReclamation) {
|
|
$returnMessage = 'Vratka vytvořena na základě reklamace č.';
|
|
}
|
|
$returnsUtil->logHistory($returnId, $returnMessage." <a href=\"javascript:nw('Reclamations', {$this->getReclamation()->getId()})\">{$this->getReclamation()->getCode()}");
|
|
|
|
$this->reclamations->setData($this->getReclamation()->getId(), 'return', $returnId);
|
|
|
|
$reclamationMessage = 'Pro vyřízení reklamace byla vytvořena vratka č.';
|
|
if (!$isReclamation) {
|
|
$reclamationMessage = 'Na základě reklamace byla vytvořená vratka č.';
|
|
}
|
|
$this->reclamations->logHistory($this->getReclamation()->getId(), $reclamationMessage.' <a href="javascript:nw(\'Returns\', '.$returnId.')">'.$return->getCode().'</a>', false, '2');
|
|
|
|
$orderMessage = 'Pro vyřízení reklamace č.';
|
|
if (!$isReclamation) {
|
|
$orderMessage = 'Na základě reklamace č.';
|
|
}
|
|
$order = new \Order($this->getReclamation()->getIdOrder());
|
|
$order->createFromDB($this->getReclamation()->getIdOrder());
|
|
$order->logHistory($orderMessage.' '.$this->getReclamation()->getId().' byla vytvořena vratka č. <a href="javascript:nw(\'Returns\', '.$returnId.')">'.$return->getCode().'</a>');
|
|
|
|
$params = [
|
|
's' => 'Returns.php',
|
|
'acn' => 'edit',
|
|
'ID' => $returnId,
|
|
];
|
|
$this->redirect($params);
|
|
}
|
|
|
|
public function prepareOrder($orderId)
|
|
{
|
|
$order = new \Order();
|
|
$order->createFromDB($orderId);
|
|
|
|
return $order;
|
|
}
|
|
|
|
public function getData()
|
|
{
|
|
$data = parent::getData();
|
|
|
|
if (getVal('Submit') && (!$this->getID() || !$this->getReclamation()->isClosed())) {
|
|
if (empty($data['status'])) {
|
|
$data['status'] = 0;
|
|
}
|
|
|
|
$dates = ['date_created', 'date_accepted', 'date_handle'];
|
|
foreach ($dates as $date) {
|
|
if (!empty($data[$date])) {
|
|
$data[$date] = $this->prepareDateTime($data[$date]);
|
|
}
|
|
}
|
|
|
|
if (($data['handle_type'] ?? -1) < 0) {
|
|
$data['handle_type'] = null;
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
protected function getReclamation()
|
|
{
|
|
if (!$this->reclamation) {
|
|
$this->reclamation = $this->reclamations->getReclamation($this->getID());
|
|
}
|
|
|
|
return $this->reclamation;
|
|
}
|
|
|
|
protected function getObject()
|
|
{
|
|
$object = $this->getReclamation();
|
|
if (!$object) {
|
|
$errStr = sprintf(translate('errorNotFound', 'base'), $this->translateType(), $this->getID());
|
|
throw new NotFoundHttpException($errStr);
|
|
}
|
|
|
|
return $object;
|
|
}
|
|
|
|
protected function getDelivery()
|
|
{
|
|
return \Delivery::getAll()[$this->getDeliveryId()] ?? null;
|
|
}
|
|
|
|
public function getUserEmails(): UserMessagesInterface
|
|
{
|
|
return ServiceContainer::getService(ReclamationMessageEmail::class);
|
|
}
|
|
}
|
|
|
|
return Reclamations::class;
|