Finalize open lot qualification and selection
This commit is contained in:
1 parent
e69eda9953
commit
17efaee53f
3 files changed
+100
-85
No files matched your search
@@ -63,6 +63,10 @@ try {
|
||||
$outQty
|
||||
);
|
||||
$productId = (int) $updatedLot['product_id'];
|
||||
if (($updatedLot['status'] ?? '') === 'open') {
|
||||
sync_open_lot_activation_selection($pdo, $productId);
|
||||
$updatedLot['next_active'] = is_open_lot_selected_for_activation($pdo, (int) $updatedLot['id']);
|
||||
}
|
||||
refresh_lager_stock_lot_forecast_for_product($pdo, $productId);
|
||||
$forecast = get_lager_product_forecast($pdo, $productId);
|
||||
json_response(200, ['ok' => true, 'productId' => $productId, 'lot' => $updatedLot, 'balance' => get_stock_lot_balance($pdo, (int) ($data['lotId'] ?? 0)), 'forecast' => $forecast]);
|
||||
|
||||
@@ -504,106 +504,117 @@ function is_open_lot_selected_for_activation(PDO $pdo, int $lotId): bool
|
||||
|
||||
function sync_open_lot_activation_selection(PDO $pdo, int $productId): void
|
||||
{
|
||||
$lockStmt = $pdo->prepare(
|
||||
"SELECT id
|
||||
FROM stock_lot
|
||||
WHERE product_id = :product_id
|
||||
AND status = 'open'
|
||||
FOR UPDATE"
|
||||
);
|
||||
$lockStmt->execute([':product_id' => $productId]);
|
||||
|
||||
$qualifiedStmt = $pdo->prepare(
|
||||
"SELECT sl.id
|
||||
FROM stock_lot sl
|
||||
INNER JOIN v_stock_lot_balance v ON v.stock_lot_id = sl.id
|
||||
WHERE sl.product_id = :product_id
|
||||
AND sl.status = 'open'
|
||||
AND NULLIF(TRIM(sl.lot_number), '') IS NOT NULL
|
||||
AND sl.manufacturer_party_id IS NOT NULL
|
||||
AND NULLIF(TRIM(sl.manufacturer_lot_number), '') IS NOT NULL
|
||||
AND sl.mfg_date IS NOT NULL
|
||||
AND sl.expiry_date IS NOT NULL
|
||||
AND sl.purchase_date IS NOT NULL
|
||||
AND v.qty_net > 0
|
||||
ORDER BY sl.id"
|
||||
);
|
||||
$qualifiedStmt->execute([':product_id' => $productId]);
|
||||
$qualifiedIds = array_map('intval', $qualifiedStmt->fetchAll(PDO::FETCH_COLUMN));
|
||||
|
||||
if (count($qualifiedIds) === 1) {
|
||||
$selectedId = $qualifiedIds[0];
|
||||
$clearStmt = $pdo->prepare(
|
||||
"UPDATE stock_lot
|
||||
SET next_active = FALSE, updated_at = NOW()
|
||||
WHERE product_id = :product_id AND status = 'open'"
|
||||
);
|
||||
$clearStmt->execute([':product_id' => $productId]);
|
||||
$selectStmt = $pdo->prepare(
|
||||
"UPDATE stock_lot
|
||||
SET next_active = TRUE, updated_at = NOW()
|
||||
WHERE id = :lot_id"
|
||||
);
|
||||
$selectStmt->execute([':lot_id' => $selectedId]);
|
||||
return;
|
||||
$startedTransaction = !$pdo->inTransaction();
|
||||
if ($startedTransaction) {
|
||||
$pdo->beginTransaction();
|
||||
}
|
||||
|
||||
if ($qualifiedIds === []) {
|
||||
$clearStmt = $pdo->prepare(
|
||||
"UPDATE stock_lot
|
||||
SET next_active = FALSE, updated_at = NOW()
|
||||
WHERE product_id = :product_id AND status = 'open'"
|
||||
try {
|
||||
$lockStmt = $pdo->prepare(
|
||||
"SELECT id
|
||||
FROM stock_lot
|
||||
WHERE product_id = :product_id
|
||||
AND status = 'open'
|
||||
FOR UPDATE"
|
||||
);
|
||||
$clearStmt->execute([':product_id' => $productId]);
|
||||
return;
|
||||
}
|
||||
$lockStmt->execute([':product_id' => $productId]);
|
||||
|
||||
$selectedStmt = $pdo->prepare(
|
||||
"SELECT id
|
||||
FROM stock_lot
|
||||
WHERE product_id = :product_id
|
||||
AND status = 'open'
|
||||
AND next_active = TRUE
|
||||
LIMIT 1
|
||||
FOR UPDATE"
|
||||
);
|
||||
$selectedStmt->execute([':product_id' => $productId]);
|
||||
$selectedId = $selectedStmt->fetchColumn();
|
||||
if ($selectedId !== false && in_array((int) $selectedId, $qualifiedIds, true)) {
|
||||
return;
|
||||
}
|
||||
$qualifiedStmt = $pdo->prepare(
|
||||
"SELECT sl.id
|
||||
FROM stock_lot sl
|
||||
INNER JOIN v_stock_lot_balance v ON v.stock_lot_id = sl.id
|
||||
WHERE sl.product_id = :product_id
|
||||
AND sl.status = 'open'
|
||||
AND NULLIF(TRIM(sl.lot_number), '') IS NOT NULL
|
||||
AND sl.manufacturer_party_id IS NOT NULL
|
||||
AND NULLIF(TRIM(sl.manufacturer_lot_number), '') IS NOT NULL
|
||||
AND sl.mfg_date IS NOT NULL
|
||||
AND sl.expiry_date IS NOT NULL
|
||||
AND sl.purchase_date IS NOT NULL
|
||||
AND v.qty_net > 0
|
||||
ORDER BY sl.id"
|
||||
);
|
||||
$qualifiedStmt->execute([':product_id' => $productId]);
|
||||
$qualifiedIds = array_map('intval', $qualifiedStmt->fetchAll(PDO::FETCH_COLUMN));
|
||||
|
||||
$clearStmt = $pdo->prepare(
|
||||
"UPDATE stock_lot
|
||||
SET next_active = FALSE, updated_at = NOW()
|
||||
WHERE product_id = :product_id AND status = 'open'"
|
||||
);
|
||||
$clearStmt->execute([':product_id' => $productId]);
|
||||
if (count($qualifiedIds) === 1) {
|
||||
$clearStmt = $pdo->prepare(
|
||||
"UPDATE stock_lot
|
||||
SET next_active = FALSE, updated_at = NOW()
|
||||
WHERE product_id = :product_id AND status = 'open'"
|
||||
);
|
||||
$clearStmt->execute([':product_id' => $productId]);
|
||||
$selectStmt = $pdo->prepare(
|
||||
"UPDATE stock_lot
|
||||
SET next_active = TRUE, updated_at = NOW()
|
||||
WHERE id = :lot_id"
|
||||
);
|
||||
$selectStmt->execute([':lot_id' => $qualifiedIds[0]]);
|
||||
} elseif ($qualifiedIds === []) {
|
||||
$clearStmt = $pdo->prepare(
|
||||
"UPDATE stock_lot
|
||||
SET next_active = FALSE, updated_at = NOW()
|
||||
WHERE product_id = :product_id AND status = 'open'"
|
||||
);
|
||||
$clearStmt->execute([':product_id' => $productId]);
|
||||
} else {
|
||||
$selectedStmt = $pdo->prepare(
|
||||
"SELECT id
|
||||
FROM stock_lot
|
||||
WHERE product_id = :product_id
|
||||
AND status = 'open'
|
||||
AND next_active = TRUE
|
||||
LIMIT 1
|
||||
FOR UPDATE"
|
||||
);
|
||||
$selectedStmt->execute([':product_id' => $productId]);
|
||||
$selectedId = $selectedStmt->fetchColumn();
|
||||
if ($selectedId === false || !in_array((int) $selectedId, $qualifiedIds, true)) {
|
||||
$clearStmt = $pdo->prepare(
|
||||
"UPDATE stock_lot
|
||||
SET next_active = FALSE, updated_at = NOW()
|
||||
WHERE product_id = :product_id AND status = 'open'"
|
||||
);
|
||||
$clearStmt->execute([':product_id' => $productId]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($startedTransaction) {
|
||||
$pdo->commit();
|
||||
}
|
||||
} catch (Throwable $error) {
|
||||
if ($startedTransaction && $pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
|
||||
function select_open_lot_for_activation(PDO $pdo, int $productId, int $lotId): void
|
||||
{
|
||||
if ($productId <= 0 || $lotId <= 0 || !is_qualified_open_lot($pdo, $lotId)) {
|
||||
if ($productId <= 0 || $lotId <= 0) {
|
||||
throw new InvalidArgumentException('Nur eine qualifizierte offene Charge kann ausgewaehlt werden');
|
||||
}
|
||||
|
||||
$lotStmt = $pdo->prepare(
|
||||
"SELECT product_id, status
|
||||
FROM stock_lot
|
||||
WHERE id = :lot_id
|
||||
FOR UPDATE"
|
||||
);
|
||||
$lotStmt->execute([':lot_id' => $lotId]);
|
||||
$lot = $lotStmt->fetch();
|
||||
if (!is_array($lot) || (int) $lot['product_id'] !== $productId || (string) $lot['status'] !== 'open') {
|
||||
throw new InvalidArgumentException('Offene Charge nicht gefunden');
|
||||
}
|
||||
|
||||
$startedTransaction = !$pdo->inTransaction();
|
||||
if ($startedTransaction) {
|
||||
$pdo->beginTransaction();
|
||||
}
|
||||
try {
|
||||
$lotStmt = $pdo->prepare(
|
||||
"SELECT product_id, status
|
||||
FROM stock_lot
|
||||
WHERE id = :lot_id
|
||||
FOR UPDATE"
|
||||
);
|
||||
$lotStmt->execute([':lot_id' => $lotId]);
|
||||
$lot = $lotStmt->fetch();
|
||||
if (!is_array($lot) || (int) $lot['product_id'] !== $productId || (string) $lot['status'] !== 'open') {
|
||||
throw new InvalidArgumentException('Offene Charge nicht gefunden');
|
||||
}
|
||||
if (!is_qualified_open_lot($pdo, $lotId)) {
|
||||
throw new InvalidArgumentException('Nur eine qualifizierte offene Charge kann ausgewaehlt werden');
|
||||
}
|
||||
|
||||
$clearStmt = $pdo->prepare(
|
||||
"UPDATE stock_lot
|
||||
SET next_active = FALSE, updated_at = NOW()
|
||||
|
||||
Reference in new issue
Block a user