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))); }