Files
wms-app/app/include_header.php
T
Thanakorn f70f226bd1 Fix timestamps, delete requests, invoice dates and GR quantities
Apply the configured timezone to PHP and both DB connections, wrap
unwrapped ajax payloads so delete buttons reach their engines, normalise
and validate invoice due dates, reject stock quantities below the stored
4dp scale, and list stock movements across all warehouses.
2026-09-17 09:00:15 +07:00

101 lines
5.3 KiB
PHP

<?php
// Output buffering must be active before the first byte of HTML below, so that
// header() calls made later in the page still work — notably the
// not-logged-in redirect in include_topbar.php, which runs *after* this file
// has already emitted <!DOCTYPE html>. Without a buffer that redirect depends
// entirely on php.ini's output_buffering: it is on for the dev stack but off
// in production, where every protected page answered 200 with a half-rendered
// body instead of sending the browser to the login form. session.php starts a
// buffer for the same reason.
if (ob_get_level() === 0) {
ob_start();
}
// Never render PHP notices/warnings into the page: they leak absolute server
// paths to anonymous visitors and corrupt the markup. Errors still reach the
// server log. This mirrors the policy db_auth.php already applies to the JSON
// API routes, and keeps the app safe even where php.ini has display_errors on.
ini_set('display_errors', '0');
ini_set('log_errors', '1');
// Apply the configured application timezone. Pages that only require config.php
// (no dbconn.php) still call date() for default values such as "today", so they
// need this too or they render a UTC date.
require_once __DIR__ . '/assets/utils/timezone.php';
// Security headers — emitted before any HTML output.
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: SAMEORIGIN');
header('Referrer-Policy: strict-origin-when-cross-origin');
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>BRN WMS</title>
<meta name="csrf-token" content="<?= htmlspecialchars($_SESSION['csrf_token'] ?? '') ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" sizes="180x180" href="<?php echo $server_url?>assets/images/favicon.png">
<link rel="icon" type="image/png" sizes="32x32" href="<?php echo $server_url?>assets/images/favicon32.png">
<link rel="icon" type="image/png" sizes="16x16" href="<?php echo $server_url?>assets/images/favicon32.png">
<link rel="manifest" href="<?php echo $server_url?>assets/site.webmanifest">
<!-- jquery -->
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
<!-- popper (must be before bootstrap) -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" crossorigin="anonymous"></script>
<!-- bootstrap -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.min.js" integrity="sha384-G/EV+4j2dNv+tEPo3++6LCgdCROaejBqfUeNjuKAiuXbjrxilcCdDz6ZAVfHWe1Y" crossorigin="anonymous"></script>
<!-- Disable CDN Bootstrap's dropdown toggle — main.js bundles Bootstrap+Popper and
handles dropdown events. CDN Bootstrap stays for window.bootstrap (Modal API). -->
<script>bootstrap.Dropdown.prototype.toggle = function() {};</script>
<!-- bootbox -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js"></script>
<!-- overlay loader -->
<script src="https://cdn.jsdelivr.net/npm/gasparesganga-jquery-loading-overlay@2.1.7/dist/loadingoverlay.min.js"></script>
<!-- bootstrap css -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<!-- flatpickr date -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<!-- flatpickr monthSelect plugin -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/plugins/monthSelect/style.css">
<script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/plugins/monthSelect/index.js"></script>
<!-- autocomplete -->
<link rel="stylesheet" href="https://code.jquery.com/ui/1.14.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.14.1/jquery-ui.min.js"></script>
<!-- alasql -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/alasql/4.6.6/alasql.min.js" integrity="sha512-a0dn7nW2exqcTrj7ZcLhRW3iDxCKOh9GPa1jf27qljXfwhYp4tnNmm+8aRNp9c3ijpGsm7EmeGSQmcu80ZB3NA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- dropzone -->
<script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>
<script>
// This kills the CDN's auto-scanner so it doesn't conflict with main.js
Dropzone.autoDiscover = false;
</script>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<!-- theme script -->
<link rel="stylesheet" href="<?php echo $server_url?>assets/css/main.css">
<script type="module" src="<?php echo $server_url?>assets/js/main.js"></script>
<link rel="stylesheet" href="<?php echo $server_url?>assets/css/custom.css">
<script src="<?php echo $server_url?>assets/js/custom.js?v=<?php echo @filemtime(__DIR__ . '/assets/js/custom.js'); ?>"></script>
<script src="<?php echo $server_url?>assets/js/batch_overlay.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5-qrcode/2.3.8/html5-qrcode.min.js"
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="<?php echo $server_url?>assets/js/scanner.js"></script>
</head>