Update besar apk finance

This commit is contained in:
Wian Drs
2026-09-11 16:03:00 +07:00
parent d42483b350
commit 4ef15c22ae
897 changed files with 98056 additions and 15979 deletions
+23
View File
@@ -0,0 +1,23 @@
(function($){
'use strict';
var cfg=window.RECEIVABLE_PAGE||{},invoices=[],files=[],sourceIndex=0;
function esc(v){return $('<div>').text(v==null?'':v).html()}
function parseMoney(v){v=String(v==null?'':v).replace(/Rp|\s/g,'');if(v.indexOf(',')>=0)v=v.replace(/\./g,'').replace(',','.');else if(/^\d{1,3}(\.\d{3})+$/.test(v))v=v.replace(/\./g,'');return Number(v)||0}
function money(v){return'Rp '+new Intl.NumberFormat('id-ID',{minimumFractionDigits:2,maximumFractionDigits:2}).format(Number(v)||0)}
function fmt(v){return new Intl.NumberFormat('id-ID',{minimumFractionDigits:0,maximumFractionDigits:2}).format(Number(v)||0)}
function toast(message,icon){if(window.AppAlert)return AppAlert.toast(message,icon||'success');return Swal.fire({toast:true,position:'top-end',icon:icon||'success',title:message,showConfirmButton:false,timer:3200})}
function fail(xhr){var m='Permintaan tidak dapat diproses.';try{var r=xhr.responseJSON||JSON.parse(xhr.responseText);m=r.message||m}catch(e){}toast(m,'error')}
function select2(selector,url,placeholder){$(selector).select2({width:'100%',placeholder:placeholder,allowClear:true,ajax:{url:cfg.base+url,dataType:'json',delay:300,data:function(p){return{q:p.term||'',page:p.page||1}},processResults:function(r){return{results:r.results||[],pagination:r.pagination||{more:false}}},cache:true}})}
function addSource(){sourceIndex++;var row=$('<div class="payment-source-row"><select class="form-select source-account"></select><input class="form-control source-amount" inputmode="decimal" placeholder="Nominal"><button type="button" class="remove-payment-source" aria-label="Hapus sumber"><i class="bi bi-x-lg"></i></button></div>');$('#paymentSources').append(row);select2(row.find('.source-account'),'receivables/lookup_cash_accounts','Pilih akun Aktiva / Passiva');row.find('.source-amount').on('input blur',function(e){if(e.type==='blur')this.value=fmt(parseMoney(this.value));calculate()})}
function renderInvoices(rows){invoices=Array.isArray(rows)?rows:[];if(!invoices.length){$('#invoiceAllocations').html('<div class="ar-empty"><i class="bi bi-receipt-cutoff"></i><span>Customer ini tidak memiliki invoice terbuka.</span></div>');$('#invoiceSelectionHint').text('Tidak ada invoice terbuka.');calculate();return}var today=new Date().toISOString().slice(0,10);$('#invoiceAllocations').html(invoices.map(function(i){var overdue=i.jatuh_tempo<today;return'<article class="invoice-allocation '+(overdue?'is-overdue':'')+'"><div class="invoice-allocation-head"><div><b>'+esc(i.no_invoice)+'</b><small>'+esc(i.invoice_type==='running'?'Berjalan / Akumulasi':'Sekali transaksi')+'</small></div><span class="badge '+(overdue?'bg-danger':'bg-warning text-dark')+'">'+(overdue?'Jatuh tempo':'Belum jatuh tempo')+'</span></div><div class="invoice-allocation-meta"><span>Total '+money(i.total)+'</span><span>Terbayar '+money(i.total_bayar)+'</span></div><div class="invoice-allocation-input"><b>Sisa '+money(i.sisa_piutang)+'</b><input class="form-control allocation-amount" data-id="'+Number(i.id)+'" data-balance="'+Number(i.sisa_piutang)+'" inputmode="decimal" value="0" aria-label="Alokasi '+esc(i.no_invoice)+'"></div></article>'}).join(''));$('#invoiceSelectionHint').text(invoices.length+' invoice belum lunas.');$('.allocation-amount').on('input blur',function(e){var value=Math.min(parseMoney(this.value),Number($(this).data('balance')));if(e.type==='blur')this.value=fmt(value);calculate()});if(cfg.focus&&Number(cfg.focus.customer_id)===Number($('#payCustomer').val())){$('.allocation-amount[data-id="'+Number(cfg.focus.id)+'"]').val(fmt(cfg.focus.sisa_piutang));cfg.focus=null}calculate()}
function loadCustomer(id){$('#paymentCustomerId').val(id||'');if(!id){renderInvoices([]);return}$('#invoiceAllocations').html('<div class="ar-empty"><span class="spinner-border spinner-border-sm"></span><span>Memuat invoice...</span></div>');$.getJSON(cfg.base+'receivables/open_invoices/'+id).done(function(r){if(!r.status)return toast(r.message,'error');renderInvoices(r.invoices)}).fail(fail);$.getJSON(cfg.base+'receivables/payment_history/'+id).done(function(r){renderHistory(r.payments||[])}).fail(fail)}
function renderHistory(rows){if(!rows.length){$('#paymentHistory').html('<div class="ar-empty"><i class="bi bi-clock-history"></i><span>Belum ada riwayat pembayaran customer ini.</span></div>');return}$('#paymentHistory').html('<div class="payment-history-list">'+rows.map(function(p){return'<div class="payment-history-row"><div><b>'+esc(p.payment_no)+'</b><small>'+esc(p.tanggal)+'</small></div><div>'+esc((p.allocations||'Uang muka').replace(/\|\|/g,', '))+'<small>Referensi '+esc(p.reference_no||'-')+' · '+esc(p.creator_name||'-')+'</small></div><b>'+money(p.jumlah)+'</b><button class="btn btn-sm btn-outline-danger preview-receipt" data-url="'+cfg.base+'sales/receipt_pdf/'+p.id+'"><i class="bi bi-file-pdf"></i> Bukti</button></div>'}).join('')+'</div>')}
function calculate(){var allocated=0;$('.allocation-amount').each(function(){allocated+=parseMoney(this.value)});var source=0;$('.source-amount').each(function(){source+=parseMoney(this.value)});var diff=source-allocated;$('#allocatedTotal').text(money(allocated));$('#sourceTotal').text(money(source));$('#paymentDifference').text(money(diff)).toggleClass('is-negative',diff<-.001).toggleClass('is-positive',diff>.001);return{allocated:allocated,source:source,difference:diff}}
function syncFileInput(){var dt=new DataTransfer();files.forEach(function(f){dt.items.add(f)});document.getElementById('paymentAttachments').files=dt.files;renderFiles()}
function renderFiles(){$('#paymentAttachmentGrid .payment-file-tile').remove();var add=$('#addPaymentAttachment');files.forEach(function(f,i){var url=URL.createObjectURL(f),pdf=f.type==='application/pdf';var tile=$('<div class="payment-file-tile" data-index="'+i+'">'+(pdf?'<div class="pdf-icon"><i class="bi bi-file-earmark-pdf"></i></div>':'<img alt="'+esc(f.name)+'" src="'+url+'">')+'<button type="button" class="payment-file-open" aria-label="Pratinjau"></button><small>'+esc(f.name)+'</small><button type="button" class="file-remove" aria-label="Hapus">×</button></div>');tile.data('url',url).data('type',f.type);add.before(tile)})}
function preview(url,type){var modal=$('#paymentPreviewModal'),frame=modal.find('iframe'),img=modal.find('img');frame.hide().attr('src','about:blank');img.hide().attr('src','');if(type==='application/pdf')frame.show().attr('src',url);else img.show().attr('src',url);bootstrap.Modal.getOrCreateInstance(modal[0]).show()}
$(function(){select2('#payCustomer','receivables/lookup_customers','Cari customer');addSource();if(cfg.focus){var option=new Option(cfg.focus.customer_name,cfg.focus.customer_id,true,true);$('#payCustomer').append(option).trigger('change')}else $('#invoiceSelectionHint').text('Pilih customer terlebih dahulu.')});
$('#payCustomer').on('change',function(){loadCustomer(this.value)});$('#addPaymentSource').on('click',addSource);$(document).on('click','.remove-payment-source',function(){if($('.payment-source-row').length===1){$(this).closest('.payment-source-row').find('select').val(null).trigger('change');$(this).closest('.payment-source-row').find('input').val('');calculate();return}$(this).closest('.payment-source-row').remove();calculate()});$('#allocateAll').on('click',function(){$('.allocation-amount').each(function(){this.value=fmt($(this).data('balance'))});calculate()});$('#clearAllocations').on('click',function(){$('.allocation-amount').val('0');calculate()});$('#addPaymentAttachment').on('click',function(){$('#paymentAttachments').trigger('click')});$('#paymentAttachments').on('change',function(){files=files.concat(Array.from(this.files));if(files.length>10){files=files.slice(0,10);toast('Maksimal 10 bukti pembayaran.','warning')}syncFileInput()});$(document).on('click','.file-remove',function(e){e.stopPropagation();files.splice(Number($(this).closest('.payment-file-tile').data('index')),1);syncFileInput()});$(document).on('click','.payment-file-open',function(){var tile=$(this).closest('.payment-file-tile');preview(tile.data('url'),tile.data('type'))});$(document).on('click','.preview-receipt',function(){preview($(this).data('url'),'application/pdf')});
$('#paymentPreviewModal').on('hidden.bs.modal',function(){$(this).find('iframe').attr('src','about:blank');$(this).find('img').attr('src','')});
$('#paymentForm').on('submit',function(e){e.preventDefault();var customer=$('#payCustomer').val(),allocations={},sources=[];$('.allocation-amount').each(function(){var value=parseMoney(this.value);if(value>0)allocations[$(this).data('id')]=value});$('.payment-source-row').each(function(){var account=$(this).find('.source-account').val(),amount=parseMoney($(this).find('.source-amount').val());if(account&&amount>0)sources.push({account_id:Number(account),amount:amount})});var totals=calculate();if(!customer)return toast('Pilih customer.','warning');if(!sources.length)return toast('Tambahkan minimal satu sumber Kas/Bank dan nominal.','warning');if(!files.length)return toast('Bukti pembayaran wajib ditambahkan.','warning');if(totals.difference<-.001)return toast('Sumber penerimaan lebih kecil dari alokasi invoice.','warning');if(totals.difference>.001&&!$('#allowAdvance').is(':checked'))return toast('Terdapat kelebihan. Centang uang muka customer atau sesuaikan nominal.','warning');var form=this,button=$('#postPayment');var confirm=window.AppAlert?AppAlert.confirm({icon:'question',title:'Post pembayaran?',html:'Penerimaan <b>'+money(totals.source)+'</b> akan dialokasikan sebesar <b>'+money(totals.allocated)+'</b>.',confirmButtonText:'Ya, Post'}):Swal.fire({icon:'question',title:'Post pembayaran?',showCancelButton:true,confirmButtonText:'Ya, Post'});confirm.then(function(r){if(!r.isConfirmed)return;var fd=new FormData(form);fd.set('customer_id',customer);fd.set('sources',JSON.stringify(sources));fd.set('allocations_json',JSON.stringify(allocations));button.prop('disabled',true).html('<span class="spinner-border spinner-border-sm"></span> Memproses...');$.ajax({url:form.action,type:'POST',data:fd,dataType:'json',processData:false,contentType:false}).done(function(x){if(!x.status)return toast(x.message,'error');toast(x.message,'success');if(x.result&&x.result.payment_id)preview(cfg.base+'sales/receipt_pdf/'+x.result.payment_id,'application/pdf');loadCustomer(customer);files=[];syncFileInput();$('.source-amount').val('');calculate()}).fail(fail).always(function(){button.prop('disabled',false).html('<i class="bi bi-check-circle"></i> Post Pembayaran')})})});
})(jQuery);