hr dan payroll
This commit is contained in:
@@ -7,14 +7,61 @@ class ProfessionalReportService
|
||||
private function filters(array$f){return array(' j.company_id=? AND j.status IN(\'posted\',\'reversed\') AND j.tanggal BETWEEN ? AND ?',array($this->CI->companycontext->id(),$f['from'],$f['to']));}
|
||||
public function trialBalance(array$f){list($w,$b)=$this->filters($f);return$this->CI->db->query("SELECT a.id account_id,a.kode_akun,a.nama_akun,a.tipe,COALESCE(SUM(d.debit),0) debit,COALESCE(SUM(d.kredit),0) credit,COALESCE(SUM(d.debit-d.kredit),0) balance FROM accounts a LEFT JOIN journal_details d ON d.account_id=a.id LEFT JOIN journals j ON j.id=d.journal_id AND j.company_id=a.company_id WHERE a.company_id=? AND (j.id IS NULL OR ($w)) GROUP BY a.id ORDER BY a.priority ASC,a.kode_akun ASC,a.id ASC",array_merge(array($this->CI->companycontext->id()),$b))->result_array();}
|
||||
public function statement($type,array$f,$priorityOrder=true){list($w,$b)=$this->filters($f);$types=$type==='profit_loss'?array('revenue','expense'):array('asset','liability','equity');$marks=implode(',',array_fill(0,count($types),'?'));$company=$this->CI->companycontext->id();$order=$priorityOrder?'a.priority ASC,a.kode_akun ASC,a.id ASC':'a.kode_akun ASC';$sql="SELECT a.id account_id,a.kode_akun,a.nama_akun,a.tipe,COALESCE(x.amount,0) amount FROM accounts a LEFT JOIN (SELECT d.account_id,SUM(IF(ac.tipe IN('asset','expense'),d.debit-d.kredit,d.kredit-d.debit)) amount FROM journal_details d JOIN journals j ON j.id=d.journal_id JOIN accounts ac ON ac.id=d.account_id WHERE $w GROUP BY d.account_id)x ON x.account_id=a.id WHERE a.company_id=? AND a.tipe IN($marks) ORDER BY $order";return$this->CI->db->query($sql,array_merge($b,array($company),$types))->result_array();}
|
||||
public function ledger(array$f){list($w,$b)=$this->filters($f);$sql="SELECT j.id journal_id,j.tanggal,j.no_ref,j.keterangan,j.ref_type,j.ref_id,a.kode_akun,a.nama_akun,d.debit,d.kredit FROM journal_details d JOIN journals j ON j.id=d.journal_id JOIN accounts a ON a.id=d.account_id WHERE $w";if(!empty($f['account_id'])){$sql.=' AND d.account_id=?';$b[]=(int)$f['account_id'];}$sql.=' ORDER BY j.tanggal,j.id,d.id';return$this->CI->db->query($sql,$b)->result_array();}
|
||||
public function cashFlow(array$f){list($w,$b)=$this->filters($f);return$this->CI->db->query("SELECT CASE WHEN j.ref_type IN('invoice','customer_payment','supplier_invoice','supplier_payment','payroll','payroll_payment') THEN 'operating' WHEN j.ref_type LIKE 'asset_%' THEN 'investing' ELSE 'financing_or_other' END section,SUM(IF(a.sub_tipe='kas',d.debit-d.kredit,0)) amount FROM journal_details d JOIN journals j ON j.id=d.journal_id JOIN accounts a ON a.id=d.account_id WHERE $w GROUP BY section",$b)->result_array();}
|
||||
public function ledger(array$f)
|
||||
{
|
||||
list($w,$b)=$this->filters($f);
|
||||
$sql="SELECT d.id detail_id,j.id journal_id,j.tanggal,j.no_ref,j.keterangan,j.ref_type,j.ref_id,a.id account_id,a.kode_akun,a.nama_akun,a.tipe,d.debit,d.kredit FROM journal_details d JOIN journals j ON j.id=d.journal_id JOIN accounts a ON a.id=d.account_id WHERE $w";
|
||||
if(!empty($f['account_id'])){$sql.=' AND d.account_id=?';$b[]=(int)$f['account_id'];}
|
||||
$sql.=' AND (d.debit<>0 OR d.kredit<>0) ORDER BY a.priority ASC,a.kode_akun ASC,j.tanggal ASC,j.id ASC,d.id ASC';
|
||||
$rows=$this->CI->db->query($sql,$b)->result_array();
|
||||
$opening=$this->ledgerOpening($f);
|
||||
$running=array();
|
||||
foreach($rows as&$row){$id=(int)$row['account_id'];if(!isset($running[$id]))$running[$id]=(float)($opening[$id]??0);$normal=in_array($row['tipe'],array('asset','expense'),true)?1:-1;$row['saldo_awal']=(float)($opening[$id]??0);$running[$id]+=$normal*((float)$row['debit']-(float)$row['kredit']);$row['saldo_berjalan']=round($running[$id],2);}
|
||||
unset($row);return$rows;
|
||||
}
|
||||
public function ledgerSummary(array$f)
|
||||
{
|
||||
$company=(int)$this->CI->companycontext->id();$opening=$this->ledgerOpening($f);
|
||||
$sql="SELECT a.id account_id,a.kode_akun,a.nama_akun,a.tipe,a.priority,COALESCE(SUM(CASE WHEN j.id IS NOT NULL THEN d.debit ELSE 0 END),0) total_debit,COALESCE(SUM(CASE WHEN j.id IS NOT NULL THEN d.kredit ELSE 0 END),0) total_kredit FROM accounts a LEFT JOIN journal_details d ON d.account_id=a.id LEFT JOIN journals j ON j.id=d.journal_id AND j.company_id=? AND j.status IN('posted','reversed') AND j.tanggal BETWEEN ? AND ? WHERE a.company_id=?";
|
||||
$bind=array($company,$f['from'],$f['to'],$company);if(!empty($f['account_id'])){$sql.=' AND a.id=?';$bind[]=(int)$f['account_id'];}$sql.=' GROUP BY a.id ORDER BY a.priority ASC,a.kode_akun ASC';
|
||||
$rows=$this->CI->db->query($sql,$bind)->result_array();$result=array();foreach($rows as$row){$id=(int)$row['account_id'];$row['saldo_awal']=(float)($opening[$id]??0);$normal=in_array($row['tipe'],array('asset','expense'),true)?1:-1;$row['saldo_akhir']=round($row['saldo_awal']+$normal*((float)$row['total_debit']-(float)$row['total_kredit']),2);if(abs($row['saldo_awal'])>.009||abs((float)$row['total_debit'])>.009||abs((float)$row['total_kredit'])>.009)$result[]=$row;}return$result;
|
||||
}
|
||||
private function ledgerOpening(array$f)
|
||||
{
|
||||
$company=(int)$this->CI->companycontext->id();$sql="SELECT d.account_id,a.tipe,SUM(d.debit) debit,SUM(d.kredit) kredit FROM journal_details d JOIN journals j ON j.id=d.journal_id JOIN accounts a ON a.id=d.account_id WHERE j.company_id=? AND j.status IN('posted','reversed') AND j.tanggal<?";$bind=array($company,$f['from']);if(!empty($f['account_id'])){$sql.=' AND d.account_id=?';$bind[]=(int)$f['account_id'];}$sql.=' GROUP BY d.account_id,a.tipe';$out=array();foreach($this->CI->db->query($sql,$bind)->result_array()as$row){$normal=in_array($row['tipe'],array('asset','expense'),true)?1:-1;$out[(int)$row['account_id']]=$normal*((float)$row['debit']-(float)$row['kredit']);}return$out;
|
||||
}
|
||||
public function cashFlow(array$f)
|
||||
{
|
||||
$company=(int)$this->CI->companycontext->id();$cashWhere="(a.sub_tipe='kas' OR EXISTS(SELECT 1 FROM cash_accounts ca WHERE ca.gl_account_id=a.id AND (ca.company_id=? OR ca.company_id IS NULL)))";
|
||||
$opening=$this->cashOpening($f);
|
||||
$sql="SELECT d.id detail_id,j.id journal_id,j.tanggal,j.no_ref,j.keterangan,j.ref_type,j.ref_id,a.kode_akun,a.nama_akun,d.debit kas_masuk,d.kredit kas_keluar FROM journal_details d JOIN journals j ON j.id=d.journal_id JOIN accounts a ON a.id=d.account_id WHERE j.company_id=? AND j.status IN('posted','reversed') AND j.tanggal BETWEEN ? AND ? AND $cashWhere AND (d.debit<>0 OR d.kredit<>0)";$bind=array($company,$f['from'],$f['to'],$company);if(!empty($f['account_id'])){$sql.=' AND a.id=?';$bind[]=(int)$f['account_id'];}$sql.=' ORDER BY j.tanggal,j.id,d.id';$rows=$this->CI->db->query($sql,$bind)->result_array();$running=$opening;
|
||||
foreach($rows as&$row){$row['section']=$this->cashSection((string)$row['ref_type']);$row['aktivitas']=$this->cashSectionLabel($row['section']);$row['akun']=$row['kode_akun'].' - '.$row['nama_akun'];$running+=(float)$row['kas_masuk']-(float)$row['kas_keluar'];$row['saldo_berjalan']=round($running,2);}unset($row);return$rows;
|
||||
}
|
||||
public function cashFlowSummary(array$f,array$rows=null)
|
||||
{
|
||||
if($rows===null)$rows=$this->cashFlow($f);$opening=$this->cashOpening($f);$summary=array('operating'=>0,'investing'=>0,'financing'=>0,'opening_balance'=>$opening,'increase_decrease'=>0,'closing_balance'=>$opening,'cash_in'=>0,'cash_out'=>0);foreach($rows as$row){$net=(float)$row['kas_masuk']-(float)$row['kas_keluar'];$summary[$row['section']]+=$net;$summary['cash_in']+=(float)$row['kas_masuk'];$summary['cash_out']+=(float)$row['kas_keluar'];}$summary['increase_decrease']=$summary['operating']+$summary['investing']+$summary['financing'];$summary['closing_balance']=$opening+$summary['increase_decrease'];return$summary;
|
||||
}
|
||||
private function cashOpening(array$f){$company=(int)$this->CI->companycontext->id();$cashWhere="(a.sub_tipe='kas' OR EXISTS(SELECT 1 FROM cash_accounts ca WHERE ca.gl_account_id=a.id AND (ca.company_id=? OR ca.company_id IS NULL)))";$sql="SELECT COALESCE(SUM(d.debit-d.kredit),0) amount FROM journal_details d JOIN journals j ON j.id=d.journal_id JOIN accounts a ON a.id=d.account_id WHERE j.company_id=? AND j.status IN('posted','reversed') AND j.tanggal<? AND $cashWhere";$bind=array($company,$f['from'],$company);if(!empty($f['account_id'])){$sql.=' AND a.id=?';$bind[]=(int)$f['account_id'];}return(float)$this->CI->db->query($sql,$bind)->row()->amount;}
|
||||
private function cashSection($refType){if(preg_match('/asset|fixed_asset|capitalization|depreciation/i',$refType))return'investing';if(preg_match('/capital|equity|dividend|loan|financing|customer_saving|deposit/i',$refType))return'financing';return'operating';}
|
||||
private function cashSectionLabel($section){return array('operating'=>'Aktivitas Operasi','investing'=>'Aktivitas Investasi','financing'=>'Aktivitas Pendanaan')[$section]??'Aktivitas Operasi';}
|
||||
public function equity(array$f){list($w,$b)=$this->filters($f);return$this->CI->db->query("SELECT a.kode_akun,a.nama_akun,SUM(d.kredit-d.debit) amount FROM journal_details d JOIN journals j ON j.id=d.journal_id JOIN accounts a ON a.id=d.account_id WHERE $w AND a.tipe='equity' GROUP BY a.id ORDER BY a.kode_akun",$b)->result_array();}
|
||||
public function actualBudget(array$f){$this->CI->load->library('BudgetService');$source=$this->CI->budgetservice->accountReport(array('from'=>substr($f['from'],0,7),'to'=>substr($f['to'],0,7),'account_id'=>(int)($f['account_id']??0)));$rows=array();foreach($source as$r)$rows[]=array('kode_akun'=>$r['kode_akun'],'nama_akun'=>$r['nama_akun'],'actual'=>$r['actual'],'budget'=>$r['budget'],'variance'=>$r['actual']-$r['budget']);return$rows;}
|
||||
public function comparative(array$f){$current=$this->statement('profit_loss',$f,false);$pm=array_merge($f,array('from'=>date('Y-m-d',strtotime($f['from'].' -1 month')),'to'=>date('Y-m-d',strtotime($f['to'].' -1 month'))));$py=array_merge($f,array('from'=>date('Y-m-d',strtotime($f['from'].' -1 year')),'to'=>date('Y-m-d',strtotime($f['to'].' -1 year'))));$idx=array();foreach($this->statement('profit_loss',$pm,false)as$r)$idx[$r['account_id']]['previous_month']=$r['amount'];foreach($this->statement('profit_loss',$py,false)as$r)$idx[$r['account_id']]['previous_year']=$r['amount'];foreach($current as&$r){$r['previous_month']=isset($idx[$r['account_id']]['previous_month'])?$idx[$r['account_id']]['previous_month']:0;$r['previous_year']=isset($idx[$r['account_id']]['previous_year'])?$idx[$r['account_id']]['previous_year']:0;$r['variance_month']=$r['amount']-$r['previous_month'];$r['variance_year']=$r['amount']-$r['previous_year'];}return$current;}
|
||||
public function purchaseReturns(array$f){return$this->CI->db->select('r.id record_id,r.return_no,r.return_date,s.supplier_code,s.name supplier,po.po_no,r.problem_category,r.requested_resolution,r.status,r.amount,r.journal_id')->from('purchase_returns r')->join('suppliers s','s.id=r.supplier_id')->join('purchase_orders po','po.id=r.purchase_order_id','left')->where('r.company_id',$this->CI->companycontext->id())->where('r.return_date >=',$f['from'])->where('r.return_date <=',$f['to'])->order_by('r.return_date')->order_by('r.id')->get()->result_array();}
|
||||
public function supplierRefunds(array$f,$outstanding=false){$this->CI->db->select('r.id record_id,r.refund_no,r.claim_date,r.expected_date,s.supplier_code,s.name supplier,po.po_no,si.internal_no invoice_supplier,r.source_type,r.status,r.claim_amount,r.received_amount,r.balance,r.entitlement_journal_id journal_id')->from('supplier_refund_claims r')->join('suppliers s','s.id=r.supplier_id')->join('purchase_orders po','po.id=r.purchase_order_id','left')->join('supplier_invoices si','si.id=r.supplier_invoice_id','left')->where('r.company_id',$this->CI->companycontext->id())->where('r.claim_date >=',$f['from'])->where('r.claim_date <=',$f['to']);if($outstanding)$this->CI->db->where('r.balance >',0)->where_not_in('r.status',array('draft','rejected','cancelled','reversed','reconciled'));return$this->CI->db->order_by('r.claim_date')->order_by('r.id')->get()->result_array();}
|
||||
public function supplierDebitNotes(array$f){return$this->CI->db->select('d.id record_id,d.debit_note_no,d.note_date,s.supplier_code,s.name supplier,po.po_no,si.internal_no invoice_supplier,d.correction_type,d.status,d.base_amount,d.tax_amount,d.amount,d.journal_id')->from('supplier_debit_notes d')->join('suppliers s','s.id=d.supplier_id')->join('purchase_orders po','po.id=d.purchase_order_id','left')->join('supplier_invoices si','si.id=d.supplier_invoice_id','left')->where('d.company_id',$this->CI->companycontext->id())->where('d.note_date >=',$f['from'])->where('d.note_date <=',$f['to'])->order_by('d.note_date')->order_by('d.id')->get()->result_array();}
|
||||
public function salesReport($code,array$f){$c=$this->CI->companycontext->id();if($code==='sales_summary')return$this->CI->db->select('i.id record_id,i.no_invoice,i.tanggal,c.nama customer,i.invoice_type,i.recognition_policy,i.status,i.total,i.total_bayar,i.sisa_piutang')->from('invoices i')->join('customers c','c.id=i.customer_id')->where(array('i.company_id'=>$c,'i.workflow_status'=>'posted'))->where('i.tanggal >=',$f['from'])->where('i.tanggal <=',$f['to'])->order_by('i.tanggal')->get()->result_array();if($code==='sales_by_customer')return$this->CI->db->select('c.id customer_id,c.nama customer,COUNT(i.id) invoice_count,SUM(i.total) sales,SUM(i.total_bayar) paid,SUM(i.sisa_piutang) balance',false)->from('invoices i')->join('customers c','c.id=i.customer_id')->where(array('i.company_id'=>$c,'i.workflow_status'=>'posted'))->where('i.tanggal >=',$f['from'])->where('i.tanggal <=',$f['to'])->group_by('c.id')->order_by('sales','DESC')->get()->result_array();if($code==='sales_by_item')return$this->CI->db->select('d.items_id item_id,it.kode_detail AS kode_barang,it.nama_barang,SUM(d.qty) qty,SUM(d.net_amount) net_sales,SUM(d.tax_amount) tax,SUM(d.subtotal) total',false)->from('invoice_details d')->join('invoices i','i.id=d.invoice_id')->join('items it','it.id=d.items_id')->where(array('i.company_id'=>$c,'i.workflow_status'=>'posted'))->where('i.tanggal >=',$f['from'])->where('i.tanggal <=',$f['to'])->group_by('d.items_id')->order_by('net_sales','DESC')->get()->result_array();if($code==='sales_by_barcode')return$this->CI->db->select('i.id record_id,i.no_invoice,i.tanggal,it.kode_detail AS kode_barang,it.nama_barang,b.barcode,b.serial_number,lb.qty,sd.delivery_no')->from('invoice_line_barcodes lb')->join('invoices i','i.id=lb.invoice_id')->join('item_barcodes b','b.id=lb.barcode_id')->join('items it','it.id=b.item_id')->join('sales_deliveries sd','sd.id=lb.sales_delivery_id','left')->where('lb.company_id',$c)->where('i.tanggal >=',$f['from'])->where('i.tanggal <=',$f['to'])->order_by('i.tanggal')->get()->result_array();if($code==='running_invoices')return$this->CI->db->select('i.id record_id,i.no_invoice,c.nama customer,i.period_start,i.period_end,i.delivery_status,i.total,i.workflow_status')->from('invoices i')->join('customers c','c.id=i.customer_id')->where(array('i.company_id'=>$c,'i.invoice_type'=>'running','i.workflow_status'=>'draft'))->order_by('i.period_end')->get()->result_array();if($code==='sales_returns')return$this->CI->db->select('r.id record_id,r.return_no,r.return_date,c.nama customer,i.no_invoice,d.delivery_no,r.resolution,r.status,SUM(l.net_amount+l.tax_amount) amount',false)->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')->join('sales_return_lines l','l.sales_return_id=r.id','left')->where('r.company_id',$c)->where('r.return_date >=',$f['from'])->where('r.return_date <=',$f['to'])->group_by('r.id')->order_by('r.return_date')->get()->result_array();if($code==='revenue_recognition')return$this->CI->db->select('i.id record_id,i.no_invoice,c.nama customer,i.recognition_policy,i.subtotal_before_tax invoice_net,i.recognized_revenue,i.subtotal_before_tax-i.recognized_revenue deferred_revenue,i.recognized_cogs')->from('invoices i')->join('customers c','c.id=i.customer_id')->where(array('i.company_id'=>$c,'i.workflow_status'=>'posted'))->where('i.tanggal >=',$f['from'])->where('i.tanggal <=',$f['to'])->order_by('i.tanggal')->get()->result_array();if($code==='unbilled_deliveries')return$this->CI->db->select('d.id record_id,d.delivery_no,d.delivery_date,c.nama customer,d.status')->from('sales_deliveries d')->join('customers c','c.id=d.customer_id')->where('d.company_id',$c)->where('d.invoice_id IS NULL',null,false)->where('d.delivery_date >=',$f['from'])->where('d.delivery_date <=',$f['to'])->get()->result_array();if($code==='receivable_reconciliation'){$ar=$this->CI->load->library('AccountMappingService')?:null;$account=$this->CI->accountmappingservice->get('accounts_receivable');$sub=(float)$this->CI->db->select('COALESCE(SUM(sisa_piutang),0) v',false)->where(array('company_id'=>$c,'workflow_status'=>'posted'))->get('invoices')->row()->v;$gl=(float)$this->CI->db->select('COALESCE(SUM(d.debit-d.kredit),0) v',false)->from('journal_details d')->join('journals j','j.id=d.journal_id')->where(array('j.company_id'=>$c,'j.status'=>'posted','d.account_id'=>$account))->get()->row()->v;return array(array('subledger_piutang'=>$sub,'buku_besar_piutang'=>$gl,'selisih'=>$sub-$gl,'status'=>abs($sub-$gl)<.01?'Balance':'Perlu direkonsiliasi'));}throw new BusinessException('Jenis laporan penjualan tidak valid.');}
|
||||
public function salesReport($code,array$f){$c=$this->CI->companycontext->id();if($code==='revenue_recognition')return$this->revenueRecognition($f);if($code==='receivable_reconciliation')return$this->receivableReconciliation($f);if($code==='sales_summary')return$this->CI->db->select('i.id record_id,i.no_invoice,i.tanggal,c.nama customer,i.invoice_type,i.recognition_policy,i.status,i.total,i.total_bayar,i.sisa_piutang')->from('invoices i')->join('customers c','c.id=i.customer_id')->where(array('i.company_id'=>$c,'i.workflow_status'=>'posted'))->where('i.tanggal >=',$f['from'])->where('i.tanggal <=',$f['to'])->order_by('i.tanggal')->get()->result_array();if($code==='sales_by_customer')return$this->CI->db->select('c.id customer_id,c.nama customer,COUNT(i.id) invoice_count,SUM(i.total) sales,SUM(i.total_bayar) paid,SUM(i.sisa_piutang) balance',false)->from('invoices i')->join('customers c','c.id=i.customer_id')->where(array('i.company_id'=>$c,'i.workflow_status'=>'posted'))->where('i.tanggal >=',$f['from'])->where('i.tanggal <=',$f['to'])->group_by('c.id')->order_by('sales','DESC')->get()->result_array();if($code==='sales_by_item')return$this->CI->db->select('d.items_id item_id,it.kode_detail AS kode_barang,it.nama_barang,SUM(d.qty) qty,SUM(d.net_amount) net_sales,SUM(d.tax_amount) tax,SUM(d.subtotal) total',false)->from('invoice_details d')->join('invoices i','i.id=d.invoice_id')->join('items it','it.id=d.items_id')->where(array('i.company_id'=>$c,'i.workflow_status'=>'posted'))->where('i.tanggal >=',$f['from'])->where('i.tanggal <=',$f['to'])->group_by('d.items_id')->order_by('net_sales','DESC')->get()->result_array();if($code==='sales_by_barcode')return$this->CI->db->select('i.id record_id,i.no_invoice,i.tanggal,it.kode_detail AS kode_barang,it.nama_barang,b.barcode,b.serial_number,lb.qty,sd.delivery_no')->from('invoice_line_barcodes lb')->join('invoices i','i.id=lb.invoice_id')->join('item_barcodes b','b.id=lb.barcode_id')->join('items it','it.id=b.item_id')->join('sales_deliveries sd','sd.id=lb.sales_delivery_id','left')->where('lb.company_id',$c)->where('i.tanggal >=',$f['from'])->where('i.tanggal <=',$f['to'])->order_by('i.tanggal')->get()->result_array();if($code==='running_invoices')return$this->CI->db->select('i.id record_id,i.no_invoice,c.nama customer,i.period_start,i.period_end,i.delivery_status,i.total,i.workflow_status')->from('invoices i')->join('customers c','c.id=i.customer_id')->where(array('i.company_id'=>$c,'i.invoice_type'=>'running','i.workflow_status'=>'draft'))->order_by('i.period_end')->get()->result_array();if($code==='sales_returns')return$this->CI->db->select('r.id record_id,r.return_no,r.return_date,c.nama customer,i.no_invoice,d.delivery_no,r.resolution,r.status,SUM(l.net_amount+l.tax_amount) amount',false)->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')->join('sales_return_lines l','l.sales_return_id=r.id','left')->where('r.company_id',$c)->where('r.return_date >=',$f['from'])->where('r.return_date <=',$f['to'])->group_by('r.id')->order_by('r.return_date')->get()->result_array();if($code==='unbilled_deliveries')return$this->CI->db->select('d.id record_id,d.delivery_no,d.delivery_date,c.nama customer,d.status')->from('sales_deliveries d')->join('customers c','c.id=d.customer_id')->where('d.company_id',$c)->where('d.invoice_id IS NULL',null,false)->where('d.delivery_date >=',$f['from'])->where('d.delivery_date <=',$f['to'])->get()->result_array();throw new BusinessException('Jenis laporan penjualan tidak valid.');}
|
||||
private function revenueRecognition(array$f)
|
||||
{
|
||||
$company=(int)$this->CI->companycontext->id();$sql="SELECT i.id record_id,i.no_invoice,i.tanggal,c.nama customer,CASE WHEN i.recognition_policy='accrual' THEN 'Diakui saat posted' ELSE 'Proporsional setelah dibayar' END recognition_policy,COALESCE(i.subtotal_before_tax,0) invoice_net,COALESCE(i.recognized_revenue,0) recognized_revenue,GREATEST(COALESCE(i.subtotal_before_tax,0)-COALESCE(i.recognized_revenue,0),0) deferred_revenue,COALESCE(i.recognized_cogs,0) recognized_cogs FROM invoices i JOIN customers c ON c.id=i.customer_id AND c.company_id=i.company_id WHERE i.company_id=? AND i.workflow_status='posted' AND i.tanggal BETWEEN ? AND ? AND i.deleted_at IS NULL ORDER BY i.tanggal,i.id";return$this->CI->db->query($sql,array($company,$f['from'],$f['to']))->result_array();
|
||||
}
|
||||
private function receivableReconciliation(array$f)
|
||||
{
|
||||
$company=(int)$this->CI->companycontext->id();$to=$f['to'];$sql="SELECT i.id record_id,c.nama customer,i.no_invoice,i.tanggal invoice_date,i.jatuh_tempo due_date,i.total receivable_amount,COALESCE(p.paid,0) payments,COALESCE(n.credit_amount,0) credit_notes,COALESCE(w.writeoff_amount,0) writeoffs,GREATEST(i.total-COALESCE(p.paid,0)-COALESCE(n.credit_amount,0)-COALESCE(w.writeoff_amount,0),0) remaining_receivable,CASE WHEN GREATEST(i.total-COALESCE(p.paid,0)-COALESCE(n.credit_amount,0)-COALESCE(w.writeoff_amount,0),0)<=0.01 THEN 'Lunas' WHEN COALESCE(p.paid,0)+COALESCE(n.credit_amount,0)+COALESCE(w.writeoff_amount,0)>0 THEN 'Partial' WHEN i.jatuh_tempo<? THEN 'Jatuh Tempo' ELSE 'Belum Lunas' END status,CONCAT_WS(' | ',NULLIF(p.payment_refs,''),NULLIF(n.credit_refs,''),NULLIF(w.writeoff_refs,'')) transaction_references,0 reconciliation_adjustment FROM invoices i JOIN customers c ON c.id=i.customer_id AND c.company_id=i.company_id LEFT JOIN(SELECT pa.invoice_id,SUM(pa.amount) paid,GROUP_CONCAT(DISTINCT p.payment_no ORDER BY p.tanggal,p.id SEPARATOR ', ') payment_refs FROM payment_allocations pa JOIN payments p ON p.id=pa.payment_id WHERE p.status='posted' AND p.tanggal<=? GROUP BY pa.invoice_id)p ON p.invoice_id=i.id LEFT JOIN(SELECT invoice_id,SUM(amount) credit_amount,GROUP_CONCAT(credit_note_no ORDER BY credit_date,id SEPARATOR ', ') credit_refs FROM credit_notes WHERE status='posted' AND credit_date<=? GROUP BY invoice_id)n ON n.invoice_id=i.id LEFT JOIN(SELECT invoice_id,SUM(amount) writeoff_amount,GROUP_CONCAT(writeoff_no ORDER BY writeoff_date,id SEPARATOR ', ') writeoff_refs FROM receivable_writeoffs WHERE status IN('approved','posted') AND writeoff_date<=? GROUP BY invoice_id)w ON w.invoice_id=i.id WHERE i.company_id=? AND i.workflow_status='posted' AND i.tanggal<=? AND i.deleted_at IS NULL ORDER BY c.nama,i.tanggal,i.id";$rows=$this->CI->db->query($sql,array($to,$to,$to,$to,$company,$to))->result_array();$summary=$this->receivableSummary($f,$rows);if(abs($summary['difference'])>.01)$rows[]=array('record_id'=>0,'customer'=>'Saldo GL belum terpetakan','no_invoice'=>'REKONSILIASI-GL','invoice_date'=>$to,'due_date'=>null,'receivable_amount'=>0,'payments'=>0,'credit_notes'=>0,'writeoffs'=>0,'remaining_receivable'=>$summary['difference'],'status'=>'Perlu ditelusuri','transaction_references'=>'Selisih saldo Buku Besar terhadap subledger invoice sampai '.$to,'reconciliation_adjustment'=>1);return$rows;
|
||||
}
|
||||
public function receivableSummary(array$f,array$rows=null)
|
||||
{
|
||||
if($rows===null)$rows=$this->receivableReconciliation($f);$subledger=0;foreach($rows as$row)if(empty($row['reconciliation_adjustment']))$subledger+=(float)$row['remaining_receivable'];$this->CI->load->library('AccountMappingService');$account=(int)$this->CI->accountmappingservice->get('accounts_receivable');$gl=(float)$this->CI->db->query("SELECT COALESCE(SUM(d.debit-d.kredit),0) amount FROM journal_details d JOIN journals j ON j.id=d.journal_id WHERE j.company_id=? AND j.status IN('posted','reversed') AND j.tanggal<=? AND d.account_id=?",array((int)$this->CI->companycontext->id(),$f['to'],$account))->row()->amount;return array('subledger'=>$subledger,'general_ledger'=>$gl,'difference'=>round($gl-$subledger,2),'balanced'=>abs($gl-$subledger)<.01);
|
||||
}
|
||||
public function run($code,array$f){if($code==='trial_balance')return$this->trialBalance($f);if(in_array($code,array('profit_loss','balance_sheet'),true))return$this->statement($code,$f);if(in_array($code,array('general_ledger','journal_register','account_detail'),true))return$this->ledger($f);if($code==='cash_flow')return$this->cashFlow($f);if($code==='changes_equity')return$this->equity($f);if($code==='actual_budget')return$this->actualBudget($f);if($code==='comparative')return$this->comparative($f);if($code==='purchase_returns')return$this->purchaseReturns($f);if($code==='supplier_refunds')return$this->supplierRefunds($f);if($code==='outstanding_supplier_refunds')return$this->supplierRefunds($f,true);if($code==='supplier_debit_notes')return$this->supplierDebitNotes($f);if(in_array($code,array('sales_summary','sales_by_customer','sales_by_item','sales_by_barcode','running_invoices','sales_returns','revenue_recognition','unbilled_deliveries','receivable_reconciliation'),true))return$this->salesReport($code,$f);throw new BusinessException('Jenis laporan tidak valid.');}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user