'code', 'direction' => 'DESC', ]; protected $tableName = 'orders'; protected ?string $tableAlias = 'o'; protected bool $useLazyNumberOfPages = true; protected $showMassEdit = true; protected $tableDef = [ 'id' => 'o.id', 'fields' => [ 'code' => ['translate' => true, 'field' => 'o.id', 'render' => 'renderCode', 'type' => 'orders', 'size' => 0.7], 'source' => ['translate' => true, 'field' => 'o.source', 'spec' => 'o.source', 'render' => 'renderOrderSource', 'visible' => 'N'], 'customer' => ['translate' => true, 'field' => 'o.invoice_name', 'raw_field' => 'IF(o.invoice_firm != "", o.invoice_firm, o.invoice_surname)', 'render' => 'renderName', 'size' => 1.5, 'spec' => 'o.invoice_name'], 'status' => ['translate' => true, 'field' => 'o.status', 'render' => 'renderStatus', 'size' => 1, 'spec' => 'o.status', 'fieldType' => OrdersList::TYPE_LIST], 'orderItems' => ['translate' => true, 'field' => 'items', 'render' => 'renderItems', 'class' => 'left tiny-list-items', 'size' => 2, 'visible' => 'N'], 'price' => ['translate' => true, 'field' => 'o.total_price', 'render' => 'renderPrice', 'class' => 'text-right alignRight', 'size' => 1, 'headerRender' => 'renderHeaderPrice', 'spec' => 'o.total_price', 'editable' => 'N', 'fieldType' => BaseList::TYPE_PRICE], 'priceWithoutVat' => ['translate' => true, 'field' => 'o.total_price_without_vat', 'render' => 'renderPrice', 'class' => 'text-right alignRight', 'size' => 1, 'headerRender' => 'renderHeaderPrice', 'spec' => 'o.total_price_without_vat', 'editable' => 'N', 'fieldType' => BaseList::TYPE_PRICE, 'visible' => 'N'], 'delivery_type' => ['translate' => true, 'field' => 'o.delivery_type', 'render' => 'renderDelivery', 'class' => 'getDeliveryClass', 'size' => 1.25, 'spec' => []], 'delivery_name' => ['translate' => true, 'field' => 'delivery_name', 'visible' => 'N', 'spec' => []], 'payment_name' => ['translate' => true, 'field' => 'payment_name', 'visible' => 'N', 'spec' => []], 'flags' => ['translate' => true, 'field' => 'o.flags', 'render' => 'renderFlags', 'class' => 'columnCampaigns product-campaigns', 'size' => 0.7, 'spec' => [], 'fieldType' => OrdersList::TYPE_LIST_MULTISELECT], 'date' => ['translate' => true, 'field' => 'o.date_created', 'render' => 'renderDateTime', 'spec' => 'o.date_created'], 'statusPaid' => ['translate' => true, 'field' => 'status_payed', 'render' => 'renderStatusPaid', 'size' => 0.5], 'discounts' => ['translate' => true, 'render' => 'renderDiscounts', 'class' => 'left tiny-list-items', 'size' => 1, 'visible' => 'N'], 'email' => ['translate' => true, 'field' => 'o.invoice_email', 'spec' => 'o.invoice_email', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'zip' => ['translate' => true, 'field' => 'o.delivery_zip', 'spec' => 'o.delivery_zip', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'deliveryCountry' => ['translate' => true, 'field' => 'o.delivery_country', 'spec' => 'o.delivery_country', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'currency' => ['translate' => true, 'field' => 'o.currency', 'spec' => 'o.currency', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'note' => ['translate' => true, 'field' => 'o.note_user', 'spec' => 'o.note_user', 'visible' => 'N'], 'noteUser' => ['translate' => true, 'field' => 'user_note', 'spec' => 'o.invoice_email', 'render' => 'renderUserNote', 'visible' => 'N'], 'date_updated' => ['translate' => true, 'field' => 'o.date_updated', 'render' => 'renderDateTime', 'visible' => 'N'], 'date_delivered' => ['translate' => true, 'field' => 'o.date_delivered', 'render' => 'renderDateTime', 'visible' => 'N'], 'userOrderNo' => ['translate' => true, 'field' => 'o.user_order_no', 'spec' => 'o.user_order_no', 'type' => 'orders', 'visible' => 'N'], 'phone' => ['translate' => true, 'field' => 'o.invoice_phone', 'spec' => 'o.invoice_phone', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'invoiceFirm' => ['translate' => true, 'field' => 'o.invoice_firm', 'spec' => 'o.invoice_firm', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'invoiceIco' => ['translate' => true, 'field' => 'o.invoice_ico', 'spec' => 'o.invoice_ico', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'invoiceDic' => ['translate' => true, 'field' => 'o.invoice_dic', 'spec' => 'o.invoice_dic', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'invoiceZip' => ['translate' => true, 'field' => 'o.invoice_zip', 'spec' => 'o.invoice_zip', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'invoiceCountry' => ['translate' => true, 'field' => 'o.invoice_country', 'spec' => 'o.invoice_country', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'deliveryFirm' => ['translate' => true, 'field' => 'o.delivery_firm', 'spec' => 'o.delivery_firm', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'deliveryStreet' => ['translate' => true, 'field' => 'o.delivery_street', 'spec' => 'o.delivery_street', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'deliveryCity' => ['translate' => true, 'field' => 'o.delivery_city', 'spec' => 'o.delivery_city', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'deliveryPhone' => ['translate' => true, 'field' => 'o.delivery_phone', 'spec' => 'o.delivery_phone', 'visible' => 'N', 'fieldType' => BaseList::TYPE_STRING], 'customerGroups' => ['translate' => true, 'field' => 'customer_groups', 'spec' => [], 'visible' => 'N'], 'trackingNumber' => ['translate' => true, 'field' => 'package_id', 'render' => 'renderPackage', 'visible' => 'N', 'spec' => []], 'priceLevel' => ['translate' => true, 'field' => 'id', 'render' => 'renderPriceLevel', 'visible' => 'N'], ], 'class' => 'getRowClass', ]; private $orderTotalPriceSum; /** * @var OrdersListFilter */ protected $ordersListFilter; /** @var OrderInfo */ protected $orderInfo; public function __construct() { $this->orderTotalPriceSum = toDecimal(0); $this->ordersListFilter = ServiceContainer::getService(OrdersListFilter::class); $this->orderInfo = ServiceContainer::getService(OrderInfo::class); } public function getSQLOrdering(&$var, &$orderParam) { parent::getSQLOrdering($var, $orderParam); if (isset($var['orderField']) && ($var['orderField'] == 'items' || $var['orderField'] == 'user_note')) { $var['orderField'] = ''; } } public function customizeTableDef($tableDef) { $tableDef = parent::customizeTableDef($tableDef); $cfg = \KupShop\KupShopBundle\Config::get(); $dbcfg = Settings::getDefault(); if (!findModule('eshop_delivery')) { unset($tableDef['fields']['delivery']); } if (!findModule(Modules::PRICE_LEVELS)) { unset($tableDef['fields']['priceLevel']); } if (empty($cfg['Order']['Flags'])) { unset($tableDef['fields']['flags']); } if (findModule(Modules::TRANSLATIONS)) { $tableDef['fields']['Jazyk'] = ['field' => 'o.id_language', 'spec' => 'o.id_language', 'visible' => 'N']; } if (findModule(Modules::INVOICES)) { $tableDef['fields']['invoiceNo'] = ['translate' => true, 'field' => 'o.invoice_no', 'render' => 'renderInvoice', 'spec' => 'o.invoice_no']; } if (findModule(Modules::PRODUCTS, Modules::SUB_WEIGHT)) { $tableDef['fields']['weight'] = ['translate' => true, 'field' => 'o.total_weight', 'spec' => 'o.total_weight', 'render' => 'renderFloat', 'visible' => 'N']; } if (findModule(Modules::DROPSHIP)) { $tableDef['fields']['dropship'] = ['translate' => true, 'field' => 'dropship_name', 'visible' => 'N', 'render' => 'renderDropshipment', 'spec' => function (Query\QueryBuilder $qb) { $qb->addSelect('dps.name as dropship_name, dps.id as dropship_id') ->leftJoin('o', 'order_dropshipment', 'odps', 'odps.id_order = o.id') ->leftJoin('odps', 'dropshipment', 'dps', 'dps.id = odps.id_dropshipment'); }]; } if (findModule(Modules::BONUS_PROGRAM)) { $tableDef['fields']['bonusPoints'] = ['translate' => true, 'field' => 'bonus_points', 'visible' => 'N', 'spec' => function (Query\QueryBuilder $qb) { $qb->addSelect('bp.points as bonus_points') ->leftJoin('o', 'bonus_points', 'bp', 'o.id = bp.id_order'); }]; } $tableDef['fields']['customerGroups']['spec'] = function (Query\QueryBuilder $qb) { $qb->addSelect('GROUP_CONCAT(ug.name) as customer_groups') ->leftJoin('o', 'users_groups_relations', 'ugr', 'ugr.id_user=o.id_user') ->leftJoin('ugr', 'users_groups', 'ug', 'ug.id=ugr.id_group') ->groupBy('o.id'); }; $tableDef['fields']['payment_name']['spec'] = function (Query\QueryBuilder $qb) { $qb->addSelect('COALESCE(dtp.name_admin, dtp.name) as payment_name') ->leftJoin('o', 'delivery_type', 'dt', 'dt.id=o.id_delivery') ->leftJoin('dt', 'delivery_type_payment', 'dtp', 'dtp.id=dt.id_payment'); }; $tableDef['fields']['trackingNumber']['spec'] = function (Query\QueryBuilder $qb) { $qb->addSelect('o.package_id, dtd.class') ->leftJoin('o', 'delivery_type', 'dt', 'dt.id=o.id_delivery') ->leftJoin('dt', 'delivery_type_delivery', 'dtd', 'dtd.id=dt.id_delivery'); }; $tableDef['fields']['delivery_name']['spec'] = function (Query\QueryBuilder $qb) { $qb->addSelect('COALESCE(dtd.name_admin, dtd.name) as delivery_name') ->leftJoin('o', 'delivery_type', 'dt', 'dt.id=o.id_delivery') ->leftJoin('dt', 'delivery_type_delivery', 'dtd', 'dtd.id=dt.id_delivery'); }; $tableDef['fields']['delivery_type']['spec'] = function (Query\QueryBuilder $qb) { $qb->addSelect('COALESCE(dtp.name_admin, dtp.name) as payment_name, COALESCE(dtd.name_admin, dtd.name) as delivery_name') ->leftJoin('o', 'delivery_type', 'dt', 'dt.id=o.id_delivery') ->leftJoin('dt', 'delivery_type_payment', 'dtp', 'dtp.id=dt.id_payment') ->leftJoin('dt', 'delivery_type_delivery', 'dtd', 'dtd.id=dt.id_delivery'); }; $tableDef['fields']['dateDue'] = ['translate' => true, 'field' => 'date_due', 'render' => 'renderDate', 'spec' => 'COALESCE(o.date_due, (COALESCE(o.date_handle, o.date_accept, o.date_created) + INTERVAL '.($dbcfg->shop_due_days ?: 14).' DAY)) as date_due', 'visible' => 'N', ]; foreach (getOrderStatuses() as $statusId => $status) { $tableDef['fields']['status']['fieldOptions'][$statusId] = $status['name']; } $tableDef['fields']['flags']['spec'] = function (Query\QueryBuilder $qb) { $qb->addSelect('o.flags'); }; if (!empty($cfg['Order']['Flags'])) { foreach ($cfg['Order']['Flags'] as $flag => $value) { $tableDef['fields']['flags']['fieldOptions'][$flag] = $value['name']; } } if (findModule(Modules::NEW_POS)) { $tableDef['fields']['pos'] = ['field' => 'pos_name', 'translate' => true, 'size' => 1.5, 'spec' => function (Query\QueryBuilder $qb) { $qb->addSelect('po.name AS pos_name, po.id AS pos_id') ->leftJoin('o', 'pos', 'po', 'o.pos = po.id'); }]; } if (findModule(Modules::SELLERS)) { $tableDef['fields']['seller'] = ['translate' => true, 'field' => 'seller_name', 'visible' => 'N', 'render' => 'renderSeller', 'spec' => function (Query\QueryBuilder $qb) { $qb->addSelect('sell.title as seller_name, sell.id as seller_id') ->leftJoin('o', 'order_sellers', 'osell', 'osell.id_order = o.id') ->leftJoin('osell', 'sellers', 'sell', 'sell.id = osell.id_seller'); }]; } return $tableDef; } public function renderInvoice(array $values): HTML { return HTML::create('a') ->attr('href', path('kupshop_admin_emailattachment_adminattachment', ['id_order' => $values['id'], 'type' => InvoicePDFAttachment::getType()])) ->attr('target', '_blank') ->text($values['invoice_no']); } public function renderDropshipment(array $values): HTML { return HTML::create('a') ->attr('href', 'javascript:nw(\'Dropshipment\', '.$values['dropship_id'].')') ->text($values['dropship_name']); } public function renderSeller(array $values): HTML { return HTML::create('a') ->attr('href', 'javascript:nw(\'sellers\', '.$values['seller_id'].')') ->text($values['seller_name']); } public function renderOrderSource(array $values): string { return OrderInfo::getOrderSources()[$values['source']] ?? ''; } public function renderStatusPaid($values, $column) { $value = $this->renderCell($values, $column); if (in_array($value, [Order::STATUS_OVERPAID, Order::STATUS_UNDERPAID])) { if ($value == Order::STATUS_OVERPAID) { $tooltip = translate('statusOverPaid', 'orders'); } else { $tooltip = translate('statusUnderPaid', 'orders'); } return $this->renderIcon('warning', 'Ne', $tooltip); } else { return $this->renderBoolean($values, $column); } } public function renderPackage($values, $column) { if (empty($values['package_id'])) { return ''; } $delivery = \Delivery::getClass($values['class']); $link = $delivery->getTrackAndTraceLink($values['package_id']) ?? ''; return HTML::create('a') ->attr('href', $link) ->attr('target', '_blank') ->text($values['package_id']); } public function renderUserNote($values, $column) { if (!empty($values['invoice_email'])) { if ($note = $this->selectSQL('users', ['email' => $values['invoice_email']], ['note'])->fetchColumn()) { return $note; } } return ''; } public function renderItems($values, $column) { $items = sqlQueryBuilder()->select('oi.descr, oi.pieces, oi.id_product, oi.id_variation') ->from('order_items', 'oi') ->where(Op::equals(['id_order' => $values['id']])) ->execute() ->fetchAll(); $output = HTML::create('span'); $idProductIn = getVal('productId'); $idProductsIn = getVal('products', default: []); $idProductIn && $idProductsIn[] = $idProductIn; foreach ($items as $item) { $searchId = $item['id_product'].($item['id_variation'] ? '-'.$item['id_variation'] : ''); if ($item['id_product'] ?? false) { $output ->tag('div') ->text(floatval($item['pieces']).'x ') ->tag('a') ->attr('href', 'javascript:nw(\'product\', \''.$item['id_product'].'\')') ->tag(in_array($searchId, $idProductsIn) || in_array($item['id_product'], $idProductsIn) ? 'strong' : 'span') ->text($item['descr']) ->end() ->end() ->end(); } else { $output ->tag('div') ->text(floatval($item['pieces']).'x '.$item['descr']) ->end(); } } return $output; } public function renderDiscounts($values, $column) { $output = HTML::create('span'); $used_order_discounts = $this->orderInfo->getUsedDiscounts($values['id']); foreach ($used_order_discounts as $id => $name) { $output->tag('div')->tag('a') ->attr('href', "javascript:nw('OrderDiscounts', '{$id}')") ->attr('title', translate('showDiscount', 'OrderDiscounts')) ->tag('span')->class('badge badge-primary badge-light') ->text($name) ->end()->end()->end(); } return $output; } public function renderDelivery($values, $column) { $delivery = $values['delivery_type']; if (!empty($values['id_delivery'])) { $delivery = $values['payment_name'].' - '.$values['delivery_name']; } $styles = $this->getStyles(); $delivery_class = 'delivery'; foreach ($styles as $id => $style) { if (!empty($style['id_delivery']) && ($style['id_delivery'] == $values['id_delivery'])) { $delivery_class = $id; } } foreach ($styles as $id => $style) { if ($style['match'] && (stripos($values['delivery_type'], $style['match']) !== false || stripos($style['match'], $values['delivery_type'] ?? '') !== false) && $style['value']) { $delivery_class = $id; } } return $this->renderBadge($delivery, 'badge-default badge-'.$delivery_class, null); } public function renderFlags($values, $column) { $cfg = \KupShop\KupShopBundle\Config::get(); $flags = $this->getListRowValue($values, $column['field']); if (empty($flags)) { return ''; } $flags = preg_split('/,/', $flags); $ret = []; foreach (array_intersect($flags, array_keys($cfg['Order']['Flags'])) as $flag) { $ret[] = HTML::create('span') ->class('badge badge-pastel-default') ->tag('span')->class('tooltip-text')->text($cfg['Order']['Flags'][$flag]['name'] ?? $flag)->end() ->tag('span')->class('badge-text')->text($flag)->end(); } return $ret; } public function getRowClass($values) { $class = ''; if ($values['status_storno'] == 1) { $class .= ' storno'; } $class .= " status{$values['status']}"; return $class; } public function getDeliveryClass($values) { $styles = $this->getStyles(); foreach ($styles as $id => $style) { if (!empty($style['id_delivery']) && ($style['id_delivery'] == $values['id_delivery'])) { return 'delivery '.$id; } } foreach ($styles as $id => $style) { if ($style['match'] && (stripos($values['delivery_type'], $style['match']) !== false || stripos($style['match'], $values['delivery_type'] ?? '') !== false)) { return 'delivery '.$id; } } return 'delivery '; } public function renderName($values, $column) { $parts = []; $name = $this->getListRowValue($values, $column['field']); $surname = $this->getListRowValue($values, 'invoice_surname'); $company = $this->getListRowValue($values, 'invoice_firm'); if ($company) { $parts[] = $company; } if ($name || $surname) { $parts[] = join(' ', [$surname, $name]); } return join(', ', $parts); } public function renderCode($values, $column) { return $this->getListRowValue($values, 'order_no'); } public function renderStatus($values, $column) { global $cfg; $status = $this->getListRowValue($values, $column['field']); if ($values['status_storno'] == 1) { return $this->renderBadge($cfg['Order']['Status']['storno'][$values['status_storno']], 'badge-danger', null); } return $this->renderBadge($cfg['Order']['Status']['global'][$status], 'badge-default status-'.$status, null); } public function getStyles() { if (isset($this->styles)) { return $this->styles; } $styles = []; $qb = sqlQueryBuilder(); if (findModule('eshop_delivery')) { $qb->select('dt.id', 'CONCAT_WS(" - ", p.name, d.name) AS name', 'dt.format') ->from(getTableName('delivery_type'), 'dt') ->leftJoin('dt', getTableName('delivery_type_delivery'), 'd', 'dt.id_delivery=d.id') ->leftJoin('dt', getTableName('delivery_type_payment'), 'p', 'dt.id_payment=p.id') ->orderBy('vat', 'ASC'); foreach ($qb->execute() as $row) { $styles["delivery{$row['id']}"] = ['match' => $row['name'], 'id_delivery' => $row['id'], 'value' => "{$row['format']}"]; } } $this->styles = $styles; return $this->styles; } public function get_vars() { /** @var \KupShop\ElninoBundle\Query\QueryBuilder $qb */ $qb = sqlQueryBuilder(); $vars = parent::get_vars(); $vars['styles'] = $this->getStyles(); $pid = getVal('productId'); $vid = getVal('variationId'); $sold = getVal('sold'); if (!empty($sold) && !empty($pid)) { $qb->select('YEAR(o.date_created) as year', 'SUM(oi.pieces) as count') ->from(getTableName('order_items'), 'oi') ->leftJoin('oi', getTableName('orders'), 'o', 'oi.id_order=o.id') ->where('oi.id_product='.$pid.' AND o.status_storno=0') ->groupBy('YEAR(o.date_created)') ->orderBy('year', 'DESC'); if (!empty($vid)) { $qb->andWhere(Op::equals(['oi.id_variation' => $vid])); } $SQL = $qb->execute(); $vars['sold'] = []; $vars['sold_total'] = 0; foreach ($SQL as $row) { $vars['sold'][] = $row; $vars['sold_total'] += $row['count']; } } return $vars; } public function renderPrice($values, $column) { $totalPrice = toDecimal($values['total_price']); if (!empty($values['currency_rate'])) { $totalPrice = $totalPrice->mul(toDecimal($values['currency_rate'])); } $this->orderTotalPriceSum = $this->orderTotalPriceSum->add($totalPrice); return parent::renderPrice($values, $column); } // renderFormatPrice na OrdersListu se pouziva pouze pro total_price // total_price nechceme zaokrouhlovat = zobrazit jak je ulozena na objednavce public function renderFormatPrice($values, $column) { $value = $this->renderCell($values, $column); $params = [ 'printcurrency' => false, 'ceil' => false, 'decimal' => 'dynamic', ]; $currencyContext = ServiceContainer::getService(CurrencyContext::class); $currency = $currencyContext->getActive(); if (!empty($values['currency'])) { $currency = $currencyContext->getAll()[$values['currency']]; $params['currency'] = $currency; } return [ printPrice($value, $params).' ', HTML::create('span')->class('currency')->text($currency->getSymbol()), ]; } public function renderPriceLevel(array $values, array $column): HTML { $data = json_decode($values['note_admin'] ?: '', true) ?: []; if (!empty($data['price_level']['name'])) { return HTML::create('a') ->attr('href', 'javascript:nw(\'pricelevel\', '.$data['price_level']['id'].')') ->attr('title', $data['price_level']['name']) ->text($data['price_level']['name']); } return HTML::create('span') ->text(''); } public function getTotalPriceSum() { return $this->orderTotalPriceSum; } public function getFilterQuery(): Query\QueryBuilder { $qb = parent::getFilterQuery(); $qb = $this->ordersListFilter->addQueryBuilderParams($qb, $_GET); if (findModule(Modules::POS) && $qb->getQueryPart('where') == null) { if (getVal('pos_orders')) { $qb->andWhere('o.pos >= 1'); } else { $qb->andWhere('o.pos = 0 OR o.pos is null'); } } return $qb; } }