getID();
$acn = $this->getAction();
$this->contextManager = ServiceContainer::getService(\KupShop\KupShopBundle\Context\ContextManager::class);
$pageVars = getVal('body', $vars);
$pageVars['data']['total_price'] = toDecimal($pageVars['data']['total_price'] ?? 0);
if (!isset($Submit)) {
if ($acn == 'add') {
$pageVars['data']['status'] = 0;
$pageVars['data']['date_created'] = date('Y-m-d H:i:s');
$pageVars['data']['status_payed'] = 0;
$pageVars['data']['status_dispatch'] = 0;
$pageVars['data']['status_storno'] = 0;
}
}
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$order = new Order($ID);
if (!$order->createFromDB($ID)) {
// Set default contexts when order does not exists
$order->currency = $currencyContext->getDefaultId();
$order->id_language = ServiceContainer::getService(LanguageContext::class)->getDefaultId();
$order->delivery_country = ServiceContainer::getService(CountryContext::class)->getActiveId();
}
$currencyContext->activate($order->currency ?? $currencyContext->getDefaultId());
$pageVars['data']['domain'] = $this->contextManager->activateOrder($order, function () {
return Contexts::get(DomainContext::class)->getActiveWithScheme();
});
$pageVars['data']['complete_order'] = true;
if (!empty($ID)) {
$pageVars['data']['total_price_without_vat'] = toDecimal('0');
$qb = sqlQueryBuilder()
->select('oi.id, oi.id_product, oi.id_variation, oi.pieces, oi.piece_price, oi.total_price, oi.descr, oi.tax, oi.note as item_note, oi.discount,
COALESCE(pv.in_store, p.in_store) in_store, COALESCE(pv.ean, p.ean) ean')
->from('order_items', 'oi')
->leftJoin('oi', 'products', 'p', 'p.id=oi.id_product')
->leftJoin('p', 'products_variations', 'pv', 'pv.id=oi.id_variation')
->where(\Query\Operator::equals(['oi.id_order' => $ID]))
->orderBySql($this->getItemsOrdering());
if (findModule(Modules::PRODUCTS_VARIATIONS, Modules::SUB_CODE)) {
$qb->addSelect('COALESCE(pv.code, p.code) code');
} else {
$qb->addSelect('p.code code');
}
if (findModule(Modules::PRODUCTS, Modules::SUB_NOTE)) {
$qb->addSelect('COALESCE(pv.note, p.note) note_');
} else {
$qb->addSelect('\'\' as note_');
}
if (findModule(Modules::STORES)) {
$qb->andWhere(\KupShop\StoresBundle\Query\StoresQuery::addStoresInStoreAmounts());
$qb->groupBy('oi.id');
}
if (findModule(Modules::PRODUCTS, Modules::SUB_PRICE_BUY)) {
$qb->addSelect('oi.price_buy price_buy');
}
$oop = [];
foreach ($qb->execute() as $key => $item) {
$product = new Product($item['id_product']);
$item['ID'] = $item['id'];
$item['discount'] = toDecimal($item['discount']);
$item['Price'] = formatPrice($item['total_price'], $item['tax']);
$item['PiecePrice'] = formatPrice($item['piece_price'], $item['tax']);
$item['pieces'] = floatval($item['pieces']);
$item['in_store'] = floatval($item['in_store']);
$pageVars['data']['total_price_without_vat'] = $pageVars['data']['total_price_without_vat']->add(toDecimal($item['total_price']));
if (!empty($item['item_note'])) {
$item['custom_data'] = $product->parseNote($item['item_note']);
$item['item_note'] = $product->printNote($product->parseNote($item['item_note']));
}
if ($item['in_store'] < 0) {
if ($item['id_product']) {
// Currently ordered offset
$query = 'SELECT SUM(oi.pieces)
FROM '.getTableName('order_items').' oi
LEFT JOIN '.getTableName('orders').' o ON oi.id_order=o.id,
'.getTableName('orders')." o2
WHERE o2.id={$ID} AND o.date_created >= o2.date_created AND oi.id_product={$item['id_product']}
AND o.status_storno=0 AND o.id!={$ID} AND o.status IN (".join(',', getStatuses('active')).')';
if (!empty($item['id_variation'])) {
$query .= "AND oi.id_variation={$item['id_variation']}";
}
$item['piecesOrdered'] = returnSQLResult($query);
if (($item['piecesOrdered'] + $item['in_store']) < 0) {
$pageVars['data']['complete_order'] = false;
}
// Suppliers products
if (findModule('products_suppliers')) {
$query = 'SELECT SUM(in_store)
FROM '.getTableName('products_of_suppliers')." pos
WHERE pos.id_product={$item['id_product']}";
if (!empty($item['id_variation'])) {
$query .= " AND pos.id_variation={$item['id_variation']}";
}
$item['piecesInSuppliers'] = returnSQLResult($query);
}
}
}
if (!empty($item['id_product']) && empty($item['id_variation']) && $product->hasVariations()) {
$item['class'] = 'row-red';
$item['variation_title'] = '!Neexistujici varianta!';
}
$item['img'] = createScriptURL([
's' => 'redir',
'type' => 'productImage',
'id' => $item['id_product'],
'id_variation' => $item['id_variation'],
]);
if ($item['id_product'] && (findModule(Modules::PRODUCTS_SUPPLIERS) || findModule(Modules::ORDERS_OF_SUPPLIERS))) {
$query = 'SELECT pos.in_store, pos.code, s.order_url, s.name, pos.price_buy, v.vat
FROM '.getTableName('products_of_suppliers').' pos
LEFT JOIN '.getTableName('suppliers').' s ON pos.id_supplier = s.id
LEFT JOIN '.getTableName('products').' AS p ON pos.id_product=p.id
LEFT JOIN '.getTableName('vats')." AS v ON v.id=p.vat
WHERE pos.id_product={$item['id_product']}";
if (!empty($item['id_variation'])) {
$query .= " AND pos.id_variation={$item['id_variation']}";
}
$query .= ' ORDER BY s.id';
$item['suppliers'] = [];
foreach (sqlQuery($query) as $supplier) {
$item['suppliers'][] = $supplier;
}
}
if (findModule(Modules::STOCK_IN)) {
$sql = sqlQuery("SELECT sii.quantity as future_stock_in_pieces, sii.id_product, sii.id_variation, si.date_issued, s.name
FROM stock_in_items sii
JOIN stock_in si ON si.id = sii.id_stock_in AND si.id_index ='future'
LEFT JOIN suppliers s ON si.id_supplier=s.id
WHERE sii.id_product=:id_product AND ((sii.id_variation IS NULL AND :id_variation IS NULL) OR sii.id_variation=:id_variation)",
['id_product' => $item['id_product'], 'id_variation' => $item['id_variation']]);
foreach (sqlFetchAll($sql) as $stock_in) {
$diff = null;
if ($stock_in['date_issued']) {
$dateIssued = DateTime::createFromFormat('Y-m-d', $stock_in['date_issued']);
$diff = (new DateTime())->diff($dateIssued);
$diff = (int) $diff->format('%r%a');
}
$item['stock_in'][] = [
'future_stock_in_pieces' => $stock_in['future_stock_in_pieces'],
'date_issued' => $stock_in['date_issued'],
'name' => $stock_in['name'],
'stock_in_days' => $diff,
];
}
$sql = sqlQuery("SELECT sii.quantity as preorder_stock_in_pieces, sii.id_product, sii.id_variation, si.date_issued, s.name
FROM stock_in_items sii
JOIN stock_in si ON si.id = sii.id_stock_in AND si.id_index ='preorder'
LEFT JOIN suppliers s ON si.id_supplier=s.id
WHERE sii.id_product=:id_product AND ((sii.id_variation IS NULL AND :id_variation IS NULL) OR sii.id_variation=:id_variation)",
['id_product' => $item['id_product'], 'id_variation' => $item['id_variation']]);
foreach (sqlFetchAll($sql) as $stock_in) {
$diff = null;
if ($stock_in['date_issued']) {
$dateIssued = DateTime::createFromFormat('Y-m-d', $stock_in['date_issued']);
$diff = (new DateTime())->diff($dateIssued);
$diff = (int) $diff->format('%r%a');
}
$item['preorder_stock_in'][] = [
'preorder_stock_in_pieces' => $stock_in['preorder_stock_in_pieces'],
'date_issued' => $stock_in['date_issued'],
'name' => $stock_in['name'],
'stock_in_days' => $diff,
];
}
}
$oop[$key] = $item;
}
$pageVars['oop'] = $oop;
if (findModule('order_payment')) {
$pageVars['paid'] = toDecimal($order->getPayments());
}
if (!empty($pageVars['data']['invoice_email'])) {
$pageVars['multipleOrder'] = returnSQLResult('SELECT o.id FROM orders o WHERE o.id!=:id AND o.status IN (:statuses) AND o.invoice_email=:email',
['id' => $ID, 'statuses' => getStatuses('active'), 'email' => $pageVars['data']['invoice_email']],
['statuses' => \Doctrine\DBAL\Connection::PARAM_INT_ARRAY]);
}
$SQL = sqlQuery("SELECT oh.id_status, oh.comment, oh.notified, a.login, DATE_FORMAT(oh.date, '{$GLOBALS['dbcfg']['date_format']} {$GLOBALS['dbcfg']['time_format']}') as datef, custom_data
FROM ".getTableName('orders_history').' oh
LEFT JOIN'.getTableName('admins')." a ON oh.admin=a.id
WHERE oh.id_order='".$ID."'
ORDER BY oh.date ASC");
$pageVars['orders_history'] = sqlFetchAll($SQL);
$attachmentLocator = ServiceContainer::getService(AttachmentLocator::class);
foreach ($pageVars['orders_history'] as &$history) {
$sentAttachments = [];
if (!empty($history['custom_data'])) {
$customData = json_decode($history['custom_data'], true);
$history['custom_data'] = $customData;
if (isset($customData['initiator'])) {
$history['custom_data']['initiator'] = Initiator::from($customData['initiator']);
}
if (!empty($customData['attachments'])) {
foreach ($customData['attachments'] as $type) {
$sentAttachments[] = $attachmentLocator->getAttachments(EmailGroupTypeEnum::ORDER)[$type];
}
}
$history['attachments'] = join(', ', $sentAttachments);
}
}
$pageVars['attachments_types'] = json_encode($attachmentLocator->getAttachments(EmailGroupTypeEnum::ORDER));
$pageVars['attachments_urls'] = [];
if ($this->getID()) {
foreach ($attachmentLocator->getAttachments(EmailGroupTypeEnum::ORDER) as $type => $name) {
$pageVars['attachments_urls'][$type] = path('kupshop_admin_emailattachment_adminattachment',
['id_order' => $this->getID(), 'type' => $type]);
}
}
$pageVars['attachments_urls'] = json_encode($pageVars['attachments_urls']);
// User price level
if (findModule(Modules::PRICE_LEVELS)) {
if ($orderPriceLevel = $order->getOrderPriceLevel()) {
$pageVars['price_level'] = \KupShop\KupShopBundle\Wrapper\PriceLevelWrapper::wrap($orderPriceLevel);
}
}
$orderInfo = ServiceContainer::getService(OrderInfo::class);
$used_order_discounts = $orderInfo->getUsedDiscounts($order->id);
$pageVars['data']['used_order_discounts'] = $used_order_discounts;
$pageVars['data']['packages'] = $orderInfo->getPackages($order);
}
$pageVars['printSetOffer'] = [
'common' => [
'Prodejka' => 'Prodejky',
],
'products' => [
'product' => 'Štítky produktů',
],
];
$pageVars['userInfo'] = $order->getUser();
if (!$pageVars['userInfo']) {
$pageVars['userInfo'] = $this->selectSQL('users', ['email' => $order->getUserEmail()], ['id', 'note'])->fetch();
}
if ($order) {
$pageVars['custom_data'] = $order->getDataAll();
}
$pageVars['delivery_editable'] = true;
if ($deliveryType = $order->getDeliveryType()) {
$pageVars['delivery_editable'] = $deliveryType->getDelivery()->requiresDeliveryAddress();
if (($payment = $deliveryType->getPayment()) && $payment->getSelectedMethodId()) {
$contextManager = ServiceContainer::getService(ContextManager::class);
$pageVars['payment_method'] = $contextManager->activateOrder($order, function () use ($payment) {
$payment->loadConfig(Contexts::get(LanguageContext::class)->getActiveId());
return $payment->getSelectedMethod();
});
}
}
$pageVars['data']['flags_array'] = explodeFlags($pageVars['data']['flags']);
/** @var SMSSender $smsSender */
$smsSender = ServiceContainer::getService(SMSSender::class);
$pageVars['SMSSenderBackend'] = $smsSender->getBackend();
return array_merge($vars, [
'type' => 'orders',
'body' => $pageVars,
'order' => $order,
]);
}
public function getPrintAttachments()
{
$order = $this->prepareOrder();
$attachments = [];
$attachmentLocator = ServiceContainer::getService(AttachmentLocator::class);
foreach ($attachmentLocator->getAttachments(EmailGroupTypeEnum::ORDER) as $type => $name) {
if (($type == 'order_invoice') && findModule(Modules::ORDERS, Modules::SUB_INVOICES_FORBIDDEN)) {
continue;
}
$attachments[$type] = $name;
}
return $attachments;
}
public function getData()
{
global $cfg, $dbcfg;
$data = parent::getData();
$acn = $this->getAction();
$ID = $this->getID();
// kontrola hodnot
if (isset($data['date_created']) && empty($data['date_created'])) {
$data['date_created'] = date('d-m-Y H:i:s');
}
if (isset($data['status']) && !is_numeric($data['status'])) {
$data['status'] = 0;
}
if (isset($data['status_payed'])) {
$this->prepareBoolean($data['status_payed']);
}
if (isset($data['status_dispatch']) && !is_numeric($data['status_dispatch'])) {
$data['status_dispatch'] = 0;
}
if (isset($data['status_storno']) && !is_numeric($data['status_storno'])) {
$data['status_storno'] = 0;
}
if (isset($data['id_user']) && intval($data['id_user']) <= 0) {
$data['id_user'] = null;
}
if (!empty($data['date_created'])) {
$data['date_created'] = $this->prepareDateTime($data['date_created']);
}
if (!empty($data['date_handle'])) {
$data['date_handle'] = $this->prepareDateTime($data['date_handle']);
}
if (!empty($data['date_delivered'])) {
$data['date_delivered'] = $this->prepareDateTime($data['date_delivered']);
}
if (!empty($data['date_accept'])) {
$data['date_accept'] = $this->prepareDateTime($data['date_accept']);
}
if (!empty($data['date_due'])) {
$data['date_due'] = $this->prepareDateTime($data['date_due']);
}
if (!empty($cfg['Order']['Flags'])) {
$flags = getVal('flags', $data, []);
$flags = join(',', $flags);
$data['flags'] = $flags;
}
if (!empty($data['tab_selected'])) {
if ($data['tab_selected'] === 'retail') {
$data['invoice_name'] = translate('retailSale', 'orders', false, true);
}
}
if (!empty($data['id_user']) && (empty($data['invoice_name']) && empty($data['invoice_email']))) {
$this->injectUserData($data);
}
$delivers_fields = [
'delivery_name' => 'invoice_name',
'delivery_surname' => 'invoice_surname',
'delivery_firm' => 'invoice_firm',
'delivery_street' => 'invoice_street',
'delivery_city' => 'invoice_city',
'delivery_zip' => 'invoice_zip',
'delivery_country' => 'invoice_country',
'delivery_phone' => 'invoice_phone',
];
if (empty($data['delivery_name']) && empty($data['delivery_surname'])
&& empty($data['delivery_firm']) && empty($data['delivery_street'])
&& empty($data['delivery_city']) && empty($data['delivery_zip']) && empty($_GET['data']['invoice_name'])
) {
foreach ($delivers_fields as $delivery_fieldname => $invoice_fieldname) {
if (!empty($data[$invoice_fieldname])) {
$data[$delivery_fieldname] = $data[$invoice_fieldname];
}
}
}
// getData se volá víckrát, a potřebujeme zajistit že máme fakt původní objednávku vč. custom data
if (!$this->oldOrder && $ID) {
$this->oldOrder = new Order();
$this->oldOrder->createFromDB($ID);
$this->oldOrder->getDataAll();
}
if (!empty($data['delivery_data']) && $ID) {
$order = new Order();
$order->createFromDB($ID);
$delivery = $order->getDeliveryType()->getDelivery();
$pointData = $delivery->storeDeliveryInfo($data['delivery_data']);
$order->setData('delivery_data', $pointData);
try {
$delivery->applyToOrder($data, $order);
} catch (InvalidArgumentException $e) {
$this->returnError($e->getMessage());
}
}
if (!empty($data['delivery']) && !empty($data['payment'])) {
if ($deliveryTypeID = $this->selectSQL('delivery_type',
['id_delivery' => $data['delivery'], 'id_payment' => $data['payment']],
['id'])->fetchColumn()) {
$deliveryType = DeliveryType::get($deliveryTypeID, true);
$data['id_delivery'] = $deliveryTypeID;
$data['delivery_type'] = $deliveryType->name;
}
} elseif (($data['delivery'] ?? false) === '0' && ($data['payment'] ?? false) === '0') {
$data['id_delivery'] = null;
$data['delivery_type'] = '';
}
if (getVal('Submit') && $acn == 'add') {
$data['order_no'] = '_999999'; // .rand(0, 999999);
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$allCurrencies = $currencyContext->getAll();
if (findModule('currencies') && isset($data['currency']) && isset($allCurrencies[$data['currency']])) {
$data['currency_rate'] = $allCurrencies[$data['currency']]->getRate();
}
$countryContext = Contexts::get(CountryContext::class);
if (!$data['delivery_country']) {
$data['delivery_country'] = $countryContext->getDefaultId();
}
if (!$data['invoice_country']) {
$data['invoice_country'] = $countryContext->getDefaultId();
}
}
return $data;
}
public function injectUserData(&$data)
{
$userFields = array_merge([
'ico' => 'invoice_ico',
'dic' => 'invoice_dic',
'email' => 'invoice_email',
'currency' => 'currency',
'id_language' => 'id_language',
],
Mapping::mapKeys(User::getFields(), function ($_, $x) {
return [$x, "invoice_{$x}"];
}),
Mapping::mapKeys(User::getFields(), function ($_, $x) {
return ["delivery_{$x}", "delivery_{$x}"];
})
);
$user = sqlQueryBuilder()
->select('*')
->from('users')
->where(Operator::equals(['id' => $data['id_user']]))
->execute()->fetchAssociative();
if (!$user) {
return false;
}
foreach ($user as $key => $field) {
if (!empty($field) && isset($userFields[$key])) {
$data[$userFields[$key]] = $field;
}
}
if (!empty($user['prefer_transport']) && empty($data['delivery']) && empty($data['payment'])) {
$deliveryType = DeliveryType::get($user['prefer_transport'], true);
$data['delivery'] = $deliveryType->id_delivery;
$data['payment'] = $deliveryType->id_payment;
}
return true;
}
public function handleUpdate()
{
$ID = $this->getID();
$acn = $this->getAction();
$data = $this->getData();
// kontrola jestli objednavka nebyla stornovana
$storno = ReturnSQLResult('SELECT status_storno
FROM '.getTableName('orders')."
WHERE id='{$ID}'");
if (intval($storno) == 1 && !$this->isDuplicate()) {
// Stornovanou objednávku již nelze upravovat
$this->returnError(getTextString('orders', 'errorCanceledCantEdit'));
}
if ($this->isDuplicate()) {
$OLD_ID = $ID;
$data['order_no'] = '';
}
$error = 0;
if (empty($error)) {
$order = new Order();
if ($acn == 'edit') {
$order->createFromDB($ID);
}
$SQL = parent::handleUpdate();
if ($SQL) {
if ($acn == 'add') {
$ID = $this->getID();
// set date created
sqlQueryBuilder()
->update('orders')
->set('date_created', 'NOW()')
->set('source', ':source')
->setParameter('source', OrderInfo::ORDER_SOURCE_ADMIN)
->where(Operator::equals(['id' => $ID]))
->execute();
$order->createFromDB($ID);
if (!empty($data['id_invoice'])) {
$order->setData('id_invoice', $data['id_invoice']);
}
// dispatch order created event - order no is generated in event subscriber
$this->getEventDispatcher()->dispatch(new OrderEvent($order), OrderEvent::ORDER_CREATED);
addActivityLog(
ActivityLog::SEVERITY_NOTICE,
ActivityLog::TYPE_CHANGE,
sprintf(getTextString('orders', 'activityAdded'), $order->order_no)
);
if ($this->isDuplicate()) {
$old_order = new Order();
$old_order->createFromDB($OLD_ID);
$manager = ServiceContainer::getService(ContextManager::class);
$manager->activateOrder($order, function () use ($order, $old_order) {
$fields = [
'date_accept' => null,
'date_handle' => null,
];
if (findModule('currencies')) {
$fields['currency'] = $old_order->currency;
$fields['currency_rate'] = $old_order->currency_rate;
}
if (findModule(Modules::TRANSLATIONS)) {
$fields['id_language'] = $old_order->id_language;
}
try {
$order->copyItems($old_order, false, dispatchEvent: true);
} catch (\Exception $e) {
$this->addError($e->getMessage());
}
$this->updateSQL('orders', $fields, ['id' => $order->id]);
if ($deliveryData = $old_order->getData('delivery_data')) {
$order->setData('delivery_data', $deliveryData);
}
if ($paymentData = $old_order->getData('payment_data')) {
$order->setData('payment_data', $paymentData);
}
$event = new OrderEvent($order);
$this->getEventDispatcher()->dispatch($event, OrderEvent::ORDER_COMPLETE);
});
}
$order->status = -1;
} elseif ($acn == 'edit') {
$event = new OrderEvent($order);
$this->getEventDispatcher()->dispatch($event, OrderEvent::ORDER_EDITED);
addActivityLog(ActivityLog::SEVERITY_NOTICE, ActivityLog::TYPE_CHANGE,
sprintf(getTextString('orders', 'activityEdited'), $data['order_no']),
data: ActivityLog::addObjectData([$order->id => $order->order_no], 'orders')
);
if ($order->id_delivery != ($data['id_delivery'] ?? false) || ($this->oldOrder !== null && $this->oldOrder->getData('delivery_data', false) != $data['delivery_data'])) {
$order->setData('delivery_data_old', $this->oldOrder->getData('delivery_data', false));
$event = new OrderEvent($order);
$this->getEventDispatcher()->dispatch($event, OrderEvent::ORDER_DELIVERY_CHANGED);
}
}
foreach ($data['custom_data'] ?? [] as $key => $value) {
$order->setData($key, $value);
}
$smsService = ServiceContainer::getService(SMSSender::class);
if ($smsService->getBackend() && !empty($data['send_telfa_sms'])) {
if (empty($data['invoice_phone'])) {
$this->returnError('Není vyplněno telefonní číslo příjemce sms!');
}
if (empty($data['comments'])) {
$this->returnError('Neodesláno - prázdná zpráva!');
}
$order = new Order($ID);
$order->createFromArray($data);
$message = $order->replacePlaceholders($data['comments']);
$res = $smsService->getBackend()->sendSMS($data['invoice_phone'], strip_tags($message));
if ($res !== true) {
$this->returnError('SMS se nepodařilo odeslat');
}
$smsService->saveSMStoOrder($ID, 'Na tel. '.$data['invoice_phone'].': '.$message, 2, $order->status);
$this->returnOK('SMS odeslána.');
}
// Custom data
$this->saveCustomOrderData($data['data'] ?? []);
// Change order status
$force = null;
$data['comments'] = trim($data['comments'] ?? '');
if ($data['comments'] != '') {
$force = true;
}
if (!empty($data['doNotNotify']) || $acn == 'add') {
$force = false;
}
$order->changeStatus($data['status'], $data['comments'], $force, $data['status_comment']);
if ($this->getErrors()) {
$this->returnError($this->getErrors()[0], true);
}
$this->returnOK(null, true);
} else {
$this->returnError($GLOBALS['txt_str']['status']['scripterror']);
}
}
}
public function saveCustomOrderData($data)
{
$order = $this->prepareOrder();
if (!empty($data)) {
foreach ($data as $key => $value) {
$order->setData($key, $value);
}
}
}
public function handleDelete()
{
$ID = $this->getID();
if (!findRight('ORDER')) {
redirect('launch.php?s=error.php&id=1');
}
try {
sqlGetConnection()->transactional(function () use ($ID) {
$SQL = sqlQuery(
'SELECT order_no
FROM '.getTableName('orders')."
WHERE id='".$ID."' "
);
$order = sqlFetchArray($SQL);
sqlFreeResult($SQL);
writeDownActivity(sprintf(getTextString('orders', 'activityDeleted'), $order['order_no']));
$SQL = sqlQuery(
'SELECT id_product, id_variation, pieces
FROM '.getTableName('order_items')."
WHERE id_order='".$ID."' AND id_product<>0 "
);
while (($row = sqlFetchArray($SQL)) !== false) {
$prod = new Product($row['id_product']);
$prod->sell($row['id_variation'], -$row['pieces']);
}
// ##########################################################
// smazat polozky objednavky
sqlQuery('DELETE FROM '.getTableName('order_items')." WHERE id_order='{$ID}' ");
// smazat objednavku
sqlQuery('DELETE FROM '.getTableName('orders')." WHERE id='{$ID}' ");
return;
});
redirect('launch.php?s=orders.php&acn=erased');
} catch (Exception $e) {
if (strpos($e->getMessage(), 'return_items') !== false) {
$this->returnError(translate('returnedItemsDeleteOrder'));
}
getRaven()->captureException($e);
}
}
protected function getEventDispatcher(): EventDispatcherInterface
{
static $eventDispatcher;
if (!$eventDispatcher) {
$eventDispatcher = ServiceContainer::getService('event_dispatcher');
}
return $eventDispatcher;
}
protected function sendToBalikobot()
{
$data = $this->getData();
$this->saveCustomOrderData($data['data'] ?? []);
$balikobot = ServiceContainer::getService(\KupShop\BalikonosBundle\Balikobot::class);
$order = $this->prepareOrder();
$data = $order->getData('balikobot');
try {
if ($balikobot->hasMultipleCollectionPlaces() && !empty($data['user'])) {
$balikobot->setCredentialsByName($data['user']);
}
$IDs[$this->getID()] = [
'packages' => $data['packages'] ?? 1,
'note' => $data['note'] ?? null,
'size' => $data['size'] ?? null,
];
$balikobot->setIDs($IDs);
$balikobot->sendDeliveries();
} catch (BalikonosException $e) {
$this->returnError($e->getMessage());
}
return $balikobot;
}
public function handlePrintTicket()
{
try {
$balikobot = $this->sendToBalikobot();
if ($error = $balikobot->getError()) {
$this->returnError($error);
} else {
$balikobot->printTickets(null, $this->getData()['data']['balikobot']['position'] ?? '1', '', [$this->getID()]);
}
} catch (BalikonosException $e) {
$this->returnError($e->getMessage());
}
}
public function handlePrintExistingTicket()
{
try {
$data = $this->getData();
$this->saveCustomOrderData($data['data'] ?? []);
$balikobot = ServiceContainer::getService(\KupShop\BalikonosBundle\Balikobot::class);
$balikobot->printTickets(null, $data['data']['balikobot']['position'] ?? '1', '', [$this->getID()]);
} catch (BalikonosException $e) {
$this->returnError($e->getMessage());
}
}
public function handleSendToBalikobot()
{
$balikobot = $this->sendToBalikobot();
if ($error = $balikobot->getError()) {
$this->returnError($error);
} else {
$this->logBalikobotResult('Ručně nahráno do Balíkobota', $this->prepareOrder(), $balikobot);
$this->returnOK('Úspěšně nahráno do Balíkobota');
}
}
public function handleDeleteFromBalikobot()
{
$balikobot = ServiceContainer::getService(\KupShop\BalikonosBundle\Balikobot::class);
try {
foreach ($this->getBalikobot() as $item) {
if ($item['close'] != 2) {
$balikobot->deletePackage($item['id'] ?? null);
}
}
$this->logBalikobotResult('Ručně odebráno z Balíkobota', $this->prepareOrder(), $balikobot);
$this->returnOK('Úspěšně odebráno z Balíkobota');
} catch (BalikonosException $e) {
$this->returnError($e->getMessage());
}
}
private function logBalikobotResult(string $message, Order $order, KupShop\BalikonosBundle\Balikobot $balikobot): void
{
$error = $balikobot->getError();
if ($error) {
$this->returnError($error);
}
$result = $balikobot->getResult();
$result = $result[0] ?? [];
$id = $result['id_balikonos'] ?? '';
$packages = implode(', ', $result['package_ids'] ?? []);
$packageCount = count($result['package_ids'] ?? []);
$order->logHistory("{$message}. Balíky ({$packageCount}): {$packages}, ID: {$id}");
}
public function getBalikobot()
{
return sqlQueryBuilder()->select('*')->from('balikonos')
->where(\Query\Operator::equals(['id_order' => $this->getID()]))
->orderBy('close', 'ASC')
->execute()->fetchAllAssociative();
}
public function changeDelivery($id_delivery, $id_order = null)
{
$order = $this->prepareOrder($id_order);
/** @var \KupShop\OrderingBundle\OrderDelivery $orderDelivery */
$orderDelivery = ServiceContainer::getService(\KupShop\OrderingBundle\OrderDelivery::class);
try {
$result = $orderDelivery->recalculateDelivery($order, $id_delivery);
if ($result) {
return true;
}
} catch (\KupShop\OrderingBundle\Exception\DeliveryException $e) {
$this->returnError($e->getMessage());
}
return false;
}
public function handleChangeCurrency()
{
sqlGetConnection()->transactional(function () {
sqlQueryBuilder()->select('currency')->from('orders')->where(Operator::equals(['id' => $this->getID()]))->forUpdate()->execute();
$order = $this->prepareOrder();
$id_currency = getVal('id_currency');
if ($order->currency == $id_currency) {
$this->returnOK('Ok', false);
}
$orderCurrencyConverter = ServiceContainer::getService(\KupShop\OrderingBundle\Util\Order\OrderCurrencyConverter::class);
return $orderCurrencyConverter->changeOrderCurrency($order, $id_currency);
}) ? $this->returnOK() : $this->returnOK('Nepodařilo se changeOrderCurrency.');
}
public function handleMerge()
{
$ID = $this->getID();
$newID = getVal('id_merge');
if (empty($newID)) {
$this->returnError('Nezadáno číslo objednávky');
}
$order_old = $this->prepareOrder($ID);
$order_new = $this->prepareOrder($newID);
$this->mergeOrders($order_old, $order_new);
$ErrStr = "Položky objednávky {$order_old->order_no} byly přesunuty do objednávky {$order_new->order_no}. Objednávka {$order_old->order_no} byla stornována.";
$this->setID($newID);
$this->returnOK($ErrStr);
}
/**
* @param $order_old Order
* @param $order_new Order
*
* @return bool
*/
public function mergeOrders($order_old, $order_new)
{
$ID = $order_old->id;
$newID = $order_new->id;
$event = new OrderMergeEvent($order_old, $order_new);
$event_result = $this->getEventDispatcher()->dispatch($event, OrderMergeEvent::BEFORE_MERGE);
if ($error = $event_result->getError()) {
$this->returnError($error['message'] ?? 'Objednávky nelze sloučit!');
}
$manager = ServiceContainer::getService(ContextManager::class);
$manager->activateOrder($order_old, function () use ($newID, $ID) {
$merged_items = sqlQueryBuilder()->select("GROUP_CONCAT(CONCAT('
', pieces, ' x ', descr)) as items")->from('order_items')->where(\Query\Operator::equals(['id_order' => $ID]))->execute()->fetch()['items'];
sqlQueryBuilder()->update('order_items')->set('id_order',
$newID)->where(\Query\Operator::equals(['id_order' => $ID]))->execute();
if (findModule(\Modules::ORDER_DISCOUNT)) {
sqlQueryBuilder()->update('discounts_coupons')->set('id_order_used',
$newID)->where(\Query\Operator::equals(['id_order_used' => $ID]))->execute();
sqlQueryBuilder()->update('discounts_coupons')->set('id_order_purchased',
$newID)->where(\Query\Operator::equals(['id_order_purchased' => $ID]))->execute();
}
if (findModule(Modules::EET)) {
sqlQueryBuilder()->update('eet_sent_payment')->set('id_order',
$newID)->where(\Query\Operator::equals(['id_order' => $ID]))->execute();
}
$order_old = $this->prepareOrder($ID);
$order_new = $this->prepareOrder($newID);
// Stornuje se az niz, ale v ramci recalculate se zavola ORDER_PAID eventa a vygeneruje se faktura i pro tu nestornovanou, coz je blbe.
$order_old->status_storno = 1;
$order_old->recalculate(true);
$order_new->recalculate(true);
$payments = $order_old->getPaymentsArray();
foreach ($payments as $payment) {
$order_new->updateSQL('order_payments', ['id_order' => $newID], ['id' => $payment['id']]);
}
$order_old->updatePayments();
$order_new->updatePayments();
$comment = sprintf(translate_shop('mergeSuccessComment', 'order_msg'), $order_new->order_no);
$order_old->storno(false, null, false); // don't send ORDER_STORNO email (customerNotified = false)
// send ORDER_COMMENT email
$order_old->sendEmail($comment, null, false, \KupShop\KupShopBundle\Email\OrderEmail::getType()); // type=ORDER_COMMENT
$comment = "Přidány položky objednávky {$order_old->order_no}:".$merged_items;
$comment .= ".
Objednávka {$order_old->order_no} byla stornována.";
$order_new->logHistory($comment, false);
});
return true;
}
public function getDeliveryList()
{
$order = $this->prepareOrder();
if ($order->id !== null) {
$contextManager = ServiceContainer::getService(ContextManager::class);
return $contextManager->activateOrder($order, function () {
return DeliveryType::getDeliveries(true);
});
}
return [];
}
public function getPaymentList()
{
$order = $this->prepareOrder();
if ($order->id !== null) {
$contextManager = ServiceContainer::getService(ContextManager::class);
return $contextManager->activateOrder($order, function () {
return DeliveryType::getPayments(true);
});
}
return [];
}
public function getValidDeliveryTypes()
{
$deliveryTypes = DeliveryType::getAll(true);
$return = [];
$return['0-0'] = true;
foreach ($deliveryTypes as $deliveryType) {
$return[$deliveryType->id_delivery.'-'.$deliveryType->id_payment] = true;
}
return $return;
}
public function handleRefreshDeliveryType()
{
$data = $this->getData();
// save old delivery data to database - needed for correct delivery type/store change
if ($this->oldOrder !== null && ($oldData = $this->oldOrder->getData('delivery_data', false))) {
$this->oldOrder->setData('delivery_data_old', $oldData);
}
if (!empty($data['id_delivery'])) {
$this->changeDelivery($data['id_delivery']);
}
$this->forceUpdate();
}
public function getDeliveryTypeList($totalPrice)
{
$order = $this->prepareOrder();
if ($order->id !== null) {
$contextManager = ServiceContainer::getService(ContextManager::class);
return $contextManager->activateOrder(
$order,
function () use ($totalPrice) {
return Order::getDeliveryTypeList($totalPrice, false, 0, true);
}
);
}
return [];
}
public function handleSendMail()
{
$order = $this->prepareOrder();
if (in_array($order->status, getStatuses('handled'))) {
$comment = sprintf(translate('commentSendInvoice', 'orders'), $order['order_no']);
$log_comment = translate('activityInvoiceEmailSent', 'orders');
} else {
$comment = sprintf(translate('commentSendRecap', 'orders'), $order['order_no']);
$log_comment = translate('activityRecapEmailSent', 'orders');
}
$order->logChange($log_comment, true);
$order->sendEmail($comment, null, true, \KupShop\KupShopBundle\Email\OrderEmail::getType()); // type=ORDER_COMMENT
$this->returnOK('Email odeslán');
}
public function handleAddUserNote()
{
$order = $this->prepareOrder();
$note = getVal('note', null, '');
$userId = $order->id_user;
if (empty($userId)) {
$userId = $this->selectSQL('users', ['email' => $order->getUserEmail()], ['id'])->fetchColumn();
if (empty($userId)) {
$userId = addUserEmail($order->getUserEmail());
}
}
if (empty($userId)) {
throw new RuntimeException('Cannot add user note! $userId is empty');
}
$this->updateSQL('users', ['note' => $note], ['id' => $userId]);
$this->returnOK('K uživateli byla přidána poznámka.');
}
public function prepareOrder($ID = null)
{
if (!$ID) {
$ID = $this->getID();
}
$order = new Order();
$order->createFromDB($ID);
return $order;
}
public function handlePayOrder()
{
$order = $this->prepareOrder();
$contextManager = ServiceContainer::getService(ContextManager::class);
$contextManager->activateOrder($order, function () use ($order) {
$delivery_type = $order->getDeliveryType($order->getDeliveryId());
$pay_method = $delivery_type?->payment_class?->getPayMethod() ?: 0;
$remaining_payment = $order->getRemainingPayment();
if (!$order->isActive()) {
$this->returnOK('Stornována objednávka');
}
if ($order->isPaid()) {
$this->returnOK('Již zaplaceno');
}
$title = 'Zaplaceno z administrace eshopu';
if ($remaining_payment < 0) {
$title = 'Vrácení částky: objednávka '.$order->order_no;
}
$newId = $order->insertPayment($remaining_payment, $title, null, true, $pay_method);
if (($remaining_payment < 0) && ($payment_class = $delivery_type->payment_class ?? null)
&& $payment_class->enabledReturnPayment()) {
try {
$payment_class->loadConfig($order->getLanguage());
$payment_class->setOrder($order);
$result = $payment_class->returnPayment($remaining_payment, null, $newId);
$message = translate('returnSucceed', 'orderPayment');
addActivityLog(ActivityLog::SEVERITY_SUCCESS, ActivityLog::TYPE_COMMUNICATION, $message,
['amount' => $remaining_payment, 'order_id' => $order->id, 'result' => $result]);
$result['paymentClass'] = $payment_class->class;
$result['session'] = ($result['id'] ?? '').'_'.$newId;
$this->updateSQL('order_payments', ['payment_data' => json_encode($result)], ['id' => $newId]);
$this->returnOK($message);
} catch (PaymentException $e) {
$this->deleteSQL('order_payments', ['id' => $newId]);
if ($e->getShortMessage() == 'Adyen') {
// the refund request was successfully received by Adyen - no result yet,
// because you receive the outcome of the refund request asynchronously, in a REFUND webhook.
addActivityLog(ActivityLog::SEVERITY_SUCCESS, ActivityLog::TYPE_COMMUNICATION, $e->getMessage(),
['amount' => $remaining_payment, 'order_id' => $order->id]);
$this->returnOK($e->getMessage());
}
$this->returnError($e->getMessage());
}
}
});
$this->returnOK();
}
public function handleCopyUserData()
{
$order_data = $this->getData();
if (!empty($order_data['id_user'])) {
$data = $this->getUserData($order_data['id_user']);
if ($data) {
$this->updateSQL('orders', $data, ['id' => $this->getID()]);
} else {
$this->returnError('Vyskytla se chyba.');
}
}
$this->returnOK('Aktualizováno');
}
public function handleGenerateInvoiceNo()
{
if (!findRight('ORDER_INVOICE')) {
redirect('launch.php?s=error.php&id=1');
}
$order = $this->prepareOrder();
if (!$order->isActive()) {
$this->returnError('Stornovaná objednávka');
}
if ($invoice_no = $order->generateInvoiceNo()) {
$order->logHistory("Ručně vygenována faktura {$invoice_no} k objednávce.");
$this->returnOK('Objednávce vytvořena faktura '.$invoice_no);
}
}
private function getUserData($id_user)
{
$SQL = $this->selectSQL('users', ['id' => $id_user])->fetchAll();
if (count($SQL) == 1) {
$user = $SQL[0];
$fields = ['name' => 'invoice_name',
'id' => 'id_user',
'surname' => 'invoice_surname',
'firm' => 'invoice_firm',
'ico' => 'invoice_ico',
'dic' => 'invoice_dic',
'street' => 'invoice_street',
'city' => 'invoice_city',
'zip' => 'invoice_zip',
'country' => 'invoice_country',
'state' => 'invoice_state',
'custom_address' => 'invoice_custom_address',
'phone' => 'invoice_phone',
'email' => 'invoice_email',
'delivery_name' => 'delivery_name',
'delivery_surname' => 'delivery_surname',
'delivery_firm' => 'delivery_firm',
'delivery_street' => 'delivery_street',
'delivery_city' => 'delivery_city',
'delivery_zip' => 'delivery_zip',
'delivery_country' => 'delivery_country',
'delivery_state' => 'delivery_state',
'delivery_custom_address' => 'delivery_custom_address',
'delivery_phone' => 'delivery_phone',
];
$data = [];
foreach ($user as $key => $field) {
if (!empty($field) && isset($fields[$key])) {
$data[$fields[$key]] = $field;
}
}
return $data;
} else {
return false;
}
}
public function getEmail()
{
/* @var OrderMessageEmail $email */
return ServiceContainer::getService(OrderMessageEmail::class);
}
public function hasRights($name = null)
{
switch ($name) {
case Window::RIGHT_DELETE:
return findRight('ORDER_ERASE');
default:
return parent::hasRights($name);
}
}
protected function getObject()
{
$object = parent::getObject(); // muze vyhodit NotFoundHttpException v pripade spatneho ID
if (findRight('ORDERS_RESTRICTION') && $this->getID()) {
$qb = sqlQueryBuilder()
->select('o.id')
->from('orders', 'o')
->where(Operator::equals(['o.id' => $this->getID()]));
$ordersFilterSpec = ServiceContainer::getService(OrdersFilterSpecs::class);
if ($specs = $ordersFilterSpec->getSpecs(getAdminUser()['data']['ordersRestrictionFilter'] ?? [])) {
$qb->andWhere($specs);
}
// pokud se mi nepodari nacist objednavku, tak nemam prava na jeji zobrazeni a nebo neexistuje, tak hodim 404
if (!$qb->execute()->fetchOne()) {
throw new AccessDeniedException(translate('orderNotFound', 'orders'));
}
}
return $object;
}
public function getUserEmails(): UserMessagesInterface
{
return ServiceContainer::getService(OrderMessageEmail::class);
}
}