Complete lot activation and virtual shortage reconciliation
This commit is contained in:
1 parent
400b352522
commit
8f7fb9875a
3 files changed
+276
-34
No files matched your search
@@ -66,10 +66,22 @@ try {
|
|||||||
if (($updatedLot['status'] ?? '') === 'open') {
|
if (($updatedLot['status'] ?? '') === 'open') {
|
||||||
sync_open_lot_activation_selection($pdo, $productId);
|
sync_open_lot_activation_selection($pdo, $productId);
|
||||||
$updatedLot['next_active'] = is_open_lot_selected_for_activation($pdo, (int) $updatedLot['id']);
|
$updatedLot['next_active'] = is_open_lot_selected_for_activation($pdo, (int) $updatedLot['id']);
|
||||||
|
} else {
|
||||||
|
ensure_current_lot_and_reconcile_virtual_shortage(
|
||||||
|
$pdo,
|
||||||
|
$productId,
|
||||||
|
(string) ($currentUser['username'] ?? $currentUser['email'] ?? 'unknown'),
|
||||||
|
'Verrechnung nach Pflege der aktiven Charge'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
refresh_lager_stock_lot_forecast_for_product($pdo, $productId);
|
refresh_lager_stock_lot_forecast_for_product($pdo, $productId);
|
||||||
$forecast = get_lager_product_forecast($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]);
|
$currentLot = get_current_lot_snapshot($pdo, $productId);
|
||||||
|
json_response(200, ['ok' => true, 'productId' => $productId, 'lot' => $currentLot, 'balance' => [
|
||||||
|
'qty_net' => $currentLot['qty_net'],
|
||||||
|
'qty_in' => $currentLot['qty_in'],
|
||||||
|
'qty_out' => $currentLot['qty_out'],
|
||||||
|
], 'forecast' => $forecast]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action === 'delete_open_lot') {
|
if ($action === 'delete_open_lot') {
|
||||||
@@ -79,7 +91,13 @@ try {
|
|||||||
(string) ($currentUser['username'] ?? $currentUser['email'] ?? 'unknown')
|
(string) ($currentUser['username'] ?? $currentUser['email'] ?? 'unknown')
|
||||||
);
|
);
|
||||||
sync_open_lot_activation_selection($pdo, $productId);
|
sync_open_lot_activation_selection($pdo, $productId);
|
||||||
json_response(200, ['ok' => true, 'productId' => $productId, 'availableQty' => get_lager_product_available_qty($pdo, $productId)]);
|
ensure_current_lot_and_reconcile_virtual_shortage(
|
||||||
|
$pdo,
|
||||||
|
$productId,
|
||||||
|
(string) ($currentUser['username'] ?? $currentUser['email'] ?? 'unknown'),
|
||||||
|
'Verrechnung nach Loeschung einer offenen Charge'
|
||||||
|
);
|
||||||
|
json_response(200, ['ok' => true, 'productId' => $productId, 'currentLot' => get_current_lot_snapshot($pdo, $productId), 'availableQty' => get_lager_product_available_qty($pdo, $productId)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action === 'prepare_lot') {
|
if ($action === 'prepare_lot') {
|
||||||
@@ -141,8 +159,15 @@ try {
|
|||||||
$productId = (int) ($data['productId'] ?? 0);
|
$productId = (int) ($data['productId'] ?? 0);
|
||||||
$lotId = (int) ($data['lotId'] ?? 0);
|
$lotId = (int) ($data['lotId'] ?? 0);
|
||||||
select_open_lot_for_activation($pdo, $productId, $lotId);
|
select_open_lot_for_activation($pdo, $productId, $lotId);
|
||||||
|
ensure_current_lot_and_reconcile_virtual_shortage(
|
||||||
|
$pdo,
|
||||||
|
$productId,
|
||||||
|
(string) ($currentUser['username'] ?? $currentUser['email'] ?? 'unknown'),
|
||||||
|
'Verrechnung nach Auswahl der naechsten aktiven Charge'
|
||||||
|
);
|
||||||
refresh_lager_stock_lot_forecast_for_product($pdo, $productId);
|
refresh_lager_stock_lot_forecast_for_product($pdo, $productId);
|
||||||
json_response(200, ['ok' => true, 'productId' => $productId, 'selectedLotId' => $lotId, 'forecast' => get_lager_product_forecast($pdo, $productId)]);
|
$currentLot = get_current_lot_snapshot($pdo, $productId);
|
||||||
|
json_response(200, ['ok' => true, 'productId' => $productId, 'selectedLotId' => $lotId, 'currentLot' => $currentLot, 'forecast' => get_lager_product_forecast($pdo, $productId)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
json_response(422, ['ok' => false, 'error' => 'Unsupported action']);
|
json_response(422, ['ok' => false, 'error' => 'Unsupported action']);
|
||||||
|
|||||||
+244
-27
@@ -452,7 +452,7 @@ function update_stock_lot_traceability(
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
if ($receiptQty > 0 || $adjustmentQty !== 0.0 || $outQty > 0) {
|
if ($receiptQty > 0 || $adjustmentQty !== 0.0 || $outQty > 0) {
|
||||||
book_stock_lot_movements($pdo, (int) $before['product_id'], $lotId, $receiptQty, $adjustmentQty, $outQty);
|
book_stock_lot_movements($pdo, (int) $before['product_id'], $lotId, $receiptQty, $adjustmentQty, $outQty, $changedBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($startedTransaction) {
|
if ($startedTransaction) {
|
||||||
@@ -598,24 +598,6 @@ function promote_open_lot_when_virtual_shortage_is_current(PDO $pdo, int $produc
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$currentStmt = $pdo->prepare(
|
|
||||||
"SELECT id
|
|
||||||
FROM stock_lot
|
|
||||||
WHERE product_id = :product_id
|
|
||||||
AND status = 'virtual_shortage'
|
|
||||||
ORDER BY id
|
|
||||||
LIMIT 1
|
|
||||||
FOR UPDATE"
|
|
||||||
);
|
|
||||||
$currentStmt->execute([':product_id' => $productId]);
|
|
||||||
$virtualShortageLotId = $currentStmt->fetchColumn();
|
|
||||||
if ($virtualShortageLotId === false || !is_qualified_open_lot($pdo, $lotId)) {
|
|
||||||
if ($startedTransaction) {
|
|
||||||
$pdo->commit();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$realCurrentStmt = $pdo->prepare(
|
$realCurrentStmt = $pdo->prepare(
|
||||||
"SELECT id
|
"SELECT id
|
||||||
FROM stock_lot
|
FROM stock_lot
|
||||||
@@ -644,6 +626,24 @@ function promote_open_lot_when_virtual_shortage_is_current(PDO $pdo, int $produc
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$currentStmt = $pdo->prepare(
|
||||||
|
"SELECT id
|
||||||
|
FROM stock_lot
|
||||||
|
WHERE product_id = :product_id
|
||||||
|
AND status = 'virtual_shortage'
|
||||||
|
ORDER BY id
|
||||||
|
LIMIT 1
|
||||||
|
FOR UPDATE"
|
||||||
|
);
|
||||||
|
$currentStmt->execute([':product_id' => $productId]);
|
||||||
|
$virtualShortageLotId = $currentStmt->fetchColumn();
|
||||||
|
if (!is_qualified_open_lot($pdo, $lotId)) {
|
||||||
|
if ($startedTransaction) {
|
||||||
|
$pdo->commit();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$lotStmt = $pdo->prepare(
|
$lotStmt = $pdo->prepare(
|
||||||
"SELECT id
|
"SELECT id
|
||||||
FROM stock_lot
|
FROM stock_lot
|
||||||
@@ -676,13 +676,15 @@ 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(
|
if ($virtualShortageLotId !== false) {
|
||||||
$pdo,
|
reconcile_virtual_shortage_allocations(
|
||||||
(int) $virtualShortageLotId,
|
$pdo,
|
||||||
$lotId,
|
(int) $virtualShortageLotId,
|
||||||
$changedBy,
|
$lotId,
|
||||||
'Automatische Verrechnung bei Aktivierung einer echten Charge'
|
$changedBy,
|
||||||
);
|
'Automatische Verrechnung bei Aktivierung einer echten Charge'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ($startedTransaction) {
|
if ($startedTransaction) {
|
||||||
$pdo->commit();
|
$pdo->commit();
|
||||||
@@ -768,6 +770,156 @@ function reconcile_virtual_shortage_allocations(
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensure_current_lot_and_reconcile_virtual_shortage(
|
||||||
|
PDO $pdo,
|
||||||
|
int $productId,
|
||||||
|
string $changedBy,
|
||||||
|
string $reason
|
||||||
|
): void {
|
||||||
|
$startedTransaction = !$pdo->inTransaction();
|
||||||
|
if ($startedTransaction) {
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$currentStmt = $pdo->prepare(
|
||||||
|
"SELECT id
|
||||||
|
FROM stock_lot
|
||||||
|
WHERE product_id = :product_id
|
||||||
|
AND status = 'current'
|
||||||
|
LIMIT 1
|
||||||
|
FOR UPDATE"
|
||||||
|
);
|
||||||
|
$currentStmt->execute([':product_id' => $productId]);
|
||||||
|
$currentLotId = $currentStmt->fetchColumn();
|
||||||
|
if ($currentLotId === false) {
|
||||||
|
throw new RuntimeException("Keine aktuelle Charge fuer Produkt {$productId} vorhanden");
|
||||||
|
}
|
||||||
|
|
||||||
|
$balanceStmt = $pdo->prepare(
|
||||||
|
"SELECT COALESCE(qty_net, 0)
|
||||||
|
FROM v_stock_lot_balance
|
||||||
|
WHERE stock_lot_id = :lot_id"
|
||||||
|
);
|
||||||
|
$balanceStmt->execute([':lot_id' => (int) $currentLotId]);
|
||||||
|
$currentQty = (float) ($balanceStmt->fetchColumn() ?: 0);
|
||||||
|
|
||||||
|
if ($currentQty <= 0.0000001) {
|
||||||
|
sync_open_lot_activation_selection($pdo, $productId);
|
||||||
|
|
||||||
|
$selectedStmt = $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 sl.next_active = TRUE
|
||||||
|
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
|
||||||
|
LIMIT 1"
|
||||||
|
);
|
||||||
|
$selectedStmt->execute([':product_id' => $productId]);
|
||||||
|
$nextLotId = $selectedStmt->fetchColumn();
|
||||||
|
|
||||||
|
if ($nextLotId === false) {
|
||||||
|
$countStmt = $pdo->prepare(
|
||||||
|
"SELECT COUNT(*), MIN(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"
|
||||||
|
);
|
||||||
|
$countStmt->execute([':product_id' => $productId]);
|
||||||
|
$candidate = $countStmt->fetch(PDO::FETCH_NUM);
|
||||||
|
if (is_array($candidate) && (int) $candidate[0] === 1) {
|
||||||
|
$nextLotId = $candidate[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($nextLotId !== false && $nextLotId !== null) {
|
||||||
|
promote_open_lot_when_virtual_shortage_is_current(
|
||||||
|
$pdo,
|
||||||
|
$productId,
|
||||||
|
(int) $nextLotId,
|
||||||
|
$changedBy
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($iteration = 0; $iteration < 100; $iteration++) {
|
||||||
|
$currentStmt->execute([':product_id' => $productId]);
|
||||||
|
$currentLotId = $currentStmt->fetchColumn();
|
||||||
|
if ($currentLotId === false) {
|
||||||
|
throw new RuntimeException("Keine aktuelle Charge fuer Produkt {$productId} vorhanden");
|
||||||
|
}
|
||||||
|
|
||||||
|
$balanceStmt->execute([':lot_id' => (int) $currentLotId]);
|
||||||
|
$currentQty = (float) ($balanceStmt->fetchColumn() ?: 0);
|
||||||
|
if ($currentQty <= 0.0000001) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$virtualStmt = $pdo->prepare(
|
||||||
|
"SELECT id
|
||||||
|
FROM stock_lot
|
||||||
|
WHERE product_id = :product_id
|
||||||
|
AND status = 'virtual_shortage'
|
||||||
|
ORDER BY id
|
||||||
|
LIMIT 1
|
||||||
|
FOR UPDATE"
|
||||||
|
);
|
||||||
|
$virtualStmt->execute([':product_id' => $productId]);
|
||||||
|
$virtualLotId = $virtualStmt->fetchColumn();
|
||||||
|
if ($virtualLotId === false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
reconcile_virtual_shortage_allocations(
|
||||||
|
$pdo,
|
||||||
|
(int) $virtualLotId,
|
||||||
|
(int) $currentLotId,
|
||||||
|
$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' => (int) $virtualLotId]);
|
||||||
|
if ((int) $remainingStmt->fetchColumn() === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($iteration >= 100) {
|
||||||
|
throw new RuntimeException("Virtuelle Fehlbestandscharge fuer Produkt {$productId} konnte nicht vollstaendig verrechnet werden");
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
function select_open_lot_for_activation(PDO $pdo, int $productId, int $lotId): void
|
||||||
{
|
{
|
||||||
if ($productId <= 0 || $lotId <= 0) {
|
if ($productId <= 0 || $lotId <= 0) {
|
||||||
@@ -869,6 +1021,46 @@ function get_stock_lot_balance(PDO $pdo, int $lotId): array
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_current_lot_snapshot(PDO $pdo, int $productId): array
|
||||||
|
{
|
||||||
|
$stmt = $pdo->prepare(
|
||||||
|
"SELECT sl.id, sl.product_id, sl.lot_number, sl.status, sl.next_active,
|
||||||
|
sl.manufacturer_party_id, sl.manufacturer_lot_number,
|
||||||
|
mp.name AS manufacturer_name, sl.mfg_date, sl.expiry_date, sl.purchase_date,
|
||||||
|
COALESCE(v.qty_net, 0) AS qty_net,
|
||||||
|
COALESCE(v.qty_in, 0) AS qty_in,
|
||||||
|
COALESCE(v.qty_out, 0) AS qty_out
|
||||||
|
FROM stock_lot sl
|
||||||
|
LEFT JOIN party mp ON mp.id = sl.manufacturer_party_id
|
||||||
|
LEFT JOIN v_stock_lot_balance v ON v.stock_lot_id = sl.id
|
||||||
|
WHERE sl.product_id = :product_id
|
||||||
|
AND sl.status = 'current'
|
||||||
|
LIMIT 1"
|
||||||
|
);
|
||||||
|
$stmt->execute([':product_id' => $productId]);
|
||||||
|
$row = $stmt->fetch();
|
||||||
|
if (!is_array($row)) {
|
||||||
|
throw new RuntimeException("Keine aktuelle Charge fuer Produkt {$productId} vorhanden");
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => (int) $row['id'],
|
||||||
|
'product_id' => (int) $row['product_id'],
|
||||||
|
'lot_number' => $row['lot_number'],
|
||||||
|
'status' => (string) $row['status'],
|
||||||
|
'next_active' => (bool) $row['next_active'],
|
||||||
|
'manufacturer_party_id' => $row['manufacturer_party_id'] === null ? null : (int) $row['manufacturer_party_id'],
|
||||||
|
'manufacturer_lot_number' => $row['manufacturer_lot_number'],
|
||||||
|
'manufacturer_name' => $row['manufacturer_name'],
|
||||||
|
'mfg_date' => $row['mfg_date'],
|
||||||
|
'expiry_date' => $row['expiry_date'],
|
||||||
|
'purchase_date' => $row['purchase_date'],
|
||||||
|
'qty_net' => (float) $row['qty_net'],
|
||||||
|
'qty_in' => (float) $row['qty_in'],
|
||||||
|
'qty_out' => (float) $row['qty_out'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
function insert_stock_move_out(
|
function insert_stock_move_out(
|
||||||
PDO $pdo,
|
PDO $pdo,
|
||||||
int $productId,
|
int $productId,
|
||||||
@@ -977,7 +1169,8 @@ function book_stock_lot_movements(
|
|||||||
int $lotId,
|
int $lotId,
|
||||||
float $receiptQty,
|
float $receiptQty,
|
||||||
float $adjustmentQty,
|
float $adjustmentQty,
|
||||||
float $outQty
|
float $outQty,
|
||||||
|
string $changedBy
|
||||||
): void {
|
): void {
|
||||||
$locations = get_default_location_ids($pdo);
|
$locations = get_default_location_ids($pdo);
|
||||||
$balanceStmt = $pdo->prepare(
|
$balanceStmt = $pdo->prepare(
|
||||||
@@ -1012,6 +1205,12 @@ function book_stock_lot_movements(
|
|||||||
insert_stock_move_adjustment($pdo, $productId, $lotId, $correctionQty, $locations['storage'], null, 'Manuelle Bestandskorrektur via Chargenformular');
|
insert_stock_move_adjustment($pdo, $productId, $lotId, $correctionQty, $locations['storage'], null, 'Manuelle Bestandskorrektur via Chargenformular');
|
||||||
}
|
}
|
||||||
$balance += $adjustmentQty;
|
$balance += $adjustmentQty;
|
||||||
|
ensure_current_lot_and_reconcile_virtual_shortage(
|
||||||
|
$pdo,
|
||||||
|
$productId,
|
||||||
|
$changedBy,
|
||||||
|
'Verrechnung nach manueller Bestandskorrektur'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($outQty > $balance) {
|
if ($outQty > $balance) {
|
||||||
@@ -1019,6 +1218,12 @@ function book_stock_lot_movements(
|
|||||||
}
|
}
|
||||||
if ($outQty > 0) {
|
if ($outQty > 0) {
|
||||||
insert_stock_move_out($pdo, $productId, $lotId, $outQty, $locations['storage'], $locations['dispatch'], 'Manueller Lagerabgang via Chargenformular');
|
insert_stock_move_out($pdo, $productId, $lotId, $outQty, $locations['storage'], $locations['dispatch'], 'Manueller Lagerabgang via Chargenformular');
|
||||||
|
ensure_current_lot_and_reconcile_virtual_shortage(
|
||||||
|
$pdo,
|
||||||
|
$productId,
|
||||||
|
$changedBy,
|
||||||
|
'Verrechnung nach manuellem Lagerabgang'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1421,6 +1626,12 @@ function allocate_components_for_line(
|
|||||||
throw new RuntimeException("Allokationsschutz ausgelost fuer Produkt {$productId}");
|
throw new RuntimeException("Allokationsschutz ausgelost fuer Produkt {$productId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensure_current_lot_and_reconcile_virtual_shortage(
|
||||||
|
$pdo,
|
||||||
|
$productId,
|
||||||
|
'system',
|
||||||
|
"Verrechnung vor Verkaufsallokation: order={$orderId}:line={$lineNo}"
|
||||||
|
);
|
||||||
$current = get_current_lot_balance_for_update($pdo, $productId);
|
$current = get_current_lot_balance_for_update($pdo, $productId);
|
||||||
$lotId = $current['lot_id'];
|
$lotId = $current['lot_id'];
|
||||||
$available = $current['qty_net'];
|
$available = $current['qty_net'];
|
||||||
@@ -1442,6 +1653,12 @@ function allocate_components_for_line(
|
|||||||
(int) $locations['dispatch'],
|
(int) $locations['dispatch'],
|
||||||
"{$movementSource}:order={$orderId}:line={$lineNo}:product={$productId}"
|
"{$movementSource}:order={$orderId}:line={$lineNo}:product={$productId}"
|
||||||
);
|
);
|
||||||
|
ensure_current_lot_and_reconcile_virtual_shortage(
|
||||||
|
$pdo,
|
||||||
|
$productId,
|
||||||
|
'system',
|
||||||
|
"Verrechnung nach Verkaufsabgang: order={$orderId}:line={$lineNo}"
|
||||||
|
);
|
||||||
$allocationStatus = 'allocated';
|
$allocationStatus = 'allocated';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -859,20 +859,20 @@ function render_auth_home_page(array $user, array $otcProducts = [], array $best
|
|||||||
echo " const syncLagerActiveLotView = (lot) => { const drawer = getDrawer(); const trigger = contentRoot.querySelector('[data-lager-drawer-open][aria-expanded=\"true\"]'); if (!drawer || !lot || !trigger) { return; } const manufacturer = drawer.querySelector('[data-lager-manufacturer]'); if (manufacturer) { manufacturer.value = lot.manufacturer_party_id ?? ''; } const manufacturerName = manufacturer?.selectedOptions?.[0]?.textContent || 'Nicht hinterlegt'; const values = { '[data-lager-drawer-lot-number]': lot.lot_number || 'Nicht hinterlegt', '[data-lager-drawer-manufacturer-name]': manufacturerName, '[data-lager-drawer-manufacturer-lot-number]': lot.manufacturer_lot_number || 'Nicht hinterlegt', '[data-lager-drawer-mfg-date]': lot.mfg_date || 'Nicht hinterlegt', '[data-lager-drawer-expiry-date]': lot.expiry_date || 'Nicht hinterlegt', '[data-lager-drawer-purchase-date]': lot.purchase_date || 'Nicht hinterlegt' }; Object.entries(values).forEach(([selector, value]) => { const target = drawer.querySelector(selector); if (target) { target.textContent = value; } }); const formValues = { '[data-lager-lot-number]': lot.lot_number || '', '[data-lager-manufacturer-lot]': lot.manufacturer_lot_number || '', '[data-lager-mfg-date]': lot.mfg_date || '', '[data-lager-expiry-date]': lot.expiry_date || '', '[data-lager-purchase-date]': lot.purchase_date || '' }; Object.entries(formValues).forEach(([selector, value]) => { const input = drawer.querySelector(selector); if (input) { input.value = value; } }); trigger.dataset.lagerDrawerLotId = String(lot.id || lot.lot_id || ''); trigger.dataset.lagerDrawerLotNumber = lot.lot_number || ''; trigger.dataset.lagerDrawerManufacturerPartyId = String(lot.manufacturer_party_id ?? ''); trigger.dataset.lagerDrawerManufacturerName = manufacturerName; trigger.dataset.lagerDrawerManufacturerLotNumber = lot.manufacturer_lot_number || ''; trigger.dataset.lagerDrawerMfgDate = lot.mfg_date || ''; trigger.dataset.lagerDrawerExpiryDate = lot.expiry_date || ''; trigger.dataset.lagerDrawerPurchaseDate = lot.purchase_date || ''; drawer.dataset.lagerActiveLotId = String(lot.id || lot.lot_id || ''); };";
|
echo " const syncLagerActiveLotView = (lot) => { const drawer = getDrawer(); const trigger = contentRoot.querySelector('[data-lager-drawer-open][aria-expanded=\"true\"]'); if (!drawer || !lot || !trigger) { return; } const manufacturer = drawer.querySelector('[data-lager-manufacturer]'); if (manufacturer) { manufacturer.value = lot.manufacturer_party_id ?? ''; } const manufacturerName = manufacturer?.selectedOptions?.[0]?.textContent || 'Nicht hinterlegt'; const values = { '[data-lager-drawer-lot-number]': lot.lot_number || 'Nicht hinterlegt', '[data-lager-drawer-manufacturer-name]': manufacturerName, '[data-lager-drawer-manufacturer-lot-number]': lot.manufacturer_lot_number || 'Nicht hinterlegt', '[data-lager-drawer-mfg-date]': lot.mfg_date || 'Nicht hinterlegt', '[data-lager-drawer-expiry-date]': lot.expiry_date || 'Nicht hinterlegt', '[data-lager-drawer-purchase-date]': lot.purchase_date || 'Nicht hinterlegt' }; Object.entries(values).forEach(([selector, value]) => { const target = drawer.querySelector(selector); if (target) { target.textContent = value; } }); const formValues = { '[data-lager-lot-number]': lot.lot_number || '', '[data-lager-manufacturer-lot]': lot.manufacturer_lot_number || '', '[data-lager-mfg-date]': lot.mfg_date || '', '[data-lager-expiry-date]': lot.expiry_date || '', '[data-lager-purchase-date]': lot.purchase_date || '' }; Object.entries(formValues).forEach(([selector, value]) => { const input = drawer.querySelector(selector); if (input) { input.value = value; } }); trigger.dataset.lagerDrawerLotId = String(lot.id || lot.lot_id || ''); trigger.dataset.lagerDrawerLotNumber = lot.lot_number || ''; trigger.dataset.lagerDrawerManufacturerPartyId = String(lot.manufacturer_party_id ?? ''); trigger.dataset.lagerDrawerManufacturerName = manufacturerName; trigger.dataset.lagerDrawerManufacturerLotNumber = lot.manufacturer_lot_number || ''; trigger.dataset.lagerDrawerMfgDate = lot.mfg_date || ''; trigger.dataset.lagerDrawerExpiryDate = lot.expiry_date || ''; trigger.dataset.lagerDrawerPurchaseDate = lot.purchase_date || ''; drawer.dataset.lagerActiveLotId = String(lot.id || lot.lot_id || ''); };";
|
||||||
echo " const clearLagerMovementInputs = () => { const drawer = getDrawer(); if (!drawer) { return; } drawer.querySelectorAll('[data-lager-receipt-qty], [data-lager-adjustment-qty], [data-lager-out-qty]').forEach((input) => { input.value = ''; }); };";
|
echo " const clearLagerMovementInputs = () => { const drawer = getDrawer(); if (!drawer) { return; } drawer.querySelectorAll('[data-lager-receipt-qty], [data-lager-adjustment-qty], [data-lager-out-qty]').forEach((input) => { input.value = ''; }); };";
|
||||||
echo " const syncLagerOpenLotCard = (lot, balance, exactCard = null) => { const drawer = getDrawer(); const lotId = lot?.id || lot?.lot_id || ''; const card = exactCard || drawer?.querySelector('[data-lager-open-card=\"' + lotId + '\"]'); if (!card) { return; } const manufacturerSelect = card.querySelector('[data-lager-open-manufacturer]') || drawer?.querySelector('[data-lager-new-manufacturer]'); const qualified = Boolean(lot?.lot_number && lot?.manufacturer_party_id && lot?.manufacturer_lot_number && lot?.mfg_date && lot?.expiry_date && lot?.purchase_date && Number(balance?.qty_net || 0) > 0); const selected = lot?.next_active === true; const values = { '[data-lager-open-card-lot-number]': lot?.lot_number || 'Nicht hinterlegt', '[data-lager-open-card-qty-net]': String(balance?.qty_net ?? 0), '[data-lager-open-card-qty-in]': String(balance?.qty_in ?? 0), '[data-lager-open-card-manufacturer]': manufacturerSelect?.selectedOptions?.[0]?.textContent || 'Nicht hinterlegt', '[data-lager-open-card-manufacturer-lot]': lot?.manufacturer_lot_number || 'Nicht hinterlegt', '[data-lager-open-card-mfg-date]': lot?.mfg_date || 'Nicht hinterlegt', '[data-lager-open-card-expiry-date]': lot?.expiry_date || 'Nicht hinterlegt', '[data-lager-open-card-purchase-date]': lot?.purchase_date || 'Nicht hinterlegt' }; Object.entries(values).forEach(([selector, value]) => { const target = card.querySelector(selector); if (target) { target.textContent = value; } }); card.classList.toggle('sg-lager-open-lot--next-active', selected); const selectedLabel = card.querySelector('[data-lager-open-card-next-active]'); if (selectedLabel) { selectedLabel.textContent = selected ? 'Als nächste aktive Charge ausgewählt' : 'Nicht ausgewählt'; } const selectButton = card.querySelector('[data-lager-open-select]'); if (selectButton) { selectButton.dataset.lagerOpenSelectable = String(qualified); selectButton.disabled = !qualified || selected; selectButton.setAttribute('aria-disabled', String(!qualified || selected)); } };";
|
echo " const syncLagerOpenLotCard = (lot, balance, exactCard = null) => { const drawer = getDrawer(); const lotId = lot?.id || lot?.lot_id || ''; const card = exactCard || drawer?.querySelector('[data-lager-open-card=\"' + lotId + '\"]'); if (!card) { return; } const manufacturerSelect = card.querySelector('[data-lager-open-manufacturer]') || drawer?.querySelector('[data-lager-new-manufacturer]'); const qualified = Boolean(lot?.lot_number && lot?.manufacturer_party_id && lot?.manufacturer_lot_number && lot?.mfg_date && lot?.expiry_date && lot?.purchase_date && Number(balance?.qty_net || 0) > 0); const selected = lot?.next_active === true; const values = { '[data-lager-open-card-lot-number]': lot?.lot_number || 'Nicht hinterlegt', '[data-lager-open-card-qty-net]': String(balance?.qty_net ?? 0), '[data-lager-open-card-qty-in]': String(balance?.qty_in ?? 0), '[data-lager-open-card-manufacturer]': manufacturerSelect?.selectedOptions?.[0]?.textContent || 'Nicht hinterlegt', '[data-lager-open-card-manufacturer-lot]': lot?.manufacturer_lot_number || 'Nicht hinterlegt', '[data-lager-open-card-mfg-date]': lot?.mfg_date || 'Nicht hinterlegt', '[data-lager-open-card-expiry-date]': lot?.expiry_date || 'Nicht hinterlegt', '[data-lager-open-card-purchase-date]': lot?.purchase_date || 'Nicht hinterlegt' }; Object.entries(values).forEach(([selector, value]) => { const target = card.querySelector(selector); if (target) { target.textContent = value; } }); card.classList.toggle('sg-lager-open-lot--next-active', selected); const selectedLabel = card.querySelector('[data-lager-open-card-next-active]'); if (selectedLabel) { selectedLabel.textContent = selected ? 'Als nächste aktive Charge ausgewählt' : 'Nicht ausgewählt'; } const selectButton = card.querySelector('[data-lager-open-select]'); if (selectButton) { selectButton.dataset.lagerOpenSelectable = String(qualified); selectButton.disabled = !qualified || selected; selectButton.setAttribute('aria-disabled', String(!qualified || selected)); } };";
|
||||||
echo " const appendLagerOpenLotCard = (lot, balance) => { if (lot?.status === 'current') { syncLagerBalanceView(balance); const activeLotNumber = getDrawer()?.querySelector('[data-lager-drawer-lot-number]'); if (activeLotNumber) { activeLotNumber.textContent = lot.lot_number || 'Nicht hinterlegt'; } return null; } const drawer = getDrawer(); const product = drawer?.querySelector('[data-lager-open-product=\"' + (drawer?.dataset.lagerProductId || '') + '\"]'); const list = product?.querySelector('[data-lager-open-lot-list]'); const templateProduct = drawer?.querySelector('[data-lager-open-lot-template]')?.content.querySelector('[data-lager-open-product]'); const card = templateProduct?.querySelector('[data-lager-open-card-wrapper]')?.cloneNode(true); const lotId = String(lot?.id || lot?.lot_id || ''); if (!list || !card || !lotId) { return null; } card.dataset.lagerOpenCardWrapper = lotId; const readView = card.querySelector('[data-lager-open-card]'); if (readView) { readView.dataset.lagerOpenCard = lotId; } const editTitle = card.querySelector('[id^=\"lager-open-charge-data-\"]'); if (editTitle) { editTitle.id = 'lager-open-charge-data-' + lotId; editTitle.closest('section')?.setAttribute('aria-labelledby', editTitle.id); } const confirmationTitle = card.querySelector('[id^=\"lager-open-confirmation-title-\"]'); if (confirmationTitle) { confirmationTitle.id = 'lager-open-confirmation-title-' + lotId; confirmationTitle.closest('[data-lager-open-confirmation-card]')?.setAttribute('aria-labelledby', confirmationTitle.id); } const deleteTitle = card.querySelector('[id^=\"lager-open-delete-title-\"]'); if (deleteTitle) { deleteTitle.id = 'lager-open-delete-title-' + lotId; deleteTitle.closest('[data-lager-open-delete-confirmation]')?.setAttribute('aria-labelledby', deleteTitle.id); } const setValue = (selector, value) => { const input = card.querySelector(selector); if (input) { input.value = value ?? ''; } }; setValue('[data-lager-open-lot-number]', lot.lot_number); setValue('[data-lager-open-manufacturer]', lot.manufacturer_party_id); setValue('[data-lager-open-manufacturer-lot]', lot.manufacturer_lot_number); setValue('[data-lager-open-mfg-date]', lot.mfg_date); setValue('[data-lager-open-expiry-date]', lot.expiry_date); setValue('[data-lager-open-purchase-date]', lot.purchase_date); setValue('[data-lager-open-target-qty]', balance?.qty_net ?? 0); const qualified = Boolean(lot.lot_number && lot.manufacturer_party_id && lot.manufacturer_lot_number && lot.mfg_date && lot.expiry_date && lot.purchase_date && Number(balance?.qty_net || 0) > 0); const selected = lot.next_active === true; card.classList.toggle('sg-lager-open-lot--next-active', selected); const selectedLabel = card.querySelector('[data-lager-open-card-next-active]'); if (selectedLabel) { selectedLabel.textContent = selected ? 'Als nächste aktive Charge ausgewählt' : 'Nicht ausgewählt'; } const selectButton = card.querySelector('[data-lager-open-select]'); if (selectButton) { selectButton.dataset.lagerOpenSelectable = String(qualified); selectButton.disabled = !qualified || selected; selectButton.setAttribute('aria-disabled', String(!qualified || selected)); } list.append(card); syncLagerOpenLotCard(lot, balance, card); return card; };";
|
echo " const appendLagerOpenLotCard = (lot, balance) => { if (lot?.status === 'current') { syncLagerActiveLotView(lot); syncLagerBalanceView(balance); return null; } const drawer = getDrawer(); const product = drawer?.querySelector('[data-lager-open-product=\"' + (drawer?.dataset.lagerProductId || '') + '\"]'); const list = product?.querySelector('[data-lager-open-lot-list]'); const templateProduct = drawer?.querySelector('[data-lager-open-lot-template]')?.content.querySelector('[data-lager-open-product]'); const card = templateProduct?.querySelector('[data-lager-open-card-wrapper]')?.cloneNode(true); const lotId = String(lot?.id || lot?.lot_id || ''); if (!list || !card || !lotId) { return null; } card.dataset.lagerOpenCardWrapper = lotId; const readView = card.querySelector('[data-lager-open-card]'); if (readView) { readView.dataset.lagerOpenCard = lotId; } const editTitle = card.querySelector('[id^=\"lager-open-charge-data-\"]'); if (editTitle) { editTitle.id = 'lager-open-charge-data-' + lotId; editTitle.closest('section')?.setAttribute('aria-labelledby', editTitle.id); } const confirmationTitle = card.querySelector('[id^=\"lager-open-confirmation-title-\"]'); if (confirmationTitle) { confirmationTitle.id = 'lager-open-confirmation-title-' + lotId; confirmationTitle.closest('[data-lager-open-confirmation-card]')?.setAttribute('aria-labelledby', confirmationTitle.id); } const deleteTitle = card.querySelector('[id^=\"lager-open-delete-title-\"]'); if (deleteTitle) { deleteTitle.id = 'lager-open-delete-title-' + lotId; deleteTitle.closest('[data-lager-open-delete-confirmation]')?.setAttribute('aria-labelledby', deleteTitle.id); } const setValue = (selector, value) => { const input = card.querySelector(selector); if (input) { input.value = value ?? ''; } }; setValue('[data-lager-open-lot-number]', lot.lot_number); setValue('[data-lager-open-manufacturer]', lot.manufacturer_party_id); setValue('[data-lager-open-manufacturer-lot]', lot.manufacturer_lot_number); setValue('[data-lager-open-mfg-date]', lot.mfg_date); setValue('[data-lager-open-expiry-date]', lot.expiry_date); setValue('[data-lager-open-purchase-date]', lot.purchase_date); setValue('[data-lager-open-target-qty]', balance?.qty_net ?? 0); const qualified = Boolean(lot.lot_number && lot.manufacturer_party_id && lot.manufacturer_lot_number && lot.mfg_date && lot.expiry_date && lot.purchase_date && Number(balance?.qty_net || 0) > 0); const selected = lot.next_active === true; card.classList.toggle('sg-lager-open-lot--next-active', selected); const selectedLabel = card.querySelector('[data-lager-open-card-next-active]'); if (selectedLabel) { selectedLabel.textContent = selected ? 'Als nächste aktive Charge ausgewählt' : 'Nicht ausgewählt'; } const selectButton = card.querySelector('[data-lager-open-select]'); if (selectButton) { selectButton.dataset.lagerOpenSelectable = String(qualified); selectButton.disabled = !qualified || selected; selectButton.setAttribute('aria-disabled', String(!qualified || selected)); } list.append(card); syncLagerOpenLotCard(lot, balance, card); return card; };";
|
||||||
echo " const resetLagerNewLotConfirmation = () => { const drawer = getDrawer(); const confirmation = drawer?.querySelector('[data-lager-new-confirmation-card]'); const list = drawer?.querySelector('[data-lager-new-confirmation-empty-fields]'); const form = drawer?.querySelector('[data-lager-new-lot-form-element]'); if (confirmation) { confirmation.hidden = true; } if (list) { list.replaceChildren(); } if (form) { form.dataset.confirmationAccepted = 'false'; } if (drawer) { drawer.dataset.dialogOpen = 'false'; } };";
|
echo " const resetLagerNewLotConfirmation = () => { const drawer = getDrawer(); const confirmation = drawer?.querySelector('[data-lager-new-confirmation-card]'); const list = drawer?.querySelector('[data-lager-new-confirmation-empty-fields]'); const form = drawer?.querySelector('[data-lager-new-lot-form-element]'); if (confirmation) { confirmation.hidden = true; } if (list) { list.replaceChildren(); } if (form) { form.dataset.confirmationAccepted = 'false'; } if (drawer) { drawer.dataset.dialogOpen = 'false'; } };";
|
||||||
echo " const resetLagerOpenLotConfirmations = () => { const drawer = getDrawer(); drawer?.querySelectorAll('[data-lager-open-card-wrapper]').forEach((card) => { const confirmation = card.querySelector('[data-lager-open-confirmation-card]'); const list = card.querySelector('[data-lager-open-confirmation-empty-fields]'); const form = card.querySelector('[data-lager-open-edit-form-element]'); if (confirmation) { confirmation.hidden = true; } if (list) { list.replaceChildren(); } if (form) { form.dataset.confirmationAccepted = 'false'; } card.dataset.dialogOpen = 'false'; }); };";
|
echo " const resetLagerOpenLotConfirmations = () => { const drawer = getDrawer(); drawer?.querySelectorAll('[data-lager-open-card-wrapper]').forEach((card) => { const confirmation = card.querySelector('[data-lager-open-confirmation-card]'); const list = card.querySelector('[data-lager-open-confirmation-empty-fields]'); const form = card.querySelector('[data-lager-open-edit-form-element]'); if (confirmation) { confirmation.hidden = true; } if (list) { list.replaceChildren(); } if (form) { form.dataset.confirmationAccepted = 'false'; } card.dataset.dialogOpen = 'false'; }); };";
|
||||||
echo " document.addEventListener('click', (event) => { const trigger = event.target.closest('[data-lager-drawer-open]'); if (!trigger || trigger.dataset.lagerDrawerType !== 'Produkt' || window.matchMedia('(max-width: 767px)').matches) { return; } const drawer = getDrawer(); const productId = trigger.closest('[data-lager-row]')?.dataset.lagerId || ''; const openProduct = drawer?.querySelector('[data-lager-open-product=\"' + productId + '\"]'); drawer?.querySelectorAll('[data-lager-open-product]').forEach((product) => { product.hidden = product !== openProduct; product.querySelectorAll('[data-lager-open-edit-form]').forEach((form) => { form.hidden = true; }); product.querySelectorAll('[data-lager-open-card]').forEach((readView) => { readView.hidden = false; }); }); resetLagerNewLotConfirmation(); resetLagerOpenLotConfirmations(); const newForm = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const newAction = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); if (newForm) { newForm.hidden = true; } if (newAction) { newAction.hidden = false; } const notificationWrapper = drawer?.querySelector('[data-lager-new-lot-notification-wrapper]'); const notification = drawer?.querySelector('[data-lager-new-lot-notification]'); const shortageQty = trigger.dataset.lagerDrawerVirtualShortageQty || '0'; const hasShortage = shortageQty !== '0' && shortageQty !== '0,00'; if (notificationWrapper) { notificationWrapper.hidden = !hasShortage; } if (notification && hasShortage) { notification.textContent = 'Für dieses Produkt bestehen virtuelle Fehlbestände in Höhe von ' + shortageQty + '. Die Eingangsmenge wird nach Aktivierung der Charge zur Nachallokation verwendet.'; } const setValue = (selector, value) => { const field = drawer?.querySelector(selector); if (field) { field.value = value || ''; } }; setValue('[data-lager-new-lot-number]', ''); setValue('[data-lager-new-manufacturer]', ''); setValue('[data-lager-new-manufacturer-lot]', ''); setValue('[data-lager-new-mfg-date]', ''); setValue('[data-lager-new-expiry-date]', ''); setValue('[data-lager-new-purchase-date]', ''); setValue('[data-lager-new-receipt-qty]', ''); if (drawer) { drawer.dataset.lagerOpenLotId = ''; drawer.dataset.lagerProductId = productId; } });";
|
echo " document.addEventListener('click', (event) => { const trigger = event.target.closest('[data-lager-drawer-open]'); if (!trigger || trigger.dataset.lagerDrawerType !== 'Produkt' || window.matchMedia('(max-width: 767px)').matches) { return; } const drawer = getDrawer(); const productId = trigger.closest('[data-lager-row]')?.dataset.lagerId || ''; const openProduct = drawer?.querySelector('[data-lager-open-product=\"' + productId + '\"]'); drawer?.querySelectorAll('[data-lager-open-product]').forEach((product) => { product.hidden = product !== openProduct; product.querySelectorAll('[data-lager-open-edit-form]').forEach((form) => { form.hidden = true; }); product.querySelectorAll('[data-lager-open-card]').forEach((readView) => { readView.hidden = false; }); }); resetLagerNewLotConfirmation(); resetLagerOpenLotConfirmations(); const newForm = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const newAction = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); if (newForm) { newForm.hidden = true; } if (newAction) { newAction.hidden = false; } const notificationWrapper = drawer?.querySelector('[data-lager-new-lot-notification-wrapper]'); const notification = drawer?.querySelector('[data-lager-new-lot-notification]'); const shortageQty = trigger.dataset.lagerDrawerVirtualShortageQty || '0'; const hasShortage = shortageQty !== '0' && shortageQty !== '0,00'; if (notificationWrapper) { notificationWrapper.hidden = !hasShortage; } if (notification && hasShortage) { notification.textContent = 'Für dieses Produkt bestehen virtuelle Fehlbestände in Höhe von ' + shortageQty + '. Die Eingangsmenge wird nach Aktivierung der Charge zur Nachallokation verwendet.'; } const setValue = (selector, value) => { const field = drawer?.querySelector(selector); if (field) { field.value = value || ''; } }; setValue('[data-lager-new-lot-number]', ''); setValue('[data-lager-new-manufacturer]', ''); setValue('[data-lager-new-manufacturer-lot]', ''); setValue('[data-lager-new-mfg-date]', ''); setValue('[data-lager-new-expiry-date]', ''); setValue('[data-lager-new-purchase-date]', ''); setValue('[data-lager-new-receipt-qty]', ''); if (drawer) { drawer.dataset.lagerOpenLotId = ''; drawer.dataset.lagerProductId = productId; } });";
|
||||||
echo " document.addEventListener('click', (event) => { const openButton = event.target.closest('[data-lager-new-lot-open]'); if (openButton) { const drawer = getDrawer(); const form = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const action = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); resetLagerNewLotConfirmation(); if (form) { form.hidden = false; } if (action) { action.hidden = true; } return; } if (event.target.closest('[data-lager-new-lot-close]')) { const drawer = getDrawer(); const form = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const action = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); resetLagerNewLotConfirmation(); if (form) { form.hidden = true; } if (action) { action.hidden = false; } } });";
|
echo " document.addEventListener('click', (event) => { const openButton = event.target.closest('[data-lager-new-lot-open]'); if (openButton) { const drawer = getDrawer(); const form = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const action = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); resetLagerNewLotConfirmation(); if (form) { form.hidden = false; } if (action) { action.hidden = true; } return; } if (event.target.closest('[data-lager-new-lot-close]')) { const drawer = getDrawer(); const form = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const action = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); resetLagerNewLotConfirmation(); if (form) { form.hidden = true; } if (action) { action.hidden = false; } } });";
|
||||||
echo " document.addEventListener('click', (event) => { const editButton = event.target.closest('[data-lager-open-edit-open]'); if (editButton) { const card = editButton.closest('[data-lager-open-card-wrapper]'); const form = card?.querySelector('[data-lager-open-edit-form]'); const readView = card?.querySelector('[data-lager-open-card]'); resetLagerOpenLotConfirmations(); if (form) { form.hidden = false; } if (readView) { readView.hidden = true; } return; } const closeButton = event.target.closest('[data-lager-open-edit-close]'); if (closeButton) { const card = closeButton.closest('[data-lager-open-card-wrapper]'); const form = card?.querySelector('[data-lager-open-edit-form]'); const readView = card?.querySelector('[data-lager-open-card]'); resetLagerOpenLotConfirmations(); if (form) { form.hidden = true; } if (readView) { readView.hidden = false; } } });";
|
echo " document.addEventListener('click', (event) => { const editButton = event.target.closest('[data-lager-open-edit-open]'); if (editButton) { const card = editButton.closest('[data-lager-open-card-wrapper]'); const form = card?.querySelector('[data-lager-open-edit-form]'); const readView = card?.querySelector('[data-lager-open-card]'); resetLagerOpenLotConfirmations(); if (form) { form.hidden = false; } if (readView) { readView.hidden = true; } return; } const closeButton = event.target.closest('[data-lager-open-edit-close]'); if (closeButton) { const card = closeButton.closest('[data-lager-open-card-wrapper]'); const form = card?.querySelector('[data-lager-open-edit-form]'); const readView = card?.querySelector('[data-lager-open-card]'); resetLagerOpenLotConfirmations(); if (form) { form.hidden = true; } if (readView) { readView.hidden = false; } } });";
|
||||||
echo " document.addEventListener('input', (event) => { const input = event.target.closest('[data-lager-open-delete-confirmation-input]'); if (!input) { return; } const card = input.closest('[data-lager-open-card-wrapper]'); const submit = card?.querySelector('[data-lager-open-delete-confirmation-submit]'); const valid = input.value === 'DELETE'; if (submit) { submit.disabled = !valid; submit.setAttribute('aria-disabled', String(!valid)); submit.classList.toggle('sg-button--process-inactive', !valid); } });";
|
echo " document.addEventListener('input', (event) => { const input = event.target.closest('[data-lager-open-delete-confirmation-input]'); if (!input) { return; } const card = input.closest('[data-lager-open-card-wrapper]'); const submit = card?.querySelector('[data-lager-open-delete-confirmation-submit]'); const valid = input.value === 'DELETE'; if (submit) { submit.disabled = !valid; submit.setAttribute('aria-disabled', String(!valid)); submit.classList.toggle('sg-button--process-inactive', !valid); } });";
|
||||||
echo " document.addEventListener('click', async (event) => { const selectButton = event.target.closest('[data-lager-open-select]'); if (!selectButton) { return; } const card = selectButton.closest('[data-lager-open-card-wrapper]'); const product = card?.closest('[data-lager-open-product]'); const drawer = getDrawer(); const productId = product?.dataset.lagerOpenProduct || drawer?.dataset.lagerProductId || ''; const lotId = card?.dataset.lagerOpenCardWrapper || ''; if (!productId || !lotId) { return; } selectButton.disabled = true; try { await postLagerChange({ action: 'select_open_lot', productId, lotId }); product.querySelectorAll('[data-lager-open-card-wrapper]').forEach((candidate) => { const selected = candidate === card; candidate.classList.toggle('sg-lager-open-lot--next-active', selected); const label = candidate.querySelector('[data-lager-open-card-next-active]'); if (label) { label.textContent = selected ? 'Als nächste aktive Charge ausgewählt' : 'Nicht ausgewählt'; } const button = candidate.querySelector('[data-lager-open-select]'); if (button) { button.disabled = selected || button.dataset.lagerOpenSelectable !== 'true'; button.setAttribute('aria-disabled', String(button.disabled)); } }); } catch (error) { const status = card?.querySelector('[data-lager-open-edit-status]'); if (status) { status.textContent = error instanceof Error ? error.message : 'Auswahl fehlgeschlagen'; } selectButton.disabled = false; selectButton.setAttribute('aria-disabled', 'false'); } });";
|
echo " document.addEventListener('click', async (event) => { const selectButton = event.target.closest('[data-lager-open-select]'); if (!selectButton) { return; } const card = selectButton.closest('[data-lager-open-card-wrapper]'); const product = card?.closest('[data-lager-open-product]'); const drawer = getDrawer(); const productId = product?.dataset.lagerOpenProduct || drawer?.dataset.lagerProductId || ''; const lotId = card?.dataset.lagerOpenCardWrapper || ''; if (!productId || !lotId) { return; } selectButton.disabled = true; try { const result = await postLagerChange({ action: 'select_open_lot', productId, lotId }); if (result.currentLot?.id && String(result.currentLot.id) === String(lotId)) { card?.remove(); syncLagerActiveLotView(result.currentLot); syncLagerBalanceView({ qty_net: result.currentLot.qty_net, qty_in: result.currentLot.qty_in, qty_out: result.currentLot.qty_out }); return; } product.querySelectorAll('[data-lager-open-card-wrapper]').forEach((candidate) => { const selected = candidate === card; candidate.classList.toggle('sg-lager-open-lot--next-active', selected); const label = candidate.querySelector('[data-lager-open-card-next-active]'); if (label) { label.textContent = selected ? 'Als nächste aktive Charge ausgewählt' : 'Nicht ausgewählt'; } const button = candidate.querySelector('[data-lager-open-select]'); if (button) { button.disabled = selected || button.dataset.lagerOpenSelectable !== 'true'; button.setAttribute('aria-disabled', String(button.disabled)); } }); } catch (error) { const status = card?.querySelector('[data-lager-open-edit-status]'); if (status) { status.textContent = error instanceof Error ? error.message : 'Auswahl fehlgeschlagen'; } selectButton.disabled = false; selectButton.setAttribute('aria-disabled', 'false'); } });";
|
||||||
echo " document.addEventListener('click', async (event) => { const deleteButton = event.target.closest('[data-lager-open-delete]'); if (deleteButton) { const card = deleteButton.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-delete-confirmation]'); const input = card?.querySelector('[data-lager-open-delete-confirmation-input]'); const submit = card?.querySelector('[data-lager-open-delete-confirmation-submit]'); if (input) { input.value = ''; } if (submit) { submit.disabled = true; submit.setAttribute('aria-disabled', 'true'); submit.classList.add('sg-button--process-inactive'); } if (confirmation) { confirmation.hidden = false; } if (card) { card.dataset.dialogOpen = 'true'; } return; } const cancel = event.target.closest('[data-lager-open-delete-confirmation-cancel]'); if (cancel) { const card = cancel.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-delete-confirmation]'); if (confirmation) { confirmation.hidden = true; } if (card) { card.dataset.dialogOpen = 'false'; } return; } const submit = event.target.closest('[data-lager-open-delete-confirmation-submit]'); if (!submit || submit.disabled) { return; } const card = submit.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-delete-confirmation]'); const status = card?.querySelector('[data-lager-open-delete-status]'); if (status) { status.textContent = 'Löschen läuft …'; } submit.disabled = true; try { await postLagerChange({ action: 'delete_open_lot', lotId: card?.dataset.lagerOpenCardWrapper || '' }); const productId = card?.closest('[data-lager-open-product]')?.dataset.lagerOpenProduct || ''; contentRoot.querySelectorAll('[data-lager-drawer-open]').forEach((trigger) => { if (trigger.closest('[data-lager-row]')?.dataset.lagerId === productId) { trigger.dataset.lagerOpenLotId = ''; } }); const drawer = getDrawer(); if (drawer) { drawer.dataset.lagerOpenLotId = ''; } card?.remove(); } catch (error) { if (status) { status.textContent = error instanceof Error ? error.message : 'Löschen fehlgeschlagen'; } submit.disabled = false; } });";
|
echo " document.addEventListener('click', async (event) => { const deleteButton = event.target.closest('[data-lager-open-delete]'); if (deleteButton) { const card = deleteButton.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-delete-confirmation]'); const input = card?.querySelector('[data-lager-open-delete-confirmation-input]'); const submit = card?.querySelector('[data-lager-open-delete-confirmation-submit]'); if (input) { input.value = ''; } if (submit) { submit.disabled = true; submit.setAttribute('aria-disabled', 'true'); submit.classList.add('sg-button--process-inactive'); } if (confirmation) { confirmation.hidden = false; } if (card) { card.dataset.dialogOpen = 'true'; } return; } const cancel = event.target.closest('[data-lager-open-delete-confirmation-cancel]'); if (cancel) { const card = cancel.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-delete-confirmation]'); if (confirmation) { confirmation.hidden = true; } if (card) { card.dataset.dialogOpen = 'false'; } return; } const submit = event.target.closest('[data-lager-open-delete-confirmation-submit]'); if (!submit || submit.disabled) { return; } const card = submit.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-delete-confirmation]'); const status = card?.querySelector('[data-lager-open-delete-status]'); if (status) { status.textContent = 'Löschen läuft …'; } submit.disabled = true; try { const result = await postLagerChange({ action: 'delete_open_lot', lotId: card?.dataset.lagerOpenCardWrapper || '' }); if (result.currentLot) { syncLagerActiveLotView(result.currentLot); syncLagerBalanceView({ qty_net: result.currentLot.qty_net, qty_in: result.currentLot.qty_in, qty_out: result.currentLot.qty_out }); } const productId = card?.closest('[data-lager-open-product]')?.dataset.lagerOpenProduct || ''; contentRoot.querySelectorAll('[data-lager-drawer-open]').forEach((trigger) => { if (trigger.closest('[data-lager-row]')?.dataset.lagerId === productId) { trigger.dataset.lagerOpenLotId = ''; } }); const drawer = getDrawer(); if (drawer) { drawer.dataset.lagerOpenLotId = ''; } card?.remove(); } catch (error) { if (status) { status.textContent = error instanceof Error ? error.message : 'Löschen fehlgeschlagen'; } submit.disabled = false; } });";
|
||||||
echo " document.addEventListener('click', (event) => { const cancel = event.target.closest('[data-lager-open-confirmation-cancel]'); if (cancel) { const card = cancel.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-confirmation-card]'); if (confirmation) { confirmation.hidden = true; } if (card) { card.dataset.dialogOpen = 'false'; } const form = card?.querySelector('[data-lager-open-edit-form-element]'); if (form) { form.dataset.confirmationAccepted = 'false'; } return; } const confirm = event.target.closest('[data-lager-open-confirmation-submit]'); if (confirm) { const card = confirm.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-confirmation-card]'); const form = card?.querySelector('[data-lager-open-edit-form-element]'); if (confirmation) { confirmation.hidden = true; } if (card) { card.dataset.dialogOpen = 'false'; } if (form) { form.dataset.confirmationAccepted = 'true'; form.requestSubmit(); } } });";
|
echo " document.addEventListener('click', (event) => { const cancel = event.target.closest('[data-lager-open-confirmation-cancel]'); if (cancel) { const card = cancel.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-confirmation-card]'); if (confirmation) { confirmation.hidden = true; } if (card) { card.dataset.dialogOpen = 'false'; } const form = card?.querySelector('[data-lager-open-edit-form-element]'); if (form) { form.dataset.confirmationAccepted = 'false'; } return; } const confirm = event.target.closest('[data-lager-open-confirmation-submit]'); if (confirm) { const card = confirm.closest('[data-lager-open-card-wrapper]'); const confirmation = card?.querySelector('[data-lager-open-confirmation-card]'); const form = card?.querySelector('[data-lager-open-edit-form-element]'); if (confirmation) { confirmation.hidden = true; } if (card) { card.dataset.dialogOpen = 'false'; } if (form) { form.dataset.confirmationAccepted = 'true'; form.requestSubmit(); } } });";
|
||||||
echo " document.addEventListener('submit', async (event) => { const openLotForm = event.target.closest('[data-lager-open-edit-form-element]'); if (!openLotForm) { return; } event.preventDefault(); const drawer = getDrawer(); const card = openLotForm.closest('[data-lager-open-card-wrapper]'); const editSection = card?.querySelector('[data-lager-open-edit-form]'); const fields = [{ label: 'Naurua-Chargennummer', input: openLotForm.querySelector('[data-lager-open-lot-number]') }, { label: 'Hersteller', input: openLotForm.querySelector('[data-lager-open-manufacturer]') }, { label: 'Hersteller-Chargennummer', input: openLotForm.querySelector('[data-lager-open-manufacturer-lot]') }, { label: 'Herstellungsdatum', input: openLotForm.querySelector('[data-lager-open-mfg-date]') }, { label: 'MHD', input: openLotForm.querySelector('[data-lager-open-expiry-date]') }, { label: 'Einkaufsdatum', input: openLotForm.querySelector('[data-lager-open-purchase-date]') }, { label: 'Menge', input: openLotForm.querySelector('[data-lager-open-target-qty]') }]; const emptyFields = fields.filter((field) => (field.input?.value || '').trim() === ''); if (emptyFields.length > 0 && openLotForm.dataset.confirmationAccepted !== 'true') { const confirmation = card?.querySelector('[data-lager-open-confirmation-card]'); const emptyFieldsList = card?.querySelector('[data-lager-open-confirmation-empty-fields]'); if (emptyFieldsList) { emptyFieldsList.replaceChildren(...emptyFields.map((field) => { const item = document.createElement('div'); item.className = 'sg-body'; item.textContent = field.label; return item; })); } if (confirmation) { confirmation.hidden = false; } if (card) { card.dataset.dialogOpen = 'true'; } return; } openLotForm.dataset.confirmationAccepted = 'false'; const status = openLotForm.querySelector('[data-lager-open-edit-status]'); if (status) { status.textContent = 'Speichern läuft …'; } try { const targetQtyInput = openLotForm.querySelector('[data-lager-open-target-qty]'); const result = await postLagerChange({ action: 'prepare_lot', productId: drawer?.dataset.lagerProductId || '', lotId: card?.dataset.lagerOpenCardWrapper || '', lotNumber: openLotForm.querySelector('[data-lager-open-lot-number]')?.value || '', manufacturerPartyId: openLotForm.querySelector('[data-lager-open-manufacturer]')?.value || null, manufacturerLotNumber: openLotForm.querySelector('[data-lager-open-manufacturer-lot]')?.value || '', mfgDate: openLotForm.querySelector('[data-lager-open-mfg-date]')?.value || '', purchaseDate: openLotForm.querySelector('[data-lager-open-purchase-date]')?.value || '', expiryDate: openLotForm.querySelector('[data-lager-open-expiry-date]')?.value || '', targetQty: targetQtyInput?.value.trim() === '' ? '0' : targetQtyInput?.value || '' }); if (result.lot?.status === 'current') { card?.remove(); syncLagerActiveLotView(result.lot); syncLagerBalanceView(result.balance); } else { syncLagerOpenLotCard(result.lot, result.balance); } if (editSection) { editSection.hidden = true; } card?.querySelector('[data-lager-open-card]')?.removeAttribute('hidden'); if (status) { status.textContent = ''; } } catch (error) { if (status) { status.textContent = error instanceof Error ? error.message : 'Speichern fehlgeschlagen'; } } });";
|
echo " document.addEventListener('submit', async (event) => { const openLotForm = event.target.closest('[data-lager-open-edit-form-element]'); if (!openLotForm) { return; } event.preventDefault(); const drawer = getDrawer(); const card = openLotForm.closest('[data-lager-open-card-wrapper]'); const editSection = card?.querySelector('[data-lager-open-edit-form]'); const fields = [{ label: 'Naurua-Chargennummer', input: openLotForm.querySelector('[data-lager-open-lot-number]') }, { label: 'Hersteller', input: openLotForm.querySelector('[data-lager-open-manufacturer]') }, { label: 'Hersteller-Chargennummer', input: openLotForm.querySelector('[data-lager-open-manufacturer-lot]') }, { label: 'Herstellungsdatum', input: openLotForm.querySelector('[data-lager-open-mfg-date]') }, { label: 'MHD', input: openLotForm.querySelector('[data-lager-open-expiry-date]') }, { label: 'Einkaufsdatum', input: openLotForm.querySelector('[data-lager-open-purchase-date]') }, { label: 'Menge', input: openLotForm.querySelector('[data-lager-open-target-qty]') }]; const emptyFields = fields.filter((field) => (field.input?.value || '').trim() === ''); if (emptyFields.length > 0 && openLotForm.dataset.confirmationAccepted !== 'true') { const confirmation = card?.querySelector('[data-lager-open-confirmation-card]'); const emptyFieldsList = card?.querySelector('[data-lager-open-confirmation-empty-fields]'); if (emptyFieldsList) { emptyFieldsList.replaceChildren(...emptyFields.map((field) => { const item = document.createElement('div'); item.className = 'sg-body'; item.textContent = field.label; return item; })); } if (confirmation) { confirmation.hidden = false; } if (card) { card.dataset.dialogOpen = 'true'; } return; } openLotForm.dataset.confirmationAccepted = 'false'; const status = openLotForm.querySelector('[data-lager-open-edit-status]'); if (status) { status.textContent = 'Speichern läuft …'; } try { const targetQtyInput = openLotForm.querySelector('[data-lager-open-target-qty]'); const result = await postLagerChange({ action: 'prepare_lot', productId: drawer?.dataset.lagerProductId || '', lotId: card?.dataset.lagerOpenCardWrapper || '', lotNumber: openLotForm.querySelector('[data-lager-open-lot-number]')?.value || '', manufacturerPartyId: openLotForm.querySelector('[data-lager-open-manufacturer]')?.value || null, manufacturerLotNumber: openLotForm.querySelector('[data-lager-open-manufacturer-lot]')?.value || '', mfgDate: openLotForm.querySelector('[data-lager-open-mfg-date]')?.value || '', purchaseDate: openLotForm.querySelector('[data-lager-open-purchase-date]')?.value || '', expiryDate: openLotForm.querySelector('[data-lager-open-expiry-date]')?.value || '', targetQty: targetQtyInput?.value.trim() === '' ? '0' : targetQtyInput?.value || '' }); if (result.lot?.status === 'current') { card?.remove(); syncLagerActiveLotView(result.lot); syncLagerBalanceView(result.balance); } else { syncLagerOpenLotCard(result.lot, result.balance); } if (editSection) { editSection.hidden = true; } card?.querySelector('[data-lager-open-card]')?.removeAttribute('hidden'); if (status) { status.textContent = ''; } } catch (error) { if (status) { status.textContent = error instanceof Error ? error.message : 'Speichern fehlgeschlagen'; } } });";
|
||||||
echo " document.addEventListener('click', (event) => { const cancel = event.target.closest('[data-lager-new-confirmation-cancel]'); if (cancel) { const drawer = getDrawer(); const confirmation = drawer?.querySelector('[data-lager-new-confirmation-card]'); if (confirmation) { confirmation.hidden = true; } if (drawer) { drawer.dataset.dialogOpen = 'false'; } const form = drawer?.querySelector('[data-lager-new-lot-form-element]'); if (form) { form.dataset.confirmationAccepted = 'false'; } return; } const confirm = event.target.closest('[data-lager-new-confirmation-submit]'); if (confirm) { const drawer = getDrawer(); const confirmation = drawer?.querySelector('[data-lager-new-confirmation-card]'); const form = drawer?.querySelector('[data-lager-new-lot-form-element]'); if (confirmation) { confirmation.hidden = true; } if (drawer) { drawer.dataset.dialogOpen = 'false'; } if (form) { form.dataset.confirmationAccepted = 'true'; form.requestSubmit(); } } });";
|
echo " document.addEventListener('click', (event) => { const cancel = event.target.closest('[data-lager-new-confirmation-cancel]'); if (cancel) { const drawer = getDrawer(); const confirmation = drawer?.querySelector('[data-lager-new-confirmation-card]'); if (confirmation) { confirmation.hidden = true; } if (drawer) { drawer.dataset.dialogOpen = 'false'; } const form = drawer?.querySelector('[data-lager-new-lot-form-element]'); if (form) { form.dataset.confirmationAccepted = 'false'; } return; } const confirm = event.target.closest('[data-lager-new-confirmation-submit]'); if (confirm) { const drawer = getDrawer(); const confirmation = drawer?.querySelector('[data-lager-new-confirmation-card]'); const form = drawer?.querySelector('[data-lager-new-lot-form-element]'); if (confirmation) { confirmation.hidden = true; } if (drawer) { drawer.dataset.dialogOpen = 'false'; } if (form) { form.dataset.confirmationAccepted = 'true'; form.requestSubmit(); } } });";
|
||||||
echo " document.addEventListener('submit', async (event) => { const newLotForm = event.target.closest('[data-lager-new-lot-form-element]'); if (!newLotForm) { return; } event.preventDefault(); const drawer = getDrawer(); const fields = [{ label: 'Naurua-Chargennummer', input: drawer?.querySelector('[data-lager-new-lot-number]') }, { label: 'Hersteller', input: drawer?.querySelector('[data-lager-new-manufacturer]') }, { label: 'Hersteller-Chargennummer', input: drawer?.querySelector('[data-lager-new-manufacturer-lot]') }, { label: 'Herstellungsdatum', input: drawer?.querySelector('[data-lager-new-mfg-date]') }, { label: 'MHD', input: drawer?.querySelector('[data-lager-new-expiry-date]') }, { label: 'Einkaufsdatum', input: drawer?.querySelector('[data-lager-new-purchase-date]') }, { label: 'Eingangsmenge', input: drawer?.querySelector('[data-lager-new-receipt-qty]') }]; const emptyFields = fields.filter((field) => (field.input?.value || '').trim() === ''); if (emptyFields.length > 0 && newLotForm.dataset.confirmationAccepted !== 'true') { const confirmation = drawer?.querySelector('[data-lager-new-confirmation-card]'); const emptyFieldsList = drawer?.querySelector('[data-lager-new-confirmation-empty-fields]'); if (emptyFieldsList) { emptyFieldsList.replaceChildren(...emptyFields.map((field) => { const item = document.createElement('div'); item.className = 'sg-body'; item.textContent = field.label; return item; })); } if (confirmation) { confirmation.hidden = false; } if (drawer) { drawer.dataset.dialogOpen = 'true'; } return; } newLotForm.dataset.confirmationAccepted = 'false'; const status = drawer?.querySelector('[data-lager-new-lot-status]'); if (status) { status.textContent = 'Speichern läuft …'; } try { const result = await postLagerChange({ action: 'prepare_lot', productId: drawer?.dataset.lagerProductId || '', lotId: '', lotNumber: drawer?.querySelector('[data-lager-new-lot-number]')?.value || '', manufacturerPartyId: drawer?.querySelector('[data-lager-new-manufacturer]')?.value || null, manufacturerLotNumber: drawer?.querySelector('[data-lager-new-manufacturer-lot]')?.value || '', mfgDate: drawer?.querySelector('[data-lager-new-mfg-date]')?.value || '', expiryDate: drawer?.querySelector('[data-lager-new-expiry-date]')?.value || '', purchaseDate: drawer?.querySelector('[data-lager-new-purchase-date]')?.value || '', receiptQty: drawer?.querySelector('[data-lager-new-receipt-qty]')?.value || '' }); appendLagerOpenLotCard(result.lot, result.balance); resetLagerNewLotConfirmation(); const form = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const action = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); if (form) { form.hidden = true; } if (action) { action.hidden = false; } if (status) { status.textContent = ''; } } catch (error) { if (status) { status.textContent = error instanceof Error ? error.message : 'Speichern fehlgeschlagen'; } } });";
|
echo " document.addEventListener('submit', async (event) => { const newLotForm = event.target.closest('[data-lager-new-lot-form-element]'); if (!newLotForm) { return; } event.preventDefault(); const drawer = getDrawer(); const fields = [{ label: 'Naurua-Chargennummer', input: drawer?.querySelector('[data-lager-new-lot-number]') }, { label: 'Hersteller', input: drawer?.querySelector('[data-lager-new-manufacturer]') }, { label: 'Hersteller-Chargennummer', input: drawer?.querySelector('[data-lager-new-manufacturer-lot]') }, { label: 'Herstellungsdatum', input: drawer?.querySelector('[data-lager-new-mfg-date]') }, { label: 'MHD', input: drawer?.querySelector('[data-lager-new-expiry-date]') }, { label: 'Einkaufsdatum', input: drawer?.querySelector('[data-lager-new-purchase-date]') }, { label: 'Eingangsmenge', input: drawer?.querySelector('[data-lager-new-receipt-qty]') }]; const emptyFields = fields.filter((field) => (field.input?.value || '').trim() === ''); if (emptyFields.length > 0 && newLotForm.dataset.confirmationAccepted !== 'true') { const confirmation = drawer?.querySelector('[data-lager-new-confirmation-card]'); const emptyFieldsList = drawer?.querySelector('[data-lager-new-confirmation-empty-fields]'); if (emptyFieldsList) { emptyFieldsList.replaceChildren(...emptyFields.map((field) => { const item = document.createElement('div'); item.className = 'sg-body'; item.textContent = field.label; return item; })); } if (confirmation) { confirmation.hidden = false; } if (drawer) { drawer.dataset.dialogOpen = 'true'; } return; } newLotForm.dataset.confirmationAccepted = 'false'; const status = drawer?.querySelector('[data-lager-new-lot-status]'); if (status) { status.textContent = 'Speichern läuft …'; } try { const result = await postLagerChange({ action: 'prepare_lot', productId: drawer?.dataset.lagerProductId || '', lotId: '', lotNumber: drawer?.querySelector('[data-lager-new-lot-number]')?.value || '', manufacturerPartyId: drawer?.querySelector('[data-lager-new-manufacturer]')?.value || null, manufacturerLotNumber: drawer?.querySelector('[data-lager-new-manufacturer-lot]')?.value || '', mfgDate: drawer?.querySelector('[data-lager-new-mfg-date]')?.value || '', expiryDate: drawer?.querySelector('[data-lager-new-expiry-date]')?.value || '', purchaseDate: drawer?.querySelector('[data-lager-new-purchase-date]')?.value || '', receiptQty: drawer?.querySelector('[data-lager-new-receipt-qty]')?.value || '' }); appendLagerOpenLotCard(result.lot, result.balance); resetLagerNewLotConfirmation(); const form = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-form\"]'); const action = drawer?.querySelector('[data-lager-drawer-topic=\"new-lot-action\"]'); if (form) { form.hidden = true; } if (action) { action.hidden = false; } if (status) { status.textContent = ''; } } catch (error) { if (status) { status.textContent = error instanceof Error ? error.message : 'Speichern fehlgeschlagen'; } } });";
|
||||||
echo " document.addEventListener('submit', async (event) => { const editForm = event.target.closest('[data-lager-edit-form-element]'); if (!editForm) { return; } event.preventDefault(); const drawer = getDrawer(); const status = drawer?.querySelector('[data-lager-edit-status]'); if (status) { status.textContent = 'Speichern läuft …'; } try { const result = await postLagerChange({ action: 'update_lot', lotId: drawer?.dataset.lagerActiveLotId || '', manufacturerPartyId: drawer?.querySelector('[data-lager-manufacturer]')?.value || null, manufacturerLotNumber: drawer?.querySelector('[data-lager-manufacturer-lot]')?.value || '', mfgDate: drawer?.querySelector('[data-lager-mfg-date]')?.value || '', expiryDate: drawer?.querySelector('[data-lager-expiry-date]')?.value || '', purchaseDate: drawer?.querySelector('[data-lager-purchase-date]')?.value || '', receiptQty: drawer?.querySelector('[data-lager-receipt-qty]')?.value || '', adjustmentQty: drawer?.querySelector('[data-lager-adjustment-qty]')?.value || '', outQty: drawer?.querySelector('[data-lager-out-qty]')?.value || '' }); syncLagerReadView(); syncLagerBalanceView(result.balance); clearLagerMovementInputs(); setLagerEditMode(false); if (status) { status.textContent = ''; } } catch (error) { if (status) { status.textContent = error instanceof Error ? error.message : 'Speichern fehlgeschlagen'; } } });";
|
echo " document.addEventListener('submit', async (event) => { const editForm = event.target.closest('[data-lager-edit-form-element]'); if (!editForm) { return; } event.preventDefault(); const drawer = getDrawer(); const status = drawer?.querySelector('[data-lager-edit-status]'); if (status) { status.textContent = 'Speichern läuft …'; } try { const result = await postLagerChange({ action: 'update_lot', lotId: drawer?.dataset.lagerActiveLotId || '', manufacturerPartyId: drawer?.querySelector('[data-lager-manufacturer]')?.value || null, manufacturerLotNumber: drawer?.querySelector('[data-lager-manufacturer-lot]')?.value || '', mfgDate: drawer?.querySelector('[data-lager-mfg-date]')?.value || '', expiryDate: drawer?.querySelector('[data-lager-expiry-date]')?.value || '', purchaseDate: drawer?.querySelector('[data-lager-purchase-date]')?.value || '', receiptQty: drawer?.querySelector('[data-lager-receipt-qty]')?.value || '', adjustmentQty: drawer?.querySelector('[data-lager-adjustment-qty]')?.value || '', outQty: drawer?.querySelector('[data-lager-out-qty]')?.value || '' }); syncLagerActiveLotView(result.lot); syncLagerBalanceView(result.balance); clearLagerMovementInputs(); setLagerEditMode(false); if (status) { status.textContent = ''; } } catch (error) { if (status) { status.textContent = error instanceof Error ? error.message : 'Speichern fehlgeschlagen'; } } });";
|
||||||
echo " document.addEventListener('click', (event) => { if (event.target.closest('[data-lager-detail-back]')) { event.preventDefault(); closeLagerMobileDetail(); } });";
|
echo " document.addEventListener('click', (event) => { if (event.target.closest('[data-lager-detail-back]')) { event.preventDefault(); closeLagerMobileDetail(); } });";
|
||||||
echo " document.addEventListener('keydown', (event) => { if (event.key === 'Escape') { closeDrawer(); closeLagerMobileDetail(); } });";
|
echo " document.addEventListener('keydown', (event) => { if (event.key === 'Escape') { closeDrawer(); closeLagerMobileDetail(); } });";
|
||||||
echo " window.addEventListener('popstate', (event) => { if (lagerMobileDetailOpen && (!event.state || event.state.lagerView !== 'detail')) { restoreLagerMobileDetail(); } });";
|
echo " window.addEventListener('popstate', (event) => { if (lagerMobileDetailOpen && (!event.state || event.state.lagerView !== 'detail')) { restoreLagerMobileDetail(); } });";
|
||||||
|
|||||||
Reference in new issue
Block a user