Fix stock-out boot, transfer 500, Clear buttons and uncaught engine errors
Return JSON from any uncaught engine exception, stop the empty stock-out warehouse list aborting page boot, reject non-transfer rows in the transfer lookup, define the missing reset_input helper, and remove a stale unreferenced copy of confirm_order.php.
This commit is contained in:
@@ -222,7 +222,7 @@
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'read',
|
||||
data: { id: <?php echo (int)$_GET['id']; ?> },
|
||||
data: { id: <?php echo (int)($_GET['id'] ?? 0); ?> },
|
||||
onSuccess: function(res) {
|
||||
var item = res.output;
|
||||
$('#id').val(item.id);
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'read',
|
||||
data: { id: <?php echo (int)$_GET['id']; ?> },
|
||||
data: { id: <?php echo (int)($_GET['id'] ?? 0); ?> },
|
||||
onSuccess: function(res) {
|
||||
var item = res.output;
|
||||
$('#id').val(item.id);
|
||||
|
||||
@@ -1074,6 +1074,36 @@ function to_iso_date(dateStr) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear every field inside a form or form-like container — the "Clear" buttons
|
||||
* on the master-data pages. It was called by five pages but never defined, so
|
||||
* each click threw a ReferenceError, and where the container is a <div> rather
|
||||
* than a <form> (Chart of Accounts, Departments) the button did nothing at all.
|
||||
* Disabled and hidden inputs are left alone: those carry the record id and
|
||||
* locked values, not user input.
|
||||
*/
|
||||
function reset_input(selector) {
|
||||
var $scope = $(selector);
|
||||
if (!$scope.length) return;
|
||||
|
||||
$scope.find('input, textarea, select').each(function () {
|
||||
if (this.disabled || this.type === 'hidden' || this.type === 'button' || this.type === 'submit') return;
|
||||
|
||||
if (this._flatpickr) {
|
||||
this._flatpickr.clear();
|
||||
} else if (this.type === 'checkbox' || this.type === 'radio') {
|
||||
this.checked = this.defaultChecked;
|
||||
} else if (this.tagName === 'SELECT') {
|
||||
this.selectedIndex = 0;
|
||||
} else {
|
||||
this.value = '';
|
||||
}
|
||||
|
||||
$(this).removeAttr('secondary').removeClass('is-invalid is-valid');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function round_dp(value, places) {
|
||||
var factor = Math.pow(10, places);
|
||||
return Math.round((Number(value) + Number.EPSILON) * factor) / factor;
|
||||
|
||||
@@ -307,7 +307,10 @@ class StockManager {
|
||||
$sth->execute([':company_id' => $this->company_id, ':id' => $id]);
|
||||
$output = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$output) return false;
|
||||
// Only a transfer's outbound row names a destination. Any other row
|
||||
// (a stock-in or stock-out reached through a stale or edited link) has
|
||||
// no ref_warehouse, and resolving it threw "Invalid warehouse id."
|
||||
if (!$output || $output['type'] !== 'transfer' || (int)$output['ref_warehouse'] <= 0) return false;
|
||||
|
||||
// Resolve the inbound (to) row via ref_warehouse + uuid
|
||||
$to_warehouse_id = (int)$output['ref_warehouse'];
|
||||
|
||||
@@ -7,6 +7,34 @@ ini_set('display_errors', 0);
|
||||
ini_set('log_errors', 1);
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
// Last-resort handler for exceptions an engine does not catch itself. Many
|
||||
// engines call a manager with no try/catch, so any exception — including the
|
||||
// managers' own deliberate validation messages — used to end as a PHP fatal
|
||||
// with an empty 500 body, which the browser could only report as "Server
|
||||
// error occurred." This mirrors the convention the catching engines already
|
||||
// use: a manager's Exception carries a user-facing message (400); a database
|
||||
// or engine fault stays generic (500) and goes to the server log.
|
||||
set_exception_handler(function (Throwable $e) {
|
||||
while (ob_get_level() > 0) ob_end_clean();
|
||||
if (!headers_sent()) header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
if ($e instanceof PDOException) {
|
||||
error_log('Uncaught PDOException: ' . $e->getMessage() . ' @ ' . $e->getFile() . ':' . $e->getLine());
|
||||
http_response_code(500);
|
||||
$message = 'Database error, please try again.';
|
||||
} elseif ($e instanceof Exception) {
|
||||
http_response_code(400);
|
||||
$message = $e->getMessage();
|
||||
} else {
|
||||
// Error / TypeError: a programming fault, not something to show users.
|
||||
error_log('Uncaught ' . get_class($e) . ': ' . $e->getMessage() . ' @ ' . $e->getFile() . ':' . $e->getLine());
|
||||
http_response_code(500);
|
||||
$message = 'Server error occurred.';
|
||||
}
|
||||
|
||||
echo json_encode(['success' => 0, 'message' => $message]);
|
||||
});
|
||||
|
||||
require_once __DIR__."/../../config.php";
|
||||
require_once __DIR__."/../../dbconn.php";
|
||||
require_once __DIR__."/db_helpers.php";
|
||||
|
||||
@@ -17,11 +17,27 @@
|
||||
$answer['output'] = $wh->getWarehouseList($type, $sku, $id);
|
||||
}
|
||||
|
||||
if (empty($answer['output'])) {
|
||||
if (!empty($answer['output'])) {
|
||||
$answer['success'] = 1;
|
||||
|
||||
} elseif ($type === 'from' && !$id && $sku === '') {
|
||||
// A source ("from") list is filtered to warehouses holding the chosen
|
||||
// product, so it is empty until a product has been picked. That is the
|
||||
// normal starting state of a stock-out form, not a failure. Reporting
|
||||
// it as one showed "create your first warehouse" on every fresh
|
||||
// stock-out, and the rejected request aborted the page's boot sequence
|
||||
// before the barcode scanner was initialised.
|
||||
$answer['success'] = 1;
|
||||
|
||||
} elseif ($type === 'from' && $sku !== '') {
|
||||
$answer['success'] = 0;
|
||||
$answer['message'] = $lot
|
||||
? 'No approved stock of this product and lot is available in any warehouse.'
|
||||
: 'No approved stock of this product is available in any warehouse.';
|
||||
|
||||
} else {
|
||||
$answer['success'] = 0;
|
||||
$answer['message'] = 'No warehouse found. Please go to <b>Inventory → Warehouse</b> to create your first warehouse before using this page.';
|
||||
} else {
|
||||
$answer['success'] = 1;
|
||||
}
|
||||
exit(json_encode($answer));
|
||||
?>
|
||||
@@ -630,6 +630,12 @@
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var data = res.output;
|
||||
if (!data || !data.ref) {
|
||||
bootbox.alert('Stock transfer not found.', function() {
|
||||
window.location.href = '<?php echo $server_url?>ics/stock_transfer.php';
|
||||
});
|
||||
return;
|
||||
}
|
||||
var from_wh = data.ref.ref_warehouse;
|
||||
var to_wh = data.ref_warehouse;
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require '../../../assets/utils/classes/OrderManager.php';
|
||||
require '../../../assets/utils/classes/StockManager.php';
|
||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||
require '../../../assets/utils/classes/InvoiceManager.php';
|
||||
require_once '../../../assets/utils/classes/CompanySettingManager.php';
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
if (!$id) {
|
||||
$answer['message'] = 'Invalid order ID.';
|
||||
http_response_code(400);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
$csm = new CompanySettingManager($pdo1, $company_id);
|
||||
$auto_approve = (int)$csm->get('default_stock_status') === 1;
|
||||
$auto_invoice = (int)$csm->get('auto_invoice_and_credit_note') === 1;
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($id, $company_id, $logging, $uuid, $auto_approve, $auto_invoice) {
|
||||
$order = new OrderManager($pdo, $company_id);
|
||||
$order->confirmOrder($id, $uuid, $logging, $auto_approve);
|
||||
|
||||
if ($auto_invoice) {
|
||||
$invMgmt = new InvoiceManager($pdo, $company_id);
|
||||
$invMgmt->createFromOrder($id, $logging);
|
||||
}
|
||||
});
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Order confirmed.';
|
||||
$answer['auto_approved'] = $auto_approve;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$answer['message'] = 'Database error, please try again.';
|
||||
http_response_code(500);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$answer['message'] = $e->getMessage();
|
||||
http_response_code(400);
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
?>
|
||||
Reference in New Issue
Block a user