61 lines
34 KiB
PHP
61 lines
34 KiB
PHP
<?php
|
|
function purchase_action_form($route,$id,$label,$ci,$step){return'<form class="d-inline" method="post" action="'.base_url('purchases/'.$route.'/'.$id).'"><input type="hidden" name="'.$ci->security->get_csrf_token_name().'" value="'.$ci->security->get_csrf_hash().'"><input type="hidden" name="return_step" value="'.$step.'"><button class="btn btn-sm btn-outline-primary">'.html_escape($label).'</button></form>';}
|
|
$step=$this->input->get('step')?:'request';$allowedSteps=array('request','order','payment','receipt','invoice');if(!in_array($step,$allowedSteps,true))$step='request';$departments=$this->db->where('is_active',1)->order_by('department_name')->get('k_departments')->result();$paymentAccounts=$this->db->where(array('is_active'=>1,'allow_posting'=>1))->group_start()->like('nama_akun','kas')->or_like('nama_akun','bank')->group_end()->order_by('kode_akun')->get('accounts')->result();$returnBarcodes=array();$isMasterAdmin=$this->session->userdata('role')==='Admin';$canPrView=$isMasterAdmin||check_permission('purchases','can_view');$canPrCreate=$isMasterAdmin||check_permission('purchases','can_create');$canPrApprove=$isMasterAdmin||check_permission('purchases','can_approve');$canPrExport=$isMasterAdmin||check_permission('purchases','can_export');
|
|
?>
|
|
<div class="container-fluid py-3 purchase-workflow">
|
|
<div class="d-flex flex-wrap justify-content-between align-items-start gap-2 mb-3"><div><h4 class="mb-1">Purchase Workflow</h4><p class="text-muted mb-0">Kelola proses normal permintaan, pemesanan, pembayaran awal, penerimaan, dan Invoice Supplier.</p></div><a class="btn btn-outline-primary" href="<?=base_url('purchases/returns')?>"><i class="bi bi-arrow-return-left me-1"></i>Retur & Refund</a></div>
|
|
<?php foreach(array('success'=>'success','error'=>'error')as$key=>$icon)if($this->session->flashdata($key)):?><div class="d-none" data-app-toast data-icon="<?=$icon?>" data-message="<?=html_escape($this->session->flashdata($key))?>"></div><?php endif?>
|
|
<?php $workflowSteps=array('request'=>array('bi-file-earmark-plus','Permintaan','Kebutuhan barang'),'order'=>array('bi-cart-check','Purchase Order','Pesanan disetujui'),'payment'=>array('bi-wallet2','Pembayaran Awal/DP','Jika disyaratkan'),'receipt'=>array('bi-box-arrow-in-down','Penerimaan','Pemeriksaan gudang'),'invoice'=>array('bi-receipt','Invoice Supplier','Final matching'));?>
|
|
<nav class="purchase-workflow-stepper mb-4" aria-label="Tahapan Purchase Workflow"><?php $stepNo=0;foreach($workflowSteps as$key=>$meta):$stepNo++;?><a class="purchase-workflow-step <?=$step===$key?'active':''?>" href="<?=base_url('purchases?step='.$key)?>"><span class="workflow-number"><?=$stepNo?></span><i class="bi <?=$meta[0]?>"></i><span><b><?=$meta[1]?></b><small><?=$meta[2]?></small></span></a><?php endforeach?></nav>
|
|
|
|
<?php if($step==='request'):?>
|
|
<?php if($canPrCreate):?>
|
|
<div class="card mb-3"><div class="card-header"><b>Buat Purchase Request</b></div><div class="card-body"><form class="row g-2" method="post" action="<?=base_url('purchases/create_request')?>"><input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>"><input type="hidden" name="return_step" value="request">
|
|
<input type="hidden" name="destination_type" value="warehouse">
|
|
<div class="col-md-2"><label class="form-label">Tanggal</label><input class="form-control" type="date" name="date" value="<?=date('Y-m-d')?>" required></div><div class="col-md-2"><label class="form-label">Dibutuhkan</label><input class="form-control" type="date" name="needed_date"></div><div class="col-md-3"><label class="form-label">Departemen</label><select class="form-select select-search" name="department_id" required><option value="">Pilih departemen</option><?php foreach($departments as$d):?><option value="<?=$d->id?>"><?=html_escape($d->code.' - '.$d->department_name)?></option><?php endforeach?></select></div><div class="col-md-5"><label class="form-label">Tujuan/Kebutuhan</label><input class="form-control" name="purpose" required></div>
|
|
<div class="col-12"><div class="form-check"><input class="form-check-input" type="checkbox" name="applicant_is_creator" value="1" id="prApplicantSelf"><label class="form-check-label" for="prApplicantSelf">Saya yang membuat dan saya yang mengajukan PR ini</label></div></div>
|
|
<div class="col-md-6" id="prApplicantNameGroup"><label class="form-label">Nama yang Mengajukan</label><input class="form-control" name="applicant_name" id="prApplicantName" maxlength="150" placeholder="Tulis nama pihak yang mengajukan" required><small class="text-muted">Diisi manual dan akan ditampilkan pada detail serta tanda tangan PDF.</small></div>
|
|
<?php if(false): // Form satu barang lama dipertahankan sementara untuk kompatibilitas riwayat. ?>
|
|
<div class="col-md-4"><label class="form-label">Master Barang</label><select class="form-select select-search" name="kode_barang_id" id="requestCatalog" required><option value="">Pilih kode - nama</option><?php foreach($catalogs as$i):?><option value="<?=$i->id?>" data-tracking="<?=strtoupper($i->tracking_type?:'UNIT')?>" data-serial="<?=strtolower($i->need_serial_number)==='true'?'1':'0'?>"><?=html_escape($i->kode_barang.' - '.$i->nama)?> · <?=strtoupper($i->tracking_type?:'UNIT')?><?=$i->need_serial_number==='true'?' · Serial':''?></option><?php endforeach?></select><small class="text-muted">UNIT: satu barang satu barcode. QTY: satu barcode dapat memuat beberapa barang.</small></div><div class="col-md-4"><label class="form-label">Deskripsi / Merek / Spesifikasi</label><input class="form-control" name="description" placeholder="Contoh: Epson L3210 warna hitam" required></div><div class="col-md-2"><label class="form-label">Qty Barang</label><input class="form-control" type="number" name="qty" min=".01" step=".01" required></div><div class="col-md-2"><label class="form-label">Estimasi Harga</label><input class="form-control format-rupiah" name="estimated_price" required></div><div class="col-md-3 d-none" id="qtyPerBarcodeGroup"><label class="form-label">Isi per Barcode</label><input class="form-control" type="number" name="qty_per_barcode" min=".01" step=".01"><small class="text-muted">Wajib untuk tracking QTY.</small></div><div class="col-12 text-end"><button class="btn btn-primary">Simpan Draft PR</button></div>
|
|
<?php endif?>
|
|
<div class="col-12"><div class="d-flex justify-content-between align-items-center mb-2"><div><b>Daftar Barang</b><small class="d-block text-muted">Satu PR dapat berisi beberapa barang.</small></div><button class="btn btn-sm btn-outline-primary" type="button" id="addPrLine"><i class="bi bi-plus-lg"></i> Tambah Barang</button></div><div id="prLines"></div></div>
|
|
<template id="prLineTemplate"><div class="pr-line border rounded p-3 mb-2"><div class="d-flex justify-content-between align-items-center mb-2"><b class="pr-line-title">Barang</b><button type="button" class="btn btn-sm btn-outline-danger remove-pr-line" aria-label="Hapus barang"><i class="bi bi-trash"></i></button></div><div class="row g-2"><div class="col-lg-4"><label class="form-label">Master Barang</label><select class="form-select pr-catalog" name="kode_barang_id[]" required><option value="">Pilih kode - nama</option><?php foreach($catalogs as$i):?><option value="<?=$i->id?>" data-tracking="<?=strtoupper($i->tracking_type?:'UNIT')?>" data-serial="<?=strtolower($i->need_serial_number)==='true'?'1':'0'?>"><?=html_escape($i->kode_barang.' - '.$i->nama)?> · <?=strtoupper($i->tracking_type?:'UNIT')?><?=$i->need_serial_number==='true'?' · Serial':''?></option><?php endforeach?></select><small class="text-muted">UNIT: satu barang satu barcode. QTY: satu barcode dapat berisi beberapa barang.</small></div><div class="col-lg-4"><label class="form-label">Deskripsi / Merek / Spesifikasi</label><input class="form-control" name="description[]" placeholder="Contoh: Epson L3210 warna hitam" maxlength="255" required></div><div class="col-lg-2 col-6"><label class="form-label">Qty Barang</label><input class="form-control pr-qty" type="number" name="qty[]" min=".01" step=".01" required></div><div class="col-lg-2 col-6"><label class="form-label">Estimasi Harga/Satuan</label><input class="form-control format-rupiah" name="estimated_price[]" inputmode="decimal" required></div><div class="col-lg-3 d-none qty-per-barcode-group"><label class="form-label">Isi per Barcode</label><input class="form-control" type="number" name="qty_per_barcode[]" min=".01" step=".01"><small class="text-muted">Wajib untuk tracking QTY.</small></div></div></div></template>
|
|
<div class="col-12 text-end"><button class="btn btn-primary">Simpan Draft PR</button></div>
|
|
</form></div></div>
|
|
<?php endif?>
|
|
<div class="card"><div class="card-header">Daftar Purchase Request</div><div class="table-responsive"><table class="table mb-0"><thead><tr><th>Nomor/Tanggal</th><th>Departemen</th><th>Kebutuhan</th><th>Status</th><th>Aksi</th></tr></thead><tbody><?php foreach($requests as$r):$isOwner=(int)$r->requested_by===(int)$this->session->userdata('user_id');if($r->status==='draft'&&!$isOwner)continue;?><tr><td><?=$r->request_no?><small class="d-block text-muted"><?=$r->request_date?></small></td><td><?=html_escape($r->department?:'-')?></td><td><?=html_escape($r->purpose)?></td><td><?=$r->status?></td><td><?php if($canPrView):?><button type="button" class="btn btn-sm btn-outline-info btn-pr-detail" data-id="<?=$r->id?>">Detail</button><?php endif?> <?php if($canPrExport):?><a class="btn btn-sm btn-outline-danger" target="_blank" href="<?=base_url('purchases/request_pdf/'.$r->id)?>"><i class="bi bi-file-earmark-pdf"></i> PDF</a><?php endif?> <?php if($r->status==='draft'&&$isOwner)echo purchase_action_form('submit_request',$r->id,'Ajukan',$this,'request');elseif($canPrApprove&&$r->status==='submitted')echo purchase_action_form('approve_request',$r->id,'Approve',$this,'request');?> <?php if($r->status==='draft'&&$isOwner):?><form class="d-inline js-confirm" method="post" action="<?=base_url('purchases/delete_request/'.$r->id)?>" data-confirm-title="Hapus draft PR?" data-confirm-text="Draft <?=html_escape($r->request_no)?> akan dihapus permanen." data-confirm-button="Ya, hapus"><input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>"><input type="hidden" name="return_step" value="request"><button class="btn btn-sm btn-outline-danger"><i class="bi bi-trash"></i> Hapus</button></form><?php endif?></td></tr><?php endforeach?></tbody></table></div></div>
|
|
|
|
<?php elseif($step==='order'):?>
|
|
<div class="card mb-3"><div class="card-header"><b>Buat Purchase Order dari PR Disetujui</b></div><div class="card-body"><form class="row g-2" method="post" action="<?=base_url('purchases/create_order')?>"><input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>"><input type="hidden" name="return_step" value="order"><input type="hidden" name="destination_type" id="poDestination" value="warehouse">
|
|
<div class="col-md-3"><label class="form-label">Purchase Request</label><select class="form-select" name="request_id" id="poRequest" required><option value="">Pilih PR</option><?php foreach($requests as$r)if($r->status==='approved'):?><option value="<?=$r->id?>" data-destination="<?=$r->destination_type?>"><?=$r->request_no?> · <?=$r->destination_type==='asset'?'Aset':'Gudang'?></option><?php endif?></select></div><div class="col-md-3"><label class="form-label">Supplier</label><select class="form-select select-search" name="supplier_id" required><?php foreach($suppliers as$s):?><option value="<?=$s->id?>"><?=html_escape($s->name)?></option><?php endforeach?></select></div><div class="col-md-2"><label class="form-label">Tanggal PO</label><input class="form-control" type="date" name="date" value="<?=date('Y-m-d')?>" required></div><div class="col-md-2"><label class="form-label">Estimasi Datang</label><input class="form-control" type="date" name="expected_date"></div><div class="col-md-2"><label class="form-label">Pajak %</label><input class="form-control" type="number" name="tax_rate" step=".01" value="0"></div>
|
|
<div class="col-md-4"><label class="form-label">Deskripsi / Merek / Spesifikasi</label><input class="form-control" name="description" required></div><div class="col-md-2"><label class="form-label">Qty</label><input class="form-control" type="number" name="qty" step=".01" required></div><div class="col-md-2"><label class="form-label">Harga Satuan</label><input class="form-control format-rupiah" name="unit_price" required></div><div class="col-md-4"><label class="form-label">Rencana Pembayaran</label><select class="form-select" name="payment_plan" required><option value="cash">Bayar Langsung</option><option value="installment">Cicilan</option><option value="credit" selected>Kredit / Jatuh Tempo</option></select><small class="text-muted">Pembayaran dicatat setelah tagihan supplier diposting.</small></div>
|
|
<div class="col-12 po-warehouse-fields"><div class="row"><div class="col-md-4"><label class="form-label">Gudang Tujuan</label><select class="form-select" name="warehouse_id"><?php foreach($warehouses as$w):?><option value="<?=$w->id?>"><?=html_escape($w->nama)?></option><?php endforeach?></select></div></div></div>
|
|
<div class="col-12 po-asset-fields d-none"><div class="row g-2"><div class="col-md-4"><label class="form-label">Akun Aset</label><select class="form-select" name="asset_account_id"><?php foreach($asset_accounts as$a):?><option value="<?=$a->id?>"><?=html_escape($a->kode_akun.' '.$a->nama_akun)?></option><?php endforeach?></select></div><div class="col-md-3"><label class="form-label">Lokasi Aset</label><select class="form-select" name="asset_location_id"><?php foreach($asset_locations as$l):?><option value="<?=$l->id?>"><?=html_escape($l->nama)?></option><?php endforeach?></select></div><div class="col-md-3"><label class="form-label">Masa Manfaat (bulan)</label><input class="form-control" type="number" name="useful_life_months" value="48"></div><div class="col-md-2"><label class="form-label">Nilai Residu</label><input class="form-control format-rupiah" name="residual_value" value="0"></div></div></div>
|
|
<div class="col-12 text-end"><button class="btn btn-primary">Buat Draft PO</button></div></form></div></div>
|
|
<div class="card"><div class="card-header">Daftar Purchase Order</div><div class="table-responsive"><table class="table mb-0"><thead><tr><th>PO</th><th>Supplier</th><th>Tujuan</th><th>Total</th><th>Status</th><th>Aksi</th></tr></thead><tbody><?php foreach($orders as$o):$line=$this->db->where('purchase_order_id',$o->id)->get('purchase_order_lines')->row();?><tr><td><?=$o->po_no?></td><td><?=html_escape($o->name)?></td><td><?=$line&&$line->destination_type==='asset'?'Aset Tetap':'Gudang'?></td><td><?=number_format($o->total,2,',','.')?></td><td><?=$o->status?></td><td><?php if($o->status==='draft')echo purchase_action_form('submit_order',$o->id,'Ajukan',$this,'order');elseif($o->status==='submitted'&&$this->session->userdata('role')==='Admin')echo purchase_action_form('approve_order',$o->id,'Approve',$this,'order');?></td></tr><?php endforeach?></tbody></table></div></div>
|
|
|
|
<?php elseif($step==='receipt'):?>
|
|
<div class="card"><div class="card-header"><b>Penerimaan Barang/Aset</b><small class="d-block text-muted">Posting penerimaan adalah satu-satunya proses yang mengaktifkan stok atau register aset.</small></div><div class="table-responsive"><table class="table mb-0"><thead><tr><th>PO/Supplier</th><th>Tujuan</th><th>Item dan Sisa</th><th>Penerimaan</th></tr></thead><tbody><?php foreach($orders as$o):if(!in_array($o->status,array('approved','partially_received')))continue;$lines=$this->db->where('purchase_order_id',$o->id)->get('purchase_order_lines')->result();?><tr><td><?=$o->po_no?><small class="d-block"><?=html_escape($o->name)?></small></td><td><?=$lines&&$lines[0]->destination_type==='asset'?'<span class="badge bg-dark">Aset Tetap</span>':'<span class="badge bg-primary">Gudang</span>'?></td><td><?php foreach($lines as$l):?><?=html_escape($l->description)?> · sisa <?=number_format($l->qty-$l->received_qty,2,',','.')?><br><?php endforeach?></td><td><form method="post" action="<?=base_url('purchases/receive/'.$o->id)?>"><input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>"><input type="hidden" name="return_step" value="receipt"><div class="d-flex flex-wrap gap-1"><input class="form-control form-control-sm" type="date" name="date" value="<?=date('Y-m-d')?>"><input class="form-control form-control-sm" name="delivery_no" placeholder="Surat jalan"><?php foreach($lines as$l):?><input class="form-control form-control-sm" type="number" name="qty[<?=$l->id?>]" min="0" max="<?=$l->qty-$l->received_qty?>" step=".01" placeholder="Qty <?=html_escape($l->description)?>"><?php endforeach?><button class="btn btn-sm btn-warning">Post Penerimaan</button></div></form></td></tr><?php endforeach?></tbody></table></div></div>
|
|
<div class="card mt-3"><div class="card-header">Riwayat Penerimaan</div><div class="table-responsive"><table class="table mb-0"><thead><tr><th>Nomor</th><th>PO</th><th>Supplier</th><th>Tanggal</th><th>Surat Jalan</th></tr></thead><tbody><?php foreach($receipts as$r):?><tr><td><?=$r->receipt_no?></td><td><?=$r->po_no?></td><td><?=html_escape($r->name)?></td><td><?=$r->receipt_date?></td><td><?=html_escape($r->supplier_delivery_no?:'-')?></td></tr><?php endforeach?></tbody></table></div></div>
|
|
|
|
<?php elseif($step==='invoice'):?>
|
|
<div class="d-flex justify-content-end mb-2"><a class="btn btn-success" href="<?=base_url('payables')?>">Bayar Tagihan Langsung / Cicilan</a></div>
|
|
<?php foreach($bills as$b):if($b->status!=='approved'||!in_array($b->payment_plan,array('cash','installment')))continue;?><div class="card mb-3 border-warning"><div class="card-header"><b><?=$b->payment_plan==='cash'?'Pembayaran Langsung':'Cicilan Pertama'?> — <?=html_escape($b->internal_no)?></b></div><div class="card-body"><form class="row g-2" method="post" action="<?=base_url('purchases/post_bill/'.$b->id)?>"><input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>"><input type="hidden" name="return_step" value="invoice"><div class="col-md-3"><label class="form-label">Kas/Bank</label><select class="form-select" name="bank_account_id" required><?php foreach($paymentAccounts as$a):?><option value="<?=$a->id?>"><?=html_escape($a->kode_akun.' - '.$a->nama_akun)?></option><?php endforeach?></select></div><?php if($b->payment_plan==='installment'):?><div class="col-md-3"><label class="form-label">Cicilan Pertama</label><input class="form-control format-rupiah" name="initial_amount" required></div><?php endif?><div class="col-md-2"><label class="form-label">Tanggal Bayar</label><input class="form-control" type="date" name="payment_date" value="<?=date('Y-m-d')?>" required></div><div class="col-md-2"><label class="form-label">Referensi</label><input class="form-control" name="reference_no"></div><div class="col-md-2 d-flex align-items-end"><button class="btn btn-warning w-100">Post & Bayar</button></div></form></div></div><?php endforeach?>
|
|
<div class="card mb-3"><div class="card-header"><b>Tagihan Supplier / Three-way Matching</b></div><div class="card-body"><form class="row g-2" method="post" action="<?=base_url('purchases/create_bill')?>"><input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>"><input type="hidden" name="return_step" value="invoice"><div class="col-md-3"><label class="form-label">PO</label><select class="form-select" name="po_id"><?php foreach($orders as$o)if(in_array($o->status,array('partially_received','received'))):?><option value="<?=$o->id?>"><?=$o->po_no?></option><?php endif?></select></div><div class="col-md-3"><label class="form-label">Penerimaan</label><select class="form-select" name="receipt_id"><?php foreach($receipts as$r):?><option value="<?=$r->id?>"><?=$r->receipt_no?> · <?=$r->po_no?></option><?php endforeach?></select></div><div class="col-md-3"><label class="form-label">No. Invoice Supplier</label><input class="form-control" name="supplier_invoice_no" required></div><div class="col-md-2"><label class="form-label">Tanggal</label><input class="form-control" type="date" name="date" value="<?=date('Y-m-d')?>"></div><div class="col-md-1 d-flex align-items-end"><button class="btn btn-primary">Match</button></div></form></div></div>
|
|
<div class="card"><div class="card-header">Daftar Tagihan</div><div class="table-responsive"><table class="table mb-0"><thead><tr><th>Tagihan</th><th>Supplier</th><th>Rencana Bayar</th><th>Jatuh Tempo</th><th>Saldo</th><th>Status</th><th>Aksi</th></tr></thead><tbody><?php foreach($bills as$b):?><tr><td><?=$b->internal_no?><small class="d-block"><?=html_escape($b->supplier_invoice_no)?></small></td><td><?=html_escape($b->name)?></td><td><?=array('cash'=>'Langsung','installment'=>'Cicilan','credit'=>'Kredit')[$b->payment_plan]??'Kredit'?></td><td><?=$b->due_date?></td><td><?=number_format($b->balance,0,',','.')?></td><td><?=html_escape(array('verified'=>'Perlu Finalisasi','partial'=>'Parsial','paid'=>'Lunas')[$b->status]??$b->status)?></td><td><?php if($b->status==='verified'):?><a class="btn btn-sm btn-warning" href="<?=base_url('purchases?step=invoice')?>">Finalisasi</a><?php endif?></td></tr><?php endforeach?></tbody></table></div></div>
|
|
|
|
<?php else:?>
|
|
<div class="row g-3"><div class="col-lg-6"><div class="card h-100"><div class="card-header">Retur Pembelian</div><div class="card-body"><form method="post" action="<?=base_url('purchases/purchase_return')?>"><input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>"><input type="hidden" name="return_step" value="adjustment"><select class="form-select mb-2" name="receipt_line_id"><?php foreach($this->db->select('goods_receipt_lines.id,goods_receipt_lines.qty,goods_receipts.receipt_no,items.nama_barang')->from('goods_receipt_lines')->join('goods_receipts','goods_receipts.id=goods_receipt_lines.goods_receipt_id')->join('items','items.id=goods_receipt_lines.item_id')->where('goods_receipt_lines.stock_log_id IS NOT NULL',null,false)->get()->result()as$l):?><option value="<?=$l->id?>"><?=html_escape($l->receipt_no.' · '.$l->nama_barang.' · '.$l->qty)?></option><?php endforeach?></select><input class="form-control mb-2" type="date" name="date" value="<?=date('Y-m-d')?>"><input class="form-control mb-2" type="number" name="qty" min=".01" step=".01" placeholder="Qty retur"><input class="form-control mb-2" name="reason" placeholder="Alasan" required><button class="btn btn-warning">Post Retur</button></form></div></div></div><div class="col-lg-6"><div class="card h-100"><div class="card-header">Debit Note Supplier</div><div class="card-body"><form method="post" action="<?=base_url('purchases/debit_note')?>"><input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>"><input type="hidden" name="return_step" value="adjustment"><select class="form-select mb-2" name="bill_id"><?php foreach($bills as$b)if($b->status==='partial'&&$b->balance>0):?><option value="<?=$b->id?>"><?=html_escape($b->internal_no.' · '.$b->name)?></option><?php endif?></select><input class="form-control mb-2" type="date" name="date" value="<?=date('Y-m-d')?>"><input class="form-control mb-2 format-rupiah" name="amount" placeholder="Nilai"><input class="form-control mb-2" name="reason" placeholder="Alasan" required><button class="btn btn-danger">Post Debit Note</button></form></div></div></div></div>
|
|
<?php endif?>
|
|
</div>
|
|
<style>
|
|
.purchase-workflow-stepper{display:flex;gap:.65rem;overflow-x:auto;padding:.2rem .1rem .65rem;scrollbar-width:thin}.purchase-workflow-step{position:relative;display:flex;align-items:center;gap:.6rem;min-width:190px;padding:.85rem .9rem;border:1px solid var(--bs-border-color);border-radius:14px;background:var(--bs-body-bg);color:var(--bs-body-color);text-decoration:none;box-shadow:0 .15rem .55rem rgba(30,42,70,.05)}.purchase-workflow-step:hover{border-color:var(--bs-primary);color:var(--bs-primary)}.purchase-workflow-step.active{background:linear-gradient(135deg,var(--bs-primary),#135ed2);border-color:var(--bs-primary);color:#fff;box-shadow:0 .4rem 1rem rgba(13,110,253,.2)}.purchase-workflow-step .workflow-number{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;background:rgba(13,110,253,.1);font-weight:700;flex:none}.purchase-workflow-step.active .workflow-number{background:rgba(255,255,255,.2)}.purchase-workflow-step>span:last-child{display:flex;flex-direction:column;white-space:nowrap}.purchase-workflow-step small{font-size:.72rem;opacity:.72}@media(max-width:575.98px){.purchase-workflow-step{min-width:150px;padding:.7rem}.purchase-workflow-step small,.purchase-workflow-step>i{display:none}}
|
|
</style>
|
|
<div class="modal fade" id="prDetailModal" tabindex="-1" aria-hidden="true"><div class="modal-dialog modal-lg modal-dialog-scrollable"><div class="modal-content"><div class="modal-header"><div><h5 class="modal-title">Detail Permintaan Pembelian</h5><small class="text-muted" id="prDetailNumber"></small></div><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Tutup"></button></div><div class="modal-body" id="prDetailBody"><div class="text-center py-4">Memuat data...</div></div><div class="modal-footer"><div class="me-auto small"><div><span class="text-muted">Dibuat oleh:</span> <b id="prCreatorName">-</b></div><div><span class="text-muted">Diajukan oleh:</span> <b id="prRequesterName">-</b></div><div><span class="text-muted">Disetujui oleh:</span> <b id="prApproverName">-</b></div></div><a class="btn btn-outline-danger" id="prDetailPdf" target="_blank"><i class="bi bi-file-earmark-pdf"></i> Buka PDF</a><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button></div></div></div></div>
|
|
<script>$(function(){function destination(){var x=$('#poRequest option:selected').data('destination')||'warehouse';$('#poDestination').val(x);$('.po-warehouse-fields').toggleClass('d-none',x!=='warehouse');$('.po-asset-fields').toggleClass('d-none',x!=='asset');}function tracking(){var q=$('#requestCatalog option:selected').data('tracking')==='QTY';$('#qtyPerBarcodeGroup').toggleClass('d-none',!q).find('input').prop('required',q);}var returnBarcodes=<?=json_encode($returnBarcodes)?>,returnForm=$('form[action*="purchases/purchase_return"]'),receiptSelect=returnForm.find('[name="receipt_line_id"]'),barcodeSelect=$('<select class="form-select mb-2" name="barcode_id" required><option value="">Pilih barcode / serial yang diretur</option></select>');receiptSelect.after(barcodeSelect);function returnOptions(){var receipt=String(receiptSelect.val()||'');barcodeSelect.html('<option value="">Pilih barcode / serial yang diretur</option>'+returnBarcodes.filter(x=>String(x.source_receipt_line_id)===receipt).map(x=>'<option value="'+x.id+'" data-max="'+x.qty_sisa+'" data-tracking="'+x.tracking_type+'">'+$('<div>').text(x.barcode+(x.serial_number?' · SN '+x.serial_number:'')+' · saldo '+Number(x.qty_sisa).toLocaleString('id-ID')).html()+'</option>').join(''));}receiptSelect.on('change',returnOptions);barcodeSelect.on('change',function(){var o=$(this).find(':selected'),unit=o.data('tracking')==='UNIT';returnForm.find('[name="qty"]').attr('max',o.data('max')||'').val(unit&&o.val()?1:'').prop('readonly',unit&&!!o.val());});$('input[name="destination_type"]').on('change',destination);$('#poRequest').on('change',destination);$('#requestCatalog').on('change',tracking);destination();tracking();returnOptions();});</script>
|
|
<script>$(document).on('click','.btn-pr-detail',async function(){var id=this.dataset.id,body=document.getElementById('prDetailBody'),modalElement=document.getElementById('prDetailModal');body.innerHTML='<div class="text-center py-4">Memuat data...</div>';document.getElementById('prDetailPdf').href='<?=base_url('purchases/request_pdf/')?>'+id;var modal=window.bootstrap?bootstrap.Modal.getOrCreateInstance(modalElement):null;if(modal)modal.show();else $('#prDetailModal').modal('show');try{var response=await fetch('<?=base_url('purchases/request_detail/')?>'+id,{headers:{Accept:'application/json','X-Requested-With':'XMLHttpRequest'}}),json=await response.json();if(!response.ok||!json.status)throw new Error(json.message||'Data tidak dapat dimuat.');var r=json.request,lines=Array.isArray(json.lines)?json.lines:[];document.getElementById('prDetailNumber').textContent=r.request_no;var esc=v=>$('<div>').text(v??'-').html();body.innerHTML='<div class="row g-2 mb-3"><div class="col-md-4"><small class="text-muted">Tanggal</small><div>'+esc(r.request_date)+'</div></div><div class="col-md-4"><small class="text-muted">Dibutuhkan</small><div>'+esc(r.needed_date||'-')+'</div></div><div class="col-md-4"><small class="text-muted">Status</small><div>'+esc(r.status)+'</div></div><div class="col-md-4"><small class="text-muted">Departemen</small><div>'+esc((r.department_code?r.department_code+' - ':'')+(r.department_name||r.department||'-'))+'</div></div><div class="col-md-8"><small class="text-muted">Kebutuhan</small><div>'+esc(r.purpose)+'</div></div></div><div class="table-responsive"><table class="table table-sm"><thead><tr><th>Master Barang</th><th>Deskripsi</th><th class="text-end">Qty</th><th>Tracking</th><th class="text-end">Estimasi</th></tr></thead><tbody>'+lines.map(x=>'<tr><td>'+esc((x.kode_barang||'-')+' - '+(x.master_name||'-'))+'</td><td>'+esc(x.description)+'</td><td class="text-end">'+Number(x.qty).toLocaleString('id-ID')+'</td><td>'+esc(x.tracking_type)+(x.tracking_type==='QTY'?' / '+Number(x.qty_per_barcode).toLocaleString('id-ID')+' per barcode':'')+'</td><td class="text-end">'+(Number(x.qty)*Number(x.estimated_price)).toLocaleString('id-ID')+'</td></tr>').join('')+'</tbody></table></div>';}catch(error){body.innerHTML='<div class="alert alert-danger mb-0">'+$('<div>').text(error.message).html()+'</div>';}});</script>
|
|
<script>$(function(){var self=$('#prApplicantSelf'),group=$('#prApplicantNameGroup'),name=$('#prApplicantName');function toggleApplicant(){var checked=self.is(':checked');group.toggleClass('d-none',checked);name.prop('required',!checked).prop('disabled',checked);if(checked)name.val('');}self.on('change',toggleApplicant);toggleApplicant();});</script>
|
|
<script>$(function(){var container=$('#prLines'),template=document.getElementById('prLineTemplate');function renumber(){container.find('.pr-line').each(function(i){$(this).find('.pr-line-title').text('Barang '+(i+1));$(this).find('.remove-pr-line').toggle(container.children().length>1);});}function syncTracking(row){var option=row.find('.pr-catalog option:selected'),tracking=option.data('tracking')||'UNIT',group=row.find('.qty-per-barcode-group'),per=group.find('input'),qty=row.find('.pr-qty');group.toggleClass('d-none',tracking!=='QTY');per.prop('required',tracking==='QTY').prop('disabled',false);if(tracking==='UNIT'){per.val('1');qty.attr({step:'1',min:'1'});}else{if(per.val()==='1')per.val('');qty.attr({step:'.01',min:'.01'});}}function addLine(){var node=$(template.content.cloneNode(true));container.append(node);var row=container.children().last();syncTracking(row);renumber();row.find('.pr-catalog').focus();}$('#addPrLine').on('click',addLine);container.on('change','.pr-catalog',function(){syncTracking($(this).closest('.pr-line'));});container.on('click','.remove-pr-line',function(){if(container.children().length<=1)return;$(this).closest('.pr-line').remove();renumber();});addLine();});</script>
|
|
<script>$(document).on('click','.btn-pr-detail',async function(){var creator=document.getElementById('prCreatorName'),requester=document.getElementById('prRequesterName'),approver=document.getElementById('prApproverName');creator.textContent=requester.textContent=approver.textContent='-';try{var response=await fetch('<?=base_url('purchases/request_detail/')?>'+this.dataset.id,{headers:{Accept:'application/json','X-Requested-With':'XMLHttpRequest'}}),json=await response.json(),r=json.request||{};creator.textContent=r.creator_name||r.creator_username||('Pengguna #'+(r.requested_by||'-'));requester.textContent=r.applicant_display||creator.textContent;approver.textContent=r.approver_name||r.approver_username||'-';}catch(error){creator.textContent=requester.textContent=approver.textContent='Data tidak tersedia';}});</script>
|
|
<script>$(function(){var pdfModal=$('<div class="modal fade" id="prPdfModal" tabindex="-1"><div class="modal-dialog modal-xl modal-dialog-centered"><div class="modal-content" style="height:min(92vh,900px)"><div class="modal-header"><h5 class="modal-title">PDF Permintaan Pembelian</h5><button class="btn-close" data-bs-dismiss="modal"></button></div><div class="modal-body p-0"><iframe title="PDF Permintaan Pembelian" style="width:100%;height:100%;border:0"></iframe></div></div></div></div>').appendTo(document.body);$(document).on('click','a[href*="purchases/request_pdf/"]',function(e){e.preventDefault();pdfModal.find('iframe').attr('src',this.href);bootstrap.Modal.getOrCreateInstance(pdfModal[0]).show();});pdfModal.on('hidden.bs.modal',function(){pdfModal.find('iframe').attr('src','about:blank')});$('form[action*="purchases/approve_request/"]').each(function(){var approve=$(this),id=approve.attr('action').split('/').pop(),button=$('<button type="button" class="btn btn-sm btn-outline-danger ms-1">Reject</button>');approve.after(button);button.on('click',function(){Swal.fire({icon:'warning',title:'Tolak Purchase Request?',input:'textarea',inputLabel:'Alasan penolakan',inputPlaceholder:'Jelaskan alasan agar pembuat dapat memperbaiki PR',inputValidator:v=>!String(v||'').trim()?'Alasan penolakan wajib diisi.':undefined,showCancelButton:true,confirmButtonText:'Tolak PR',cancelButtonText:'Batal'}).then(function(r){if(!r.isConfirmed)return;var form=$('<form method="post" action="<?=base_url('purchases/reject_request/')?>'+id+'"><input type="hidden" name="<?=$this->security->get_csrf_token_name()?>" value="<?=$this->security->get_csrf_hash()?>"><input type="hidden" name="return_step" value="request"><input type="hidden" name="reason"></form>');form.find('[name=reason]').val(r.value);form.appendTo(document.body).trigger('submit');});});});});</script>
|