38471-vm/pages/sales_purchases_handlers.php
2026-05-07 08:08:50 +00:00

141 lines
6.2 KiB
PHP

<?php
// Shared Sales/Purchases secondary handlers extracted from index.php.
if (!function_exists('sales_purchases_target_page')) {
function sales_purchases_target_page(string $type): string {
return $type === 'purchase' ? 'purchases' : 'sales';
}
}
if (isset($_POST['delete_invoice'])) {
$id = (int)($_POST['id'] ?? 0);
$type = ($page === 'purchases') ? 'purchase' : 'sale';
$table = ($type === 'purchase') ? 'purchases' : 'invoices';
$item_table = ($type === 'purchase') ? 'purchase_items' : 'invoice_items';
$fk_col = ($type === 'purchase') ? 'purchase_id' : 'invoice_id';
db()->prepare("DELETE FROM $table WHERE id = ?")->execute([$id]);
db()->prepare("DELETE FROM $item_table WHERE $fk_col = ?")->execute([$id]);
redirectWithMessage(($type === 'purchase' ? 'Purchase' : 'Invoice') . ' deleted!', page_url(sales_purchases_target_page($type)));
}
if (isset($_POST['convert_to_invoice'])) {
$db = db();
try {
$db->beginTransaction();
$quot_id = (int)($_POST['quotation_id'] ?? 0);
$stmt = $db->prepare("SELECT * FROM quotations WHERE id = ?");
$stmt->execute([$quot_id]);
$quot = $stmt->fetch();
if (!$quot) {
throw new Exception('Quotation not found.');
}
if (($quot['status'] ?? '') === 'converted') {
throw new Exception('Quotation already converted.');
}
$stmtItems = $db->prepare("SELECT * FROM quotation_items WHERE quotation_id = ?");
$stmtItems->execute([$quot_id]);
$qItems = $stmtItems->fetchAll();
$inv_date = date('Y-m-d');
$stmtInv = $db->prepare("INSERT INTO invoices (customer_id, invoice_date, status, payment_type, total_amount, vat_amount, total_with_vat, paid_amount, outlet_id) VALUES (?, ?, 'unpaid', 'credit', ?, ?, ?, 0, ?)");
$stmtInv->execute([$quot['customer_id'], $inv_date, $quot['total_amount'], $quot['vat_amount'], $quot['total_with_vat'], current_outlet_id()]);
$inv_id = $db->lastInsertId();
$items_for_journal = [];
foreach ($qItems as $item) {
$qty = normalize_quantity($item['quantity'] ?? 0);
$lineVatAmount = line_item_vat_amount($db, $item);
$db->prepare("INSERT INTO invoice_items (invoice_id, item_id, quantity, unit_price, vat_amount, total_price) VALUES (?, ?, ?, ?, ?, ?)")
->execute([$inv_id, $item['item_id'], $qty, $item['unit_price'], $lineVatAmount, $item['total_price']]);
update_stock($item['item_id'], -$qty);
$items_for_journal[] = ['id' => $item['item_id'], 'qty' => $qty];
}
$db->prepare("UPDATE quotations SET status = 'converted' WHERE id = ?")->execute([$quot_id]);
recordSaleJournal($inv_id, $quot['total_with_vat'], $inv_date, $items_for_journal, $quot['vat_amount']);
$db->commit();
redirectWithMessage("Quotation converted to Invoice #$inv_id successfully!", page_url('sales'));
} catch (Exception $e) {
$db->rollBack();
$message = 'Error: ' . $e->getMessage();
}
}
if (isset($_POST['convert_lpo_to_purchase'])) {
$db = db();
try {
$db->beginTransaction();
$lpo_id = (int)($_POST['lpo_id'] ?? 0);
$stmt = $db->prepare("SELECT * FROM lpos WHERE id = ?");
$stmt->execute([$lpo_id]);
$lpo = $stmt->fetch();
if (!$lpo) {
throw new Exception('LPO not found.');
}
if (($lpo['status'] ?? '') === 'converted') {
throw new Exception('LPO already converted.');
}
$stmtItems = $db->prepare("SELECT * FROM lpo_items WHERE lpo_id = ?");
$stmtItems->execute([$lpo_id]);
$lItems = $stmtItems->fetchAll();
$pur_date = date('Y-m-d');
$stmtPur = $db->prepare("INSERT INTO purchases (supplier_id, invoice_date, status, payment_type, total_amount, vat_amount, total_with_vat, paid_amount, outlet_id) VALUES (?, ?, 'unpaid', 'credit', ?, ?, ?, 0, ?)");
$stmtPur->execute([$lpo['supplier_id'], $pur_date, $lpo['total_amount'], $lpo['vat_amount'], $lpo['total_with_vat'], current_outlet_id()]);
$pur_id = $db->lastInsertId();
foreach ($lItems as $item) {
$qty = normalize_quantity($item['quantity'] ?? 0);
$db->prepare("INSERT INTO purchase_items (purchase_id, item_id, quantity, unit_price, vat_amount, total_price) VALUES (?, ?, ?, ?, ?, ?)")
->execute([$pur_id, $item['item_id'], $qty, $item['unit_price'], $item['vat_amount'], $item['total_amount']]);
update_stock($item['item_id'], $qty);
}
$db->prepare("UPDATE lpos SET status = 'converted' WHERE id = ?")->execute([$lpo_id]);
$db->commit();
redirectWithMessage("LPO converted to Purchase Invoice #$pur_id successfully!", page_url('purchases'));
} catch (Exception $e) {
$db->rollBack();
$message = 'Error: ' . $e->getMessage();
}
}
if (isset($_POST['record_payment'])) {
$id = (int)($_POST['invoice_id'] ?? 0);
$amount = (float)($_POST['amount'] ?? 0);
$date = !empty($_POST['payment_date']) ? (string)$_POST['payment_date'] : date('Y-m-d');
$method = $_POST['payment_method'] ?? 'Cash';
$type = ($page === 'purchases') ? 'purchase' : 'sale';
$table = ($type === 'purchase') ? 'purchases' : 'invoices';
$payment_table = ($type === 'purchase') ? 'purchase_payments' : 'payments';
$fk_col = ($type === 'purchase') ? 'purchase_id' : 'invoice_id';
$db = db();
$db->prepare("INSERT INTO $payment_table ($fk_col, amount, payment_date, payment_method, notes) VALUES (?, ?, ?, ?, ?)")
->execute([$id, $amount, $date, $method, $_POST['notes'] ?? '']);
$pay_id = $db->lastInsertId();
$db->prepare("UPDATE $table SET paid_amount = paid_amount + ?, status = IF(paid_amount + ? >= total_with_vat, 'paid', 'partially_paid') WHERE id = ?")
->execute([$amount, $amount, $id]);
if ($type === 'sale') {
recordPaymentReceivedJournal((int)$pay_id, $amount, $date, $method);
} else {
recordPaymentMadeJournal((int)$pay_id, $amount, $date, $method);
}
$_SESSION['trigger_receipt_modal'] = true;
$_SESSION['show_receipt_id'] = $pay_id;
redirectWithMessage('Payment recorded!', page_url(sales_purchases_target_page($type)));
}