|
|
|
@@ -0,0 +1,114 @@
|
|
|
|
|
<?php
|
|
|
|
|
$p=$permissions;
|
|
|
|
|
$creating=$mode==='create';
|
|
|
|
|
$draft=$invoice&&$invoice->workflow_status==='draft';
|
|
|
|
|
$editable=$draft&&$p['update'];
|
|
|
|
|
$csrfName=$this->security->get_csrf_token_name();
|
|
|
|
|
$csrfHash=$this->security->get_csrf_hash();
|
|
|
|
|
$lineDate=$invoice?max($invoice->tanggal,date('Y-m-d')):date('Y-m-d');
|
|
|
|
|
function invLabel($value){$labels=array('draft'=>'Draft','submitted'=>'Menunggu Approval','approved'=>'Disetujui','posted'=>'Posted','one_time'=>'Sekali Transaksi','running'=>'Berjalan / Akumulasi','accrual'=>'Diakui saat Invoice Diposting','on_payment'=>'Diakui Proporsional Setelah Dibayar','not_delivered'=>'Belum Dikirim','partial'=>'Sebagian Dikirim','delivered'=>'Sudah Dikirim');return$labels[$value]??ucwords(str_replace('_',' ',$value));}
|
|
|
|
|
?>
|
|
|
|
|
<link rel="stylesheet" href="<?=base_url('assets/css/invoices-professional.css').'?v='.filemtime(FCPATH.'assets/css/invoices-professional.css')?>">
|
|
|
|
|
<link rel="stylesheet" href="<?=base_url('assets/css/invoice-editor-modal.css').'?v='.filemtime(FCPATH.'assets/css/invoice-editor-modal.css')?>">
|
|
|
|
|
|
|
|
|
|
<section class="invoice-workspace invoice-editor-page p-0">
|
|
|
|
|
<header class="invoice-hero">
|
|
|
|
|
<div><span><?=$creating?'INVOICE BARU':'KELOLA INVOICE'?></span><h5><?=$creating?'Buat Invoice':html_escape($invoice->no_invoice)?></h5><p><?=$creating?'Tentukan customer dan aturan penagihan. Item dapat ditambahkan setelah Draft tersimpan.':'Item dapat ditambahkan bertahap dan langsung tersimpan pada Draft invoice.'?></p></div>
|
|
|
|
|
<div class="hero-actions"><a class="btn btn-light" href="<?=base_url('invoices')?>"><i class="bi bi-arrow-left"></i> Daftar Invoice</a><?php if($invoice&&$p['export']):?><button class="btn btn-outline-danger open-invoice-pdf" data-url="<?=base_url('invoices/pdf/'.$invoice->id)?>"><i class="bi bi-file-pdf"></i> PDF</button><?php endif?></div>
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<?php if($invoice):?><div class="invoice-progress"><span class="done"><i class="bi bi-check-lg"></i> Header Draft</span><span class="<?=$invoice->delivery_status==='delivered'?'done':''?>"><i class="bi bi-truck"></i> <?=$invoice->inventory_line_count?'Pengiriman':'Tanpa Surat Jalan'?></span><span class="<?=in_array($invoice->workflow_status,array('submitted','approved','posted'),true)?'done':''?>"><i class="bi bi-send"></i> Diajukan</span><span class="<?=$invoice->workflow_status==='posted'?'done':''?>"><i class="bi bi-patch-check"></i> Approved & Posted</span></div><?php endif?>
|
|
|
|
|
|
|
|
|
|
<div class="invoice-editor-grid <?=$creating?'is-creating':''?>">
|
|
|
|
|
<main class="invoice-editor-main">
|
|
|
|
|
<div class="card editor-card item-list-card">
|
|
|
|
|
<div class="card-header"><div><b>Daftar Item Invoice</b><small><?=$creating?'Daftar item akan aktif setelah invoice disimpan.':'Data dibaca langsung dari database dan aman untuk invoice akumulasi.'?></small></div><?php if($invoice):?><span id="lineCountBadge" class="count-badge">0 item</span><?php endif?></div>
|
|
|
|
|
<div class="card-body <?=$creating?'empty-editor':''?>">
|
|
|
|
|
<?php if($creating):?><div class="invoice-empty"><i class="bi bi-receipt-cutoff"></i><h5>Invoice belum disimpan</h5><p>Lengkapi data invoice pada panel sebelah kiri.</p></div><?php else:?><div class="table-responsive"><table class="table align-middle w-100" id="invoiceLinesTable"><thead><tr><th>Tanggal</th><th>Barang / Jasa / Tabungan</th><th>Alokasi Akun</th><th>Barcode / Serial</th><th class="text-end">Qty</th><th class="text-end">Harga</th><th class="text-end">Diskon</th><th class="text-end">Pajak</th><th class="text-end">Subtotal</th><th>Aksi</th></tr></thead></table></div><?php endif?>
|
|
|
|
|
</div>
|
|
|
|
|
<?php if($invoice):?><div class="invoice-summary"><div><span>Subtotal Bersih</span><b id="summaryNet">Rp 0,00</b></div><div><span>Diskon</span><b id="summaryDiscount">Rp 0,00</b></div><div><span>Pajak</span><b id="summaryTax">Rp 0,00</b></div><div class="grand"><span>Total Invoice</span><strong id="summaryTotal">Rp 0,00</strong></div></div><?php endif?>
|
|
|
|
|
</div>
|
|
|
|
|
</main>
|
|
|
|
|
|
|
|
|
|
<aside class="invoice-editor-sidebar">
|
|
|
|
|
<div class="invoice-editor-sidebar-inner">
|
|
|
|
|
<?php if($creating):?>
|
|
|
|
|
<div class="card editor-card customer-rule-card">
|
|
|
|
|
<div class="card-header"><div><b>Customer & Aturan Invoice</b><small>Header tersimpan sebagai Draft tanpa jurnal dan mutasi stok.</small></div></div>
|
|
|
|
|
<div class="card-body"><form id="invoiceHeaderForm" data-ajax="true">
|
|
|
|
|
<input type="hidden" name="<?=$csrfName?>" value="<?=$csrfHash?>"><input type="hidden" name="idempotency_key" value="<?=bin2hex(random_bytes(20))?>"><input type="hidden" name="source_sales_order_id" value="<?=$source_order?:''?>">
|
|
|
|
|
<div class="mb-3"><label class="form-label">Customer <span class="text-danger">*</span></label><select class="form-select ajax-customer" name="customer_id" required></select><div id="selectedCustomerPreview" class="selected-customer-preview d-none"></div></div>
|
|
|
|
|
<input type="hidden" name="recognition_policy" value="on_payment">
|
|
|
|
|
<div class="alert alert-light border mb-3"><small><b>Pengakuan pendapatan:</b> dilakukan proporsional saat pembayaran invoice diterima.</small></div>
|
|
|
|
|
<div class="row g-3"><div class="col-md-6"><label class="form-label">Tanggal Invoice</label><input class="form-control" type="date" name="date" value="<?=date('Y-m-d')?>" required></div><div class="col-md-6"><label class="form-label">Jatuh Tempo</label><input class="form-control" type="date" name="due_date" value="<?=date('Y-m-d')?>" required></div></div>
|
|
|
|
|
<div class="mt-3"><label class="form-label">Catatan</label><textarea class="form-control" name="notes" rows="3" placeholder="Catatan atau aturan penagihan untuk customer"></textarea></div>
|
|
|
|
|
<button class="btn btn-primary w-100 mt-3" type="submit"><i class="bi bi-save"></i> Simpan Invoice & Lanjut</button>
|
|
|
|
|
</form></div>
|
|
|
|
|
</div>
|
|
|
|
|
<?php else:?>
|
|
|
|
|
<div class="card editor-card customer-rule-card">
|
|
|
|
|
<div class="card-header"><div><b>Detail Customer</b><small>Informasi customer dan aturan invoice</small></div><div class="d-flex gap-2 align-items-center"><?php if($editable&&!(int)$invoice->line_count):?><button class="btn btn-sm btn-outline-secondary" type="button" data-bs-toggle="modal" data-bs-target="#headerEditModal"><i class="bi bi-pencil"></i> Koreksi</button><?php endif?><span class="invoice-status status-<?=html_escape($invoice->workflow_status)?>"><?=invLabel($invoice->workflow_status)?></span></div></div>
|
|
|
|
|
<div class="card-body">
|
|
|
|
|
<h5><?=html_escape($invoice->customer_name)?></h5><p class="text-muted mb-3"><?=nl2br(html_escape($invoice->customer_address?:'-'))?><br><?=html_escape($invoice->customer_phone?:'-')?> · <?=html_escape($invoice->customer_email?:'-')?></p>
|
|
|
|
|
<dl class="invoice-rule-list"><div><dt>Tanggal / Jatuh Tempo</dt><dd><?=html_escape($invoice->tanggal.' / '.$invoice->jatuh_tempo)?></dd></div><div><dt>Pengakuan</dt><dd><?=invLabel($invoice->recognition_policy)?></dd></div><div><dt>Pengiriman</dt><dd><?=$invoice->inventory_line_count?invLabel($invoice->delivery_status):'Tidak Memerlukan Surat Jalan'?></dd></div><div><dt>Pembuat</dt><dd><?=html_escape($invoice->creator_name?:'-')?></dd></div><?php if($invoice->approved_by):?><div><dt>Disetujui oleh</dt><dd><?=html_escape($invoice->approver_name?:'-')?></dd></div><?php endif?></dl>
|
|
|
|
|
<small class="auto-rule-note"><i class="bi bi-magic"></i> Jenis dan periode invoice ditentukan otomatis dari tanggal item.</small>
|
|
|
|
|
<?php if($invoice->rejection_reason):?><div class="alert alert-danger mt-3 mb-0"><b>Alasan penolakan</b><br><?=nl2br(html_escape($invoice->rejection_reason))?></div><?php endif?><?php if($invoice->keterangan):?><div class="invoice-note"><small>Catatan</small><?=nl2br(html_escape($invoice->keterangan))?></div><?php endif?>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<?php if($editable):?><button class="btn btn-primary btn-lg w-100 add-invoice-item-button" type="button" data-bs-toggle="modal" data-bs-target="#invoiceItemModal"><i class="bi bi-plus-lg"></i> Tambah Item</button><?php if((int)$invoice->pending_delivery_count>0):?><button class="btn btn-outline-primary w-100 generate-delivery"><i class="bi bi-truck"></i> Buat Surat Jalan</button><?php endif?><?php endif?>
|
|
|
|
|
<?php endif?>
|
|
|
|
|
<?php if($invoice):?><div class="card editor-card invoice-sidebar-actions"><div class="card-body"><div class="sidebar-next-status"><small>Status selanjutnya</small><b><?=$draft?($invoice->pending_delivery_count?'Buat dan posting Surat Jalan, lalu ajukan invoice.':'Ajukan invoice untuk approval.'):invLabel($invoice->workflow_status)?></b></div><div class="sidebar-action-buttons"><?php if($draft&&$p['submit']):?><button class="btn btn-primary submit-invoice"><i class="bi bi-send"></i> Ajukan Invoice</button><?php endif?><?php if($draft&&$p['delete']):?><button class="btn btn-outline-danger delete-invoice"><i class="bi bi-trash"></i> Batalkan Draft</button><?php endif?><?php if($invoice->workflow_status==='submitted'&&$p['approve']):?><button class="btn btn-success approve-invoice"><i class="bi bi-check-lg"></i> Setujui & Posting</button><button class="btn btn-outline-danger reject-invoice"><i class="bi bi-x-lg"></i> Tolak</button><?php endif?><?php if($invoice->workflow_status==='posted'&&in_array($invoice->status,array('unpaid','partial'),true)&&$p['post']):?><a class="btn btn-warning" href="<?=base_url('receivables?invoice_id='.$invoice->id)?>"><i class="bi bi-cash-coin"></i> Terima Pembayaran</a><?php endif?></div></div></div><?php endif?>
|
|
|
|
|
</div>
|
|
|
|
|
</aside>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<?php if($invoice&&$editable):?>
|
|
|
|
|
<div class="modal fade invoice-item-modal" id="invoiceItemModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false"><div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable"><div class="modal-content"><form id="invoiceLineForm" data-ajax="true">
|
|
|
|
|
<div class="modal-header"><div><h5 class="modal-title">Tambah Beberapa Item Invoice</h5><small>Susun maksimal 100 barang, jasa, atau tabungan dalam satu kali penyimpanan.</small></div><button class="btn-close" type="button" data-bs-dismiss="modal"></button></div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<input type="hidden" name="<?=$csrfName?>" value="<?=$csrfHash?>"><input type="hidden" name="idempotency_key" id="lineIdempotency" value="<?=bin2hex(random_bytes(20))?>">
|
|
|
|
|
<section class="invoice-batch-common">
|
|
|
|
|
<div class="row g-3 align-items-end">
|
|
|
|
|
<div class="col-sm-6"><label class="form-label">Tanggal Transaksi <span class="text-danger">*</span></label><input class="form-control" type="date" name="service_date" value="<?=html_escape($lineDate)?>" required><small class="form-text">Satu tanggal untuk seluruh item dalam penambahan ini.</small></div>
|
|
|
|
|
<div class="col-sm-6"><label class="form-label">Diskon Penambahan</label><input class="form-control money-input" name="batch_discount" inputmode="decimal" value="0"><small class="form-text">Dialokasikan proporsional ke semua item.</small></div>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
<div class="invoice-batch-composer">
|
|
|
|
|
<input type="hidden" name="editing_line_id" value="">
|
|
|
|
|
<div class="line-type-switch mb-3"><label><input type="radio" name="line_type" value="inventory" checked><span><i class="bi bi-box-seam"></i> Barang Gudang</span></label><label><input type="radio" name="line_type" value="service"><span><i class="bi bi-tools"></i> Jasa / Nonbarang</span></label><label><input type="radio" name="line_type" value="savings"><span><i class="bi bi-piggy-bank"></i> Tabungan</span></label></div>
|
|
|
|
|
<div class="row g-4">
|
|
|
|
|
<div class="col-lg-6">
|
|
|
|
|
<div class="mb-3 sales-account-field"><label class="form-label">Akun Pendapatan Item <span class="text-danger">*</span></label><select class="form-select ajax-account" name="revenue_account_id"></select><small class="form-text">Dapat berbeda untuk barang dan jasa berikutnya.</small></div>
|
|
|
|
|
<div class="inventory-only"><div class="mb-3"><label class="form-label">Gudang <span class="text-danger">*</span></label><select class="form-select ajax-warehouse" name="warehouse_id"></select></div><div class="mb-3"><label class="form-label">Barang <span class="text-danger">*</span></label><select class="form-select ajax-item" name="item_id"></select><small id="trackingHint" class="form-text">Pilih gudang dan barang terlebih dahulu.</small></div></div>
|
|
|
|
|
<div class="noninventory-only d-none"><div class="mb-3"><label class="form-label" id="nonInventoryDescriptionLabel">Nama Jasa / Deskripsi <span class="text-danger">*</span></label><input class="form-control" name="description" placeholder="Tuliskan deskripsi transaksi"></div><div class="service-unit-field"><label class="form-label">Satuan</label><input class="form-control" name="unit" value="Jasa"></div></div>
|
|
|
|
|
<div class="savings-only d-none mt-3"><label class="form-label">Akun Simpanan Customer (Passiva) <span class="text-danger">*</span></label><select class="form-select ajax-liability-account" name="savings_account_id"></select></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-lg-6">
|
|
|
|
|
<div class="inventory-only barcode-panel mb-3"><label class="form-label">Barcode / Serial</label><div class="barcode-scan"><input class="form-control" id="barcodeScan" placeholder="Scan atau ketik barcode/serial exact" autocomplete="off"><button class="btn btn-outline-primary" type="button" id="scanBarcodeButton"><i class="bi bi-qr-code-scan"></i></button></div><select class="form-select ajax-barcode mt-2" id="barcodeSelect" multiple></select><div id="selectedBarcodes" class="selected-barcodes"></div></div>
|
|
|
|
|
<div class="row g-3"><div class="col-6 line-qty-field"><label class="form-label">Qty</label><input class="form-control" name="qty" inputmode="decimal" value="1" required></div><div class="col-6 line-value-field"><label class="form-label" id="lineValueLabel">Harga Satuan / Nominal</label><input class="form-control money-input" name="unit_price" inputmode="decimal" required></div><div class="col-6 sales-tax-field"><label class="form-label">Pajak (%)</label><input class="form-control" name="tax_rate" type="number" min="0" step="0.01" value="0"></div><div class="col-6 d-flex align-items-end stage-line-field"><button class="btn btn-outline-primary w-100" type="button" id="stageInvoiceLine"><i class="bi bi-plus-lg"></i> Masukkan ke Daftar</button></div></div>
|
|
|
|
|
<div class="mt-3"><label class="form-label">Keterangan</label><textarea class="form-control" name="notes" rows="2" placeholder="Rincian tambahan barang atau jasa"></textarea></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<section class="invoice-batch-list mt-4">
|
|
|
|
|
<div class="d-flex justify-content-between align-items-center mb-2"><div><b>Item yang Akan Ditambahkan</b><small>Belum tersimpan sebelum tombol simpan ditekan.</small></div><span class="count-badge" id="batchLineCount">0 item</span></div>
|
|
|
|
|
<div class="table-responsive"><table class="table table-sm align-middle mb-0"><thead><tr><th>Barang / Jasa / Tabungan</th><th>Alokasi Akun</th><th>Jenis</th><th class="text-end">Qty</th><th class="text-end">Harga</th><th class="text-end">Pajak</th><th class="text-end">Bruto</th><th class="text-center">Aksi</th></tr></thead><tbody id="invoiceBatchLines"><tr class="batch-empty-row"><td colspan="8">Belum ada item. Isi form di atas lalu klik “Masukkan ke Daftar”.</td></tr></tbody></table></div>
|
|
|
|
|
</section>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer invoice-item-footer"><div class="batch-live-summary"><span>Bruto <b id="batchGrossTotal">Rp 0,00</b></span><span>Diskon <b id="batchDiscountTotal">Rp 0,00</b></span><span>Total + Pajak <strong id="lineLiveTotal">Rp 0,00</strong></span></div><div><button class="btn btn-light" type="button" data-bs-dismiss="modal">Tutup</button><button class="btn btn-primary batch-submit-button" type="submit" disabled><i class="bi bi-save"></i> Simpan 0 Item</button></div></div>
|
|
|
|
|
</form></div></div></div>
|
|
|
|
|
<?php endif?>
|
|
|
|
|
|
|
|
|
|
<div class="modal fade" id="invoicePdfModal" tabindex="-1"><div class="modal-dialog modal-xl modal-dialog-centered"><div class="modal-content"><div class="modal-header"><h5>Pratinjau Invoice</h5><button class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body p-0"><iframe title="Pratinjau Invoice"></iframe></div></div></div></div>
|
|
|
|
|
|
|
|
|
|
<?php if($invoice&&$editable&&!(int)$invoice->line_count):?>
|
|
|
|
|
<div class="modal fade" id="headerEditModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false"><div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable"><div class="modal-content"><form id="invoiceHeaderEditForm" data-ajax="true">
|
|
|
|
|
<div class="modal-header"><h5>Koreksi Data Invoice</h5><button class="btn-close" type="button" data-bs-dismiss="modal"></button></div>
|
|
|
|
|
<div class="modal-body"><input type="hidden" name="<?=$csrfName?>" value="<?=$csrfHash?>"><input type="hidden" name="recognition_policy" value="on_payment"><div class="mb-3"><label class="form-label">Customer</label><select class="form-select ajax-customer-edit" name="customer_id"><option value="<?=$invoice->customer_id?>" selected><?=html_escape($invoice->customer_name)?></option></select></div><div class="row g-3"><div class="col-md-6"><label class="form-label">Tanggal Invoice</label><input class="form-control" type="date" name="date" value="<?=$invoice->tanggal?>" required></div><div class="col-md-6"><label class="form-label">Jatuh Tempo</label><input class="form-control" type="date" name="due_date" value="<?=$invoice->jatuh_tempo?>" required></div></div><div class="mt-3"><label class="form-label">Catatan</label><textarea class="form-control" name="notes" rows="3"><?=html_escape($invoice->keterangan)?></textarea></div></div>
|
|
|
|
|
<div class="modal-footer"><button class="btn btn-light" type="button" data-bs-dismiss="modal">Batal</button><button class="btn btn-primary" type="submit">Simpan Koreksi</button></div>
|
|
|
|
|
</form></div></div></div>
|
|
|
|
|
<?php endif?>
|
|
|
|
|
|
|
|
|
|
<script>window.INVOICE_PAGE=<?=json_encode(array('base'=>base_url(),'mode'=>$mode,'invoiceId'=>$invoice?(int)$invoice->id:0,'csrfName'=>$csrfName,'csrfHash'=>$csrfHash,'permissions'=>$p,'sourceOrder'=>(int)$source_order),JSON_UNESCAPED_SLASHES)?>;</script>
|
|
|
|
|
<script src="<?=base_url('assets/js/invoices-professional.js').'?v='.filemtime(FCPATH.'assets/js/invoices-professional.js')?>"></script>
|