61 lines
9.4 KiB
PHP
61 lines
9.4 KiB
PHP
<?php
|
|
$company=$pdf_company;
|
|
$previous_invoices=isset($previous_invoices)?$previous_invoices:array();
|
|
$pdf_bank_accounts=isset($pdf_bank_accounts)?$pdf_bank_accounts:array();
|
|
$currencyCode=isset($pdf_currency->code)?$pdf_currency->code:($company->base_currency??'IDR');
|
|
$currencySymbol=isset($pdf_currency->symbol)&&trim((string)$pdf_currency->symbol)!==''?$pdf_currency->symbol:$currencyCode;
|
|
$groups=array();
|
|
$barcodesByLine=array();
|
|
foreach($barcodes as$b)$barcodesByLine[(int)$b->invoice_detail_id][]=$b;
|
|
foreach($lines as$l){
|
|
$code=trim((string)($l->item_code??''));
|
|
$name=trim((string)$l->nama_item);
|
|
$key=$l->service_date.'|'.$l->line_type.'|'.$code.'|'.$name.'|'.$l->unit;
|
|
$label=trim(($code!==''?$code.' - ':'').$name);
|
|
if(!isset($groups[$key]))$groups[$key]=array('date'=>$l->service_date,'item'=>$label,'qty'=>0,'unit'=>$l->unit,'gross'=>0,'discount'=>0,'tax'=>0,'total'=>0);
|
|
$groups[$key]['qty']+=(float)$l->qty;
|
|
$groups[$key]['gross']+=(float)$l->harga*(float)$l->qty;
|
|
$groups[$key]['discount']+=(float)$l->discount_amount;
|
|
$groups[$key]['tax']+=(float)$l->tax_amount;
|
|
$groups[$key]['total']+=(float)$l->subtotal;
|
|
}
|
|
function ipMoney($v){return number_format((float)$v,2,',','.');}
|
|
function ipQty($v){return floor((float)$v)==(float)$v?number_format((float)$v,0,',','.'):rtrim(rtrim(number_format((float)$v,4,',','.'),'0'),',');}
|
|
$statusKey=$invoice->workflow_status==='posted'?$invoice->status:$invoice->workflow_status;
|
|
$statusLabels=array('draft'=>'DRAFT','submitted'=>'MENUNGGU PERSETUJUAN','approved'=>'DISETUJUI','posted'=>'POSTED','unpaid'=>'BELUM LUNAS','partial'=>'DIBAYAR SEBAGIAN','paid'=>'LUNAS','cancelled'=>'DIBATALKAN','reversed'=>'DIBALIK');
|
|
$statusLabel=$statusLabels[$statusKey]??strtoupper(str_replace('_',' ',$statusKey));
|
|
$previousTotal=0;foreach($previous_invoices as$old)$previousTotal+=(float)$old->sisa_piutang;$customerOutstanding=$previousTotal+(float)$invoice->sisa_piutang;
|
|
?>
|
|
<!doctype html>
|
|
<html><head><meta charset="utf-8"><style>
|
|
@page{margin:27px 32px}body{font-family:DejaVu Sans,sans-serif;font-size:9.5px;color:#20242c;line-height:1.42}h1{font-size:21px;margin:0}h2{font-size:15px;margin:0 0 4px}.muted{color:#667085}.head{width:100%;margin-bottom:16px}.head td{vertical-align:top}.brand{width:64%}.logo{float:left;width:62px;height:62px;object-fit:contain;margin-right:11px}.company-name{font-size:15px;font-weight:bold;margin:0 0 3px}.right{text-align:right}.invoice-number{font-size:11px;margin:2px 0 6px}.status{display:inline-block;padding:4px 9px;border-radius:11px;font-size:8px;font-weight:bold;color:#fff;background:#475467}.status-paid{background:#15803d}.status-partial{background:#d97706}.status-unpaid,.status-submitted{background:#dc2626}.status-draft{background:#64748b}.status-approved,.status-posted{background:#2563eb}.status-cancelled,.status-reversed{background:#475467}.info{width:100%;margin:8px 0 14px;border-collapse:collapse}.info td{width:50%;vertical-align:top;padding:10px;border:1px solid #d8dee8}.info-label{font-size:8px;color:#667085;text-transform:uppercase;letter-spacing:.06em;margin-bottom:3px}table.grid{width:100%;border-collapse:collapse}table.grid th{background:#eef2f6;text-align:left;font-size:7.5px;letter-spacing:.04em}table.grid th,table.grid td{border:1px solid #d8dee8;padding:6px}.num{text-align:right}.summary{margin:12px 0 0 auto;width:46%;border-collapse:collapse}.summary td{padding:3px 5px}.summary .grand td{padding-top:6px;border-top:1px solid #98a2b3;font-size:11px}.section-title{font-size:11px;font-weight:bold;margin-bottom:6px}.outstanding{margin-top:16px;padding-top:10px;border-top:1px solid #d8dee8}.outstanding-total{text-align:right;font-weight:bold;margin-top:6px}.bank-box{margin-top:14px;padding:9px 11px;border:1px solid #d8dee8;background:#f8fafc}.bank-row{margin-top:3px}.page{page-break-before:always}.sign{margin-top:35px;width:100%;text-align:center}.sign td{width:33%;height:78px;vertical-align:top}.repeat{display:table-header-group}.detail-note{max-width:175px}.empty{text-align:center;color:#667085;padding:15px!important}
|
|
</style></head><body>
|
|
<table class="head"><tr><td class="brand">
|
|
<?php if(!empty($pdf_logo_data)):?><img class="logo" src="<?=$pdf_logo_data?>"><?php endif?>
|
|
<div class="company-name"><?=html_escape($company->name??'Perusahaan')?></div>
|
|
<div><?=nl2br(html_escape($company->address??'-'))?></div>
|
|
<div>Telp: <?=html_escape($company->phone??'-')?></div>
|
|
</td><td class="right"><h1>INVOICE</h1><div class="invoice-number"><b><?=html_escape($invoice->no_invoice)?></b><br><?=html_escape($invoice->tanggal)?></div><span class="status status-<?=html_escape($statusKey)?>"><?=html_escape($statusLabel)?></span></td></tr></table>
|
|
|
|
<table class="info"><tr><td><div class="info-label">Ditagihkan kepada</div><b><?=html_escape($invoice->customer_name)?></b><br><?=nl2br(html_escape($invoice->customer_address?:'-'))?></td><td><div class="info-label">Informasi Invoice</div><b>Tanggal Invoice:</b> <?=html_escape($invoice->tanggal)?><br><b>Tanggal Jatuh Tempo:</b> <?=html_escape($invoice->jatuh_tempo)?><br><b>Mata Uang:</b> <?=html_escape($currencyCode)?></td></tr></table>
|
|
|
|
<table class="grid"><thead><tr><th>TANGGAL</th><th>BARANG / JASA / TABUNGAN</th><th>QTY</th><th class="num">HARGA</th><th class="num">DISKON</th><th class="num">PAJAK</th><th class="num">SUBTOTAL</th></tr></thead><tbody>
|
|
<?php foreach($groups as$g):$average=$g['qty']!=0?$g['gross']/$g['qty']:0;?><tr><td><?=html_escape($g['date'])?></td><td><b><?=html_escape($g['item'])?></b></td><td><?=ipQty($g['qty']).' '.html_escape($g['unit'])?></td><td class="num"><?=ipMoney($average)?></td><td class="num"><?=ipMoney($g['discount'])?></td><td class="num"><?=ipMoney($g['tax'])?></td><td class="num"><b><?=ipMoney($g['total'])?></b></td></tr><?php endforeach?>
|
|
<?php if(!$groups):?><tr><td colspan="7" class="empty">Belum ada item pada invoice ini.</td></tr><?php endif?>
|
|
</tbody></table>
|
|
|
|
<table class="summary"><tr><td>Subtotal bersih</td><td class="num"><?=ipMoney($invoice->subtotal_before_tax)?></td></tr><tr><td>Diskon</td><td class="num"><?=ipMoney($invoice->discount_total)?></td></tr><tr><td>Pajak</td><td class="num"><?=ipMoney($invoice->tax_total)?></td></tr><tr class="grand"><td><b>Total Invoice</b></td><td class="num"><b><?=html_escape($currencySymbol)?> <?=ipMoney($invoice->total)?></b></td></tr><tr><td>Sudah dibayar</td><td class="num"><?=ipMoney($invoice->total_bayar)?></td></tr><tr><td><b>Sisa tagihan</b></td><td class="num"><b><?=ipMoney($invoice->sisa_piutang)?></b></td></tr></table>
|
|
|
|
<?php if($previous_invoices):?><div class="outstanding"><div class="section-title">Daftar Tagihan Sebelumnya yang Belum Lunas</div><table class="grid"><thead><tr><th>INVOICE</th><th>TANGGAL</th><th>JATUH TEMPO</th><th class="num">TOTAL</th><th class="num">TERBAYAR</th><th class="num">SISA TAGIHAN</th></tr></thead><tbody><?php foreach($previous_invoices as$old):?><tr><td><b><?=html_escape($old->no_invoice)?></b></td><td><?=html_escape($old->tanggal)?></td><td><?=html_escape($old->jatuh_tempo)?></td><td class="num"><?=ipMoney($old->total)?></td><td class="num"><?=ipMoney($old->total_bayar)?></td><td class="num"><b><?=ipMoney($old->sisa_piutang)?></b></td></tr><?php endforeach?></tbody></table><div class="outstanding-total">Total sisa tagihan <?=html_escape($invoice->customer_name)?>, termasuk invoice ini: <?=html_escape($currencySymbol)?> <?=ipMoney($customerOutstanding)?></div></div><?php endif?>
|
|
|
|
<?php if($pdf_bank_accounts):?><div class="bank-box"><b>Rekening Pembayaran Perusahaan</b><?php foreach($pdf_bank_accounts as$bank):?><div class="bank-row"><?=html_escape($bank->bank_name)?> · <?=html_escape($bank->account_number)?> · a.n. <?=html_escape($bank->account_holder)?> (<?=html_escape($bank->currency)?>)<?=$bank->is_primary?' · Utama':''?></div><?php endforeach?></div><?php endif?>
|
|
|
|
<p><b>Surat Jalan:</b> <?=html_escape(implode(', ',array_map(function($d){return$d->delivery_no;},$deliveries))?:'-')?><br><b>Catatan:</b> <?=html_escape($invoice->keterangan?:'-')?></p>
|
|
<table class="sign"><tr><td>Dibuat oleh<br><br><br><b><?=html_escape($invoice->creator_name?:'-')?></b></td><td>Disetujui<br><br><br><b><?=html_escape($invoice->approver_name?:'-')?></b></td><td>Diterima Customer</td></tr></table>
|
|
|
|
<div class="page"><h2>Lampiran Detail</h2><p class="muted">Rincian seluruh item Invoice <?=html_escape($invoice->no_invoice)?>.</p><table class="grid"><thead class="repeat"><tr><th>TANGGAL</th><th>SURAT JALAN</th><th>BARANG / JASA / TABUNGAN</th><th>BARCODE / SERIAL</th><th>QTY</th><th>KETERANGAN</th></tr></thead><tbody>
|
|
<?php foreach($lines as$l):$lineBars=$barcodesByLine[(int)$l->id]??array();$label=trim((!empty($l->item_code)?$l->item_code.' - ':'').$l->nama_item);$note=trim((string)($l->keterangan?:$l->specification));if($lineBars):foreach($lineBars as$b):?><tr><td><?=html_escape($l->service_date)?></td><td><?=html_escape($b->delivery_no?:'-')?></td><td><b><?=html_escape($label)?></b></td><td><b><?=html_escape($b->barcode)?></b><br><?=html_escape($b->serial_number?:'-')?></td><td><?=ipQty($b->qty).' '.html_escape($l->unit)?></td><td class="detail-note"><?=nl2br(html_escape($note?:'-'))?></td></tr><?php endforeach;else:?><tr><td><?=html_escape($l->service_date)?></td><td>-</td><td><b><?=html_escape($label)?></b></td><td>-</td><td><?=ipQty($l->qty).' '.html_escape($l->unit)?></td><td class="detail-note"><?=nl2br(html_escape($note?:'-'))?></td></tr><?php endif;endforeach?>
|
|
<?php if(!$lines):?><tr><td colspan="6" class="empty">Belum ada detail item pada invoice ini.</td></tr><?php endif?>
|
|
</tbody></table></div>
|
|
</body></html>
|