Fix customer return confirm, auto credit note VAT and quotation link
Store the put-away location on return lines (new td_return_item columns, needs setup.php), split auto credit notes into net and VAT with the parent's department, drop the write to a td_quotation column that does not exist, and have the demo seed confirm its customer return.
This commit is contained in:
+36
-18
@@ -21,13 +21,11 @@
|
||||
* order/api/engine/issue_invoice.php and finance/api/engine/manage_receipt.php
|
||||
* do it), so the data matches what the real UI would have produced.
|
||||
*
|
||||
* NOTE — customer returns: ReturnManager::confirmReturn() reads zone/aisle/bin
|
||||
* from td_return_item rows, but td_return_item has no zone/aisle/bin columns
|
||||
* (see setup.php) and no engine file back-fills them before calling
|
||||
* confirmReturn(). Confirming ANY customer return in this app currently
|
||||
* throws "Location - - - does not exist" from WarehouseManager::occupyBin().
|
||||
* This script creates one customer return and leaves it in draft status —
|
||||
* confirming it is not possible until that's fixed.
|
||||
* Customer returns: the return is saved with a put-away bin and then
|
||||
* confirmed, the same two steps the Customer Return page performs. (It used to
|
||||
* be left in draft: td_return_item had no zone/aisle/bin columns, so the
|
||||
* location was lost on save and confirmReturn() could not restock. setup.php
|
||||
* now adds them.)
|
||||
*
|
||||
* Safe to re-run: every insert is guarded by an existence check.
|
||||
*/
|
||||
@@ -300,12 +298,9 @@ $quotMgmt = new QuotationManager($pdo2, $company_id);
|
||||
$orderMgmt = new OrderManager($pdo2, $company_id);
|
||||
$invMgmt = new InvoiceManager($pdo2, $company_id);
|
||||
|
||||
// NOTE: OrderManager::linkQuotationToOrder() is broken — it writes to a
|
||||
// td_quotation.order_id column that does not exist in the schema (see
|
||||
// setup.php's td_quotation definition). We never call it. The real link
|
||||
// between a quotation and its order is source='quotation'/source_id=$qid on
|
||||
// td_order, which QuotationManager::getById() already joins on — that's what
|
||||
// this script relies on too, both to link and to look the link back up.
|
||||
// The link between a quotation and its order is source='quotation' /
|
||||
// source_id=$qid on td_order, which QuotationManager::getById() joins on —
|
||||
// that's what this script relies on, both to link and to look the link back up.
|
||||
|
||||
$sth = $pdo2->prepare("SELECT id FROM td_quotation WHERE company_id = :c AND notes = 'Demo seed sales cycle' LIMIT 1");
|
||||
$sth->execute([':c' => $company_id]);
|
||||
@@ -704,10 +699,9 @@ if ($supplier_return_id) {
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// 10. Customer return — draft only (see NOTE at top of this file: confirming
|
||||
// customer returns is currently broken in the app itself).
|
||||
// 10. Customer return — saved with a put-away bin, then confirmed (restocked).
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
echo "\n--- Customer return (draft only — confirming is currently broken, see file header) ---\n";
|
||||
echo "\n--- Customer return ---\n";
|
||||
|
||||
$returnMgmt = new ReturnManager($pdo2, $company_id);
|
||||
|
||||
@@ -730,7 +724,18 @@ if ($customer_return_id) {
|
||||
$ret_total = round($ret_qty * (float)$order_line['unit_price'], 4);
|
||||
$ret_tax = round($ret_total * (float)$order_line['tax_rate'] / 100, 4);
|
||||
|
||||
$customer_return_id = dbTransaction($pdo2, function ($pdo2) use ($returnMgmt, $customer_ids, $order_line, $ret_qty, $ret_total, $ret_tax, $sales_order_id, $sales_invoice_id, $logging) {
|
||||
// Returned goods go back into a free bin of the warehouse they shipped from.
|
||||
$sth = $pdo2->prepare(
|
||||
"SELECT bin FROM md_bin WHERE company_id = :c AND warehouse = :w AND product_sku IS NULL
|
||||
ORDER BY CAST(SUBSTRING(bin, 3) AS UNSIGNED) ASC LIMIT 1"
|
||||
);
|
||||
$sth->execute([':c' => $company_id, ':w' => (int)$order_line['warehouse_id']]);
|
||||
$return_bin = (string)($sth->fetchColumn() ?: '');
|
||||
if ($return_bin === '') {
|
||||
throw new Exception("No free bin in warehouse #{$order_line['warehouse_id']} for the demo customer return.");
|
||||
}
|
||||
|
||||
$customer_return_id = dbTransaction($pdo2, function ($pdo2) use ($returnMgmt, $customer_ids, $order_line, $ret_qty, $ret_total, $ret_tax, $sales_order_id, $sales_invoice_id, $logging, $return_bin) {
|
||||
return $returnMgmt->saveReturn([
|
||||
'id' => 0, 'order_id' => $sales_order_id, 'invoice_id' => $sales_invoice_id,
|
||||
'contact_id' => $customer_ids[0], 'return_date' => date('Y-m-d'),
|
||||
@@ -742,10 +747,23 @@ if ($customer_return_id) {
|
||||
'total_price' => $ret_total, 'tax_amount' => $ret_tax, 'tax_rate' => $order_line['tax_rate'],
|
||||
'warehouse_id' => $order_line['warehouse_id'], 'stock_out_id' => $order_line['stock_out_id'],
|
||||
'stock_out_warehouse_id' => $order_line['warehouse_id'],
|
||||
// simple location mode: zone and aisle mirror the bin
|
||||
'zone' => $return_bin, 'aisle' => $return_bin, 'bin' => $return_bin,
|
||||
]],
|
||||
], $logging);
|
||||
});
|
||||
ok("Created draft customer return for {$ret_qty} x {$order_line['product_sku']} (id={$customer_return_id}) — left in draft, not confirmed");
|
||||
|
||||
// Confirm exactly as order/api/engine/confirm_return.php does: restock,
|
||||
// auto-approve the stock-in, and raise the credit note.
|
||||
dbTransaction($pdo2, function ($pdo2) use ($company_id, $customer_return_id, $logging) {
|
||||
$ret = new ReturnManager($pdo2, $company_id);
|
||||
$ret->confirmReturn(
|
||||
$customer_return_id, bin2hex(random_bytes(16)), $logging,
|
||||
new WarehouseManager($pdo2, $company_id), new InvoiceManager($pdo2, $company_id),
|
||||
true, true
|
||||
);
|
||||
});
|
||||
ok("Created + confirmed customer return for {$ret_qty} x {$order_line['product_sku']} into bin {$return_bin} (id={$customer_return_id})");
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user