Files
accounting_dev_v2/application/libraries/MultiCurrencyService.php
T
2026-09-11 16:03:00 +07:00

9 lines
3.1 KiB
PHP

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class MultiCurrencyService
{
private $CI;public function __construct(){$this->CI=&get_instance();$this->CI->load->library(array('CompanyContext','PostingService','AccountMappingService','FiscalPeriodService'));}
public function rate($currency,$date){$company=$this->CI->db->get_where('companies',array('id'=>$this->CI->companycontext->id()))->row();if($currency===$company->base_currency)return 1;$r=$this->CI->db->where('company_id',$company->id)->where('from_currency',$currency)->where('to_currency',$company->base_currency)->where('rate_date <=',$date)->order_by('rate_date','DESC')->get('exchange_rates')->row();if(!$r)throw new BusinessException('Kurs '.$currency.'/'.$company->base_currency.' belum tersedia pada '.$date);return(float)$r->rate;}
public function revalue($date,$uid){$db=$this->CI->db;$db->trans_begin();try{$cid=$this->CI->companycontext->id();$this->CI->fiscalperiodservice->assertOpen($date);$db->insert('fx_revaluations',array('company_id'=>$cid,'revaluation_no'=>'FXR-'.date('YmdHis'),'revaluation_date'=>$date,'created_by'=>$uid));$id=$db->insert_id();$gain=$loss=0;$lines=array();$ar=$this->CI->accountmappingservice->get('accounts_receivable');foreach($db->where('company_id',$cid)->where('workflow_status','posted')->where('sisa_piutang >',0)->where('transaction_currency !=','IDR')->get('invoices')->result()as$i){$foreign=(float)($i->foreign_balance?:$i->foreign_total);if($foreign<=0)continue;$diff=round($foreign*$this->rate($i->transaction_currency,$date)-(float)$i->sisa_piutang,2);if(abs($diff)<.01)continue;$lines[]=array('account_id'=>$ar,'debit'=>$diff>0?$diff:0,'kredit'=>$diff<0?abs($diff):0);if($diff>0)$gain+=$diff;else$loss+=abs($diff);}$ap=$this->CI->accountmappingservice->get('accounts_payable');foreach($db->where('company_id',$cid)->where('status','partial')->where('balance >',0)->where('transaction_currency !=','IDR')->get('supplier_invoices')->result()as$i){$foreign=(float)($i->foreign_balance?:$i->foreign_total);if($foreign<=0)continue;$diff=round($foreign*$this->rate($i->transaction_currency,$date)-(float)$i->balance,2);if(abs($diff)<.01)continue;$lines[]=array('account_id'=>$ap,'debit'=>$diff<0?abs($diff):0,'kredit'=>$diff>0?$diff:0);if($diff>0)$loss+=$diff;else$gain+=abs($diff);}if(!$lines)throw new BusinessException('Tidak ada saldo valuta asing yang perlu direvaluasi.');if($loss>0)$lines[]=array('account_id'=>$this->CI->accountmappingservice->get('unrealized_fx_loss'),'debit'=>$loss,'kredit'=>0);if($gain>0)$lines[]=array('account_id'=>$this->CI->accountmappingservice->get('unrealized_fx_gain'),'debit'=>0,'kredit'=>$gain);$jid=$this->CI->postingservice->post(array('tanggal'=>$date,'no_ref'=>'FXR-'.$id.'-'.str_replace('-','',$date),'keterangan'=>'Revaluasi saldo valuta asing pada '.$date,'ref_type'=>'fx_revaluation','ref_id'=>$id,'created_by'=>$uid),$lines,false,true);$db->where('id',$id)->update('fx_revaluations',array('status'=>'posted','gain_amount'=>$gain,'loss_amount'=>$loss,'journal_id'=>$jid,'posted_at'=>date('Y-m-d H:i:s')));$db->trans_commit();return$jid;}catch(Throwable$e){$db->trans_rollback();throw$e;}}
}