Fix item counts, PR/QT conversions, validation and department loss
This commit is contained in:
@@ -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,
|
||||
];
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user