Files
kupshop/bundles/KupShop/StoresBundle/Admin/storesTransfers.php
2025-08-02 16:30:27 +02:00

356 lines
13 KiB
PHP

<?php
use KupShop\KupShopBundle\Config;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\LoggingContext;
use KupShop\StoresBundle\Utils\StoresInStore;
use Query\Operator;
$main_class = 'StoresTransfers';
class StoresTransfers extends Window
{
use DatabaseCommunication;
protected $template = 'window/storesTransfers.tpl';
protected $tableName = 'stores_transfers';
protected $nameField = 'id';
protected $defaults = [
'state' => 'O',
];
protected $required = [
'number' => true,
'code' => true,
];
public function __construct()
{
if (getVal('print')) {
$this->setTemplate('window/storesTransfersPrint.tpl');
}
}
public function get_vars()
{
$vars = parent::get_vars();
$pageVars = getVal('body', $vars);
$acn = $this->getAction();
$storesInStoreService = ServiceContainer::getService(StoresInStore::class);
$pageVars['states'] = StoresInStore::$states;
$pageVars['stores'] = $storesInStoreService->getStoresNames();
$storesInfo = $storesInStoreService->getStores();
$ID = $this->getID();
if ($ID) {
$object = $this->getObject();
$id_store_from = $object['id_store_from'];
$id_store_to = $object['id_store_to'];
if (findModule(Modules::WAREHOUSE)
&& $storesInfo[$id_store_from]['type'] == StoresInStore::TYPE_EXTERNAL_STORE
&& $storesInfo[$id_store_to]['type'] == StoresInStore::TYPE_MAIN_STORE) {
$pageVars['data']['check_app'] = true;
}
if (findModule(Modules::CHECK_APP)
&& in_array($storesInfo[$id_store_from]['type'], [StoresInStore::TYPE_MAIN_STORE, StoresInStore::TYPE_STORE])) {
$pageVars['data']['check_app_send'] = true;
}
if ($id_store_from == $id_store_to) {
$pageVars['data']['state'] = 'E'; // error
$vars['body'] = $pageVars;
return $vars;
}
$SQL = ServiceContainer::getService(\KupShop\StoresBundle\Utils\StoresTransfers::class)->getTransferItems($ID);
$items = [];
$can_send = true;
foreach ($SQL as $row) {
$row['bg_color'] = '#FFF';
if ($object['state'] == 'O') {
if ($row['quantity'] <= 0) {
$row['bg_color'] = '#FDD7DB';
$row['warning'][] = 'Přenášené množství musí být větší než nula!';
} else {
$cur_store_in_store = ($row["store{$id_store_from}_in_store"] ?? 0);
if ($cur_store_in_store - $row['quantity'] < 0) {
$row['bg_color'] = '#FDD7DB';
$row['warning'][] = 'V převodce je více kusů než je skladem!';
$can_send = false;
} else {
$cur_store_min_in_store = $row["store{$id_store_from}_min_in_store"] ?? 0;
if ($cur_store_min_in_store && ($cur_store_in_store - $row['quantity'] < $cur_store_min_in_store)) {
$row['bg_color'] = '#FCEECD';
$row['warning'][] = 'Převodem se dostanete pod minimální stav skladu!';
}
}
$cur_store_in_store = -($row["store{$id_store_to}_in_store"] ?? 0);
if ($row['quantity'] < $cur_store_in_store) {
$row['bg_color'] = '#FCEECD';
$row['warning'][] = 'Na doplnění potřebného množství není dostatek kusů.';
}
}
}
$row['total_in_store'] = floatval($row['total_in_store']);
$row['batches'] = $this->getBatchData($row);
$items[$row['id']] = $row;
}
$pageVars['items'] = $items;
$pageVars['can_send'] = true; // $can_send;
}
$vars['body'] = $pageVars;
return $vars;
}
protected function getBatchData($item)
{
$batchesRaw = json_decode($item['custom_data'], true)['batch_numbers'] ?? [];
$batches = [];
if ($batchesRaw) {
$batches = sqlFetchAll(sqlQueryBuilder()->select('id, code, date_expiry')->from('products_batches', 'pb')
->where(Operator::inIntArray(array_keys($batchesRaw), 'id'))
->execute(),
'id');
foreach ($batchesRaw as $batchId => $batchAmount) {
if (!empty($batches[$batchId])) {
$batches[$batchId]['pieces'] = $batchAmount;
}
}
}
return $batches;
}
public function createObject()
{
$data = parent::createObject();
if (empty($data['date_created'])) {
$data['date_created'] = date('Y-m-d H:i:s');
}
return $data;
}
public function handleUpdate()
{
$acn = $this->getAction();
$data = $this->getData();
$ID = $this->getID();
$submit = getVal('Submit');
if ($submit == 'recieved') {
$object = $this->getObject();
if (($object['state'] ?? '') != 'S') {
$this->returnError('Nelze přijmout neodeslanou nebo přijatou převodku!');
}
if (findModule(Modules::WAREHOUSE)) {
$warehouseLogger = ServiceContainer::getService(\KupShop\WarehouseBundle\Util\Logger::class);
$warehouseLogger->setIdTransfer($ID);
}
try {
ServiceContainer::getService(LoggingContext::class)->activateStoreTransfer($ID, function () use ($object) {
$storesInStore = ServiceContainer::getService(StoresInStore::class);
$storesInStore->transferReceived($object);
});
} catch (LogicException $e) {
$this->returnError('Chyba! '.$e->getMessage());
} catch (Exception $e) {
$sentryLogger = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Logging\SentryLogger::class);
$sentryLogger->captureException($e);
$this->returnError('Chyba! '.$e->getMessage());
}
return true;
}
if ($acn == 'edit' && !empty($ID)) {
$closed = returnSQLResult("SELECT (s.state <> 'O') FROM stores_transfers s WHERE s.id='{$ID}' ");
if ($closed) {
$this->returnError('Nelze upravovat uzavřenou převodku');
}
}
if ($submit == 'sent') {
$object = $this->getObject();
if (($object['state'] ?? '') != 'O') {
$this->returnError('Nelze odeslat přijatou nebo odeslanou převodku!');
}
if (findModule(Modules::WAREHOUSE) && !empty($ID)) {
$storeTransferWorker = ServiceContainer::getService(\KupShop\WarehouseBundle\Util\StoreTransferWorker::class);
$errors = $storeTransferWorker->checkTransferMatchesBoxContent($ID);
foreach ($errors as $error) {
$this->addHTMLError($error['message']);
}
if (!empty($errors)) {
return true;
}
}
if (findModule(\Modules::STORES, \Modules::SUB_ON_THE_FLY_STORE)) {
$object = $this->getObject();
$config = Config::get();
if ($onTheFlyStore = ($config['Modules']['stores']['on_the_fly_store']['store'] ?? false)) {
try {
sqlGetConnection()->transactional(function () use ($ID, $object, $onTheFlyStore) {
ServiceContainer::getService(LoggingContext::class)->activateStoreTransfer($ID,
function () use ($ID, $object, $onTheFlyStore) {
$storesInStore = ServiceContainer::getService(StoresInStore::class);
$storesInStore->moveBetweenStores($ID, $object['id_store_from'], $onTheFlyStore);
});
});
} catch (Exception $e) {
$sentryLogger = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Logging\SentryLogger::class);
$sentryLogger->captureException($e);
$this->returnError('Chyba! '.$e->getMessage());
}
} else {
$this->addError('Není nastaven mezisklad!');
return true;
}
}
$this->updateSQL('stores_transfers', ['state' => 'S', 'date_created' => date('Y-m-d H:i:s')], ['id' => $ID]);
return true;
}
parent::handleUpdate();
$object = $this->getObject();
if ($acn == 'add' && $submit) {
$eventDispatcher = ServiceContainer::getService('event_dispatcher');
$event = new \KupShop\StoresBundle\Event\StoreEvent($object);
$eventDispatcher->dispatch($event, \KupShop\StoresBundle\Event\StoreEvent::CREATE_TRANSFER);
}
$items = getVal('items', $data, []);
krsort($items, SORT_NUMERIC);
foreach ($items as $id => $item) {
$item['id'] = intval($id);
if (!empty($item['delete']) || !$id) {
if ($id > 0) {
$this->handleDeleteValue($item);
}
continue;
}
if ($id < 0) {
$this->handleAddValue($item);
} else {
$this->handleUpdateValue($item);
}
}
if ($acn == 'add' && ($object['state'] == 'O') && ($auto_transfer = getVal('auto_transfer', $data))) {
$transfers = ServiceContainer::getService(\KupShop\StoresBundle\Utils\StoresTransfers::class);
$missingItems = $transfers->getMissingItems($object['id_store_from'], $object['id_store_to'], $auto_transfer);
foreach ($missingItems as $item) {
$this->handleAddValue($item);
}
}
return true;
}
public function handleDelete()
{
if (!findRight('INSTORE_STOCKIN_ERASE')) {
redirect('launch.php?s=error.php&id=1');
}
parent::handleDelete();
}
public function handleDeleteValue($item)
{
$this->deleteSQL('stores_transfers_items', ['id' => $item['id']]);
}
public function handleAddValue($item)
{
if (empty($item['id_product'])) {
return false;
}
$ID = $this->getID();
$item['id_stores_transfer'] = $ID;
if (empty($item['quantity'])) {
$item['quantity'] = 0;
}
$fields = ['id_stores_transfer', 'quantity', 'id_product', 'id_variation'];
$SQLfields = $this->getSQLFields($item, $fields);
sqlQuery('INSERT INTO stores_transfers_items
SET id_stores_transfer=:id_stores_transfer, id_product=:id_product, id_variation=:id_variation,
quantity=:quantity ON DUPLICATE KEY UPDATE quantity=quantity+:quantity', $SQLfields);
}
public function handleUpdateValue($item)
{
$this->updateSQL('stores_transfers_items', ['quantity' => $item['quantity']], ['id' => $item['id']]);
}
public function handleExport()
{
$ID = $this->getID();
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="export_store_transfer_'.$ID.'.csv"');
$SQL = sqlQuery("SELECT si.id, si.id_product, si.id_variation, si.quantity,
p.title as product_title, pv.title as variation_title
FROM stores_transfers_items si
LEFT JOIN products p ON p.id=si.id_product
LEFT JOIN products_variations pv ON pv.id=si.id_variation
WHERE si.id_stores_transfer='{$ID}' ");
echo '"id";"id_product";"id_variation";"product_title";"variation_title";"quantity"';
while (($row = sqlFetchAssoc($SQL)) !== false) {
$row['id_variation'] = $row['id_variation'] ?: '';
echo "\n\"{$row['id']}\";\"{$row['id_product']}\";\"{$row['id_variation']}\";\"{$row['product_title']}\";\"{$row['variation_title']}\";\"{$row['quantity']}\"";
}
exit;
}
public function hasRights($name = null)
{
switch ($name) {
case Window::RIGHT_DELETE:
return findRight('INSTORE_STOCKIN_ERASE');
default:
return true;
}
}
}