1425 lines
39 KiB
PHP
1425 lines
39 KiB
PHP
<?php
|
|
/**
|
|
* Raktári Kiszedési Lista Generátor Osztály
|
|
*
|
|
* Funkció: Rendelések teljesítéséhez szükséges picking list generálása
|
|
* Használat: require_once, majd PickingListGenerator::generate() hívás
|
|
*/
|
|
|
|
class PickingListGenerator {
|
|
|
|
private $conn;
|
|
private $warehouseConfig;
|
|
private $primaryWarehouse;
|
|
|
|
const PRIMARY_WAREHOUSE_CODE = 'FŐ';
|
|
const FOIL_WAREHOUSE_LABEL = 'Fóliás raktár';
|
|
const CL_SET_PREFIX = 'CL';
|
|
|
|
/**
|
|
* Konstruktor
|
|
*/
|
|
public function __construct($conn) {
|
|
$this->conn = $conn;
|
|
$this->primaryWarehouse = self::PRIMARY_WAREHOUSE_CODE;
|
|
$this->warehouseConfig = $this->loadWarehouseStructure();
|
|
}
|
|
|
|
/**
|
|
* Fő generáló metódus
|
|
*/
|
|
public static function generate($conn, $inputData, $coderclass = null) {
|
|
$generator = new self($conn);
|
|
return $generator->processPickingList($inputData, $coderclass);
|
|
}
|
|
|
|
/**
|
|
* Picking list feldolgozás
|
|
*/
|
|
private function processPickingList($inputData, $coderclass) {
|
|
$orders = [];
|
|
$reason = '';
|
|
$orderDate = '';
|
|
|
|
// Input típus meghatározása
|
|
if (isset($inputData['manual']) && is_array($inputData['manual'])) {
|
|
$orders = $this->buildManualOrders($inputData['manual']);
|
|
} else {
|
|
if ($coderclass === null) {
|
|
return ['result' => 'error', 'message' => 'CoderClass szükséges reason alapú lekérdezéshez'];
|
|
}
|
|
|
|
$encodedData = htmlspecialchars($inputData['reason'] ?? '');
|
|
$decodedData = $coderclass->decode($encodedData, 'SZ4TUN4');
|
|
$dataParts = explode('|', $decodedData);
|
|
|
|
if (count($dataParts) != 2) {
|
|
return ['result' => 'error', 'message' => 'Érvénytelen kiszedési lista azonosító'];
|
|
}
|
|
|
|
$reason = $dataParts[0];
|
|
$orderDate = $dataParts[1];
|
|
|
|
$orders = $this->loadOrders($reason, $orderDate);
|
|
}
|
|
|
|
// Készletek betöltése
|
|
$boxStock = $this->loadBoxStock();
|
|
$foilStock = $this->loadFoilStock();
|
|
|
|
// Picking listák generálása
|
|
$allPickingLists = [];
|
|
|
|
foreach ($orders as $key => $orderData) {
|
|
|
|
$localBoxStock = $boxStock;
|
|
$localFoilStock = $foilStock;
|
|
|
|
$orderPrimaryWarehouse = $orderData['primary_warehouse'] ?? $this->primaryWarehouse;
|
|
|
|
$this->prioritizeStock($localBoxStock, $orderPrimaryWarehouse);
|
|
$this->prioritizeFoilStock($localFoilStock, $orderPrimaryWarehouse);
|
|
|
|
$pickingList = $this->generatePickingList($orderData, $localBoxStock, $localFoilStock);
|
|
|
|
$this->formatPositionForSort($pickingList);
|
|
$this->sortPickingList($pickingList);
|
|
|
|
$icon = $this->determineIcon($pickingList);
|
|
if (!empty($icon)) {
|
|
$icon = $orderData['overal_order_id'] . ' ' . $icon;
|
|
}
|
|
|
|
$allPickingLists[] = [
|
|
'overal_order_id' => $orderData['overal_order_id'],
|
|
'order_id' => $orderData['order_id'],
|
|
'order_name' => $orderData['order_name'],
|
|
'order_mail' => $orderData['order_mail'],
|
|
'receipt_method' => $orderData['receipt_method'],
|
|
'order_note' => $orderData['order_note'],
|
|
'picking_list' => $pickingList
|
|
];
|
|
}
|
|
|
|
$this->sortOrders($allPickingLists);
|
|
|
|
return [
|
|
'result' => 'ok',
|
|
'reason' => $reason,
|
|
'date' => $orderDate,
|
|
'all_picking_lists' => $allPickingLists
|
|
];
|
|
}
|
|
|
|
// ========================================================================
|
|
// ADATBETÖLTŐ METÓDUSOK
|
|
// ========================================================================
|
|
|
|
private function loadWarehouseStructure() {
|
|
$config = [];
|
|
$sql = "SELECT warehouse_id, location, name, code FROM warehouse_structure WHERE status=1";
|
|
$result = $this->conn->query($sql);
|
|
|
|
if ($result) {
|
|
while ($row = $result->fetch_assoc()) {
|
|
$config[intval($row['warehouse_id'])] = [
|
|
'location' => $row['location'],
|
|
'name' => $row['name'],
|
|
'code' => $row['code']
|
|
];
|
|
}
|
|
}
|
|
|
|
return $config;
|
|
}
|
|
|
|
private function buildManualOrders($manualData) {
|
|
$manualItems = [];
|
|
|
|
foreach ($manualData as $entry) {
|
|
$itemId = $entry['item_id'] ?? '';
|
|
$amount = intval($entry['amount'] ?? 0);
|
|
$primarySource = intval($entry['primary_source'] ?? 0);
|
|
$amountType = intval($entry['amount_type'] ?? 0);
|
|
|
|
if (empty($itemId) || $amount <= 0) continue;
|
|
|
|
$key = $itemId . '_' . $primarySource . '_' . $amountType;
|
|
|
|
if (!isset($manualItems[$key])) {
|
|
$manualItems[$key] = [
|
|
'item_id' => $itemId,
|
|
'amount' => 0,
|
|
'primary_source' => $primarySource,
|
|
'amount_type' => $amountType
|
|
];
|
|
}
|
|
|
|
$manualItems[$key]['amount'] += $amount;
|
|
}
|
|
|
|
$orders = [];
|
|
$orders['manual'] = [
|
|
'overal_order_id' => 'Manuális kiszedés',
|
|
'order_id' => '',
|
|
'order_name' => 'Manuális kiszedés',
|
|
'order_mail' => '',
|
|
'receipt_method' => '',
|
|
'order_note' => '',
|
|
'items' => [],
|
|
'totalneed' => 0,
|
|
'primary_warehouse' => $this->primaryWarehouse
|
|
];
|
|
|
|
foreach ($manualItems as $item) {
|
|
$orders['manual']['items'][] = [
|
|
'item_id' => $item['item_id'],
|
|
'need' => $item['amount'],
|
|
'taken_out' => 0,
|
|
'ordered' => $item['amount'],
|
|
'amount_type' => $item['amount_type'],
|
|
'primary_source' => $item['primary_source']
|
|
];
|
|
$orders['manual']['totalneed'] += $item['amount'];
|
|
}
|
|
|
|
return $orders;
|
|
}
|
|
|
|
private function loadOrders($reason, $orderDate) {
|
|
$orders = [];
|
|
|
|
$sql = "SELECT
|
|
item_id,
|
|
SUM(amount) AS ordered,
|
|
SUM(taken_out) AS taken_out,
|
|
SUM(amount) - SUM(taken_out) AS need,
|
|
IFNULL(order_id, '') AS order_id,
|
|
IFNULL(order_name, '') AS order_name,
|
|
IFNULL(order_mail, '') AS order_mail,
|
|
MAX(reason) AS reason,
|
|
primary_source,
|
|
primary_warehouse,
|
|
MAX(amount_type) AS amount_type,
|
|
GROUP_CONCAT(DISTINCT IFNULL(note, '') SEPARATOR ' ') AS note,
|
|
GROUP_CONCAT(DISTINCT IFNULL(receipt_method, '') SEPARATOR ' ') AS receipt_method
|
|
FROM warehouse_reservation
|
|
WHERE reason = ?
|
|
AND DATE(FROM_UNIXTIME(date_create)) = ?
|
|
AND is_active = 1
|
|
GROUP BY item_id, order_id, order_name, order_mail, primary_source, amount_type, primary_warehouse
|
|
ORDER BY amount_type DESC, item_id";
|
|
|
|
$stmt = $this->conn->prepare($sql);
|
|
$stmt->bind_param("ss", $reason, $orderDate);
|
|
$stmt->execute();
|
|
$result = $stmt->get_result();
|
|
|
|
while ($row = $result->fetch_assoc()) {
|
|
$hasOrder = !empty($row['order_id']) || !empty($row['order_name']) || !empty($row['order_mail']);
|
|
|
|
if ($hasOrder) {
|
|
$key = $row['order_id'] . '~' . $row['order_name'] . '~' . $row['order_mail'];
|
|
$label = $row['order_name'] . ' - (' . $row['order_id'] . ')';
|
|
} else {
|
|
$key = 'maradek';
|
|
$label = '!&maradek&! ';
|
|
}
|
|
|
|
if (!isset($orders[$key])) {
|
|
$orders[$key] = [
|
|
'overal_order_id' => $label,
|
|
'order_id' => strval($row['order_id']),
|
|
'order_name' => $row['order_name'],
|
|
'order_mail' => $row['order_mail'],
|
|
'receipt_method' => '',
|
|
'order_note' => '',
|
|
'items' => [],
|
|
'totalneed' => 0,
|
|
'primary_warehouse' => $row['primary_warehouse'] ?? $this->primaryWarehouse
|
|
];
|
|
}
|
|
|
|
if (!empty($row['receipt_method'])) {
|
|
if (empty($orders[$key]['receipt_method']) || strpos($orders[$key]['receipt_method'], $row['receipt_method']) === false) {
|
|
$orders[$key]['receipt_method'] = trim($orders[$key]['receipt_method'] . ' ' . $row['receipt_method']);
|
|
}
|
|
}
|
|
|
|
if (!empty($row['note'])) {
|
|
if (empty($orders[$key]['order_note']) || strpos($orders[$key]['order_note'], $row['note']) === false) {
|
|
$orders[$key]['order_note'] = trim($orders[$key]['order_note'] . ' ' . $row['note']);
|
|
}
|
|
}
|
|
|
|
$need = intval($row['need']);
|
|
$orders[$key]['items'][] = [
|
|
'item_id' => $row['item_id'],
|
|
'need' => $need,
|
|
'taken_out' => intval($row['taken_out']),
|
|
'ordered' => intval($row['ordered']),
|
|
'amount_type' => intval($row['amount_type']),
|
|
'primary_source' => intval($row['primary_source'])
|
|
];
|
|
$orders[$key]['totalneed'] += max(0, $need);
|
|
}
|
|
|
|
$stmt->close();
|
|
return $orders;
|
|
}
|
|
|
|
private function loadBoxStock() {
|
|
$stock = [];
|
|
|
|
$sql = "SELECT item_id, wid, position AS pos, amount, warehouse_id
|
|
FROM warehouse
|
|
WHERE amount > 0
|
|
ORDER BY item_id,
|
|
CAST(SUBSTRING_INDEX(position, ':', 1) AS UNSIGNED) DESC,
|
|
CAST(SUBSTRING_INDEX(position, ':', -1) AS UNSIGNED) ASC,
|
|
amount ASC";
|
|
|
|
$result = $this->conn->query($sql);
|
|
|
|
if ($result) {
|
|
while ($row = $result->fetch_assoc()) {
|
|
$stock[$row['item_id']][] = [
|
|
'wid' => intval($row['wid']),
|
|
'pos' => $row['pos'],
|
|
'amount' => intval($row['amount']),
|
|
'warehouse_id' => intval($row['warehouse_id'])
|
|
];
|
|
}
|
|
}
|
|
|
|
return $stock;
|
|
}
|
|
|
|
private function loadFoilStock() {
|
|
$stock = [];
|
|
|
|
$sql = "SELECT item_id, wid, place AS pos, right_db, left_db
|
|
FROM warehouse_foil
|
|
WHERE (right_db > 0 OR left_db > 0)
|
|
AND is_active = 1
|
|
ORDER BY item_id, right_db ASC";
|
|
|
|
$result = $this->conn->query($sql);
|
|
|
|
if ($result) {
|
|
while ($row = $result->fetch_assoc()) {
|
|
$stock[$row['item_id']][] = [
|
|
'wid' => 'F' . intval($row['wid']),
|
|
'pos' => $row['pos'],
|
|
'amount' => min(intval($row['right_db']), intval($row['left_db'])),
|
|
'warehouse_id' => 'FOIL',
|
|
'right_db' => intval($row['right_db']),
|
|
'left_db' => intval($row['left_db'])
|
|
];
|
|
}
|
|
}
|
|
|
|
return $stock;
|
|
}
|
|
|
|
/**
|
|
* Dobozos raktár priorizálása rendelésenként
|
|
*/
|
|
private function prioritizeStock(&$stock, $primaryWarehouse = null) {
|
|
$primary = $primaryWarehouse ?? $this->primaryWarehouse;
|
|
|
|
foreach ($stock as $itemId => &$bins) {
|
|
usort($bins, function($a, $b) use ($primary) {
|
|
$aCode = $this->warehouseConfig[$a['warehouse_id']]['code'] ?? '';
|
|
$bCode = $this->warehouseConfig[$b['warehouse_id']]['code'] ?? '';
|
|
|
|
$aIsMain = (strpos($aCode, $primary) === 0) ? 1 : 0;
|
|
$bIsMain = (strpos($bCode, $primary) === 0) ? 1 : 0;
|
|
|
|
if ($aIsMain !== $bIsMain) {
|
|
return $bIsMain - $aIsMain;
|
|
}
|
|
|
|
return 0;
|
|
});
|
|
}
|
|
unset($bins);
|
|
}
|
|
|
|
/**
|
|
* Fóliás raktár priorizálása rendelésenként
|
|
*/
|
|
private function prioritizeFoilStock(&$stock, $primaryWarehouse = null) {
|
|
$primary = $primaryWarehouse ?? $this->primaryWarehouse;
|
|
|
|
foreach ($stock as $itemId => &$bins) {
|
|
usort($bins, function($a, $b) use ($primary) {
|
|
$aIsMain = (strpos($a['pos'], $primary) === 0) ? 1 : 0;
|
|
$bIsMain = (strpos($b['pos'], $primary) === 0) ? 1 : 0;
|
|
|
|
if ($aIsMain !== $bIsMain) {
|
|
return $bIsMain - $aIsMain;
|
|
}
|
|
|
|
return 0;
|
|
});
|
|
}
|
|
unset($bins);
|
|
}
|
|
|
|
|
|
// ========================================================================
|
|
// KISZEDÉSI LOGIKA
|
|
// ========================================================================
|
|
|
|
private function generatePickingList($orderData, $boxStock, $foilStock) {
|
|
$pickingList = [];
|
|
$localBoxStock = $boxStock;
|
|
$localFoilStock = $foilStock;
|
|
|
|
foreach ($orderData['items'] as $item) {
|
|
$itemId = $item['item_id'];
|
|
$need = $item['need'];
|
|
$takenOut = $item['taken_out'];
|
|
$ordered = $item['ordered'];
|
|
$amountType = $item['amount_type'];
|
|
$primarySource = $item['primary_source'];
|
|
|
|
if ($takenOut > 0) {
|
|
$pickingList[] = [
|
|
'wid' => 0,
|
|
'item_id' => $itemId,
|
|
'pos' => '00',
|
|
'code' => '',
|
|
'amount' => $takenOut . ' / ' . $ordered,
|
|
'amount_type' => $amountType,
|
|
'location' => '',
|
|
'type' => 'taken'
|
|
];
|
|
}
|
|
|
|
if ($need <= 0) continue;
|
|
|
|
$setInfo = $this->splitSetItemId($itemId);
|
|
|
|
if ($setInfo === false) {
|
|
$picks = $this->pickSimpleItem($itemId, $need, $amountType, $primarySource, $localBoxStock, $localFoilStock);
|
|
$pickingList = array_merge($pickingList, $picks);
|
|
} else {
|
|
if ($this->isCLSet($itemId)) {
|
|
$picks = $this->pickCLSet($itemId, $setInfo, $need, $amountType, $localBoxStock);
|
|
$pickingList = array_merge($pickingList, $picks);
|
|
} else {
|
|
$picks = $this->pickNormalSet($itemId, $setInfo, $need, $amountType, $primarySource, $localBoxStock, $localFoilStock);
|
|
$pickingList = array_merge($pickingList, $picks);
|
|
}
|
|
}
|
|
|
|
if ($need > 0) {
|
|
$pickingList[] = [
|
|
'wid' => -1,
|
|
'item_id' => $itemId,
|
|
'pos' => '00',
|
|
'code' => '',
|
|
'amount' => $need,
|
|
'amount_type' => $amountType,
|
|
'location' => '',
|
|
'type' => 'missing'
|
|
];
|
|
}
|
|
}
|
|
|
|
return $pickingList;
|
|
}
|
|
|
|
private function pickSimpleItem($itemId, &$need, $amountType, $primarySource, &$boxStock, &$foilStock) {
|
|
$picks = [];
|
|
$sources = ($primarySource === 1) ? ['foil', 'box'] : ['box', 'foil'];
|
|
|
|
foreach ($sources as $sourceType) {
|
|
if ($need <= 0) break;
|
|
|
|
if ($amountType !== 0 && $sourceType !== 'foil') {
|
|
continue;
|
|
}
|
|
|
|
if ($sourceType === 'box' && isset($boxStock[$itemId])) {
|
|
$picks = array_merge($picks, $this->pickFromBoxStock($itemId, $need, $amountType, $boxStock));
|
|
}
|
|
|
|
if ($sourceType === 'foil' && isset($foilStock[$itemId])) {
|
|
$picks = array_merge($picks, $this->pickFromFoilStock($itemId, $need, $amountType, $foilStock));
|
|
}
|
|
}
|
|
|
|
return $picks;
|
|
}
|
|
|
|
private function pickFromBoxStock($itemId, &$need, $amountType, &$stock) {
|
|
$picks = [];
|
|
|
|
while ($need > 0 && isset($stock[$itemId]) && !empty($stock[$itemId])) {
|
|
$bin = &$stock[$itemId][0];
|
|
$take = min($bin['amount'], $need);
|
|
|
|
$picks[] = [
|
|
'wid' => $bin['wid'],
|
|
'item_id' => $itemId,
|
|
'pos' => $this->formatWarehousePosition($bin['pos'], $bin['warehouse_id']),
|
|
'code' => $this->warehouseConfig[$bin['warehouse_id']]['code'] ?? '',
|
|
'amount' => $take,
|
|
'amount_type' => $amountType,
|
|
'location' => ($this->warehouseConfig[$bin['warehouse_id']]['location'] ?? '') . ' / ' . ($this->warehouseConfig[$bin['warehouse_id']]['name'] ?? ''),
|
|
'type' => 'stock'
|
|
];
|
|
|
|
$bin['amount'] -= $take;
|
|
$need -= $take;
|
|
|
|
if ($bin['amount'] <= 0) {
|
|
array_shift($stock[$itemId]);
|
|
}
|
|
}
|
|
|
|
return $picks;
|
|
}
|
|
|
|
private function pickFromFoilStock($itemId, &$need, $amountType, &$stock) {
|
|
$picks = [];
|
|
|
|
while ($need > 0 && isset($stock[$itemId]) && !empty($stock[$itemId])) {
|
|
$bin = &$stock[$itemId][0];
|
|
|
|
if ($amountType === 0) {
|
|
$take = min($bin['amount'], $need);
|
|
} elseif ($amountType === 1) {
|
|
$take = min($bin['right_db'], $need);
|
|
} elseif ($amountType === 2) {
|
|
$take = min($bin['left_db'], $need);
|
|
} else {
|
|
$take = 0;
|
|
}
|
|
|
|
if ($take <= 0) {
|
|
array_shift($stock[$itemId]);
|
|
continue;
|
|
}
|
|
|
|
$picks[] = [
|
|
'wid' => $bin['wid'],
|
|
'item_id' => $itemId,
|
|
'pos' => $bin['pos'],
|
|
'code' => '',
|
|
'amount' => $take,
|
|
'amount_type' => $amountType,
|
|
'location' => self::FOIL_WAREHOUSE_LABEL,
|
|
'type' => 'foil'
|
|
];
|
|
|
|
if ($amountType === 0) {
|
|
$bin['right_db'] -= $take;
|
|
$bin['left_db'] -= $take;
|
|
} elseif ($amountType === 1) {
|
|
$bin['right_db'] -= $take;
|
|
} elseif ($amountType === 2) {
|
|
$bin['left_db'] -= $take;
|
|
}
|
|
|
|
$bin['amount'] = min($bin['right_db'], $bin['left_db']);
|
|
$need -= $take;
|
|
|
|
if ($bin['right_db'] <= 0 && $bin['left_db'] <= 0) {
|
|
array_shift($stock[$itemId]);
|
|
}
|
|
}
|
|
|
|
return $picks;
|
|
}
|
|
|
|
private function pickCLSet($itemId, $setInfo, &$need, $amountType, &$boxStock) {
|
|
$picks = [];
|
|
$item1 = $setInfo['item1'];
|
|
$item2 = $setInfo['item2'];
|
|
|
|
$available1 = 0;
|
|
$available2 = 0;
|
|
|
|
if (isset($boxStock[$item1])) {
|
|
foreach ($boxStock[$item1] as $bin) {
|
|
$available1 += $bin['amount'];
|
|
}
|
|
}
|
|
|
|
if (isset($boxStock[$item2])) {
|
|
foreach ($boxStock[$item2] as $bin) {
|
|
$available2 += $bin['amount'];
|
|
}
|
|
}
|
|
|
|
$maxCanTake = min($available1, $available2, $need);
|
|
|
|
if ($maxCanTake > 0) {
|
|
$tempNeed = $maxCanTake;
|
|
|
|
while ($tempNeed > 0 && !empty($boxStock[$item1]) && !empty($boxStock[$item2])) {
|
|
$bin1 = &$boxStock[$item1][0];
|
|
$bin2 = &$boxStock[$item2][0];
|
|
|
|
$take = min($bin1['amount'], $bin2['amount'], $tempNeed);
|
|
|
|
$pos1 = $this->formatWarehousePosition($bin1['pos'], $bin1['warehouse_id']);
|
|
$pos2 = $this->formatWarehousePosition($bin2['pos'], $bin2['warehouse_id']);
|
|
|
|
$picks[] = [
|
|
'wid' => $bin1['wid'] . '/' . $bin2['wid'],
|
|
'item_id' => $itemId,
|
|
'pos' => $pos1 . '<br>' . $pos2, // + helyett <br>
|
|
'code' => '',
|
|
'amount' => $take,
|
|
'amount_type' => $amountType,
|
|
'location' => ($this->warehouseConfig[$bin1['warehouse_id']]['location'] ?? '') . ' / ' . ($this->warehouseConfig[$bin1['warehouse_id']]['name'] ?? '') . '<br>' . ($this->warehouseConfig[$bin2['warehouse_id']]['location'] ?? '') . ' / ' . ($this->warehouseConfig[$bin2['warehouse_id']]['name'] ?? ''),
|
|
'type' => 'stock'
|
|
];
|
|
|
|
$bin1['amount'] -= $take;
|
|
$bin2['amount'] -= $take;
|
|
$tempNeed -= $take;
|
|
|
|
if ($bin1['amount'] <= 0) {
|
|
array_shift($boxStock[$item1]);
|
|
}
|
|
if ($bin2['amount'] <= 0) {
|
|
array_shift($boxStock[$item2]);
|
|
}
|
|
}
|
|
|
|
$need -= $maxCanTake;
|
|
}
|
|
|
|
return $picks;
|
|
}
|
|
|
|
private function pickNormalSet($itemId, $setInfo, &$need, $amountType, $primarySource, &$boxStock, &$foilStock) {
|
|
$picks = [];
|
|
$item1 = $setInfo['item1'];
|
|
$item2 = $setInfo['item2'];
|
|
|
|
$sources = ($primarySource === 1) ? ['foil', 'box', 'hybrid'] : ['box', 'foil', 'hybrid'];
|
|
|
|
foreach ($sources as $sourceType) {
|
|
if ($need <= 0) break;
|
|
|
|
if ($sourceType === 'box' && isset($boxStock[$itemId])) {
|
|
while ($need > 0 && !empty($boxStock[$itemId])) {
|
|
$bin = &$boxStock[$itemId][0];
|
|
$take = min($bin['amount'], $need);
|
|
|
|
$picks[] = [
|
|
'wid' => $bin['wid'],
|
|
'item_id' => $itemId,
|
|
'pos' => $this->formatWarehousePosition($bin['pos'], $bin['warehouse_id']),
|
|
'code' => $this->warehouseConfig[$bin['warehouse_id']]['code'] ?? '',
|
|
'amount' => $take,
|
|
'amount_type' => $amountType,
|
|
'location' => ($this->warehouseConfig[$bin['warehouse_id']]['location'] ?? '') . ' / ' . ($this->warehouseConfig[$bin['warehouse_id']]['name'] ?? ''),
|
|
'type' => 'stock'
|
|
];
|
|
|
|
$bin['amount'] -= $take;
|
|
$need -= $take;
|
|
|
|
if ($bin['amount'] <= 0) {
|
|
array_shift($boxStock[$itemId]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($sourceType === 'foil' && $need > 0) {
|
|
$picks = array_merge($picks, $this->pickSetFromFoil($itemId, $item1, $item2, $need, $amountType, $foilStock));
|
|
}
|
|
|
|
if ($sourceType === 'hybrid' && $need > 0) {
|
|
$picks = array_merge($picks, $this->pickSetHybrid($itemId, $item1, $item2, $need, $amountType, $boxStock, $foilStock));
|
|
}
|
|
}
|
|
|
|
return $picks;
|
|
}
|
|
|
|
private function pickSetFromFoil($itemId, $item1, $item2, &$need, $amountType, &$foilStock) {
|
|
$picks = [];
|
|
|
|
$available1 = 0;
|
|
$available2 = 0;
|
|
|
|
if (isset($foilStock[$item1])) {
|
|
foreach ($foilStock[$item1] as $bin) {
|
|
$available1 += $bin['amount'];
|
|
}
|
|
}
|
|
|
|
if (isset($foilStock[$item2])) {
|
|
foreach ($foilStock[$item2] as $bin) {
|
|
$available2 += $bin['amount'];
|
|
}
|
|
}
|
|
|
|
$maxCanTake = min($available1, $available2, $need);
|
|
|
|
if ($maxCanTake > 0) {
|
|
$tempNeed = $maxCanTake;
|
|
|
|
while ($tempNeed > 0 && !empty($foilStock[$item1]) && !empty($foilStock[$item2])) {
|
|
$bin1 = &$foilStock[$item1][0];
|
|
$bin2 = &$foilStock[$item2][0];
|
|
|
|
$take = min($bin1['amount'], $bin2['amount'], $tempNeed);
|
|
|
|
if ($take > 0) {
|
|
$picks[] = [
|
|
'wid' => $bin1['wid'] . '/' . $bin2['wid'],
|
|
'item_id' => $itemId,
|
|
'pos' => $bin1['pos'] . '<br>' . $bin2['pos'], // + helyett <br>
|
|
'code' => '',
|
|
'amount' => $take,
|
|
'amount_type' => $amountType,
|
|
'location' => self::FOIL_WAREHOUSE_LABEL,
|
|
'type' => 'foil'
|
|
];
|
|
|
|
$bin1['amount'] -= $take;
|
|
$bin2['amount'] -= $take;
|
|
$bin1['right_db'] -= $take;
|
|
$bin1['left_db'] -= $take;
|
|
$bin2['right_db'] -= $take;
|
|
$bin2['left_db'] -= $take;
|
|
$tempNeed -= $take;
|
|
}
|
|
|
|
if ($bin1['amount'] <= 0) {
|
|
array_shift($foilStock[$item1]);
|
|
}
|
|
if ($bin2['amount'] <= 0) {
|
|
array_shift($foilStock[$item2]);
|
|
}
|
|
}
|
|
|
|
$need -= $maxCanTake;
|
|
}
|
|
|
|
return $picks;
|
|
}
|
|
|
|
private function pickSetHybrid($itemId, $item1, $item2, &$need, $amountType, &$boxStock, &$foilStock) {
|
|
$picks = [];
|
|
|
|
// item1 dobozból, item2 fóliásból
|
|
$availableBox1 = 0;
|
|
$availableFoil2 = 0;
|
|
|
|
if (isset($boxStock[$item1])) {
|
|
foreach ($boxStock[$item1] as $bin) {
|
|
$availableBox1 += $bin['amount'];
|
|
}
|
|
}
|
|
|
|
if (isset($foilStock[$item2])) {
|
|
foreach ($foilStock[$item2] as $bin) {
|
|
$availableFoil2 += $bin['amount'];
|
|
}
|
|
}
|
|
|
|
$maxCanTake1 = min($availableBox1, $availableFoil2, $need);
|
|
|
|
if ($maxCanTake1 > 0) {
|
|
$tempNeed = $maxCanTake1;
|
|
|
|
while ($tempNeed > 0 && !empty($boxStock[$item1]) && !empty($foilStock[$item2])) {
|
|
$bin1 = &$boxStock[$item1][0];
|
|
$bin2 = &$foilStock[$item2][0];
|
|
|
|
$take = min($bin1['amount'], $bin2['amount'], $tempNeed);
|
|
|
|
if ($take > 0) {
|
|
$pos1 = $this->formatWarehousePosition($bin1['pos'], $bin1['warehouse_id']);
|
|
|
|
$picks[] = [
|
|
'wid' => $bin1['wid'] . '/' . $bin2['wid'],
|
|
'item_id' => $itemId,
|
|
'pos' => $pos1 . '<br>' . $bin2['pos'], // + helyett <br>
|
|
'code' => '',
|
|
'amount' => $take,
|
|
'amount_type' => $amountType,
|
|
'location' => ($this->warehouseConfig[$bin1['warehouse_id']]['location'] ?? '') . ' / ' . ($this->warehouseConfig[$bin1['warehouse_id']]['name'] ?? '') . '<br>' . self::FOIL_WAREHOUSE_LABEL,
|
|
'type' => 'hybrid'
|
|
];
|
|
|
|
$bin1['amount'] -= $take;
|
|
$bin2['amount'] -= $take;
|
|
$bin2['right_db'] -= $take;
|
|
$bin2['left_db'] -= $take;
|
|
$tempNeed -= $take;
|
|
}
|
|
|
|
if ($bin1['amount'] <= 0) {
|
|
array_shift($boxStock[$item1]);
|
|
}
|
|
if ($bin2['amount'] <= 0) {
|
|
array_shift($foilStock[$item2]);
|
|
}
|
|
}
|
|
|
|
$need -= $maxCanTake1;
|
|
}
|
|
|
|
// item1 fóliásból, item2 dobozból
|
|
if ($need > 0) {
|
|
$availableFoil1 = 0;
|
|
$availableBox2 = 0;
|
|
|
|
if (isset($foilStock[$item1])) {
|
|
foreach ($foilStock[$item1] as $bin) {
|
|
$availableFoil1 += $bin['amount'];
|
|
}
|
|
}
|
|
|
|
if (isset($boxStock[$item2])) {
|
|
foreach ($boxStock[$item2] as $bin) {
|
|
$availableBox2 += $bin['amount'];
|
|
}
|
|
}
|
|
|
|
$maxCanTake2 = min($availableFoil1, $availableBox2, $need);
|
|
|
|
if ($maxCanTake2 > 0) {
|
|
$tempNeed = $maxCanTake2;
|
|
|
|
while ($tempNeed > 0 && !empty($foilStock[$item1]) && !empty($boxStock[$item2])) {
|
|
$bin1 = &$foilStock[$item1][0];
|
|
$bin2 = &$boxStock[$item2][0];
|
|
|
|
$take = min($bin1['amount'], $bin2['amount'], $tempNeed);
|
|
|
|
if ($take > 0) {
|
|
$pos2 = $this->formatWarehousePosition($bin2['pos'], $bin2['warehouse_id']);
|
|
|
|
$picks[] = [
|
|
'wid' => $bin1['wid'] . '/' . $bin2['wid'],
|
|
'item_id' => $itemId,
|
|
'pos' => $bin1['pos'] . '<br>' . $pos2, // + helyett <br>
|
|
'code' => '',
|
|
'amount' => $take,
|
|
'amount_type' => $amountType,
|
|
'location' => self::FOIL_WAREHOUSE_LABEL . '<br>' . ($this->warehouseConfig[$bin2['warehouse_id']]['location'] ?? '') . ' / ' . ($this->warehouseConfig[$bin2['warehouse_id']]['name'] ?? ''),
|
|
'type' => 'hybrid'
|
|
];
|
|
|
|
$bin1['amount'] -= $take;
|
|
$bin1['right_db'] -= $take;
|
|
$bin1['left_db'] -= $take;
|
|
$bin2['amount'] -= $take;
|
|
$tempNeed -= $take;
|
|
}
|
|
|
|
if ($bin1['amount'] <= 0) {
|
|
array_shift($foilStock[$item1]);
|
|
}
|
|
if ($bin2['amount'] <= 0) {
|
|
array_shift($boxStock[$item2]);
|
|
}
|
|
}
|
|
|
|
$need -= $maxCanTake2;
|
|
}
|
|
}
|
|
|
|
return $picks;
|
|
}
|
|
|
|
// ========================================================================
|
|
// SEGÉD METÓDUSOK
|
|
// ========================================================================
|
|
|
|
/**
|
|
* Szett item_id szétbontása
|
|
* Ha van prefix (betű), akkor vezető nullák maradnak
|
|
* Ha nincs prefix, akkor vezető nullák eltávolítása
|
|
*/
|
|
private function splitSetItemId($itemId) {
|
|
// Ellenőrzés: tartalmaz-e '+' jelet
|
|
if (strpos($itemId, '+') === false) {
|
|
return false;
|
|
}
|
|
|
|
$parts = explode('+', $itemId, 2);
|
|
$first = trim($parts[0]);
|
|
$second = trim($parts[1]);
|
|
|
|
// Prefix detektálás (nem számjegy karakterek az elején)
|
|
$prefix = '';
|
|
$firstNumeric = $first;
|
|
|
|
if (preg_match('/^([^0-9]{1,2})(.*)$/', $first, $matches)) {
|
|
// Van prefix (pl. CL, FR, LR)
|
|
$prefix = $matches[1];
|
|
$firstNumeric = $matches[2];
|
|
|
|
// Prefix esetén vezető nullák MARADNAK
|
|
$item1 = $prefix . $firstNumeric;
|
|
$item2 = $prefix . $second;
|
|
} else {
|
|
// Nincs prefix - csak számok
|
|
// Vezető nullák ELTÁVOLÍTÁSA
|
|
$item1 = (string)intval($first);
|
|
$item2 = (string)intval($second);
|
|
}
|
|
|
|
return ['item1' => $item1, 'item2' => $item2];
|
|
}
|
|
|
|
|
|
private function isCLSet($itemId) {
|
|
return substr($itemId, 0, 2) === self::CL_SET_PREFIX;
|
|
}
|
|
|
|
private function formatWarehousePosition($position, $warehouseId) {
|
|
$parts = explode(':', $position);
|
|
if (count($parts) === 2) {
|
|
$letter = $this->numberToLetter(intval($parts[0]));
|
|
$number = $this->padZero($parts[1]);
|
|
$code = $this->warehouseConfig[$warehouseId]['code'] ?? '';
|
|
return $code . $letter . $number;
|
|
}
|
|
return $position;
|
|
}
|
|
|
|
private function numberToLetter($n) {
|
|
if ($n < 1 || $n > 26) return null;
|
|
return chr(64 + $n);
|
|
}
|
|
|
|
private function padZero($str) {
|
|
return str_pad(strval($str), 2, '0', STR_PAD_LEFT);
|
|
}
|
|
|
|
private function formatPositionForSort(&$pickingList) {
|
|
foreach ($pickingList as &$entry) {
|
|
if (strpos($entry['pos'], ',') !== false) {
|
|
list($row, $col) = explode(',', $entry['pos']);
|
|
$entry['pos'] = $col . '~' . $row;
|
|
}
|
|
}
|
|
unset($entry);
|
|
}
|
|
|
|
private function sortPickingList(&$pickingList) {
|
|
$typeOrder = [
|
|
'foil' => 1,
|
|
'stock' => 2,
|
|
'hybrid' => 2,
|
|
'taken' => 3,
|
|
'missing' => 4
|
|
];
|
|
|
|
usort($pickingList, function($a, $b) use ($typeOrder) {
|
|
$aType = $a['type'] ?? 'stock';
|
|
$bType = $b['type'] ?? 'stock';
|
|
|
|
$aPriority = $typeOrder[$aType] ?? 3;
|
|
$bPriority = $typeOrder[$bType] ?? 3;
|
|
|
|
if ($aPriority != $bPriority) {
|
|
return $aPriority - $bPriority;
|
|
}
|
|
|
|
if ($aType === 'taken' || $aType === 'missing') {
|
|
return strcmp($a['item_id'], $b['item_id']);
|
|
}
|
|
|
|
// Lokáció természetes rendezés
|
|
$locCmp = strnatcmp($a['location'], $b['location']);
|
|
if ($locCmp != 0) {
|
|
return $locCmp;
|
|
}
|
|
|
|
// Pozíció természetes rendezés
|
|
if (in_array($aType, ['stock', 'hybrid'])) {
|
|
if (strpos($a['pos'], '~') !== false && strpos($b['pos'], '~') !== false) {
|
|
list($aCol, $aRow) = explode('~', $a['pos']);
|
|
list($bCol, $bRow) = explode('~', $b['pos']);
|
|
|
|
if (intval($aRow) != intval($bRow)) {
|
|
return intval($aRow) - intval($bRow);
|
|
}
|
|
if (intval($aCol) != intval($bCol)) {
|
|
return intval($aCol) - intval($bCol);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Természetes rendezés pozíción (FŐ01, FŐ02, ... FŐ10)
|
|
$posCmp = strnatcmp($a['pos'], $b['pos']);
|
|
if ($posCmp != 0) {
|
|
return $posCmp;
|
|
}
|
|
|
|
return strcmp($a['item_id'], $b['item_id']);
|
|
});
|
|
}
|
|
|
|
|
|
private function sortOrders(&$orders) {
|
|
$typeOrder = [
|
|
'foil' => 1,
|
|
'stock' => 2,
|
|
'hybrid' => 2,
|
|
'taken' => 3,
|
|
'missing' => 4
|
|
];
|
|
|
|
usort($orders, function($a, $b) use ($typeOrder) {
|
|
if (empty($a['picking_list']) || empty($b['picking_list'])) {
|
|
return 0;
|
|
}
|
|
|
|
$aFirst = $a['picking_list'][0];
|
|
$bFirst = $b['picking_list'][0];
|
|
|
|
$aType = $aFirst['type'] ?? 'stock';
|
|
$bType = $bFirst['type'] ?? 'stock';
|
|
|
|
$aPriority = $typeOrder[$aType] ?? 3;
|
|
$bPriority = $typeOrder[$bType] ?? 3;
|
|
|
|
if ($aPriority != $bPriority) {
|
|
return $aPriority - $bPriority;
|
|
}
|
|
|
|
// Természetes rendezés lokáción
|
|
$locCmp = strnatcmp($aFirst['location'], $bFirst['location']);
|
|
if ($locCmp != 0) {
|
|
return $locCmp;
|
|
}
|
|
|
|
// Pozíció rendezés
|
|
if (in_array($aType, ['stock', 'hybrid'])) {
|
|
if (strpos($aFirst['pos'], '~') !== false && strpos($bFirst['pos'], '~') !== false) {
|
|
list($aCol, $aRow) = explode('~', $aFirst['pos']);
|
|
list($bCol, $bRow) = explode('~', $bFirst['pos']);
|
|
|
|
if (intval($aRow) != intval($bRow)) {
|
|
return intval($aRow) - intval($bRow);
|
|
}
|
|
if (intval($aCol) != intval($bCol)) {
|
|
return intval($aCol) - intval($bCol);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Természetes rendezés pozíción
|
|
return strnatcmp($aFirst['pos'], $bFirst['pos']);
|
|
});
|
|
}
|
|
|
|
|
|
private function determineIcon($pickingList) {
|
|
foreach ($pickingList as $entry) {
|
|
if ($entry['wid'] != 0) {
|
|
return '✓';
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Raktárból Eltávolítás Osztály
|
|
*
|
|
* Funkció: Kiszedett termékek eltávolítása a raktárból és lefoglalás frissítése
|
|
*
|
|
*/
|
|
|
|
class WarehouseRemover {
|
|
|
|
private $conn;
|
|
|
|
/**
|
|
* Konstruktor
|
|
*/
|
|
public function __construct($conn) {
|
|
$this->conn = $conn;
|
|
}
|
|
|
|
/**
|
|
* Statikus hívás
|
|
*/
|
|
public static function remove($conn, $inputData, $coderclass) {
|
|
$remover = new self($conn);
|
|
return $remover->processRemoval($inputData, $coderclass);
|
|
}
|
|
|
|
/**
|
|
* Eltávolítás feldolgozás
|
|
*/
|
|
private function processRemoval($inputData, $coderclass) {
|
|
// Input adatok kinyerése és tisztítása
|
|
$wid = htmlspecialchars($inputData['wid'] ?? '');
|
|
$amount = htmlspecialchars($inputData['amount'] ?? '');
|
|
$item_id = htmlspecialchars(str_replace(' ', '+', $inputData['item_id'] ?? ''));
|
|
$corrigate = htmlspecialchars($inputData['corrigate'] ?? 'false');
|
|
$overal_order_id = $inputData['overal_order_id'] ?? '';
|
|
$encoded_reason = htmlspecialchars($inputData['reason'] ?? '');
|
|
|
|
// Order ID és order name feldolgozása
|
|
$order_info = $this->parseOrderInfo($overal_order_id);
|
|
$order_name = $order_info['order_name'];
|
|
$order_id = $order_info['order_id'];
|
|
|
|
// Reason dekódolás
|
|
$decoded_data = $coderclass->decode($encoded_reason, 'SZ4TUN4');
|
|
$data_parts = explode('|', $decoded_data);
|
|
|
|
if (count($data_parts) != 2) {
|
|
return ['result' => 'error', 'message' => 'Érvénytelen kiszedési lista azonosító'];
|
|
}
|
|
|
|
$reason = $data_parts[0];
|
|
$order_date = $data_parts[1];
|
|
|
|
// Amount type feldolgozása
|
|
$amount_info = $this->parseAmount($amount);
|
|
$amount_type = $amount_info['amount_type'];
|
|
$amount_value = $amount_info['amount'];
|
|
|
|
// WID lista feldolgozása és szétválogatása
|
|
$wid_info = $this->parseWids($wid);
|
|
$foil_wids = $wid_info['foil_wids'];
|
|
$box_wids = $wid_info['box_wids'];
|
|
|
|
// Raktár ellenőrzés
|
|
$warehouse_check = $this->checkWarehouseStock($foil_wids, $box_wids, $amount_value, $amount_type);
|
|
if (!$warehouse_check['success']) {
|
|
return $warehouse_check;
|
|
}
|
|
|
|
$warehouse_foil_list = $warehouse_check['foil_list'];
|
|
$warehouse_box_list = $warehouse_check['box_list'];
|
|
|
|
// Lefoglalás ellenőrzés
|
|
$reservation_check = $this->checkReservation($item_id, $order_date, $reason, $order_name, $order_id, $amount_type, $amount_value);
|
|
if (!$reservation_check['success']) {
|
|
return $reservation_check;
|
|
}
|
|
|
|
$reserv_id = $reservation_check['reserv_id'];
|
|
$new_taken_out = $reservation_check['new_taken_out'];
|
|
|
|
// Lefoglalás frissítése
|
|
$this->updateReservation($reserv_id, $new_taken_out);
|
|
|
|
// Raktár frissítése
|
|
$update_result = $this->updateWarehouseStock(
|
|
$foil_wids,
|
|
$box_wids,
|
|
$warehouse_foil_list,
|
|
$warehouse_box_list,
|
|
$amount_value,
|
|
$amount_type,
|
|
$corrigate
|
|
);
|
|
|
|
return [
|
|
'result' => 'ok',
|
|
'reset' => $update_result['reset'],
|
|
'message' => $update_result['message']
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Order info feldolgozás
|
|
*/
|
|
private function parseOrderInfo($overal_order_id) {
|
|
$order_name = '';
|
|
$order_id = '';
|
|
|
|
if ($overal_order_id != '!&maradek&! ') {
|
|
$last_dash_pos = strrpos($overal_order_id, ' - ');
|
|
|
|
if ($last_dash_pos !== false) {
|
|
$order_name = htmlspecialchars(substr($overal_order_id, 0, $last_dash_pos));
|
|
$order_part = substr($overal_order_id, $last_dash_pos + 3);
|
|
$order_id = substr($order_part, 1, -1);
|
|
} else {
|
|
$order_name = htmlspecialchars($overal_order_id);
|
|
}
|
|
}
|
|
|
|
return ['order_name' => $order_name, 'order_id' => $order_id];
|
|
}
|
|
|
|
/**
|
|
* Amount feldolgozás (J/B prefix kezelése)
|
|
*/
|
|
private function parseAmount($amount) {
|
|
$amount_type = 0;
|
|
|
|
if (substr($amount, 0, 1) == "J") {
|
|
$amount_type = 1;
|
|
$amount = substr($amount, 1);
|
|
} else if (substr($amount, 0, 1) == "B") {
|
|
$amount_type = 2;
|
|
$amount = substr($amount, 1);
|
|
}
|
|
|
|
return ['amount_type' => $amount_type, 'amount' => intval($amount)];
|
|
}
|
|
|
|
/**
|
|
* WID lista feldolgozása és szétválogatása
|
|
*/
|
|
private function parseWids($wid) {
|
|
$wid_list = explode('/', $wid);
|
|
$foil_wids = [];
|
|
$box_wids = [];
|
|
|
|
foreach ($wid_list as $single_wid) {
|
|
if (substr($single_wid, 0, 1) == "F") {
|
|
$foil_wids[] = substr($single_wid, 1);
|
|
} else {
|
|
$box_wids[] = $single_wid;
|
|
}
|
|
}
|
|
|
|
return ['foil_wids' => $foil_wids, 'box_wids' => $box_wids];
|
|
}
|
|
|
|
/**
|
|
* Raktár készlet ellenőrzés
|
|
*/
|
|
private function checkWarehouseStock($foil_wids, $box_wids, $amount, $amount_type) {
|
|
$warehouse_foil_list = [];
|
|
$warehouse_box_list = [];
|
|
|
|
// Fóliás raktár ellenőrzés
|
|
foreach ($foil_wids as $foil_wid) {
|
|
$stmt = $this->conn->prepare("SELECT * FROM warehouse_foil WHERE wid = ? AND is_active = 1");
|
|
$stmt->bind_param("i", $foil_wid);
|
|
$stmt->execute();
|
|
$result = $stmt->get_result();
|
|
$warehouse_foil = $result->fetch_assoc();
|
|
$stmt->close();
|
|
|
|
if ($warehouse_foil == null) {
|
|
return [
|
|
'success' => false,
|
|
'result' => 'error',
|
|
'reset' => 'true',
|
|
'message' => 'Érvénytelen fóliás raktár azonosító (WID: F' . $foil_wid . ')'
|
|
];
|
|
}
|
|
|
|
// Mennyiség ellenőrzés
|
|
if ($amount_type == 1) {
|
|
$inWarehouse = intval($warehouse_foil['right_db']);
|
|
} else if ($amount_type == 2) {
|
|
$inWarehouse = intval($warehouse_foil['left_db']);
|
|
} else {
|
|
$inWarehouse = min(intval($warehouse_foil['right_db']), intval($warehouse_foil['left_db']));
|
|
}
|
|
|
|
if ($inWarehouse < $amount) {
|
|
return [
|
|
'success' => false,
|
|
'result' => 'error',
|
|
'reset' => 'true',
|
|
'message' => 'Érvénytelen raktár bejegyzés, a fóliás raktár szerint nincs ennyi termék a polcon (van: ' . $inWarehouse . ', kell: ' . $amount . ')'
|
|
];
|
|
}
|
|
|
|
$warehouse_foil_list[] = $warehouse_foil;
|
|
}
|
|
|
|
// Dobozos raktár ellenőrzés
|
|
foreach ($box_wids as $box_wid) {
|
|
$stmt = $this->conn->prepare("SELECT * FROM warehouse WHERE wid = ?");
|
|
$stmt->bind_param("i", $box_wid);
|
|
$stmt->execute();
|
|
$result = $stmt->get_result();
|
|
$warehouse_box = $result->fetch_assoc();
|
|
$stmt->close();
|
|
|
|
if ($warehouse_box == null) {
|
|
return [
|
|
'success' => false,
|
|
'result' => 'error',
|
|
'reset' => 'true',
|
|
'message' => 'Érvénytelen dobozos raktár azonosító (WID: ' . $box_wid . ')'
|
|
];
|
|
}
|
|
|
|
if (intval($warehouse_box['amount']) < $amount) {
|
|
return [
|
|
'success' => false,
|
|
'result' => 'error',
|
|
'reset' => 'true',
|
|
'message' => 'Érvénytelen raktár bejegyzés, a dobozos raktár szerint nincs ennyi termék a polcon (van: ' . $warehouse_box['amount'] . ', kell: ' . $amount . ')'
|
|
];
|
|
}
|
|
|
|
$warehouse_box_list[] = $warehouse_box;
|
|
}
|
|
|
|
return [
|
|
'success' => true,
|
|
'foil_list' => $warehouse_foil_list,
|
|
'box_list' => $warehouse_box_list
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Lefoglalás ellenőrzés
|
|
*/
|
|
private function checkReservation($item_id, $order_date, $reason, $order_name, $order_id, $amount_type, $amount) {
|
|
$stmt = $this->conn->prepare("SELECT * FROM warehouse_reservation
|
|
WHERE DATE(FROM_UNIXTIME(date_create)) = ?
|
|
AND item_id = ?
|
|
AND reason = ?
|
|
AND order_name = ?
|
|
AND order_id = ?
|
|
AND is_active = 1
|
|
AND amount_type = ?");
|
|
$stmt->bind_param("sssssi", $order_date, $item_id, $reason, $order_name, $order_id, $amount_type);
|
|
$stmt->execute();
|
|
$result = $stmt->get_result();
|
|
$reservation_sql = $result->fetch_assoc();
|
|
$stmt->close();
|
|
|
|
if ($reservation_sql == null) {
|
|
return [
|
|
'success' => false,
|
|
'result' => 'error',
|
|
'reset' => 'true',
|
|
'message' => 'Érvénytelen rendelési azonosító (item: ' . $item_id . ', order: ' . $order_name . ', date: ' . $order_date . ')'
|
|
];
|
|
}
|
|
|
|
$reserv_id = $reservation_sql['reserv_id'];
|
|
$current_taken_out = intval($reservation_sql['taken_out']);
|
|
$ordered_amount = intval($reservation_sql['amount']);
|
|
$new_taken_out = $current_taken_out + $amount;
|
|
|
|
if ($new_taken_out > $ordered_amount) {
|
|
return [
|
|
'success' => false,
|
|
'result' => 'error',
|
|
'reset' => 'true',
|
|
'message' => 'Hiba történt a mennyiségek megadásakor! Több terméket akart kiszedni mint amennyi a rendelésben szerepel. (Rendelt: ' . $ordered_amount . ', már kiszedve: ' . $current_taken_out . ', most kiszedni kívánt: ' . $amount . ')'
|
|
];
|
|
}
|
|
|
|
if ($new_taken_out < 0) {
|
|
return [
|
|
'success' => false,
|
|
'result' => 'error',
|
|
'reset' => 'true',
|
|
'message' => 'Hiba történt a mennyiségek megadásakor, negatív érték nem megengedett!'
|
|
];
|
|
}
|
|
|
|
return [
|
|
'success' => true,
|
|
'reserv_id' => $reserv_id,
|
|
'new_taken_out' => $new_taken_out
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Lefoglalás frissítése
|
|
*/
|
|
private function updateReservation($reserv_id, $new_taken_out) {
|
|
$stmt = $this->conn->prepare("UPDATE warehouse_reservation SET taken_out = ? WHERE reserv_id = ?");
|
|
$stmt->bind_param("ii", $new_taken_out, $reserv_id);
|
|
$stmt->execute();
|
|
$stmt->close();
|
|
}
|
|
|
|
/**
|
|
* Raktár készlet frissítése
|
|
*/
|
|
private function updateWarehouseStock($foil_wids, $box_wids, $warehouse_foil_list, $warehouse_box_list, $amount, $amount_type, $corrigate) {
|
|
$reset = 'false';
|
|
$message = '';
|
|
|
|
// Fóliás raktár frissítése
|
|
foreach ($foil_wids as $idx => $foil_wid) {
|
|
$warehouse_foil = $warehouse_foil_list[$idx];
|
|
|
|
// Mennyiség számítás
|
|
if ($amount_type == 1) {
|
|
$left_db = 0;
|
|
$right_db = -$amount;
|
|
} else if ($amount_type == 2) {
|
|
$left_db = -$amount;
|
|
$right_db = 0;
|
|
} else {
|
|
$left_db = -$amount;
|
|
$right_db = -$amount;
|
|
}
|
|
|
|
// Korrigálás
|
|
if ($corrigate == 'true') {
|
|
if ($amount_type == 1) {
|
|
$left_db = 0;
|
|
$right_db = -intval($warehouse_foil['right_db']);
|
|
} else if ($amount_type == 2) {
|
|
$left_db = -intval($warehouse_foil['left_db']);
|
|
$right_db = 0;
|
|
} else {
|
|
if (intval($warehouse_foil['right_db']) > intval($warehouse_foil['left_db'])) {
|
|
$left_db = -intval($warehouse_foil['left_db']);
|
|
$right_db = -intval($warehouse_foil['left_db']);
|
|
} else {
|
|
$left_db = -intval($warehouse_foil['right_db']);
|
|
$right_db = -intval($warehouse_foil['right_db']);
|
|
}
|
|
}
|
|
|
|
$reset = 'true';
|
|
$message = 'A raktár megfelelő polcán a mennyiség nullázva lett';
|
|
}
|
|
|
|
// Frissítés
|
|
$stmt = $this->conn->prepare("UPDATE warehouse_foil
|
|
SET left_db = CASE WHEN left_db + ? < 0 THEN 0 ELSE left_db + ? END,
|
|
right_db = CASE WHEN right_db + ? < 0 THEN 0 ELSE right_db + ? END
|
|
WHERE wid = ?");
|
|
$stmt->bind_param("iiiii", $left_db, $left_db, $right_db, $right_db, $foil_wid);
|
|
$stmt->execute();
|
|
$stmt->close();
|
|
}
|
|
|
|
// Dobozos raktár frissítése
|
|
foreach ($box_wids as $idx => $box_wid) {
|
|
$warehouse_box = $warehouse_box_list[$idx];
|
|
|
|
$new_amount_in_warehouse = 0;
|
|
|
|
if ($corrigate == 'true') {
|
|
$new_amount_in_warehouse = 0;
|
|
$reset = 'true';
|
|
$message = 'A raktár megfelelő polcán a mennyiség nullázva lett';
|
|
} else {
|
|
$new_amount_in_warehouse = intval($warehouse_box['amount']) - $amount;
|
|
}
|
|
|
|
$stmt = $this->conn->prepare("UPDATE warehouse SET amount = ? WHERE wid = ?");
|
|
$stmt->bind_param("ii", $new_amount_in_warehouse, $box_wid);
|
|
$stmt->execute();
|
|
$stmt->close();
|
|
}
|
|
|
|
return ['reset' => $reset, 'message' => $message];
|
|
}
|
|
}
|
|
?>
|