<?php
declare(strict_types=1);
require __DIR__.'/app/bootstrap.php';require_permission('tax.manage');require __DIR__.'/app/layout.php';
$pdo=db();$companyId=company_id();$userId=(int)user()['id'];$currencyId=(int)scalar('SELECT base_currency_id FROM companies WHERE id=?',[$companyId]);
if($_SERVER['REQUEST_METHOD']==='POST'){verify_csrf();try{$action=(string)($_POST['action']??'');
 if($action==='sales_create'){$certId=(int)$_POST['certificate_id'];$s=$pdo->prepare("SELECT cc.*,pc.id contract_id,p.customer_id,p.id project_id FROM customer_certificates cc JOIN project_contracts pc ON pc.id=cc.contract_id JOIN projects p ON p.id=cc.project_id WHERE cc.id=? AND p.company_id=? AND cc.status='certified'");$s->execute([$certId,$companyId]);$c=$s->fetch();if(!$c)throw new RuntimeException('اختر مستخلص عميل معتمدًا وغير مفوتر.');$no=trim((string)$_POST['invoice_no']);if(!$no)throw new RuntimeException('رقم الفاتورة مطلوب.');$subtotal=(float)$c['taxable_amount'];$tax=(float)$c['tax_amount'];$gross=$subtotal+$tax;$net=(float)$c['net_due_amount'];$pdo->beginTransaction();$s=$pdo->prepare("INSERT INTO sales_invoices(company_id,branch_id,customer_id,project_id,contract_id,customer_certificate_id,invoice_no,invoice_type,invoice_date,supply_date,due_date,currency_id,subtotal,tax_amount,gross_amount,retention_amount,advance_applied_amount,net_due_amount,zatca_status,status,created_by,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'tax_invoice',?,?,?,?,?,?,?,?,?,?,'pending','draft',?,NOW(),NOW())");$s->execute([$companyId,(int)user()['branch_id'],$c['customer_id'],$c['project_id'],$c['contract_id'],$certId,$no,$_POST['invoice_date'],($_POST['supply_date']??'')?:null,($_POST['due_date']??'')?:null,$currencyId,$subtotal,$tax,$gross,$c['retention_amount'],$c['advance_recovery_amount'],$net,$userId]);$invoiceId=(int)$pdo->lastInsertId();$pdo->prepare("INSERT INTO sales_invoice_items(sales_invoice_id,description,quantity,unit_code,unit_price,tax_amount,line_total) VALUES (?,'أعمال مقاولات حسب المستخلص',1,'مستخلص',?,?,?)")->execute([$invoiceId,$subtotal,$tax,$gross]);$pdo->prepare("UPDATE customer_certificates SET status='invoiced' WHERE id=?")->execute([$certId]);$pdo->commit();audit('sales_invoice.create','sales_invoice',(string)$invoiceId,['invoice_no'=>$no]);flash('success','تم إنشاء فاتورة العميل.');
 }elseif($action==='supplier_create'){$poId=(int)$_POST['purchase_order_id'];$s=$pdo->prepare("SELECT * FROM purchase_orders WHERE id=? AND company_id=? AND status IN ('received','partially_received')");$s->execute([$poId,$companyId]);$po=$s->fetch();if(!$po)throw new RuntimeException('اختر أمر شراء مستلمًا.');$supplierNo=trim((string)$_POST['supplier_invoice_no']);if(!$supplierNo)throw new RuntimeException('رقم فاتورة المورد مطلوب.');$internal='SI-'.date('Ym').'-'.str_pad((string)((int)scalar('SELECT COUNT(*)+1 FROM supplier_invoices WHERE company_id=?',[$companyId])),5,'0',STR_PAD_LEFT);$pdo->beginTransaction();$s=$pdo->prepare("INSERT INTO supplier_invoices(company_id,branch_id,project_id,supplier_id,purchase_order_id,invoice_no,internal_no,invoice_date,due_date,currency_id,subtotal,tax_amount,total_amount,status,matching_status,created_by,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,'draft','matched',?,NOW(),NOW())");$s->execute([$companyId,$po['branch_id'],$po['project_id'],$po['supplier_id'],$poId,$supplierNo,$internal,$_POST['invoice_date'],($_POST['due_date']??'')?:null,$currencyId,$po['subtotal'],$po['tax_amount'],$po['total_amount'],$userId]);$invoiceId=(int)$pdo->lastInsertId();$lines=$pdo->prepare('SELECT * FROM purchase_order_items WHERE purchase_order_id=?');$lines->execute([$poId]);$insert=$pdo->prepare('INSERT INTO supplier_invoice_items(supplier_invoice_id,purchase_order_item_id,item_id,description,quantity,unit_code,unit_price,discount_amount,tax_amount,line_total) VALUES (?,?,?,?,?,?,?,?,?,?)');foreach($lines->fetchAll() as $l)$insert->execute([$invoiceId,$l['id'],$l['item_id'],$l['description'],$l['ordered_qty'],$l['unit_code'],$l['unit_price'],$l['discount_amount'],$l['tax_amount'],$l['total_amount']]);$pdo->commit();audit('supplier_invoice.create','supplier_invoice',(string)$invoiceId,['internal_no'=>$internal]);flash('success','تم تسجيل فاتورة المورد: '.$internal);
 }elseif(in_array($action,['sales_approve','sales_issue','supplier_approve','supplier_post'],true)){$id=(int)$_POST['id'];if($action==='sales_approve'){$s=$pdo->prepare("UPDATE sales_invoices SET status='approved',approved_by=?,approved_at=NOW() WHERE id=? AND company_id=? AND status='draft'");$s->execute([$userId,$id,$companyId]);}elseif($action==='sales_issue'){$q=$pdo->prepare("SELECT * FROM sales_invoices WHERE id=? AND company_id=? AND status='approved'");$q->execute([$id,$companyId]);$inv=$q->fetch();if(!$inv)throw new RuntimeException('الفاتورة غير متاحة للإصدار.');$lines=[['account_id'=>mapped_account('AR_CONTROL'),'debit'=>$inv['net_due_amount'],'project_id'=>$inv['project_id']],['account_id'=>mapped_account('RETENTION_RECEIVABLE'),'debit'=>$inv['retention_amount'],'project_id'=>$inv['project_id']],['account_id'=>mapped_account('CUSTOMER_ADVANCES'),'debit'=>$inv['advance_applied_amount'],'project_id'=>$inv['project_id']],['account_id'=>mapped_account('CONSTRUCTION_REVENUE'),'credit'=>$inv['subtotal']+$inv['retention_amount']+$inv['advance_applied_amount'],'project_id'=>$inv['project_id']],['account_id'=>mapped_account('VAT_OUTPUT'),'credit'=>$inv['tax_amount'],'project_id'=>$inv['project_id']]];$lines=array_values(array_filter($lines,fn($l)=>(float)($l['debit']??$l['credit']??0)>0));$pdo->beginTransaction();$journalId=post_system_journal($inv['invoice_date'],'فاتورة عميل '.$inv['invoice_no'],'sales_invoice',$id,$lines);$s=$pdo->prepare("UPDATE sales_invoices SET status='issued',issued_at=NOW(),journal_entry_id=? WHERE id=?");$s->execute([$journalId,$id]);$pdo->commit();}elseif($action==='supplier_approve'){$s=$pdo->prepare("UPDATE supplier_invoices SET status='approved',approved_by=?,approved_at=NOW() WHERE id=? AND company_id=? AND status='draft'");$s->execute([$userId,$id,$companyId]);}else{$q=$pdo->prepare("SELECT * FROM supplier_invoices WHERE id=? AND company_id=? AND status='approved'");$q->execute([$id,$companyId]);$inv=$q->fetch();if(!$inv)throw new RuntimeException('الفاتورة غير متاحة للترحيل.');$lines=[['account_id'=>mapped_account('PROJECT_MATERIAL_COST'),'debit'=>$inv['subtotal'],'project_id'=>$inv['project_id']],['account_id'=>mapped_account('VAT_INPUT'),'debit'=>$inv['tax_amount'],'project_id'=>$inv['project_id']],['account_id'=>mapped_account('AP_CONTROL'),'credit'=>$inv['total_amount'],'project_id'=>$inv['project_id']]];$pdo->beginTransaction();$journalId=post_system_journal($inv['invoice_date'],'فاتورة مورد '.$inv['internal_no'],'supplier_invoice',$id,$lines);$s=$pdo->prepare("UPDATE supplier_invoices SET status='posted',journal_entry_id=? WHERE id=?");$s->execute([$journalId,$id]);$pdo->prepare("UPDATE purchase_orders SET status='invoiced' WHERE id=?")->execute([$inv['purchase_order_id']]);$pdo->commit();}if(!$s->rowCount())throw new RuntimeException('تعذر تغيير حالة الفاتورة.');audit($action,str_starts_with($action,'sales')?'sales_invoice':'supplier_invoice',(string)$id);flash('success','تم تحديث الحالة وإنشاء القيد المحاسبي الآلي.');
 }
 }catch(Throwable $e){if($pdo->inTransaction())$pdo->rollBack();flash('error',$e instanceof PDOException?'رقم الفاتورة مكرر أو البيانات مرتبطة بسجل آخر.':$e->getMessage());}redirect('invoices.php');}
$certs=$pdo->prepare("SELECT cc.id,cc.certificate_no,cc.net_due_amount,p.name_ar project_name,bp.legal_name_ar customer_name FROM customer_certificates cc JOIN projects p ON p.id=cc.project_id JOIN customers c ON c.id=p.customer_id JOIN business_partners bp ON bp.id=c.partner_id WHERE p.company_id=? AND cc.status='certified' ORDER BY cc.id DESC");$certs->execute([$companyId]);$certs=$certs->fetchAll();$pos=$pdo->prepare("SELECT po.id,po.po_no,po.total_amount,bp.legal_name_ar supplier_name FROM purchase_orders po JOIN suppliers s ON s.id=po.supplier_id JOIN business_partners bp ON bp.id=s.partner_id WHERE po.company_id=? AND po.status IN ('received','partially_received') ORDER BY po.id DESC");$pos->execute([$companyId]);$pos=$pos->fetchAll();
$sales=$pdo->prepare("SELECT si.*,bp.legal_name_ar customer_name,p.name_ar project_name FROM sales_invoices si JOIN customers c ON c.id=si.customer_id JOIN business_partners bp ON bp.id=c.partner_id LEFT JOIN projects p ON p.id=si.project_id WHERE si.company_id=? ORDER BY si.id DESC LIMIT 100");$sales->execute([$companyId]);$sales=$sales->fetchAll();$supplierInvoices=$pdo->prepare("SELECT si.*,bp.legal_name_ar supplier_name,p.name_ar project_name FROM supplier_invoices si JOIN suppliers s ON s.id=si.supplier_id JOIN business_partners bp ON bp.id=s.partner_id LEFT JOIN projects p ON p.id=si.project_id WHERE si.company_id=? ORDER BY si.id DESC LIMIT 100");$supplierInvoices->execute([$companyId]);$supplierInvoices=$supplierInvoices->fetchAll();
render_header('invoices','الفواتير والضريبة','فواتير العملاء والموردين المرتبطة بالمستخلصات وأوامر الشراء.');?>
<div class="settings-grid"><details class="panel quick-add" open><summary>＋ فاتورة عميل</summary><form method="post"><?= csrf_field() ?><input type="hidden" name="action" value="sales_create"><label>المستخلص المعتمد<select name="certificate_id"><?php foreach($certs as $c):?><option value="<?= (int)$c['id'] ?>"><?= e($c['certificate_no'].' — '.$c['customer_name'].' — '.number_format((float)$c['net_due_amount'],2)) ?></option><?php endforeach;?></select></label><label>رقم الفاتورة<input name="invoice_no" required></label><label>تاريخ الفاتورة<input type="date" name="invoice_date" value="<?= date('Y-m-d') ?>"></label><label>تاريخ التوريد<input type="date" name="supply_date" value="<?= date('Y-m-d') ?>"></label><label>تاريخ الاستحقاق<input type="date" name="due_date"></label><button class="primary-btn">إنشاء الفاتورة</button></form></details><section class="panel quick-add"><h2>فواتير الموردين</h2><p>تُسجل فواتير الموردين بعد مطابقة أمر الشراء مع المواد المستلمة والأسعار.</p><a class="primary-btn" href="<?= e(app_url('payables.php')) ?>">فتح المطابقة الثلاثية</a></section></div>
<?php foreach([['فواتير العملاء',$sales,'sales','invoice_no','customer_name','net_due_amount'],['فواتير الموردين',$supplierInvoices,'supplier','internal_no','supplier_name','total_amount']] as [$title,$rows,$kind,$noField,$partnerField,$amountField]):?><section class="panel data-card"><header><h2><?= e($title) ?></h2></header><div class="responsive-table"><table><thead><tr><th>الرقم</th><th>الطرف</th><th>المشروع</th><th>التاريخ</th><th>قبل الضريبة</th><th>الضريبة</th><th>الصافي</th><th>الحالة</th><th>الإجراء</th></tr></thead><tbody><?php foreach($rows as $r):?><tr><td><?= e($r[$noField]) ?></td><td><?= e($r[$partnerField]) ?></td><td><?= e($r['project_name']?:'عام') ?></td><td><?= e($r['invoice_date']) ?></td><td><?= number_format((float)$r['subtotal'],2) ?></td><td><?= number_format((float)$r['tax_amount'],2) ?></td><td><?= number_format((float)$r[$amountField],2) ?></td><td><span class="chip"><?= e($r['status']) ?></span></td><td><?php if($r['status']==='draft'):?><form method="post"><?= csrf_field() ?><input type="hidden" name="action" value="<?= $kind ?>_approve"><input type="hidden" name="id" value="<?= (int)$r['id'] ?>"><button>اعتماد</button></form><?php elseif($r['status']==='approved'):?><form method="post"><?= csrf_field() ?><input type="hidden" name="action" value="<?= $kind==='sales'?'sales_issue':'supplier_post' ?>"><input type="hidden" name="id" value="<?= (int)$r['id'] ?>"><button><?= $kind==='sales'?'إصدار':'ترحيل' ?></button></form><?php endif;?></td></tr><?php endforeach;?></tbody></table></div></section><?php endforeach;render_footer();
