Files
kupshop/admin/lists/OrdersMassProcessList.php
2025-08-02 16:30:27 +02:00

474 lines
16 KiB
PHP

<?php
use KupShop\AdminBundle\AdminList\FiltersStorage;
use KupShop\AdminBundle\Util\OrdersListFilter;
use KupShop\BalikonosBundle\Balikobot;
use KupShop\KupShopBundle\Email\OrderMessageEmail;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\HtmlBuilder\HTML;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
use PhpOffice\PhpSpreadsheet\Writer\Xls;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Query\Operator;
use Query\QueryBuilder;
require_once $cfg['Path']['shared_version'].'admin/lists/OrdersList.php';
class OrdersMassProcessList extends OrdersList
{
use FiltersStorage;
/**
* @var OrdersListFilter
*/
protected $ordersListFilter;
protected $template = 'list/ordersMassProcess.tpl';
protected $changeOrdersCodes = [];
protected $orderParam = [
'sort' => 'code',
'direction' => 'DESC',
];
protected $pageDivide = 500;
public function customizeTableDef($tableDef)
{
$fields = [
'customer' => ['translate' => true, 'field' => 'customer', 'render' => 'renderCustomer', 'size' => 3.5, 'translation_section' => 'orders'],
'Položek' => ['field' => 'amount', 'spec' => 'COUNT(o.id) as amount'],
'Hmotnost' => ['field' => 'weight', 'render' => 'renderWeight'],
'ČP Velikost' => ['field' => 'weight', 'render' => 'renderSize', 'class' => 'has-input'],
'Balíků' => ['field' => 'packages', 'render' => 'renderPackages', 'class' => 'has-input'],
];
if (findModule(Modules::PRODUCTS, Modules::SUB_WEIGHT)) {
$fields['Hmotnost'] = ['field' => 'o.total_weight', 'spec' => 'o.total_weight', 'render' => 'renderWeight', 'class' => 'has-input'];
}
if (findModule('balikonos', 'provider') == 'balikobot') {
$dbcfg = Settings::getDefault();
$balikobotSettings = $dbcfg['balikobot']['delivery_type'] ?? [];
$balikobotSettings = array_combine(array_keys($balikobotSettings), array_column($balikobotSettings, 'carrier'));
if ($balikobotSettings = array_filter($balikobotSettings)) {
$fields['Balíkobot dopravce'] = [
'field' => 'balikobot_carrier',
'render' => 'renderBalikobotCarrier',
'spec' => function (QueryBuilder $qb) use ($balikobotSettings) {
$json = json_encode($balikobotSettings);
$qb->addSelect("JSON_VALUE(:json, CONCAT('$.', dt.id_delivery)) as balikobot_carrier")
->leftJoin('o', 'delivery_type', 'dt', 'dt.id=o.id_delivery')
->setParameter('json', $json);
},
'visible' => 'N',
];
}
}
$excludeInherit = ['code', 'date', 'customer', 'price'];
foreach ($tableDef['fields'] as $name => &$field) {
if (!in_array($name, $excludeInherit)) {
$field['visible'] = 'N';
}
$field['translation_section'] = 'orders';
}
$tableDef['fields'] = array_merge(
[
'check' => [
'translate' => true,
'field' => 'id',
'size' => '55px',
'render' => 'renderCheck',
'translation_section' => 'orders',
'type' => '',
'class' => 'hiddenTooltip overflow-visible',
],
],
$tableDef['fields'],
$fields
);
$tableDef = parent::customizeTableDef($tableDef);
return $tableDef;
}
public function getPageDivide(): int
{
$cfg = \KupShop\KupShopBundle\Config::get();
if (!empty($cfg['Modules']['orders_mass_process']['pageDivide'])) {
return $cfg['Modules']['orders_mass_process']['pageDivide'];
}
return parent::getPageDivide();
}
public function getRowClass($values)
{
$class = '';
$action = $this->getAction();
$status = intval(getVal('status', $_POST));
if (!empty($status) && $values['status'] == $status && $action == 'multiInvoiceChangeStatus') {
$class = ' row-green';
}
return $class;
}
public function renderBalikobotCarrier($values, $column)
{
$carrier = $values['balikobot_carrier'];
if (!isset($this->balikobotCarriers)) {
$balikobot = ServiceContainer::getService(Balikobot::class);
$this->balikobotCarriers = $balikobot->getCarriers();
}
return $this->balikobotCarriers[$carrier] ?? '-';
}
public function renderPackages($values, $column)
{
$id_order = $this->getListRowValue($values, 'id');
return HTML::create('input')
->attr('type', 'text')
->attr('style', 'width:60px;')
->attr('name', 'packages['.$id_order.']')
->attr('value', 1);
}
public function renderWeight($values, $column)
{
$id_order = $this->getListRowValue($values, 'id');
global $dbcfg;
if (findModule('products', 'weight')) {
$weight = $this->getOrderWeight($id_order);
}
if (empty($weight)) {
$weight = $dbcfg[$cfg['Modules'][\Modules::BALIKONOS]['provider'] ?? 'balikonos']['weight'] ?? '';
}
return HTML::create('input')
->attr('type', 'text')
->attr('style', 'width:60px;')
->attr('name', 'weights['.$id_order.']')
->attr('value', $weight);
}
public function renderSize($values, $column)
{
$id_order = $this->getListRowValue($values, 'id');
$select = HTML::create('select')
->attr('name', 'sizes['.$id_order.']');
foreach (['Výchozí' => '', 'S' => 'S', 'M' => 'M', 'L' => 'L', 'XL' => 'XL'] as $size => $value) {
$select->tag('option')
->text($size)
->attr('value', $value);
}
return $select;
}
public function renderCustomer($values, $column)
{
$customer = $this->getListRowValue($values, 'customer');
$parts = explode(', ', $customer);
$parts = array_filter($parts);
return join(', ', $parts);
}
public function renderCheck($values, $column)
{
$id_order = $this->getListRowValue($values, 'id');
return [
HTML::create('input')
->attr('type', 'checkbox')
->attr('style', 'margin: 0;')
->attr('checked', 'checked')
->attr('name', 'orders[]')
->attr('value', $id_order),
];
}
public function getOrderWeight($idOrder)
{
return sqlQueryBuilder()->select('total_weight')
->from('orders')->where(Operator::equals(['id' => $idOrder]))
->execute()->fetchOne() ?? 0.0;
}
public function getSQLOrdering(&$var, &$orderParam)
{
parent::getSQLOrdering($var, $orderParam);
if (isset($var['orderField']) && ($var['orderField'] == 'weight' || $var['orderField'] == 'packages')) {
$var['orderField'] = '';
}
if (findModule(Modules::WAREHOUSE) && ($this->getAction() == 'massInvoice' || $this->getAction() == 'edit') && !getVal('order')) {
$var['orderField'] = '('.\KupShop\WarehouseBundle\Query\Orders::orderLocationPositionField('').')';
$var['orderDir'] = 'ASC';
}
}
// TOHLE JE FAKT HNUS, ALE NEZ DELAT PODMINKY NA x SHOPECH, TAK RADSI TADY JEDNOU..
protected function getAction()
{
if (empty($this->action)) {
$acn = getVal('acn');
if (empty($acn)) {
$acn = 'massInvoice';
}
$this->action = $acn;
}
return $this->action;
}
public function getQuery()
{
$qb = parent::getQuery();
$qb->addSelect('CONCAT_WS(", ", o.delivery_name, o.delivery_surname, o.delivery_firm, o.delivery_street, o.delivery_city, o.delivery_zip, o.delivery_country) as customer')
->leftJoin('o', 'order_items', 'oi', 'oi.id_order=o.id')
->groupBy('o.id');
return $qb;
}
public function getFilterQuery(): Query\QueryBuilder
{
$qb = parent::getFilterQuery();
$action = $this->getAction();
if (getVal('balikonos')) {
$qb->andWhere('o.status_storno != 1');
}
if ($action == 'massInvoice') {
if (!getVal('status')) {
if ($qb->getQueryPart('where') == null) {
$qb->andWhere(Operator::inIntArray(getStatuses('active'), 'o.status'));
} else {
$qb->resetQueryPart('where');
if (isset($_REQUEST['orders'])) {
$codes = [];
$codesString = [];
foreach ($_REQUEST['orders'] as $code) {
if (trim($code)) {
$codes[] = intval($code);
$codesString[] = trim($code);
}
}
$qb->andWhere(
Operator::orX(
Operator::inIntArray($codes, 'o.id'),
Operator::inStringArray($codesString, 'o.order_no')
)
);
}
}
}
}
$qb = $this->ordersListFilter->addQueryBuilderParams($qb, $_GET);
if ($action == 'multiInvoiceChangeStatus') {
$qb->resetQueryPart('where');
if (getVal('status')) {
$qb->andWhere(Operator::inIntArray($this->changeOrdersCodes, 'o.id'));
}
}
return $qb;
}
public function handleMultiInvoiceSend()
{
$var = [];
$postType = getVal('postType');
$content = $this->getContent($var, $postType);
if ($postType == 'cp') {
$content = iconv('utf8', 'cp1250//TRANSLIT//IGNORE', $content);
$content = iconv('cp1250', 'utf8', $content);
}
if ($postType == 'ppl') {
$filetype = 'xml';
} elseif ($postType == 'dpd') {
$filetype = 'xlsx';
} else {
$filetype = 'txt';
}
if ($filetype == 'xls' || $filetype == 'xlsx') {
$file = tempnam(sys_get_temp_dir(), 'excel_');
$handle = fopen($file, 'w');
fwrite($handle, $content);
$reader = new Csv();
$reader->setDelimiter(';');
$reader->setInputEncoding('UTF-8');
$spreadsheet = $reader->load($file);
fclose($handle);
unlink($file);
header('Content-Disposition: attachment; filename="'.$postType.'-'.date('Y-m-d_H-i').'.'.$filetype.'"');
if ($filetype == 'xls') {
$writer = new Xls($spreadsheet);
} elseif ($filetype == 'xlsx') {
$writer = new Xlsx($spreadsheet);
}
$writer->save('php://output');
exit;
} else {
header('Content-type: application/'.$filetype);
header('Content-Disposition: attachment; filename="'.$postType.'-'.date('Y-m-d_H-i').'.'.$filetype.'"');
}
echo $content;
exit;
}
/**
* @return bool|mixed|string
*/
protected function getContent($var, $postType)
{
$var['fields'] = ' o.id, order_no, o.delivery_name, o.delivery_surname, o.delivery_firm, o.delivery_type, o.delivery_firm as name,
o.delivery_street, o.delivery_city, o.delivery_zip, o.delivery_country, o.total_price, COUNT(o.id) as amount,
NOW() AS date,o.invoice_phone , o.invoice_email, o.id_delivery,
o.invoice_name, o.invoice_surname, o.invoice_street, o.invoice_city, o.invoice_zip, dtd.name delivery_type_name,
dtd.id as id_dtd, o.note_admin, o.note_user, oh.comment ';
$var['from'] = ' orders AS o
LEFT JOIN delivery_type as dt ON dt.id=o.id_delivery
LEFT JOIN delivery_type_delivery as dtd ON dtd.id=dt.id_delivery
LEFT JOIN orders_history as oh ON oh.id_order=o.id ';
$var['where'] = ' o.id IN (:codes)';
$var['query'] = 'SELECT '.$var['fields'].' FROM '.$var['from'].' WHERE '.$var['where'].' GROUP BY o.id';
$codes = $_REQUEST['orders'];
$indexes = array_flip($codes);
$SQL = sqlQuery($var['query'], ['codes' => $codes], ['codes' => \Doctrine\DBAL\Connection::PARAM_INT_ARRAY]);
$weights = getVal('weights');
$sizes = getVal('sizes');
$packages = getVal('packages');
$orders = [];
foreach ($SQL as $order) {
$order['delivery_suburb'] = '';
if (!empty($order['note_admin'])) {
$order['note_admin'] = json_decode($order['note_admin'], true);
}
if (preg_match('/^(.*) ([0-9\\/]*)$/', trim($order['delivery_street']), $matches)) {
$order['delivery_street'] = trim($matches[1]);
$order['delivery_suburb'] = $matches[2];
}
if (!empty($weights)) {
$order['weight'] = $weights[$order['id']];
}
if (!empty($sizes[$order['id']])) {
$order['size'] = $sizes[$order['id']];
}
if (!empty($packages)) {
$order['packages'] = $packages[$order['id']] ?? 1;
}
$order['note_user'] = $order['note_user'] ?: '';
$order['to_pay'] = roundPrice($order['total_price']);
$orderCls = new Order();
$orderCls->createFromDB($order['id']);
if (findModule('order_payment')) {
$orderCls->total_price = toDecimal($order['total_price']);
$order['to_pay'] = $orderCls->getRemainingPayment();
}
$order['orderclass'] = $orderCls;
$order['delivery_zip'] = strtr($order['delivery_zip'], [' ' => '']);
$orders[$indexes[$order['id']]] = $order;
}
ksort($orders);
global $dbcfg;
preg_match("/\d{3} ?\d{2}/i", $dbcfg['shop_address'], $zip);
/* if ($FileType == "xls"){
return $this->getXLS($orders);
}
*/
$smart = createSmarty(true);
$smart->assign(
[
'orders' => $orders,
'zip' => $zip,
'dbcfg' => $dbcfg,
]
);
$content = $smart->fetch('massprocess/'.$postType.'.tpl');
return $content;
}
public function handleMultiInvoiceChangeStatus()
{
$status = intval(getVal('status'));
if (!is_null($status)) {
foreach (getVal('orders', null, []) as $code) {
$order = new Order();
$order->createFromDB($code);
$email = ServiceContainer::getService(OrderMessageEmail::class);
$order_messages = $email->getOrderStatusMessagesByStatus($status);
if (count($order_messages) == 0) {
$order_message = null;
} else {
$order_message = $order_messages[0]['name'];
}
$this->changeOrdersCodes[] = $code;
$comment = null;
$forceSendMail = null;
if (getVal('donotsend') === 'ON' and $status !== $order->status) {
$order_message = null;
$forceSendMail = false;
$comment = translate('statusChangeComment', 'ordersMassProcess');
}
$order->changeStatus($status, $comment, $forceSendMail, $order_message);
}
}
}
}
return OrdersMassProcessList::class;