38471-vm/pages/sales_purchases_save_logic.php
2026-05-03 07:32:13 +00:00

187 lines
9.1 KiB
PHP

<?php
// Shared Sales/Purchases create/update handlers extracted from index.php
// to reduce regression risk while preserving the existing behavior.
// Invoices
if (isset($_POST['add_invoice'])) {
$db = db();
try {
$db->beginTransaction();
$type = $_POST['type'] ?? 'sale';
$table = ($type === 'purchase') ? 'purchases' : 'invoices';
$item_table = ($type === 'purchase') ? 'purchase_items' : 'invoice_items';
$cust_supplier_col = ($type === 'purchase') ? 'supplier_id' : 'customer_id';
$fk_col = ($type === 'purchase') ? 'purchase_id' : 'invoice_id';
$cust_id = (int)$_POST['customer_id'];
$inv_date = $_POST['invoice_date'] ?: date('Y-m-d');
$due_date = $_POST['due_date'] ?: null;
$status = $_POST['status'] ?? 'pending';
$pay_type = $_POST['payment_type'] ?? 'cash';
$items = $_POST['item_ids'] ?? [];
if (empty($items)) {
throw new Exception("Please add at least one item.");
}
$qtys = $_POST['quantities'] ?? [];
$prices = $_POST['prices'] ?? [];
$total_subtotal = 0;
$total_vat = 0;
foreach ($items as $i => $item_id) {
if (!$item_id) continue;
$qty = (float)$qtys[$i];
$price = (float)$prices[$i];
$subtotal = $qty * $price;
$stmtVat = $db->prepare("SELECT vat_rate FROM stock_items WHERE id = ?");
$stmtVat->execute([$item_id]);
$vatRate = (float)$stmtVat->fetchColumn();
$vatAmount = $subtotal * ($vatRate / 100);
$total_subtotal += $subtotal;
$total_vat += $vatAmount;
}
$total_with_vat = $total_subtotal + $total_vat;
$paid = (float)($_POST['paid_amount'] ?? 0);
if ($status === 'paid') $paid = $total_with_vat;
$stmt = $db->prepare("INSERT INTO $table ($cust_supplier_col, invoice_date, due_date, status, payment_type, total_amount, vat_amount, total_with_vat, paid_amount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([$cust_id, $inv_date, $due_date, $status, $pay_type, $total_subtotal, $total_vat, $total_with_vat, $paid]);
$inv_id = $db->lastInsertId();
if (db_column_exists($table, 'outlet_id')) {
$db->prepare("UPDATE $table SET outlet_id = ? WHERE id = ?")->execute([current_outlet_id(), $inv_id]);
}
$items_for_journal = [];
foreach ($items as $i => $item_id) {
if (!$item_id) continue;
$qty = (float)$qtys[$i];
$price = (float)$prices[$i];
$subtotal = $qty * $price;
$stmtVat = $db->prepare("SELECT vat_rate FROM stock_items WHERE id = ?");
$stmtVat->execute([$item_id]);
$vatRate = (float)$stmtVat->fetchColumn();
$vatAmount = $subtotal * ($vatRate / 100);
$db->prepare("INSERT INTO $item_table ($fk_col, item_id, quantity, unit_price, vat_amount, total_price) VALUES (?, ?, ?, ?, ?, ?)")->execute([$inv_id, $item_id, $qty, $price, $vatAmount, $subtotal]);
// Update stock
$change = ($type === 'sale') ? -$qty : $qty;
update_stock($item_id, $change);
$items_for_journal[] = ['id' => $item_id, 'qty' => $qty];
}
// Accounting
if ($type === 'sale') {
recordSaleJournal($inv_id, $total_with_vat, $inv_date, $items_for_journal, $total_vat);
} else {
// For purchases, you might have recordPurchaseJournal, but let's check if it exists
if (function_exists('recordPurchaseJournal')) {
recordPurchaseJournal($inv_id, $total_with_vat, $inv_date, $items_for_journal, $total_vat);
}
}
$db->commit();
$wablasNotice = '';
if ($type === 'sale' && function_exists('wablasQueueInvoiceNotification')) {
$wablasQueue = wablasQueueInvoiceNotification((int)$inv_id);
$wablasNotice = (string)($wablasQueue['notice'] ?? '');
}
$_SESSION['trigger_invoice_modal'] = true;
$_SESSION['show_invoice_id'] = (int)$inv_id;
$_SESSION['show_invoice_page'] = ($type === 'purchase') ? 'purchases' : 'sales';
$msg = ($type === 'purchase' ? "Purchase" : "Invoice") . " #$inv_id created!" . $wablasNotice;
redirectWithMessage($msg, page_url($type === 'purchase' ? 'purchases' : 'sales'));
} catch (Exception $e) { $db->rollBack(); $message = "Error: " . $e->getMessage(); }
}
if (isset($_POST['edit_invoice'])) {
$db = db();
try {
$db->beginTransaction();
$id = (int)$_POST['invoice_id'];
$type = ($page === 'purchases') ? 'purchase' : 'sale';
$table = ($type === 'purchase') ? 'purchases' : 'invoices';
$item_table = ($type === 'purchase') ? 'purchase_items' : 'invoice_items';
$cust_supplier_col = ($type === 'purchase') ? 'supplier_id' : 'customer_id';
$fk_col = ($type === 'purchase') ? 'purchase_id' : 'invoice_id';
$cust_id = (int)$_POST['customer_id'];
$date = $_POST['invoice_date'] ?: date('Y-m-d');
$due_date = $_POST['due_date'] ?: null;
$status = $_POST['status'] ?? 'pending';
$pay_type = $_POST['payment_type'] ?? 'cash';
$items = $_POST['item_ids'] ?? [];
$qtys = $_POST['quantities'] ?? [];
$prices = $_POST['prices'] ?? [];
$total_subtotal = 0;
$total_vat = 0;
foreach ($items as $i => $item_id) {
if (!$item_id) continue;
$qty = (float)$qtys[$i];
$price = (float)$prices[$i];
$subtotal = $qty * $price;
$stmtVat = $db->prepare("SELECT vat_rate FROM stock_items WHERE id = ?");
$stmtVat->execute([$item_id]);
$vatRate = (float)$stmtVat->fetchColumn();
$vatAmount = $subtotal * ($vatRate / 100);
$total_subtotal += $subtotal;
$total_vat += $vatAmount;
}
$total_with_vat = $total_subtotal + $total_vat;
$paid = (float)($_POST['paid_amount'] ?? 0);
if ($status === 'paid') $paid = $total_with_vat;
$db->prepare("UPDATE $table SET $cust_supplier_col = ?, invoice_date = ?, due_date = ?, status = ?, payment_type = ?, total_amount = ?, vat_amount = ?, total_with_vat = ?, paid_amount = ? WHERE id = ?")
->execute([$cust_id, $date, $due_date, $status, $pay_type, $total_subtotal, $total_vat, $total_with_vat, $paid, $id]);
if (db_column_exists($table, 'outlet_id')) {
$db->prepare("UPDATE $table SET outlet_id = COALESCE(outlet_id, ?) WHERE id = ?")->execute([current_outlet_id(), $id]);
}
// Revert stock for old items
$stmtOld = $db->prepare("SELECT item_id, quantity FROM $item_table WHERE $fk_col = ?");
$stmtOld->execute([$id]);
$oldItems = $stmtOld->fetchAll();
foreach ($oldItems as $old) {
$change = ($type === 'sale') ? (float)$old['quantity'] : -(float)$old['quantity'];
update_stock($old['item_id'], $change);
}
// Delete old items
$db->prepare("DELETE FROM $item_table WHERE $fk_col = ?")->execute([$id]);
// Insert new items and update stock
foreach ($items as $i => $item_id) {
if (!$item_id) continue;
$qty = (float)$qtys[$i];
$price = (float)$prices[$i];
$subtotal = $qty * $price;
$stmtVat = $db->prepare("SELECT vat_rate FROM stock_items WHERE id = ?");
$stmtVat->execute([$item_id]);
$vatRate = (float)$stmtVat->fetchColumn();
$vatAmount = $subtotal * ($vatRate / 100);
$db->prepare("INSERT INTO $item_table ($fk_col, item_id, quantity, unit_price, vat_amount, total_price) VALUES (?, ?, ?, ?, ?, ?)")->execute([$id, $item_id, $qty, $price, $vatAmount, $subtotal]);
$change = ($type === 'sale') ? -$qty : $qty;
update_stock($item_id, $change);
}
$db->commit();
$msg = ($type === 'purchase' ? "Purchase" : "Invoice") . " updated successfully!";
redirectWithMessage($msg, page_url($type === 'purchase' ? 'purchases' : 'sales'));
} catch (Exception $e) { $db->rollBack(); $message = "Error: " . $e->getMessage(); }
}