update koneksi DB
This commit is contained in:
@@ -111,7 +111,7 @@ class SalesService
|
||||
$price=$this->money($priceValue);
|
||||
if($price<0)throw new BusinessException('Harga item ke-'.($index+1).' tidak boleh negatif.');
|
||||
$row['qty']=$qty;$row['unit_price']=$price;$row['discount_amount']=0;$row['specification']='';
|
||||
$grossValues[$index]=round($qty*$price,2);$totalGross+=$grossValues[$index];
|
||||
$grossValues[$index]=round($qty*$price,2);if(($row['line_type']??'inventory')!=='savings')$totalGross+=$grossValues[$index];
|
||||
}
|
||||
unset($row);
|
||||
|
||||
@@ -119,10 +119,10 @@ class SalesService
|
||||
if($discount<0)throw new BusinessException('Diskon penambahan item tidak boleh negatif.');
|
||||
if($discount>$totalGross+.001)throw new BusinessException('Diskon tidak boleh melebihi total bruto item yang ditambahkan.');
|
||||
|
||||
$positiveIndexes=array_keys(array_filter($grossValues,function($gross){return$gross>0;}));
|
||||
$positiveIndexes=array();foreach($grossValues as$index=>$gross)if($gross>0&&($rows[$index]['line_type']??'inventory')!=='savings')$positiveIndexes[]=$index;
|
||||
$lastPositive=$positiveIndexes?end($positiveIndexes):null;$allocated=0.0;
|
||||
foreach($rows as $index=>&$row){
|
||||
if($discount<=0||$grossValues[$index]<=0){$lineDiscount=0.0;}
|
||||
if(($row['line_type']??'inventory')==='savings'||$discount<=0||$grossValues[$index]<=0){$lineDiscount=0.0;}
|
||||
elseif($index===$lastPositive){$lineDiscount=round($discount-$allocated,2);}
|
||||
else{$lineDiscount=round($discount*$grossValues[$index]/$totalGross,2);}
|
||||
$lineDiscount=max(0,min($grossValues[$index],$lineDiscount));
|
||||
@@ -154,10 +154,7 @@ class SalesService
|
||||
$customer=$this->tenant('customers',$invoice->customer_id,'Customer');
|
||||
$existingLines=$this->CI->db->select('id,line_type,subtotal,total_hpp_barang')->where(array('invoice_id'=>$invoice->id,'company_id'=>$this->company()))->get('invoice_details')->result();$lineJournalMode=true;foreach($existingLines as$existingLine)if($existingLine->line_type!=='savings'&&((float)$existingLine->subtotal>0||(float)$existingLine->total_hpp_barang>0)){$existingJournal=$this->initialLineJournal($existingLine->id);if(!$existingJournal||$existingJournal->is_reversed||$existingJournal->status!=='posted'){$lineJournalMode=false;break;}}
|
||||
$existingTypes=$this->CI->db->select('DISTINCT line_type',false)->where(array('invoice_id'=>$invoice->id,'company_id'=>$this->company()))->get('invoice_details')->result_array();
|
||||
$families=array();foreach($existingTypes as$t)$families[$this->lineFamily($t['line_type'])]=true;foreach($rows as$r)$families[$this->lineFamily($r['line_type']??'inventory')]=true;
|
||||
if(count($families)>1)throw new BusinessException('Invoice penjualan barang/jasa tidak dapat dicampur dengan invoice tabungan. Buat invoice terpisah agar jurnal dan pelunasannya jelas.');
|
||||
$financialTypes=array();foreach($existingTypes as$t)if($this->lineFamily($t['line_type'])==='financial')$financialTypes[$t['line_type']]=true;foreach($rows as$r)if($this->lineFamily($r['line_type']??'inventory')==='financial')$financialTypes[$r['line_type']]=true;
|
||||
if(count($financialTypes)>1)throw new BusinessException('Data pinjaman lama dan tabungan tidak dapat dicampur pada invoice yang sama.');
|
||||
foreach($existingTypes as$t)if($t['line_type']==='loan')throw new BusinessException('Invoice Pinjaman lama tidak dapat ditambah dengan jenis transaksi baru. Buat invoice baru untuk Barang, Jasa, atau Tabungan.');
|
||||
foreach($rows as$n=>$row){
|
||||
$requestedType=$row['line_type']??'inventory';if($requestedType==='loan')throw new BusinessException('Piutang/Pinjaman sudah tidak tersedia pada Invoice. Gunakan jenis Tabungan sesuai alur terbaru.');
|
||||
$lineType=in_array($requestedType,array('inventory','service','savings'),true)?$requestedType:'inventory';$item=null;$warehouse=null;$kb=null;$key=trim((string)($row['idempotency_key']??''));
|
||||
@@ -222,11 +219,13 @@ class SalesService
|
||||
$qty=number_format((float)$line->qty,abs((float)$line->qty-round((float)$line->qty))<.0001?0:4,',','.');
|
||||
if($line->line_type==='inventory'){
|
||||
$codes=array();foreach($barcodes as$b)if(isset($b['row']->barcode))$codes[]=$b['row']->barcode;
|
||||
$description="Penjualan '".$item->nama_barang."' Sebanyak '".$qty."' '".($line->unit?:'-')."' - Kode: '".($codes?implode(', ',$codes):'-')."' - Kepada: '".$customer->nama."'";
|
||||
$unit=trim((string)$line->unit);$quantity=$qty.($unit!==''&&$unit!=='-'?' '.$unit:'');
|
||||
$description='Penjualan '.$item->nama_barang.' Sebanyak '.$quantity.' - Kode: '.($codes?implode(', ',$codes):'-').' - Kepada: '.$customer->nama;
|
||||
}else{
|
||||
$description="Penjualan '".$line->nama_item."' Sebanyak '".$qty."' - Kepada: '".$customer->nama."' - '".($line->keterangan?:'-')."'";
|
||||
$description='Penjualan '.$line->nama_item.' Sebanyak '.$qty.' - Kepada: '.$customer->nama;
|
||||
if(trim((string)$line->keterangan)!=='')$description.=' - '.trim((string)$line->keterangan);
|
||||
}
|
||||
return$this->CI->postingservice->post(array('tanggal'=>$line->service_date,'no_ref'=>$this->CI->numberingservice->next('invoice_line_journal',$line->service_date),'keterangan'=>$description,'ref_type'=>'invoice_line','ref_id'=>(int)$detailId,'created_by'=>$user),$entries,false,false);
|
||||
return$this->CI->postingservice->post(array('tanggal'=>$line->service_date,'no_ref'=>$this->CI->numberingservice->next('invoice_line_journal',$line->service_date),'keterangan'=>$description,'natural_description'=>true,'ref_type'=>'invoice_line','ref_id'=>(int)$detailId,'created_by'=>$user),$entries,false,false);
|
||||
}
|
||||
|
||||
private function initialLineJournal($lineId,$lock=false)
|
||||
@@ -241,7 +240,9 @@ class SalesService
|
||||
$entries=array();foreach($this->CI->db->where('journal_id',$journal->id)->order_by('id')->get('journal_details')->result()as$d)$entries[]=array('account_id'=>$d->account_id,'debit'=>(float)$d->kredit,'kredit'=>(float)$d->debit);
|
||||
if(!$entries)return null;
|
||||
$date=$line->service_date?:($line->tanggal?:date('Y-m-d'));
|
||||
$reversal=$this->CI->postingservice->post(array('tanggal'=>$date,'no_ref'=>$this->CI->numberingservice->next('invoice_line_reversal',$date),'keterangan'=>'Pembalikan item invoice: '.$reason,'ref_type'=>'invoice_line_reversal','ref_id'=>(int)$journal->id,'reversal_of'=>(int)$journal->id,'reversal_reason'=>$reason,'created_by'=>$user),$entries,false,true);
|
||||
$invoice=$this->CI->db->select('no_invoice')->get_where('invoices',array('id'=>$line->invoice_id,'company_id'=>$this->company()))->row();
|
||||
$description='Pembatalan item pada Invoice '.($invoice?$invoice->no_invoice:'#'.$line->invoice_id).' karena '.$reason;
|
||||
$reversal=$this->CI->postingservice->post(array('tanggal'=>$date,'no_ref'=>$this->CI->numberingservice->next('invoice_line_reversal',$date),'keterangan'=>$description,'natural_description'=>true,'ref_type'=>'invoice_line_reversal','ref_id'=>(int)$journal->id,'reversal_of'=>(int)$journal->id,'reversal_reason'=>$reason,'created_by'=>$user),$entries,false,true);
|
||||
$this->CI->db->where('id',$journal->id)->update('journals',array('status'=>'reversed','is_reversed'=>1,'updated_by'=>$user,'updated_at'=>date('Y-m-d H:i:s'),'reversal_reason'=>$reason));
|
||||
return$reversal;
|
||||
}
|
||||
@@ -360,7 +361,7 @@ class SalesService
|
||||
foreach($bars as$b){$log=$this->addCompany('stock_logs',array('item_id'=>$l->item_id,'warehouse_id'=>$d->warehouse_id,'barcode_id'=>$b->barcode_id,'qty'=>$b->qty,'tipe'=>'keluar','unit_cost'=>$l->qty>0?$cost/$l->qty:0,'keterangan'=>$desc,'ref_type'=>'sales_delivery','ref_id'=>$l->id,'idempotency_key'=>$key.'-B'.$b->id));$this->CI->db->insert('stock_logs',$log);$move=$this->addCompany('item_movements',array('item_id'=>$l->item_id,'barcode_id'=>$b->barcode_id,'qty'=>$b->qty,'from_type'=>'warehouse','from_id'=>$d->warehouse_id,'to_type'=>'customer','to_id'=>$d->customer_id,'movement_type'=>'sold_out','reference_type'=>'sales_delivery','reference_id'=>$l->id,'notes'=>$desc,'created_at'=>date('Y-m-d H:i:s')));$this->CI->db->insert('item_movements',$move);}
|
||||
$this->CI->salesInventoryModel->synchronizeStock($l->item_id);$this->CI->db->where('id',$l->id)->update('sales_delivery_lines',array('unit_cost'=>$l->qty>0?$cost/$l->qty:0,'total_cost'=>$cost,'stock_posted_at'=>date('Y-m-d H:i:s')));$this->CI->db->where('id',$l->invoice_detail_id)->update('invoice_details',array('total_hpp_barang'=>$cost,'stock_posted_at'=>date('Y-m-d H:i:s')));
|
||||
}
|
||||
$journal=null;if(abs($inventoryReclass)>.001){$amount=abs(round($inventoryReclass,2));$entries=$inventoryReclass>0?array(array('account_id'=>$this->CI->accountmappingservice->get('inventory_in_sales'),'debit'=>$amount,'kredit'=>0),array('account_id'=>$this->CI->accountmappingservice->get('inventory'),'debit'=>0,'kredit'=>$amount)):array(array('account_id'=>$this->CI->accountmappingservice->get('inventory'),'debit'=>$amount,'kredit'=>0),array('account_id'=>$this->CI->accountmappingservice->get('inventory_in_sales'),'debit'=>0,'kredit'=>$amount));$journal=$this->CI->postingservice->post(array('tanggal'=>$d->delivery_date,'no_ref'=>$this->CI->numberingservice->next('sales_delivery_journal',$d->delivery_date),'keterangan'=>'[AUTO] Penyesuaian biaya aktual pengiriman '.$d->delivery_no.' | Customer #'.$d->customer_id.' | Selisih Rp '.number_format($inventoryReclass,2,',','.'),'ref_type'=>'sales_delivery','ref_id'=>$d->id,'created_by'=>$user),$entries,false,true);}
|
||||
$journal=null;if(abs($inventoryReclass)>.001){$amount=abs(round($inventoryReclass,2));$entries=$inventoryReclass>0?array(array('account_id'=>$this->CI->accountmappingservice->get('inventory_in_sales'),'debit'=>$amount,'kredit'=>0),array('account_id'=>$this->CI->accountmappingservice->get('inventory'),'debit'=>0,'kredit'=>$amount)):array(array('account_id'=>$this->CI->accountmappingservice->get('inventory'),'debit'=>$amount,'kredit'=>0),array('account_id'=>$this->CI->accountmappingservice->get('inventory_in_sales'),'debit'=>0,'kredit'=>$amount));$deliveryCustomer=$this->CI->db->select('nama')->get_where('customers',array('id'=>$d->customer_id,'company_id'=>$this->company()))->row();$description='Penyesuaian harga modal pada pengiriman '.$d->delivery_no.' kepada '.($deliveryCustomer?$deliveryCustomer->nama:'Customer #'.$d->customer_id).' sebesar Rp '.number_format($amount,2,',','.');$journal=$this->CI->postingservice->post(array('tanggal'=>$d->delivery_date,'no_ref'=>$this->CI->numberingservice->next('sales_delivery_journal',$d->delivery_date),'keterangan'=>$description,'natural_description'=>true,'ref_type'=>'sales_delivery','ref_id'=>$d->id,'created_by'=>$user),$entries,false,true);}
|
||||
$this->CI->db->where('id',$d->id)->update('sales_deliveries',array('status'=>'posted','journal_id'=>$journal,'posted_by'=>$user,'posted_at'=>date('Y-m-d H:i:s'),'version'=>(int)$d->version+1));$this->updateInvoiceDeliveryStatus($d->invoice_id);$this->CI->auditservice->record('sales','sales_delivery',$d->id,'post',$d,array('journal_id'=>$journal,'cost'=>$totalCost),$user);return$d->id;
|
||||
});
|
||||
}
|
||||
@@ -390,19 +391,25 @@ class SalesService
|
||||
private function postInvoiceInternal($id,$user)
|
||||
{
|
||||
$i=$this->lockInvoice($id,'approved');$this->CI->fiscalperiodservice->assertOpen($i->tanggal);if($i->journal_id)throw new BusinessException('Invoice sudah pernah diposting.');if($i->delivery_status!=='delivered')throw new BusinessException('Invoice hanya dapat diposting setelah seluruh Surat Jalan diposting.');$lines=$this->CI->db->where(array('invoice_id'=>$i->id,'company_id'=>$this->company()))->get('invoice_details')->result();if(!$lines)throw new BusinessException('Invoice belum mempunyai item.');
|
||||
$family=$this->lineFamily($lines[0]->line_type);$entries=array();$cogs=0;$revenueAmount=0;
|
||||
if($family==='financial'&&$lines[0]->line_type==='savings'){
|
||||
$family=$this->lineFamily($lines[0]->line_type);$entries=array();$cogs=0;$revenueAmount=0;$hasSales=false;$hasSavings=false;$hasLoan=false;foreach($lines as$l){if(in_array($l->line_type,array('inventory','service'),true))$hasSales=true;elseif($l->line_type==='savings')$hasSavings=true;elseif($l->line_type==='loan')$hasLoan=true;}
|
||||
if($hasSavings&&!$hasSales&&!$hasLoan){
|
||||
$this->CI->db->where('id',$i->id)->update('invoices',array('workflow_status'=>'posted','posted'=>1,'posted_by'=>$user,'posted_at'=>date('Y-m-d H:i:s'),'journal_id'=>null,'status'=>'unpaid','sisa_piutang'=>$i->total,'recognized_revenue'=>0,'recognized_cogs'=>0,'recognition_policy'=>'on_payment'));
|
||||
$this->CI->auditservice->record('sales','invoice',$i->id,'post',$i,array('journal_id'=>null,'purpose'=>'Tabungan; jurnal dibentuk saat pembayaran'),$user);return$i->id;
|
||||
}
|
||||
if($family==='sales'){
|
||||
$initialJournals=array();$journalizedLines=0;foreach($lines as$l){if((float)$l->subtotal<=0&&(float)$l->total_hpp_barang<=0){$journalizedLines++;continue;}$lineJournal=$this->initialLineJournal($l->id);if($lineJournal&&!$lineJournal->is_reversed&&$lineJournal->status==='posted'){$initialJournals[]=$lineJournal;$journalizedLines++;}}
|
||||
if($hasSales&&!$hasLoan){
|
||||
$initialJournals=array();$journalizedLines=0;foreach($lines as$l){if($l->line_type==='savings'||((float)$l->subtotal<=0&&(float)$l->total_hpp_barang<=0)){$journalizedLines++;continue;}$lineJournal=$this->initialLineJournal($l->id);if($lineJournal&&!$lineJournal->is_reversed&&$lineJournal->status==='posted'){$initialJournals[]=$lineJournal;$journalizedLines++;}}
|
||||
if($journalizedLines===count($lines)&&$initialJournals){
|
||||
foreach($lines as$l){$revenueAmount+=(float)$l->net_amount;$cogs+=(float)$l->total_hpp_barang;}
|
||||
foreach($lines as$l)if(in_array($l->line_type,array('inventory','service'),true)){$revenueAmount+=(float)$l->net_amount;$cogs+=(float)$l->total_hpp_barang;}
|
||||
$journal=(int)$initialJournals[0]->id;$this->CI->db->where('id',$i->id)->update('invoices',array('workflow_status'=>'posted','posted'=>1,'posted_by'=>$user,'posted_at'=>date('Y-m-d H:i:s'),'journal_id'=>$journal,'status'=>'unpaid','sisa_piutang'=>$i->total,'recognized_revenue'=>0,'recognized_cogs'=>0,'recognition_policy'=>'on_payment'));
|
||||
$this->CI->load->library('TaxService');$this->CI->taxservice->invoice($i->id,$journal);$this->CI->auditservice->record('sales','invoice',$i->id,'post',$i,array('journal_id'=>$journal,'purpose'=>'Pendapatan diakui proporsional saat pembayaran','line_journal_count'=>count($initialJournals)),$user);return$i->id;
|
||||
}
|
||||
}
|
||||
if($hasSales&&$hasSavings&&!$hasLoan){
|
||||
$legacyEntries=array();$legacyReceivable=0;$legacyDeferred=0;$legacyTax=0;foreach($lines as$l){if(!in_array($l->line_type,array('inventory','service'),true))continue;$lineJournal=$this->initialLineJournal($l->id);if($lineJournal&&!$lineJournal->is_reversed&&$lineJournal->status==='posted')continue;$legacyReceivable+=(float)$l->subtotal;$legacyDeferred+=(float)$l->net_amount;$legacyTax+=(float)$l->tax_amount;}
|
||||
if($legacyReceivable<=0)throw new BusinessException('Komposisi jurnal invoice campuran tidak valid.');$legacyEntries[]=array('account_id'=>$this->CI->accountmappingservice->get('accounts_receivable'),'debit'=>$legacyReceivable,'kredit'=>0);if($legacyDeferred>0)$legacyEntries[]=array('account_id'=>$this->CI->accountmappingservice->get('deferred_revenue'),'debit'=>0,'kredit'=>$legacyDeferred);if($legacyTax>0)$legacyEntries[]=array('account_id'=>$this->CI->accountmappingservice->get('sales_tax_payable'),'debit'=>0,'kredit'=>$legacyTax);
|
||||
$legacyCustomer=$this->CI->db->select('nama')->get_where('customers',array('id'=>$i->customer_id,'company_id'=>$this->company()))->row();$description='Pencatatan komponen penjualan Invoice '.$i->no_invoice.' kepada '.($legacyCustomer?$legacyCustomer->nama:'Customer #'.$i->customer_id).' sebesar Rp '.number_format($legacyReceivable,2,',','.').'; komponen Tabungan dicatat saat pembayaran';$journal=$this->CI->postingservice->post(array('tanggal'=>$i->tanggal,'no_ref'=>$this->CI->numberingservice->next('invoice_journal',$i->tanggal),'keterangan'=>$description,'natural_description'=>true,'ref_type'=>'invoice','ref_id'=>$i->id,'created_by'=>$user),$legacyEntries,false,true);$this->CI->db->where('id',$i->id)->update('invoices',array('workflow_status'=>'posted','posted'=>1,'posted_by'=>$user,'posted_at'=>date('Y-m-d H:i:s'),'journal_id'=>$journal,'status'=>'unpaid','sisa_piutang'=>$i->total,'recognized_revenue'=>0,'recognized_cogs'=>0,'recognition_policy'=>'on_payment'));
|
||||
$this->CI->load->library('TaxService');$this->CI->taxservice->invoice($i->id,$journal);$this->CI->auditservice->record('sales','invoice',$i->id,'post',$i,array('journal_id'=>$journal,'purpose'=>'Invoice campuran Barang/Jasa dan Tabungan'),$user);return$i->id;
|
||||
}
|
||||
if($family==='financial'){
|
||||
$debits=array();$credits=array();foreach($lines as$l){$value=(float)$l->subtotal;if($l->line_type==='loan'){$debits[(int)$l->account_id]=($debits[(int)$l->account_id]??0)+$value;$credits[(int)$l->counter_account_id]=($credits[(int)$l->counter_account_id]??0)+$value;}else{$ar=$this->CI->accountmappingservice->get('accounts_receivable');$debits[$ar]=($debits[$ar]??0)+$value;$credits[(int)$l->account_id]=($credits[(int)$l->account_id]??0)+$value;}}
|
||||
foreach($debits as$a=>$v)if($v>0)$entries[]=array('account_id'=>$a,'debit'=>$v,'kredit'=>0);foreach($credits as$a=>$v)if($v>0)$entries[]=array('account_id'=>$a,'debit'=>0,'kredit'=>$v);
|
||||
@@ -413,8 +420,8 @@ class SalesService
|
||||
if($i->recognition_policy==='accrual'&&$revenueAmount>0){$entries[]=array('account_id'=>$deferred,'debit'=>$revenueAmount,'kredit'=>0);foreach($revenueCredits as$a=>$v)if($v>0)$entries[]=array('account_id'=>$a,'debit'=>0,'kredit'=>$v);}
|
||||
if($i->recognition_policy==='accrual'&&$cogs>0){$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('cost_of_goods_sold'),'debit'=>$cogs,'kredit'=>0);$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('inventory_in_sales'),'debit'=>0,'kredit'=>$cogs);}
|
||||
}
|
||||
$customer=$this->CI->db->select('nama')->get_where('customers',array('id'=>$i->customer_id,'company_id'=>$this->company()))->row();$purpose=$family==='financial'?($lines[0]->line_type==='loan'?'Tagihan Pinjaman':'Tagihan Tabungan'):($i->recognition_policy==='accrual'?'Pendapatan diakui saat posting':'Pendapatan diakui proporsional setelah pembayaran');$journalDescription='[AUTO] Posting Invoice '.$i->no_invoice.' | Customer '.($customer?$customer->nama:'#'.$i->customer_id).' | Tujuan '.$purpose.' | Total Rp '.number_format($i->total,2,',','.').' | Referensi invoice #'.$i->id;
|
||||
$journal=$this->CI->postingservice->post(array('tanggal'=>$i->tanggal,'no_ref'=>$this->CI->numberingservice->next('invoice_journal',$i->tanggal),'keterangan'=>$journalDescription,'ref_type'=>'invoice','ref_id'=>$i->id,'created_by'=>$user),$entries,false,true);
|
||||
$customer=$this->CI->db->select('nama')->get_where('customers',array('id'=>$i->customer_id,'company_id'=>$this->company()))->row();$purpose=$family==='financial'?($lines[0]->line_type==='loan'?'tagihan pinjaman':'tagihan Tabungan'):($i->recognition_policy==='accrual'?'pendapatan yang diakui saat posting':'pendapatan yang diakui setelah pembayaran');$journalDescription='Pencatatan Invoice '.$i->no_invoice.' kepada '.($customer?$customer->nama:'Customer #'.$i->customer_id).' sebesar Rp '.number_format($i->total,2,',','.').' sebagai '.$purpose;
|
||||
$journal=$this->CI->postingservice->post(array('tanggal'=>$i->tanggal,'no_ref'=>$this->CI->numberingservice->next('invoice_journal',$i->tanggal),'keterangan'=>$journalDescription,'natural_description'=>true,'ref_type'=>'invoice','ref_id'=>$i->id,'created_by'=>$user),$entries,false,true);
|
||||
if($family==='financial'&&$lines[0]->line_type==='loan')foreach($credits as$accountId=>$value)$this->recordCashSubledger($accountId,$i->tanggal,'out',$value,'customer',$i->customer_id,'invoice_loan',$i->id,$journal,$journalDescription,$user);
|
||||
if($family==='sales'&&$i->recognition_policy==='accrual'){$this->CI->db->insert('revenue_recognition_ledger',array('company_id'=>$this->company(),'invoice_id'=>$i->id,'recognition_date'=>$i->tanggal,'revenue_amount'=>$revenueAmount,'cogs_amount'=>$cogs,'journal_id'=>$journal,'idempotency_key'=>'INVOICE-ACCRUAL-'.$i->id,'created_by'=>$user,'created_at'=>date('Y-m-d H:i:s')));}
|
||||
$this->CI->db->where('id',$i->id)->update('invoices',array('workflow_status'=>'posted','posted'=>1,'posted_by'=>$user,'posted_at'=>date('Y-m-d H:i:s'),'journal_id'=>$journal,'status'=>'unpaid','sisa_piutang'=>$i->total,'recognized_revenue'=>$family==='sales'&&$i->recognition_policy==='accrual'?$revenueAmount:0,'recognized_cogs'=>$family==='sales'&&$i->recognition_policy==='accrual'?$cogs:0));if($family==='sales'){$this->CI->load->library('TaxService');$this->CI->taxservice->invoice($i->id,$journal);}$this->CI->auditservice->record('sales','invoice',$i->id,'post',$i,array('journal_id'=>$journal,'purpose'=>$purpose),$user);return$i->id;
|
||||
@@ -443,13 +450,13 @@ class SalesService
|
||||
}
|
||||
if($allocated>$sourceTotal+.001)throw new BusinessException('Total alokasi invoice melebihi sumber pembayaran.');
|
||||
$advance=round($sourceTotal-$allocated,2);if($advance>.001&&!$allowAdvance)throw new BusinessException('Terdapat kelebihan pembayaran. Aktifkan pencatatan uang muka pelanggan.');
|
||||
$settlementCredits=array();foreach($locked as$row)foreach($this->paymentReceivableDistribution($row[0],$row[1])as$accountId=>$value)$settlementCredits[$accountId]=($settlementCredits[$accountId]??0)+$value;foreach($sourceRows as$s)if(isset($settlementCredits[$s['account_id']]))throw new BusinessException('Akun penerimaan/pelunasan tidak boleh sama dengan akun piutang yang sedang dilunasi.');foreach($settlementCredits as$accountId=>$value)if($value>0)$entries[]=array('account_id'=>$accountId,'debit'=>0,'kredit'=>$value);
|
||||
$settlementCredits=array();$allocationDistributions=array();foreach($locked as$row){$distribution=$this->paymentReceivableDistribution($row[0],$row[1]);$allocationDistributions[(int)$row[0]->id]=$distribution;foreach($distribution as$accountId=>$value)$settlementCredits[$accountId]=($settlementCredits[$accountId]??0)+$value;}foreach($sourceRows as$s)if(isset($settlementCredits[$s['account_id']]))throw new BusinessException('Akun penerimaan/pelunasan tidak boleh sama dengan akun piutang atau simpanan yang sedang diproses.');foreach($settlementCredits as$accountId=>$value)if($value>0)$entries[]=array('account_id'=>$accountId,'debit'=>0,'kredit'=>$value);
|
||||
if($advance>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('customer_advances'),'debit'=>0,'kredit'=>$advance);
|
||||
$paymentNo=$this->CI->numberingservice->next('payment',$date);
|
||||
$invoiceNames=array_map(function($x){return$x[0]->no_invoice.' Rp '.number_format($x[1],2,',','.');},$locked);
|
||||
$savingsPayment=!empty($locked);foreach($locked as$row){$firstLine=$this->CI->db->select('line_type')->where(array('invoice_id'=>$row[0]->id,'company_id'=>$this->company()))->order_by('id')->limit(1)->get('invoice_details')->row();if(!$firstLine||$firstLine->line_type!=='savings'){$savingsPayment=false;break;}}
|
||||
$paymentDescription=$savingsPayment?"Tabungan '".$customer->nama."' - '".(trim((string)$notes)?:'-')."'":'[AUTO] Penerimaan '.$paymentNo.' | Customer '.$customer->nama.' | Alokasi '.implode(', ',$invoiceNames).' | Referensi '.($reference?:'-').' | Total Rp '.number_format($sourceTotal,2,',','.');
|
||||
$journal=$this->CI->postingservice->post(array('tanggal'=>$date,'no_ref'=>$paymentNo,'keterangan'=>$paymentDescription,'ref_type'=>'customer_payment','ref_id'=>null,'created_by'=>$user),$entries,false,false);
|
||||
if($savingsPayment){$paymentDescription='Tabungan '.$customer->nama;if(trim((string)$notes)!=='')$paymentDescription.=" - '".trim((string)$notes)."'";}else{$allocationText=$invoiceNames?' untuk '.implode(', ',$invoiceNames):' sebagai uang muka pelanggan';$paymentDescription='Penerimaan pembayaran '.$paymentNo.' dari '.$customer->nama.$allocationText.' dengan total Rp '.number_format($sourceTotal,2,',','.');if(trim((string)$reference)!=='')$paymentDescription.=' - Referensi: '.trim((string)$reference);if(trim((string)$notes)!=='')$paymentDescription.=' - '.trim((string)$notes);}
|
||||
$journal=$this->CI->postingservice->post(array('tanggal'=>$date,'no_ref'=>$paymentNo,'keterangan'=>$paymentDescription,'natural_description'=>true,'ref_type'=>'customer_payment','ref_id'=>null,'created_by'=>$user),$entries,false,false);
|
||||
$payment=$this->columns('payments',array('company_id'=>$this->company(),'invoice_id'=>count($locked)===1?$locked[0][0]->id:null,'tanggal'=>$date,'jumlah'=>$sourceTotal,'journal_id'=>$journal,'metode'=>count($sourceRows)>1?'multi_account':'manual','payment_no'=>$paymentNo,'customer_id'=>$customer->id,'status'=>'posted','reference_no'=>$reference,'notes'=>$notes,'created_by'=>$user,'created_at'=>date('Y-m-d H:i:s')));
|
||||
$this->CI->db->insert('payments',$payment);$paymentId=(int)$this->CI->db->insert_id();
|
||||
foreach($sourceRows as$s){$this->CI->db->insert('payment_sources',array('company_id'=>$this->company(),'payment_id'=>$paymentId,'account_id'=>$s['account_id'],'amount'=>$s['amount'],'created_at'=>date('Y-m-d H:i:s')));$this->recordCashSubledger($s['account_id'],$date,'in',$s['amount'],'customer',$customer->id,'customer_payment',$paymentId,$journal,'Penerimaan '.$paymentNo.' dari '.$customer->nama,$user);}
|
||||
@@ -457,7 +464,7 @@ class SalesService
|
||||
list($invoice,$amount)=$row;$this->CI->db->insert('payment_allocations',$this->columns('payment_allocations',array('company_id'=>$this->company(),'payment_id'=>$paymentId,'invoice_id'=>$invoice->id,'amount'=>$amount,'created_at'=>date('Y-m-d H:i:s'))));
|
||||
$paid=round((float)$invoice->total_bayar+$amount,2);$balance=max(0,round((float)$invoice->sisa_piutang-$amount,2));
|
||||
$this->CI->db->where(array('id'=>$invoice->id,'company_id'=>$this->company()))->update('invoices',array('total_bayar'=>$paid,'sisa_piutang'=>$balance,'status'=>$balance<=.001?'paid':'partial'));
|
||||
if($this->invoiceFamily($invoice->id)==='sales')$this->recognizeOnPayment($invoice,$paymentId,$amount,$date,$user);
|
||||
$receivableAccount=$this->CI->accountmappingservice->get('accounts_receivable');$salesPayment=(float)($allocationDistributions[(int)$invoice->id][$receivableAccount]??0);if($salesPayment>0)$this->recognizeOnPayment($invoice,$paymentId,$salesPayment,$date,$user);
|
||||
}
|
||||
if($advance>0)$this->CI->db->insert('customer_advances',$this->columns('customer_advances',array('company_id'=>$this->company(),'advance_no'=>'ADV-'.$paymentNo,'customer_id'=>$customer->id,'payment_id'=>$paymentId,'original_amount'=>$advance,'available_amount'=>$advance,'status'=>'available','journal_id'=>$journal,'created_at'=>date('Y-m-d H:i:s'))));
|
||||
foreach($attachments as$a)$this->insertAttachment('customer_payment',$paymentId,$a,$user);
|
||||
@@ -491,14 +498,15 @@ class SalesService
|
||||
|
||||
private function recognizeOnPayment($invoice,$paymentId,$allocated,$date,$user)
|
||||
{
|
||||
$netTotal=max(.01,(float)$invoice->subtotal_before_tax);$gross=max(.01,(float)$invoice->total);
|
||||
$lines=$this->CI->db->where(array('invoice_id'=>$invoice->id,'company_id'=>$this->company()))->where_in('line_type',array('inventory','service'))->order_by('id')->get('invoice_details')->result();if(!$lines)return;
|
||||
$netTotal=0;$gross=0;foreach($lines as$l){$netTotal+=(float)$l->net_amount;$gross+=(float)$l->subtotal;}$netTotal=max(.01,$netTotal);$gross=max(.01,$gross);
|
||||
$remainingRevenue=max(0,$netTotal-(float)$invoice->recognized_revenue);$revenue=min($remainingRevenue,round($allocated*($netTotal/$gross),2));
|
||||
$lines=$this->CI->db->where(array('invoice_id'=>$invoice->id,'company_id'=>$this->company()))->get('invoice_details')->result();
|
||||
$allCost=0;foreach($lines as$l)$allCost+=(float)$l->total_hpp_barang;$remainingCost=max(0,$allCost-(float)$invoice->recognized_cogs);$cost=min($remainingCost,round($allocated*($allCost/$gross),2));
|
||||
if($revenue<=0&&$cost<=0)return;
|
||||
$entries=array();if($revenue>0){$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('deferred_revenue'),'debit'=>$revenue,'kredit'=>0);$left=$revenue;foreach($lines as$idx=>$l){$part=$idx===count($lines)-1?$left:round($revenue*((float)$l->net_amount/$netTotal),2);$left-=$part;if($part>0)$entries[]=array('account_id'=>$l->account_id,'debit'=>0,'kredit'=>$part);}}
|
||||
if($cost>0){$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('cost_of_goods_sold'),'debit'=>$cost,'kredit'=>0);$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('inventory_in_sales'),'debit'=>0,'kredit'=>$cost);}
|
||||
$journal=$this->CI->postingservice->post(array('tanggal'=>$date,'no_ref'=>$this->CI->numberingservice->next('revenue_recognition',$date),'keterangan'=>'[AUTO] Pengakuan pendapatan setelah pembayaran | Invoice '.$invoice->no_invoice.' | Pembayaran #'.$paymentId.' | Pendapatan Rp '.number_format($revenue,2,',','.').' | HPP Rp '.number_format($cost,2,',','.'),'ref_type'=>'revenue_recognition','ref_id'=>$paymentId,'created_by'=>$user),$entries,false,false);
|
||||
$recognitionDescription='Pengakuan pendapatan Invoice '.$invoice->no_invoice.' setelah pembayaran sebesar Rp '.number_format($revenue,2,',','.');if($cost>0)$recognitionDescription.=' dengan harga pokok Rp '.number_format($cost,2,',','.');
|
||||
$journal=$this->CI->postingservice->post(array('tanggal'=>$date,'no_ref'=>$this->CI->numberingservice->next('revenue_recognition',$date),'keterangan'=>$recognitionDescription,'natural_description'=>true,'ref_type'=>'revenue_recognition','ref_id'=>$paymentId,'created_by'=>$user),$entries,false,false);
|
||||
$this->CI->db->insert('revenue_recognition_ledger',array('company_id'=>$this->company(),'invoice_id'=>$invoice->id,'payment_id'=>$paymentId,'recognition_date'=>$date,'revenue_amount'=>$revenue,'cogs_amount'=>$cost,'journal_id'=>$journal,'idempotency_key'=>'PAYMENT-RECOGNITION-'.$paymentId.'-'.$invoice->id,'created_by'=>$user,'created_at'=>date('Y-m-d H:i:s')));
|
||||
$this->CI->db->where(array('id'=>$invoice->id,'company_id'=>$this->company()))->set('recognized_revenue','recognized_revenue+'.(float)$revenue,false)->set('recognized_cogs','recognized_cogs+'.(float)$cost,false)->update('invoices');
|
||||
}
|
||||
@@ -510,6 +518,15 @@ class SalesService
|
||||
$payments=$this->CI->db->select('p.*,pa.amount allocated')->from('payment_allocations pa')->join('payments p','p.id=pa.payment_id')->where('pa.invoice_id',$invoice->id)->order_by('p.tanggal,p.id')->get()->result();foreach($payments as$p)$p->attachments=$this->attachments(array('customer_payment'),$p->id);
|
||||
return array('invoice'=>$invoice,'lines'=>$lines,'barcodes'=>$barcodes,'deliveries'=>$this->CI->db->where(array('invoice_id'=>$invoice->id,'company_id'=>$this->company()))->get('sales_deliveries')->result(),'payments'=>$payments,'returns'=>$this->CI->db->where(array('invoice_id'=>$invoice->id,'company_id'=>$this->company()))->get('sales_returns')->result(),'attachments'=>$this->attachments(array('invoice'),$invoice->id));
|
||||
}
|
||||
public function previousOutstandingInvoices($invoiceId)
|
||||
{
|
||||
$invoice=$this->invoiceForEditor($invoiceId);
|
||||
return $this->CI->db->select('id,no_invoice,tanggal,jatuh_tempo,total,total_bayar,sisa_piutang,status')
|
||||
->from('invoices')->where(array('company_id'=>$this->company(),'customer_id'=>$invoice->customer_id,'workflow_status'=>'posted'))
|
||||
->where('deleted_at IS NULL',null,false)->where('sisa_piutang >',0.001)->where('id !=',$invoice->id)
|
||||
->group_start()->where('tanggal <',$invoice->tanggal)->or_group_start()->where('tanggal',$invoice->tanggal)->where('id <',$invoice->id)->group_end()->group_end()
|
||||
->order_by('tanggal','ASC')->order_by('id','ASC')->get()->result();
|
||||
}
|
||||
public function deliveryDetail($id)
|
||||
{
|
||||
$delivery=$this->CI->db->select('d.*,c.nama customer_name,c.alamat customer_address,i.no_invoice,w.nama warehouse_name,u.nama creator_name')->from('sales_deliveries d')->join('customers c','c.id=d.customer_id')->join('invoices i','i.id=d.invoice_id','left')->join('warehouses w','w.id=d.warehouse_id','left')->join('users u','u.id=d.created_by','left')->where(array('d.id'=>(int)$id,'d.company_id'=>$this->company()))->get()->row();if(!$delivery)throw new BusinessException('Surat Jalan tidak ditemukan.');
|
||||
@@ -536,7 +553,7 @@ class SalesService
|
||||
return$this->CI->transactionservice->run(function()use($id,$user){$r=$this->lockReturn($id,'received');$this->CI->fiscalperiodservice->assertOpen($r->return_date);$lines=$this->CI->db->where(array('sales_return_id'=>$r->id,'company_id'=>$this->company()))->get('sales_return_lines')->result();$net=0;$tax=0;$cost=0;
|
||||
foreach($lines as$l){$bars=$this->CI->db->where('sales_return_line_id',$l->id)->get('sales_return_barcodes')->result();foreach($bars as$b){$source=$this->CI->db->query('SELECT * FROM sales_delivery_barcodes WHERE id=? FOR UPDATE',array($b->sales_delivery_barcode_id))->row();if(!$source||(float)$source->returned_qty+(float)$b->qty>(float)$source->qty+.0001)throw new BusinessException('Barcode retur sudah diproses atau qty tidak valid.');$barcode=$this->CI->db->query('SELECT * FROM item_barcodes WHERE id=? FOR UPDATE',array($b->barcode_id))->row();$status=$l->physical_condition==='saleable'?'available':($l->physical_condition==='damaged'?'damaged':'quarantine');$this->CI->db->where('id',$barcode->id)->update('item_barcodes',array('qty_sisa'=>(float)$barcode->qty_sisa+(float)$b->qty,'status'=>$status,'version'=>(int)$barcode->version+1));$this->CI->db->where('id',$source->id)->update('sales_delivery_barcodes',array('returned_qty'=>(float)$source->returned_qty+(float)$b->qty,'status'=>(float)$source->returned_qty+(float)$b->qty>=(float)$source->qty?'returned':'partially_returned'));$this->CI->db->where('id',$b->id)->update('sales_return_barcodes',array('status'=>'posted'));}
|
||||
$value=round((float)$l->unit_cost*(float)$l->qty,2);$key='SALES-RETURN-LINE-'.$l->id;$warehouse=$this->CI->db->select('warehouse_id')->get_where('sales_deliveries',array('id'=>$r->sales_delivery_id))->row()->warehouse_id;$ledger=$this->addCompany('inventory_ledger',array('item_id'=>$l->item_id,'warehouse_id'=>$warehouse,'movement_date'=>$r->return_date,'direction'=>'in','qty'=>$l->qty,'unit_cost'=>$l->unit_cost,'value'=>$value,'document_type'=>'sales_return','document_id'=>$r->id,'document_line_id'=>$l->id,'idempotency_key'=>$key,'created_at'=>date('Y-m-d H:i:s')));$this->CI->db->insert('inventory_ledger',$ledger);if($l->physical_condition==='saleable')$this->CI->db->insert('inventory_cost_layers',$this->columns('inventory_cost_layers',array('company_id'=>$this->company(),'item_id'=>$l->item_id,'warehouse_id'=>$warehouse,'source_ledger_id'=>$this->CI->db->insert_id(),'received_date'=>$r->return_date,'original_qty'=>$l->qty,'remaining_qty'=>$l->qty,'unit_cost'=>$l->unit_cost,'status'=>'open')));$this->CI->db->insert('stock_logs',$this->addCompany('stock_logs',array('item_id'=>$l->item_id,'warehouse_id'=>$warehouse,'qty'=>$l->qty,'tipe'=>'masuk','unit_cost'=>$l->unit_cost,'keterangan'=>'[AUTO] Retur Penjualan '.$r->return_no.' | Kondisi '.$l->physical_condition,'ref_type'=>'sales_return','ref_id'=>$l->id,'idempotency_key'=>$key)));$this->CI->db->insert('item_movements',$this->addCompany('item_movements',array('item_id'=>$l->item_id,'qty'=>$l->qty,'from_type'=>'customer','from_id'=>$r->customer_id,'to_type'=>$l->physical_condition==='saleable'?'warehouse':'quarantine','to_id'=>$warehouse,'movement_type'=>'customer_return','reference_type'=>'sales_return','reference_id'=>$l->id,'notes'=>'[AUTO] Retur '.$r->return_no,'created_at'=>date('Y-m-d H:i:s'))));$this->CI->salesInventoryModel->synchronizeStock($l->item_id);$net+=(float)$l->net_amount;$tax+=(float)$l->tax_amount;$cost+=$value;$this->CI->db->where('id',$l->id)->update('sales_return_lines',array('posted_at'=>date('Y-m-d H:i:s')));}
|
||||
$invoice=$this->lockInvoice($r->invoice_id);$credit=min((float)$invoice->sisa_piutang,$net+$tax);$excess=max(0,$net+$tax-$credit);$entries=array();$revenueRatio=$invoice->recognition_policy==='accrual'?1:min(1,(float)$invoice->recognized_revenue/max(.01,(float)$invoice->subtotal_before_tax));$recognizedNet=round($net*$revenueRatio,2);$deferredNet=$net-$recognizedNet;if($recognizedNet>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('goods_revenue'),'debit'=>$recognizedNet,'kredit'=>0);if($deferredNet>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('deferred_revenue'),'debit'=>$deferredNet,'kredit'=>0);if($tax>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('sales_tax_payable'),'debit'=>$tax,'kredit'=>0);if($credit>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('accounts_receivable'),'debit'=>0,'kredit'=>$credit);if($excess>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('customer_advances'),'debit'=>0,'kredit'=>$excess);if($cost>0){$allInvoiceCost=(float)$this->CI->db->select('COALESCE(SUM(total_hpp_barang),0) v',false)->get_where('invoice_details',array('invoice_id'=>$invoice->id,'company_id'=>$this->company()))->row()->v;$costRatio=$invoice->recognition_policy==='accrual'?1:min(1,(float)$invoice->recognized_cogs/max(.01,$allInvoiceCost));$recognizedCost=round($cost*$costRatio,2);$deferredCost=$cost-$recognizedCost;$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('inventory'),'debit'=>$cost,'kredit'=>0);if($recognizedCost>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('cost_of_goods_sold'),'debit'=>0,'kredit'=>$recognizedCost);if($deferredCost>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('inventory_in_sales'),'debit'=>0,'kredit'=>$deferredCost);}$journal=$this->CI->postingservice->post(array('tanggal'=>$r->return_date,'no_ref'=>$r->return_no,'keterangan'=>'[AUTO] Retur Penjualan '.$r->return_no.' | Invoice '.$invoice->no_invoice.' | Customer #'.$r->customer_id.' | Nilai Rp '.number_format($net+$tax,2,',','.'),'ref_type'=>'sales_return','ref_id'=>$r->id,'created_by'=>$user),$entries,false,true);
|
||||
$invoice=$this->lockInvoice($r->invoice_id);$credit=min((float)$invoice->sisa_piutang,$net+$tax);$excess=max(0,$net+$tax-$credit);$entries=array();$revenueRatio=$invoice->recognition_policy==='accrual'?1:min(1,(float)$invoice->recognized_revenue/max(.01,(float)$invoice->subtotal_before_tax));$recognizedNet=round($net*$revenueRatio,2);$deferredNet=$net-$recognizedNet;if($recognizedNet>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('goods_revenue'),'debit'=>$recognizedNet,'kredit'=>0);if($deferredNet>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('deferred_revenue'),'debit'=>$deferredNet,'kredit'=>0);if($tax>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('sales_tax_payable'),'debit'=>$tax,'kredit'=>0);if($credit>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('accounts_receivable'),'debit'=>0,'kredit'=>$credit);if($excess>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('customer_advances'),'debit'=>0,'kredit'=>$excess);if($cost>0){$allInvoiceCost=(float)$this->CI->db->select('COALESCE(SUM(total_hpp_barang),0) v',false)->get_where('invoice_details',array('invoice_id'=>$invoice->id,'company_id'=>$this->company()))->row()->v;$costRatio=$invoice->recognition_policy==='accrual'?1:min(1,(float)$invoice->recognized_cogs/max(.01,$allInvoiceCost));$recognizedCost=round($cost*$costRatio,2);$deferredCost=$cost-$recognizedCost;$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('inventory'),'debit'=>$cost,'kredit'=>0);if($recognizedCost>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('cost_of_goods_sold'),'debit'=>0,'kredit'=>$recognizedCost);if($deferredCost>0)$entries[]=array('account_id'=>$this->CI->accountmappingservice->get('inventory_in_sales'),'debit'=>0,'kredit'=>$deferredCost);}$returnCustomer=$this->CI->db->select('nama')->get_where('customers',array('id'=>$r->customer_id,'company_id'=>$this->company()))->row();$returnDescription='Retur penjualan '.$r->return_no.' atas Invoice '.$invoice->no_invoice.' dari '.($returnCustomer?$returnCustomer->nama:'Customer #'.$r->customer_id).' sebesar Rp '.number_format($net+$tax,2,',','.');if(trim((string)$r->reason)!=='')$returnDescription.=' karena '.trim((string)$r->reason);$journal=$this->CI->postingservice->post(array('tanggal'=>$r->return_date,'no_ref'=>$r->return_no,'keterangan'=>$returnDescription,'natural_description'=>true,'ref_type'=>'sales_return','ref_id'=>$r->id,'created_by'=>$user),$entries,false,true);
|
||||
$balance=max(0,(float)$invoice->sisa_piutang-$credit);$this->CI->db->where('id',$invoice->id)->update('invoices',array('sisa_piutang'=>$balance,'status'=>$balance<=.001?'paid':'partial'));$this->CI->db->insert('credit_notes',$this->columns('credit_notes',array('company_id'=>$this->company(),'credit_note_no'=>'CN-'.$r->return_no,'invoice_id'=>$invoice->id,'customer_id'=>$r->customer_id,'credit_date'=>$r->return_date,'amount'=>$net+$tax,'reason'=>$r->reason,'status'=>'posted','journal_id'=>$journal,'created_by'=>$user,'created_at'=>date('Y-m-d H:i:s'))));$creditId=(int)$this->CI->db->insert_id();if($excess>0)$this->CI->db->insert('customer_advances',$this->columns('customer_advances',array('company_id'=>$this->company(),'advance_no'=>'ADV-'.$r->return_no,'customer_id'=>$r->customer_id,'payment_id'=>null,'original_amount'=>$excess,'available_amount'=>$excess,'status'=>'available','journal_id'=>$journal,'created_at'=>date('Y-m-d H:i:s'))));$this->CI->db->where('id',$r->id)->update('sales_returns',array('status'=>'completed','credit_note_id'=>$creditId,'journal_id'=>$journal,'posted_by'=>$user,'posted_at'=>date('Y-m-d H:i:s')));$this->returnHistory($r->id,'received','completed','Stok dan credit note diposting.',$user);return$r->id;});
|
||||
}
|
||||
public function returnDetail($id){$r=$this->CI->db->select('r.*,c.nama customer_name,i.no_invoice,d.delivery_no')->from('sales_returns r')->join('customers c','c.id=r.customer_id')->join('invoices i','i.id=r.invoice_id','left')->join('sales_deliveries d','d.id=r.sales_delivery_id','left')->where(array('r.id'=>(int)$id,'r.company_id'=>$this->company()))->get()->row();if(!$r)throw new BusinessException('Retur tidak ditemukan.');return array('return'=>$r,'lines'=>$this->CI->db->select('l.*,it.kode_detail AS kode_barang,it.nama_barang')->from('sales_return_lines l')->join('items it','it.id=l.item_id')->where('l.sales_return_id',$r->id)->get()->result(),'barcodes'=>$this->CI->db->select('b.*,ib.barcode,ib.serial_number')->from('sales_return_barcodes b')->join('item_barcodes ib','ib.id=b.barcode_id')->where('b.sales_return_id',$r->id)->get()->result(),'history'=>$this->CI->db->select('h.*,u.nama user_name')->from('sales_return_history h')->join('users u','u.id=h.user_id','left')->where('h.sales_return_id',$r->id)->order_by('h.id')->get()->result(),'attachments'=>$this->attachments(array('sales_return'),$r->id));}
|
||||
|
||||
Reference in New Issue
Block a user