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 === ''
|
$lotNumber === ''
|
||||||
);
|
);
|
||||||
sync_open_lot_activation_selection($pdo, $productId);
|
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['status'] = 'current';
|
||||||
$preparedLot['next_active'] = false;
|
$preparedLot['next_active'] = false;
|
||||||
} else {
|
} 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();
|
$startedTransaction = !$pdo->inTransaction();
|
||||||
if ($startedTransaction) {
|
if ($startedTransaction) {
|
||||||
@@ -608,7 +608,8 @@ function promote_open_lot_when_virtual_shortage_is_current(PDO $pdo, int $produc
|
|||||||
FOR UPDATE"
|
FOR UPDATE"
|
||||||
);
|
);
|
||||||
$currentStmt->execute([':product_id' => $productId]);
|
$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) {
|
if ($startedTransaction) {
|
||||||
$pdo->commit();
|
$pdo->commit();
|
||||||
}
|
}
|
||||||
@@ -675,6 +676,14 @@ function promote_open_lot_when_virtual_shortage_is_current(PDO $pdo, int $produc
|
|||||||
);
|
);
|
||||||
$promoteStmt->execute([':lot_id' => $lotId]);
|
$promoteStmt->execute([':lot_id' => $lotId]);
|
||||||
|
|
||||||
|
reconcile_virtual_shortage_allocations(
|
||||||
|
$pdo,
|
||||||
|
(int) $virtualShortageLotId,
|
||||||
|
$lotId,
|
||||||
|
$changedBy,
|
||||||
|
'Automatische Verrechnung bei Aktivierung einer echten Charge'
|
||||||
|
);
|
||||||
|
|
||||||
if ($startedTransaction) {
|
if ($startedTransaction) {
|
||||||
$pdo->commit();
|
$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
|
function select_open_lot_for_activation(PDO $pdo, int $productId, int $lotId): void
|
||||||
{
|
{
|
||||||
if ($productId <= 0 || $lotId <= 0) {
|
if ($productId <= 0 || $lotId <= 0) {
|
||||||
@@ -1217,8 +1298,7 @@ function replace_virtual_lot_allocation(
|
|||||||
$balanceStmt = $pdo->prepare(
|
$balanceStmt = $pdo->prepare(
|
||||||
"SELECT COALESCE(v.qty_net, 0)
|
"SELECT COALESCE(v.qty_net, 0)
|
||||||
FROM v_stock_lot_balance v
|
FROM v_stock_lot_balance v
|
||||||
WHERE v.stock_lot_id = :lot_id
|
WHERE v.stock_lot_id = :lot_id"
|
||||||
FOR UPDATE"
|
|
||||||
);
|
);
|
||||||
$balanceStmt->execute([':lot_id' => $realLotId]);
|
$balanceStmt->execute([':lot_id' => $realLotId]);
|
||||||
$available = (float) ($balanceStmt->fetchColumn() ?: 0);
|
$available = (float) ($balanceStmt->fetchColumn() ?: 0);
|
||||||
|
|||||||
Reference in new issue
Block a user