remove actions and data integrity

This commit is contained in:
Thanakorn S
2026-04-24 14:25:39 +07:00
parent a75e180686
commit 92d116fd21
26 changed files with 1325 additions and 249 deletions
+32
View File
@@ -0,0 +1,32 @@
<?php
session_start();
require '../../../assets/utils/db_auth.php';
require '../../../assets/utils/classes/WarehouseManager.php';
try {
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
$whMgmt = new WarehouseManager($pdo, $company_id);
$whMgmt->deleteStockIn(
(int)$data['id'],
(int)$data['wh']
);
});
$answer["success"] = 1;
} catch (PDOException $e) {
$answer["success"] = 0;
$answer["message"] = "Database error, please try again";
http_response_code(500);
} catch (Exception $e) {
$answer["success"] = 0;
$answer["message"] = $e->getMessage();
http_response_code(400);
}
exit(json_encode($answer));
?>
+32
View File
@@ -0,0 +1,32 @@
<?php
session_start();
require '../../../assets/utils/db_auth.php';
require '../../../assets/utils/classes/WarehouseManager.php';
try {
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
$whMgmt = new WarehouseManager($pdo, $company_id);
$whMgmt->deleteStockOut(
(int)$data['id'],
(int)$data['wh']
);
});
$answer["success"] = 1;
} catch (PDOException $e) {
$answer["success"] = 0;
$answer["message"] = "Database error, please try again";
http_response_code(500);
} catch (Exception $e) {
$answer["success"] = 0;
$answer["message"] = $e->getMessage();
http_response_code(400);
}
exit(json_encode($answer));
?>
@@ -0,0 +1,32 @@
<?php
session_start();
require '../../../assets/utils/db_auth.php';
require '../../../assets/utils/classes/WarehouseManager.php';
try {
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
$whMgmt = new WarehouseManager($pdo, $company_id);
$whMgmt->deleteTransfer(
(int)$data['id'],
(int)$data['wh']
);
});
$answer["success"] = 1;
} catch (PDOException $e) {
$answer["success"] = 0;
$answer["message"] = "Database error, please try again";
http_response_code(500);
} catch (Exception $e) {
$answer["success"] = 0;
$answer["message"] = $e->getMessage();
http_response_code(400);
}
exit(json_encode($answer));
?>
+10 -44
View File
@@ -24,11 +24,6 @@
// UPDATE existing stock_in record
$sql = "UPDATE `$table` SET
`product_sku` = :product_sku,
`in` = :quantity,
`zone` = :zone,
`aisle` = :aisle,
`rack` = :rack,
`contact_id` = :contact_id,
`description` = :description,
`log` = :log
@@ -38,41 +33,12 @@
$sth->execute([
":id" => $id,
":company_id" => $company_id,
":product_sku" => $data["product_sku"],
":quantity" => $data["quantity"],
":zone" => $data["zone"],
":aisle" => $data["aisle"],
":rack" => $data["rack"],
":contact_id" => (int)$data["contact_id"],
":description" => $data["description"],
":log" => json_encode($table_log),
]);
// On UPDATE, td_stock_id stays the same (this record's ID)
$td_stock_id = $id;
// Only touch md_rack if the physical location actually changed.
// Skipping when unchanged avoids redundant log entries and release/occupy cycles.
$rack_changed = (
($row['zone'] ?? '') != $data['zone'] ||
($row['aisle'] ?? '') != $data['aisle'] ||
($row['rack'] ?? '') != $data['rack']
);
if ($rack_changed) {
// Free up the old rack
$whMgmt->releaseRack(
$warehouse_id,
$row['zone'], $row['aisle'], $row['rack']
);
// Claim the new rack, linked to the same stock record
$whMgmt->occupyRack(
$warehouse_id,
$data['zone'], $data['aisle'], $data['rack'],
$data['product_sku'],
$td_stock_id
);
}
} else {
@@ -107,17 +73,17 @@
$data['product_sku'],
$td_stock_id
);
}
// Balance adjustment handles both INSERT (delta = full qty)
// and UPDATE (delta = new - old) via the same formula.
$whMgmt->adjustBalance(
'in',
$warehouse_id,
$data["product_sku"],
$row['in'] ?? 0,
$data["quantity"]
);
// Balance adjustment handles both INSERT (delta = full qty)
// and UPDATE (delta = new - old) via the same formula.
$whMgmt->adjustBalance(
'in',
$warehouse_id,
$data["product_sku"],
$row['in'] ?? 0,
$data["quantity"]
);
}
});
+34 -68
View File
@@ -19,42 +19,10 @@
$table_log = json_decode($row['log'] ?? '[]', true);
$table_log[] = $logging;
// Look up the source stock record via the rack.
// Under 1:1, the rack points to exactly one td_stock_<wh> row.
$source_stock = $whMgmt->getRackStock(
$warehouse_id,
$data["zone"],
$data["aisle"],
$data["rack"]
);
if (!$source_stock) {
throw new Exception(
"Rack {$data['zone']}-{$data['aisle']}-{$data['rack']} is empty — nothing to take out."
);
}
// Defensive check — UI cascade should already prevent mismatches
if ($source_stock['product_sku'] !== $data["product_sku"]) {
throw new Exception(
"Rack holds {$source_stock['product_sku']}, not {$data['product_sku']}."
);
}
// Quantity comes from the source stock_in row, NOT user input.
// Under 1:1, taking from this rack = taking the full batch.
$quantity = (int) $source_stock['in'];
$ref_id = (int) $source_stock['id'];
if ($id > 0) {
// UPDATE existing stock_out record
$sql = "UPDATE `$table` SET
`product_sku` = :product_sku,
`out` = :quantity,
`zone` = :zone,
`aisle` = :aisle,
`rack` = :rack,
`contact_id` = :contact_id,
`description` = :description,
`log` = :log
@@ -64,41 +32,39 @@
$sth->execute([
":id" => $id,
":company_id" => $company_id,
":product_sku" => $data["product_sku"],
":quantity" => $quantity,
":zone" => $data["zone"],
":aisle" => $data["aisle"],
":rack" => $data["rack"],
":contact_id" => (int)$data["contact_id"],
":description" => $data["description"],
":log" => json_encode($table_log),
]);
// Only touch md_rack if the physical location actually changed.
$rack_changed = (
($row['zone'] ?? '') != $data['zone'] ||
($row['aisle'] ?? '') != $data['aisle'] ||
($row['rack'] ?? '') != $data['rack']
} else {
// Look up the source stock record via the rack.
// Under 1:1, the rack points to exactly one td_stock_<wh> row.
$source_stock = $whMgmt->getRackStock(
$warehouse_id,
$data["zone"],
$data["aisle"],
$data["rack"]
);
if ($rack_changed) {
// Re-occupy the old rack with the batch it originally held
// (logically: the stock goes back to where it came from)
$whMgmt->occupyRack(
$warehouse_id,
$row['zone'], $row['aisle'], $row['rack'],
$row['product_sku'],
$row['ref_id'] ?? null
);
// Release the new rack (the real stock-out action)
$whMgmt->releaseRack(
$warehouse_id,
$data['zone'], $data['aisle'], $data['rack']
if (!$source_stock) {
throw new Exception(
"Rack {$data['zone']}-{$data['aisle']}-{$data['rack']} is empty — nothing to take out."
);
}
} else {
// Defensive check — UI cascade should already prevent mismatches
if ($source_stock['product_sku'] !== $data["product_sku"]) {
throw new Exception(
"Rack holds {$source_stock['product_sku']}, not {$data['product_sku']}."
);
}
// Quantity comes from the source stock_in row, NOT user input.
// Under 1:1, taking from this rack = taking the full batch.
$quantity = (int) $source_stock['in'];
$ref_id = (int) $source_stock['id'];
// INSERT new stock_out record.
// ref_id links this stock_out row back to the stock_in batch it consumed.
@@ -130,18 +96,18 @@
$warehouse_id,
$data["zone"], $data["aisle"], $data["rack"]
);
}
// Balance: total_out increases by delta.
// INSERT: $row['out'] = 0 → delta = full quantity
// UPDATE: $row['out'] = old → delta = new - old
$whMgmt->adjustBalance(
'out',
$warehouse_id,
$data["product_sku"],
$row['out'] ?? 0,
$quantity
);
// Balance: total_out increases by delta.
// INSERT: $row['out'] = 0 → delta = full quantity
// UPDATE: $row['out'] = old → delta = new - old
$whMgmt->adjustBalance(
'out',
$warehouse_id,
$data["product_sku"],
$row['out'] ?? 0,
$quantity
);
}
});
+1 -1
View File
@@ -31,7 +31,7 @@
a.company_id = b.company_id and
a.contact_id = b.id
LEFT JOIN md_product c ON
a.company_id = b.company_id and
a.company_id = c.company_id and
a.product_sku = c.sku
WHERE
a.company_id = :company_id and
+1 -1
View File
@@ -31,7 +31,7 @@
a.company_id = b.company_id and
a.contact_id = b.id
LEFT JOIN md_product c ON
a.company_id = b.company_id and
a.company_id = c.company_id and
a.product_sku = c.sku
WHERE
a.company_id = :company_id and