Reconcile virtual shortage allocations on lot activation
This commit is contained in:
1 parent
0e8df45548
commit
4a8936761b
2 files changed
+85
-5
No files matched your search
@@ -126,7 +126,7 @@ try {
|
||||
$lotNumber === ''
|
||||
);
|
||||
sync_open_lot_activation_selection($pdo, $productId);
|
||||
if (promote_open_lot_when_virtual_shortage_is_current($pdo, $productId, $lotId)) {
|
||||
if (promote_open_lot_when_virtual_shortage_is_current($pdo, $productId, $lotId, (string) ($currentUser['username'] ?? $currentUser['email'] ?? 'unknown'))) {
|
||||
$preparedLot['status'] = 'current';
|
||||
$preparedLot['next_active'] = false;
|
||||
} else {
|
||||
|
||||
@@ -590,7 +590,7 @@ function sync_open_lot_activation_selection(PDO $pdo, int $productId): void
|
||||
}
|
||||
}
|
||||
|
||||
function promote_open_lot_when_virtual_shortage_is_current(PDO $pdo, int $productId, int $lotId): bool
|
||||
function promote_open_lot_when_virtual_shortage_is_current(PDO $pdo, int $productId, int $lotId, string $changedBy): bool
|
||||
{
|
||||
$startedTransaction = !$pdo->inTransaction();
|
||||
if ($startedTransaction) {
|
||||
@@ -608,7 +608,8 @@ function promote_open_lot_when_virtual_shortage_is_current(PDO $pdo, int $produc
|
||||
FOR UPDATE"
|
||||
);
|
||||
$currentStmt->execute([':product_id' => $productId]);
|
||||
if ($currentStmt->fetchColumn() === false || !is_qualified_open_lot($pdo, $lotId)) {
|
||||
$virtualShortageLotId = $currentStmt->fetchColumn();
|
||||
if ($virtualShortageLotId === false || !is_qualified_open_lot($pdo, $lotId)) {
|
||||
if ($startedTransaction) {
|
||||
$pdo->commit();
|
||||
}
|
||||
@@ -675,6 +676,14 @@ function promote_open_lot_when_virtual_shortage_is_current(PDO $pdo, int $produc
|
||||
);
|
||||
$promoteStmt->execute([':lot_id' => $lotId]);
|
||||
|
||||
reconcile_virtual_shortage_allocations(
|
||||
$pdo,
|
||||
(int) $virtualShortageLotId,
|
||||
$lotId,
|
||||
$changedBy,
|
||||
'Automatische Verrechnung bei Aktivierung einer echten Charge'
|
||||
);
|
||||
|
||||
if ($startedTransaction) {
|
||||
$pdo->commit();
|
||||
}
|
||||
@@ -687,6 +696,78 @@ function promote_open_lot_when_virtual_shortage_is_current(PDO $pdo, int $produc
|
||||
}
|
||||
}
|
||||
|
||||
function reconcile_virtual_shortage_allocations(
|
||||
PDO $pdo,
|
||||
int $virtualLotId,
|
||||
int $realLotId,
|
||||
string $changedBy,
|
||||
string $reason
|
||||
): void {
|
||||
$allocationStmt = $pdo->prepare(
|
||||
"SELECT id, qty
|
||||
FROM sales_order_line_lot_allocation
|
||||
WHERE lot_id = :lot_id
|
||||
AND allocation_status = 'reserved'
|
||||
ORDER BY id
|
||||
FOR UPDATE"
|
||||
);
|
||||
$allocationStmt->execute([':lot_id' => $virtualLotId]);
|
||||
$allocations = $allocationStmt->fetchAll();
|
||||
|
||||
foreach ($allocations as $allocation) {
|
||||
$balanceStmt = $pdo->prepare(
|
||||
"SELECT COALESCE(qty_net, 0)
|
||||
FROM v_stock_lot_balance
|
||||
WHERE stock_lot_id = :lot_id"
|
||||
);
|
||||
$balanceStmt->execute([':lot_id' => $realLotId]);
|
||||
$availableQty = (float) ($balanceStmt->fetchColumn() ?: 0);
|
||||
if ($availableQty <= 0.0000001) {
|
||||
break;
|
||||
}
|
||||
|
||||
$replaceQty = min((float) $allocation['qty'], $availableQty);
|
||||
replace_virtual_lot_allocation(
|
||||
$pdo,
|
||||
(int) $allocation['id'],
|
||||
$realLotId,
|
||||
$replaceQty,
|
||||
$changedBy,
|
||||
$reason
|
||||
);
|
||||
}
|
||||
|
||||
$remainingStmt = $pdo->prepare(
|
||||
"SELECT COUNT(*)
|
||||
FROM sales_order_line_lot_allocation
|
||||
WHERE lot_id = :lot_id
|
||||
AND allocation_status = 'reserved'"
|
||||
);
|
||||
$remainingStmt->execute([':lot_id' => $virtualLotId]);
|
||||
if ((int) $remainingStmt->fetchColumn() !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$closeStmt = $pdo->prepare(
|
||||
"UPDATE stock_lot
|
||||
SET status = 'closed', next_active = FALSE, updated_at = NOW()
|
||||
WHERE id = :lot_id
|
||||
AND status = 'virtual_shortage'"
|
||||
);
|
||||
$closeStmt->execute([':lot_id' => $virtualLotId]);
|
||||
if ($closeStmt->rowCount() !== 1) {
|
||||
throw new RuntimeException('Virtuelle Fehlbestandscharge konnte nicht aufgeloest werden');
|
||||
}
|
||||
system_write_audit_log($pdo, 'stock_lot', (string) $virtualLotId, 'closed', $changedBy, [
|
||||
'status' => 'virtual_shortage',
|
||||
], [
|
||||
'status' => 'closed',
|
||||
], [
|
||||
'module' => 'erp.lager',
|
||||
'reason' => $reason,
|
||||
]);
|
||||
}
|
||||
|
||||
function select_open_lot_for_activation(PDO $pdo, int $productId, int $lotId): void
|
||||
{
|
||||
if ($productId <= 0 || $lotId <= 0) {
|
||||
@@ -1217,8 +1298,7 @@ function replace_virtual_lot_allocation(
|
||||
$balanceStmt = $pdo->prepare(
|
||||
"SELECT COALESCE(v.qty_net, 0)
|
||||
FROM v_stock_lot_balance v
|
||||
WHERE v.stock_lot_id = :lot_id
|
||||
FOR UPDATE"
|
||||
WHERE v.stock_lot_id = :lot_id"
|
||||
);
|
||||
$balanceStmt->execute([':lot_id' => $realLotId]);
|
||||
$available = (float) ($balanceStmt->fetchColumn() ?: 0);
|
||||
|
||||
Reference in new issue
Block a user