Fix item counts, PR/QT conversions, validation and department loss

This commit is contained in:
Thanakorn
2026-09-15 16:11:47 +07:00
parent 78d69d81df
commit c915379e2e
23 changed files with 100 additions and 45 deletions
@@ -15,10 +15,6 @@ if (!$request_id) {
$answer['message'] = 'Purchase request ID is required.';
exit(json_encode($answer));
}
if (!$contact_id) {
$answer['message'] = 'Supplier (contact_id) is required for the PO.';
exit(json_encode($answer));
}
$prm = new PurchaseRequestManager($pdo2, $company_id);
@@ -29,6 +25,15 @@ if (!$pr || (int)$pr['status'] !== 2) {
exit(json_encode($answer));
}
// Default to the PR's preferred supplier
if (!$contact_id) {
$contact_id = (int)($pr['contact_id'] ?? 0);
}
if (!$contact_id) {
$answer['message'] = 'Set a Preferred Supplier on this purchase request before converting it to a PO.';
exit(json_encode($answer));
}
$pr_items = $pr['items'];
if (empty($pr_items)) {
$answer['message'] = 'Purchase request has no items.';
@@ -92,6 +97,7 @@ foreach ($convert_items as $ci) {
'unit_price' => $unit_price,
'total_price' => $total_price,
'tax_amount' => $tax_amount,
'tax_rate' => (float)($pi['tax_rate'] ?? 0),
'received_qty' => 0,
'stock_in_id' => 0,
];
+3 -3
View File
@@ -194,7 +194,7 @@
<td><input type="number" class="form-control form-control-sm item_qty" value="${item.quantity || 1}" min="0.0001" step="any" oninput="recalc_totals()"></td>
<td><input type="number" class="form-control form-control-sm item_price" value="${item.unit_price || item.price || 0}" min="0" step="any" oninput="recalc_totals()"></td>
<td>
<input type="number" class="form-control form-control-sm item_tax_rate" value="${parseFloat(item.tax_rate || 0).toFixed(2)}" min="0" max="100" step="0.01" oninput="recalc_totals()">
<input type="number" class="form-control form-control-sm item_tax_rate" value="${line_tax_rate(item).toFixed(2)}" min="0" max="100" step="0.01" oninput="recalc_totals()">
<input type="hidden" class="item_tax_amount" value="${item.tax_amount || 0}">
</td>
<td class="item_total text-end">${format_number((item.quantity || 1) * (item.unit_price || item.price || 0), 2)}</td>
@@ -371,8 +371,8 @@
recalc_totals();
});
$(function() {
load_departments('department_id');
$(async function() {
await Promise.resolve(load_departments('department_id')).catch(function() {});
flatpickr('#po_date', { dateFormat: 'd/m/Y', allowInput: true });
flatpickr('#expected_date', { dateFormat: 'd/m/Y', allowInput: true });
if (po_id) {
+3 -2
View File
@@ -370,8 +370,9 @@
recalc_totals();
});
$(function() {
load_departments('department_id');
$(async function() {
// Options must exist before retrieve_request() selects the saved department
await Promise.resolve(load_departments('department_id')).catch(function() {});
flatpickr('#request_date', { dateFormat: 'd/m/Y', allowInput: true });
flatpickr('#required_date', { dateFormat: 'd/m/Y', allowInput: true });
if (request_id) {
+2 -2
View File
@@ -180,7 +180,7 @@
return;
}
$.each(rows, function(i, r) {
var items = typeof r.items === 'string' ? JSON.parse(r.items || '[]') : (r.items || []);
var item_count = parseInt(r.item_count) || 0;
var po_link = r.po_id > 0
? `<a href="<?php echo $server_url?>expense/manage_purchase_order.php?id=${r.po_id}">${escape_html(r.po_number || ('PO #' + r.po_id))}</a>`
: '<span class="text-muted">—</span>';
@@ -190,7 +190,7 @@
<td class="py-3">${r.required_date ? format_date(r.required_date) : '<span class="text-muted">—</span>'}</td>
<td class="py-3">${escape_html(r.contact_name || '—')}</td>
<td class="py-3">${get_dept_label(r.department_id)}</td>
<td class="py-3">${items.length} item${items.length !== 1 ? 's' : ''}</td>
<td class="py-3">${item_count} item${item_count !== 1 ? 's' : ''}</td>
<td class="py-3 fw-semibold">${format_number(r.grand_total, 2)}</td>
<td class="py-3">${status_badge[String(r.status)] || r.status}</td>
<td class="py-3">${po_link}</td>