mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 08:29:36 +01:00
fix(inventory): saveChildren Delete-All durch Upsert für stock_batches ersetzen
stock_movements hat einen FK auf stock_batches mit RESTRICT, daher schlug das bisherige Delete-All + Re-Insert Pattern fehl sobald Bestandsbewegungen existierten (HTTP 500 bei Reservierung). Lösung: Upsert-Pattern (UPDATE bestehende, INSERT neue, DELETE entfernte).
This commit is contained in:
parent
8948103957
commit
206921d2a6
1 changed files with 40 additions and 9 deletions
|
|
@ -223,21 +223,34 @@ public class JdbcStockRepository implements StockRepository {
|
||||||
String stockId = stock.id().value();
|
String stockId = stock.id().value();
|
||||||
|
|
||||||
// Delete reservations first (cascades to allocations via FK ON DELETE CASCADE)
|
// Delete reservations first (cascades to allocations via FK ON DELETE CASCADE)
|
||||||
// Must happen before deleting batches due to FK from allocations -> stock_batches
|
|
||||||
jdbc.sql("DELETE FROM reservations WHERE stock_id = :stockId")
|
jdbc.sql("DELETE FROM reservations WHERE stock_id = :stockId")
|
||||||
.param("stockId", stockId)
|
.param("stockId", stockId)
|
||||||
.update();
|
.update();
|
||||||
|
|
||||||
// Delete + re-insert batches
|
// Upsert batches: stock_movements has FK to stock_batches (RESTRICT),
|
||||||
jdbc.sql("DELETE FROM stock_batches WHERE stock_id = :stockId")
|
// so we cannot delete-all + re-insert. Instead: remove stale, upsert current.
|
||||||
.param("stockId", stockId)
|
var currentBatchIds = stock.batches().stream()
|
||||||
.update();
|
.map(b -> b.id().value())
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (currentBatchIds.isEmpty()) {
|
||||||
|
jdbc.sql("DELETE FROM stock_batches WHERE stock_id = :stockId")
|
||||||
|
.param("stockId", stockId)
|
||||||
|
.update();
|
||||||
|
} else {
|
||||||
|
jdbc.sql("DELETE FROM stock_batches WHERE stock_id = :stockId AND id NOT IN (:batchIds)")
|
||||||
|
.param("stockId", stockId)
|
||||||
|
.param("batchIds", currentBatchIds)
|
||||||
|
.update();
|
||||||
|
}
|
||||||
|
|
||||||
for (StockBatch batch : stock.batches()) {
|
for (StockBatch batch : stock.batches()) {
|
||||||
jdbc.sql("""
|
int updated = jdbc.sql("""
|
||||||
INSERT INTO stock_batches
|
UPDATE stock_batches
|
||||||
(id, stock_id, batch_id, batch_type, quantity_amount, quantity_unit, expiry_date, status, received_at)
|
SET batch_id = :batchId, batch_type = :batchType,
|
||||||
VALUES (:id, :stockId, :batchId, :batchType, :quantityAmount, :quantityUnit, :expiryDate, :status, :receivedAt)
|
quantity_amount = :quantityAmount, quantity_unit = :quantityUnit,
|
||||||
|
expiry_date = :expiryDate, status = :status, received_at = :receivedAt
|
||||||
|
WHERE id = :id AND stock_id = :stockId
|
||||||
""")
|
""")
|
||||||
.param("id", batch.id().value())
|
.param("id", batch.id().value())
|
||||||
.param("stockId", stockId)
|
.param("stockId", stockId)
|
||||||
|
|
@ -249,6 +262,24 @@ public class JdbcStockRepository implements StockRepository {
|
||||||
.param("status", batch.status().name())
|
.param("status", batch.status().name())
|
||||||
.param("receivedAt", batch.receivedAt().atOffset(ZoneOffset.UTC))
|
.param("receivedAt", batch.receivedAt().atOffset(ZoneOffset.UTC))
|
||||||
.update();
|
.update();
|
||||||
|
|
||||||
|
if (updated == 0) {
|
||||||
|
jdbc.sql("""
|
||||||
|
INSERT INTO stock_batches
|
||||||
|
(id, stock_id, batch_id, batch_type, quantity_amount, quantity_unit, expiry_date, status, received_at)
|
||||||
|
VALUES (:id, :stockId, :batchId, :batchType, :quantityAmount, :quantityUnit, :expiryDate, :status, :receivedAt)
|
||||||
|
""")
|
||||||
|
.param("id", batch.id().value())
|
||||||
|
.param("stockId", stockId)
|
||||||
|
.param("batchId", batch.batchReference().batchId())
|
||||||
|
.param("batchType", batch.batchReference().batchType().name())
|
||||||
|
.param("quantityAmount", batch.quantity().amount())
|
||||||
|
.param("quantityUnit", batch.quantity().uom().name())
|
||||||
|
.param("expiryDate", batch.expiryDate())
|
||||||
|
.param("status", batch.status().name())
|
||||||
|
.param("receivedAt", batch.receivedAt().atOffset(ZoneOffset.UTC))
|
||||||
|
.update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Reservation reservation : stock.reservations()) {
|
for (Reservation reservation : stock.reservations()) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue