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

153 lines
5.8 KiB
PHP

<?php
use KupShop\AdminBundle\AdminList\BaseList;
use KupShop\AdminBundle\AdminList\FiltersStorage;
class InventoryList extends BaseList
{
use FiltersStorage;
protected $tableDef = [
'id' => 's.id',
'fields' => [
'ID' => ['field' => 's.id'],
'Pozice ve skladu' => ['field' => 's.name'],
'Hotovo' => ['field' => 'finished', 'render' => 'renderBoolean', 'size' => 0.5],
'Poznámka' => ['field' => 's.note', 'size' => 2],
'Datum aplikace' => ['field' => 'date_apply', 'render' => 'renderDatetime', 'size' => 0.5],
],
];
public function getQuery()
{
$qb = sqlQueryBuilder()
->select('s.id', 's.ID', 's.name', 'IF(s.finished,"Y","N") as finished', 's.note', 's.date_apply')
->from('inventory', 's');
extract($_GET, EXTR_SKIP | EXTR_REFS);
// ###########
if (!empty($IDs)) {
$qb->andWhere(\Query\Operator::equals(['s.id' => $IDs, 's.name' => $IDs], 'OR'));
}
// ###########
if (!empty($IDpv)) {
list($IDp, $IDv) = explode(':', $IDpv);
}
// ###########
if (!empty($IDp)) {
$qb->leftJoin('s', 'inventory_items', 'si', 'si.id_inventory=s.id')
->leftJoin('si', 'products', 'p', 'si.id_product=p.id')
->leftJoin('p', 'vats', 'v', 'p.vat=v.id');
if (!empty($IDv)) {
$qb->andWhere(\Query\Operator::equals(['si.id_variation' => $IDv]));
}
$qb->andWhere(\Query\Operator::equals(['si.id_product' => $IDp]));
}
// ###########
if (!empty($name)) {
$qb->andWhere(\Query\Operator::equals(['s.name' => $name]));
}
return $qb;
}
public function handleCleanProducts()
{
sqlQuery('TRUNCATE TABLE inventory_items');
$this->returnOK('Produkty na všech pozicích byly smazány');
}
public function handleCleanAll()
{
sqlQuery('DELETE FROM inventory');
$this->returnOK('Všechny pozice byly odstraněny');
}
public function handleApplyToProducts()
{
$changeCount = 0;
sqlQuery('DROP TABLE IF EXISTS tmp_inventory');
sqlQuery("CREATE TABLE tmp_inventory
SELECT p.id id_product, pv.id id_variation, COALESCE(SUM(ii.quantity),0) quantity, GROUP_CONCAT(DISTINCT i.name ORDER BY i.name SEPARATOR ',') position
FROM products p
LEFT JOIN products_variations pv ON p.id=pv.id_product
LEFT JOIN inventory_items ii ON ii.id_product = p.id AND ((pv.id IS NULL AND ii.id_variation IS NULL) OR (ii.id_variation = pv.id))
LEFT JOIN inventory i ON ii.id_inventory=i.id
GROUP BY p.id, pv.id");
sqlQuery('ALTER TABLE tmp_inventory ADD INDEX ( `id_product` )');
sqlQuery('ALTER TABLE tmp_inventory ADD INDEX ( `id_variation` )');
sqlStartTransaction();
$notPacked = ' ('.join(', ', getStatuses('notpacked')).') ';
$pNote = '';
$vNote = '';
if (findModule('products', 'note')) {
$pNote = ', p.note=COALESCE(ti.position, p.note)';
$vNote = ', pv.note=COALESCE(ti.position, pv.note)';
}
$SQL = sqlQuery("UPDATE products p
LEFT JOIN products_variations pv ON p.id=pv.id_product
LEFT JOIN tmp_inventory ti ON ti.id_product = p.id AND ti.id_variation IS NULL
SET p.in_store = COALESCE(ti.quantity, 0) - COALESCE((
SELECT COALESCE(SUM(pieces), 0)
FROM order_items oi
LEFT JOIN orders o ON oi.id_order = o.id
WHERE o.status IN {$notPacked} AND o.status_storno=0 AND oi.id_product = p.id AND oi.id_variation IS NULL
), 0){$pNote}
WHERE pv.id IS NULL");
$changeCount += sqlAffectedRows($SQL);
$SQL = sqlQuery("UPDATE products p
LEFT JOIN products_variations pv ON p.id=pv.id_product
LEFT JOIN tmp_inventory ti ON ti.id_product = p.id AND ti.id_variation = pv.id
SET pv.in_store = COALESCE(ti.quantity, 0) - COALESCE((
SELECT COALESCE(SUM(pieces), 0)
FROM order_items oi
LEFT JOIN orders o ON oi.id_order = o.id
WHERE o.status IN {$notPacked} AND o.status_storno=0 AND oi.id_product = p.id AND oi.id_variation = pv.id
), 0){$vNote}
WHERE pv.id IS NOT NULL");
$changeCount += sqlAffectedRows($SQL);
Variations::recalcInStore();
// Warehouse bundle - propagate to positions
if (findModule(\Modules::WAREHOUSE)) {
$wrongPositions = array_column(sqlQuery('SELECT name FROM inventory i LEFT JOIN warehouse_positions wp ON wp.code = i.name WHERE wp.id IS NULL')->fetchAll(), 'name');
if ($wrongPositions) {
$this->returnError('Nemůžu najít pozici ve skladu k těmto pozicím v inventuře: '.join(', ', $wrongPositions));
}
sqlQuery('DELETE FROM warehouse_products');
sqlQuery('INSERT INTO warehouse_products (id_product, id_variation, id_position, pieces)
SELECT ii.id_product, ii.id_variation, wp.id, SUM(ii.quantity)
FROM inventory_items ii
LEFT JOIN inventory i ON ii.id_inventory = i.id
LEFT JOIN warehouse_positions wp ON wp.code = i.name
GROUP BY ii.id_product, ii.id_variation, wp.id;');
}
sqlQueryBuilder()->update('inventory')->set('date_apply', 'NOW()')->execute();
addActivityLog(\KupShop\AdminBundle\Util\ActivityLog::SEVERITY_SUCCESS, \KupShop\AdminBundle\Util\ActivityLog::TYPE_CHANGE, "Proběhla aplikace inventury. Aktualizováno {$changeCount} položek. ");
sqlFinishTransaction();
$ErrStr = "Byl aktualizován stav {$changeCount} položek";
$this->returnOK($ErrStr);
}
}