Autosave: 20260426-021157

This commit is contained in:
Flatlogic Bot 2026-04-26 02:11:55 +00:00
parent 10edd2e5bc
commit a2cefc7b7a
8 changed files with 109 additions and 17 deletions

View File

@ -157,7 +157,14 @@ try {
? ', sale_date DESC'
: ', COALESCE(delivery_date, DATE(sale_date)) ASC, sale_date DESC';
$sql = 'SELECT * FROM sales_orders' . $where . ' ORDER BY ' . $primarySort . $secondarySort . ' LIMIT :limit OFFSET :offset';
$sql = "SELECT sales_orders.*, (
SELECT COUNT(*)
FROM sales_orders AS seq
WHERE seq.order_type = sales_orders.order_type
AND seq.sale_mode = sales_orders.sale_mode
AND seq.id <= sales_orders.id
) AS mode_serial_no
FROM sales_orders" . $where . ' ORDER BY ' . $primarySort . $secondarySort . ' LIMIT :limit OFFSET :offset';
$stmt = db()->prepare($sql);
foreach ($params as $key => $value) {
$stmt->bindValue($key, $value);
@ -408,7 +415,13 @@ require __DIR__ . '/includes/header.php';
<?php $effectiveDelivery = $order['delivery_date'] ?: date('Y-m-d', strtotime((string) $order['sale_date'])); ?>
<tr>
<td>
<div class="fw-semibold"><?= h($order['receipt_no']) ?></div>
<?php
$modeSerialNo = max(1, (int) ($order['mode_serial_no'] ?? 0));
$modeSerialPrefix = (($order['sale_mode'] ?? 'normal') === 'pos') ? 'P' : 'N';
$modeSerialLabel = $modeSerialPrefix . '-' . str_pad((string) $modeSerialNo, 4, '0', STR_PAD_LEFT);
?>
<div class="fw-semibold"><?= h($modeSerialLabel) ?></div>
<div class="small text-muted">#<?= h($order['receipt_no']) ?> · <?= h(sale_mode_label((string) ($order['sale_mode'] ?? 'normal'))) ?></div>
</td>
<?php
$rawCustomerName = (string) ($order['customer_name'] ?: tr('عميل نقدي', 'Walk-in customer'));

View File

@ -98,6 +98,10 @@ try {
$items = is_array($decodedItems) ? $decodedItems : [];
$order['items'] = $items;
if (($order['delivery_status'] ?? '') === 'cancelled') {
continue;
}
foreach ($items as $item) {
$sku = trim((string) ($item['sku'] ?? ''));
$name = trim((string) ($item['name_ar'] ?? ''));

View File

@ -10,6 +10,8 @@ $activeNav = $activeNav ?? ($isEidOrder ? 'eid_orders' : ($saleMode === 'normal'
$backUrl = $backUrl ?? ($isEidOrder ? url_for('eid_orders.php') : url_for('sales.php'));
$backLabel = $backLabel ?? ($isEidOrder ? tr('عودة لطلبات العيد', 'Back to Eid Orders') : tr('عودة للمبيعات', 'Back to Sales'));
$saveLabel = $saveLabel ?? ($isEidOrder ? tr('حفظ طلب العيد', 'Save Eid Order') : tr('حفظ الفاتورة', 'Save Invoice'));
$saveOnlyLabel = $saveOnlyLabel ?? tr('حفظ فقط', 'Save only');
$savePrintLabel = $savePrintLabel ?? tr('حفظ مع الطباعة', 'Save with print');
$error = '';
$paymentAmountInput = (string) ($_POST['payment_amount'] ?? '');
$catalog = catalog();
@ -27,6 +29,11 @@ try {
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$submitAction = trim((string) ($_POST['submit_action'] ?? 'save'));
if (!in_array($submitAction, ['save', 'save_print'], true)) {
$submitAction = 'save';
}
$branchCode = trim((string) ($_POST['branch_code'] ?? ''));
$customerId = isset($_POST['customer_id']) && $_POST['customer_id'] !== '' ? (int)$_POST['customer_id'] : null;
$customerName = trim((string) ($_POST['customer_name'] ?? ''));
@ -152,7 +159,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
: ($saleMode === 'normal'
? tr('تم حفظ الفاتورة بنجاح.', 'Invoice saved successfully.')
: tr('تم حفظ عملية POS بنجاح.', 'POS sale saved successfully.')));
redirect_to('sale.php', ['id' => $saleId]);
if ($submitAction === 'save') {
if ($isEidOrder) {
redirect_to('eid_sale.php');
}
if ($saleMode === 'normal') {
redirect_to('normal_sale.php');
}
redirect_to('pos.php');
}
$redirectParams = ['id' => $saleId, 'print' => 1];
redirect_to('sale.php', $redirectParams);
}
}
}
@ -482,9 +500,15 @@ require __DIR__ . '/header.php';
</div>
</div>
<button type="submit" class="btn btn-primary w-100 py-2 fs-5 rounded-3 shadow-sm">
<i class="bi bi-check-circle me-1"></i> <?= h($saveLabel) ?>
</button>
<div class="d-grid gap-2">
<button type="submit" name="submit_action" value="save" class="btn btn-primary w-100 py-2 fs-5 rounded-3 shadow-sm">
<i class="bi bi-check-circle me-1"></i> <?= h($saveOnlyLabel) ?>
</button>
<button type="submit" name="submit_action" value="save_print" class="btn btn-outline-dark w-100 py-2 fs-5 rounded-3 shadow-sm">
<i class="bi bi-printer me-1"></i> <?= h($savePrintLabel) ?>
</button>
</div>
<div class="form-text mt-2"><?= h(tr('اختر إذا كنت تريد الحفظ فقط أو الحفظ وفتح نافذة الطباعة مباشرة.', 'Choose whether to save only or save and open the print dialog immediately.')) ?></div>
</div>
</div>
</div>

0
patch.php Normal file
View File

38
pos.php
View File

@ -6,6 +6,10 @@ $pageTitle = tr('نقاط البيع', 'Smart POS');
$activeNav = 'pos';
$error = '';
$paymentAmountInput = (string) ($_POST['payment_amount'] ?? '');
$submitAction = trim((string) ($_POST['submit_action'] ?? 'save_print'));
if (!in_array($submitAction, ['save', 'save_print'], true)) {
$submitAction = 'save_print';
}
$catalog = catalog();
$allowedBranches = get_user_branches($user);
@ -102,7 +106,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
wablas_notify_sale_invoice($saleId);
set_flash('success', tr('تم حفظ عملية POS بنجاح.', 'POS sale saved successfully.'));
redirect_to('print_receipt.php', ['id' => $saleId]);
if ($submitAction === 'save') {
redirect_to('pos.php');
}
redirect_to('print_receipt.php', ['id' => $saleId, 'print' => 1]);
}
}
}
@ -594,6 +601,7 @@ require __DIR__ . '/includes/header.php';
<input type="hidden" name="payment_method" id="inputPayment">
<input type="hidden" name="payment_amount" id="inputPaymentAmount">
<input type="hidden" name="notes" id="inputNotes">
<input type="hidden" name="submit_action" id="inputSubmitAction">
<input type="hidden" name="cart_json" id="inputCart">
</form>
@ -612,17 +620,28 @@ require __DIR__ . '/includes/header.php';
<input type="number" id="modalPaidAmount" class="form-control rounded-3" min="0" step="0.001" value="<?= h($paymentAmountInput) ?>" placeholder="0.000">
<div class="form-text" id="modalDueHint"><?= h(tr('سيتم تتبع المبلغ المتبقي تلقائياً.', 'The remaining balance will be tracked automatically.')) ?></div>
</div>
<div class="mb-3 text-start">
<label class="form-label small text-muted d-block"><?= h(tr('بعد الحفظ', 'After saving')) ?></label>
<div class="btn-group w-100" role="group" aria-label="<?= h(tr('خيارات الحفظ', 'Save options')) ?>">
<input type="radio" class="btn-check" name="save_mode" id="saveActionOnly" autocomplete="off">
<label class="btn btn-outline-dark" for="saveActionOnly"><?= h(tr('حفظ فقط', 'Save only')) ?></label>
<input type="radio" class="btn-check" name="save_mode" id="saveActionPrint" autocomplete="off" checked>
<label class="btn btn-outline-dark" for="saveActionPrint"><?= h(tr('حفظ مع طباعة', 'Save with print')) ?></label>
</div>
<div class="form-text"><?= h(tr('اختر إذا كنت تريد حفظ الفاتورة فقط أو حفظها وفتح الطباعة مباشرة.', 'Choose whether to save the receipt only or save it and open printing immediately.')) ?></div>
</div>
<div class="d-grid gap-3">
<button class="btn btn-lg btn-outline-success rounded-pill fw-semibold" onclick="submitSale('cash')">
<button type="button" class="btn btn-lg btn-outline-success rounded-pill fw-semibold" onclick="submitSale('cash')">
<i class="bi bi-cash-coin me-2"></i> <?= h(tr('نقداً', 'Cash')) ?>
</button>
<button class="btn btn-lg btn-outline-primary rounded-pill fw-semibold" onclick="submitSale('card')">
<button type="button" class="btn btn-lg btn-outline-primary rounded-pill fw-semibold" onclick="submitSale('card')">
<i class="bi bi-credit-card me-2"></i> <?= h(tr('بطاقة', 'Card')) ?>
</button>
<button class="btn btn-lg btn-outline-secondary rounded-pill fw-semibold" onclick="submitSale('transfer')">
<button type="button" class="btn btn-lg btn-outline-secondary rounded-pill fw-semibold" onclick="submitSale('transfer')">
<i class="bi bi-phone me-2"></i> <?= h(tr('تحويل بنكي', 'Transfer')) ?>
</button>
<button class="btn btn-lg btn-outline-warning rounded-pill fw-semibold" onclick="submitSale('pay_later')">
<button type="button" class="btn btn-lg btn-outline-warning rounded-pill fw-semibold" onclick="submitSale('pay_later')">
<i class="bi bi-clock-history me-2"></i> <?= h(tr('آجل', 'Pay Later')) ?>
</button>
</div>
@ -973,10 +992,18 @@ function openPaymentModal() {
paidField.value = total.toFixed(3);
paidField.dataset.manual = '0';
}
const saveActionPrint = document.getElementById('saveActionPrint');
if (saveActionPrint) {
saveActionPrint.checked = true;
}
updateModalDueHint();
paymentModalObj.show();
}
function getSelectedSubmitAction() {
return document.getElementById('saveActionOnly')?.checked ? 'save' : 'save_print';
}
function submitSale(method) {
const branch = document.getElementById('posBranch').value || '<?= h($allowedBranches[0] ?? '') ?>';
const customer = document.getElementById('posCustomer').value;
@ -1014,6 +1041,7 @@ function submitSale(method) {
document.getElementById('inputCustomer').value = customer;
document.getElementById('inputPayment').value = method;
document.getElementById('inputPaymentAmount').value = paidAmount.toFixed(3);
document.getElementById('inputSubmitAction').value = getSelectedSubmitAction();
document.getElementById('inputCart').value = JSON.stringify(itemsArr);
document.getElementById('checkoutForm').submit();

View File

@ -2,6 +2,7 @@
require_once __DIR__ . '/includes/app.php';
$user = require_permission('sales', 'show');
$id = (int) ($_GET['id'] ?? 0);
$autoPrint = isset($_GET['print']) && $_GET['print'] === '1';
$sale = null;
$dbError = null;
if ($id > 0) {
@ -295,14 +296,16 @@ $registerNo = 'REG-01';
<button onclick="window.print()" class="btn"><?= h(tr('طباعة الآن', 'Print Now')) ?></button>
</div>
<?php if ($autoPrint): ?>
<script>
// Auto print when page loads
// Auto print when page loads only when explicitly requested
window.onload = function() {
setTimeout(() => {
window.print();
}, 500);
};
</script>
<?php endif; ?>
</body>
</html>

View File

@ -15,6 +15,7 @@ if ($id > 0) {
}
$paymentSummary = $sale ? sale_payment_summary($sale) : ['paid_amount' => 0, 'due_amount' => 0, 'payment_status' => 'paid'];
$isEidSale = $sale && (($sale['order_type'] ?? 'standard') === 'eid');
$autoPrint = isset($_GET['print']) && $_GET['print'] === '1';
// Company Info for Invoice
$companyName = current_lang() === 'ar' ? get_setting('company_name_ar', 'حلوى الريامي') : get_setting('company_name_en', 'Al Riyami Sweets');
@ -490,4 +491,14 @@ require __DIR__ . '/includes/header.php';
<?php endif; ?>
</div>
<?php require __DIR__ . '/includes/footer.php'; ?>
<?php require __DIR__ . '/includes/footer.php'; ?>
<?php if ($autoPrint && $sale): ?>
<script>
window.addEventListener('load', function () {
setTimeout(function () {
window.print();
}, 300);
});
</script>
<?php endif; ?>

View File

@ -46,7 +46,7 @@ foreach ($items as $item) {
}
body { background-color: #f8f9fa; }
body { background: linear-gradient(135deg, #fdfbfb 0%, #ebedee 100%); background-attachment: fixed; min-height: 100vh; }
/* Hide scrollbar for category filter */
.category-filter-container::-webkit-scrollbar {
@ -88,9 +88,18 @@ body { background-color: #f8f9fa; }
<!-- Sticky Header -->
<div class="sticky-top bg-white p-3 rounded-4 shadow-sm mb-4" style="top: 15px; z-index: 1020;">
<div class="d-flex flex-wrap justify-content-between align-items-center gap-3">
<div>
<h2 class="fw-bold text-primary mb-1"><i class="bi bi-shop me-2"></i><?= h(get_setting('company_name_' . current_lang(), app_name())) ?></h2>
<p class="text-muted mb-0 d-none d-sm-block" style="font-size: 0.9rem;"><?= h(tr('اطلب الآن وسنقوم بتجهيز طلبك', 'Order now and we will prepare your request')) ?></p>
<div class="d-flex align-items-center gap-3">
<?php if (get_setting('company_logo')): ?>
<img src="<?= h(get_setting('company_logo')) ?>" alt="Logo" class="rounded shadow-sm bg-white" style="max-height: 55px; max-width: 120px; object-fit: contain; padding: 4px;">
<?php else: ?>
<div class="bg-primary bg-gradient text-white rounded shadow-sm d-flex align-items-center justify-content-center" style="width: 50px; height: 50px;">
<i class="bi bi-shop fs-4"></i>
</div>
<?php endif; ?>
<div>
<h3 class="fw-bold text-primary mb-1" style="font-size: 1.5rem;"><?= h(get_setting('company_name_' . current_lang(), app_name())) ?></h3>
<p class="text-muted mb-0 d-none d-sm-block" style="font-size: 0.85rem;"><?= h(tr('اطلب الآن وسنقوم بتجهيز طلبك', 'Order now and we will prepare your request')) ?></p>
</div>
</div>
<div class="d-flex align-items-center gap-2 gap-md-3">
<button class="btn btn-primary rounded-pill px-3 px-md-4 py-2 position-relative shadow-sm fw-bold d-flex align-items-center gap-2" onclick="openCart()">