Update besar apk finance
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
require_once APPPATH . 'exceptions/BusinessException.php';
|
||||
|
||||
class JournalWorkflowService
|
||||
{
|
||||
private $CI;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->CI =& get_instance();
|
||||
$this->CI->load->model('JournalModel', 'workflowJournalModel');
|
||||
$this->CI->load->library('TransactionService');
|
||||
$this->CI->load->library('FiscalPeriodService');
|
||||
$this->CI->load->library('NumberingService');
|
||||
$this->CI->load->library('PostingService');
|
||||
$this->CI->load->library('ApprovalService');
|
||||
$this->CI->load->library('AuditService');
|
||||
$this->CI->config->load('accounting', true);
|
||||
}
|
||||
|
||||
public function submit($journalId, $userId)
|
||||
{
|
||||
return $this->CI->transactionservice->run(function () use ($journalId, $userId) {
|
||||
$journal = $this->lockedJournal($journalId, 'draft');
|
||||
if ((int)$journal->created_by !== (int)$userId && $this->CI->session->userdata('role') !== 'Admin') throw new BusinessException('Anda hanya dapat mengajukan jurnal yang Anda buat.');
|
||||
$this->CI->fiscalperiodservice->assertOpen($journal->tanggal);
|
||||
$lines=$this->CI->workflowJournalModel->lines($journal->id); $amount=0;
|
||||
foreach($lines as $line) $amount+=(float)$line['debit'];
|
||||
$this->CI->approvalservice->create('journal','journal',$journal->id,$amount,$userId,array('journal'=>$journal,'lines'=>$lines));
|
||||
$this->CI->workflowJournalModel->updateStatus($journal->id,'submitted',array('submitted_at'=>date('Y-m-d H:i:s'),'submitted_by'=>(int)$userId));
|
||||
$this->CI->workflowJournalModel->addStatusHistory($journal->id,'draft','submitted',$userId);
|
||||
$after=$this->CI->workflowJournalModel->find($journal->id);
|
||||
$this->CI->auditservice->record('journal','journal',$journal->id,'submit',$journal,$after,$userId);
|
||||
return $after;
|
||||
});
|
||||
}
|
||||
|
||||
public function approve($journalId, $userId)
|
||||
{
|
||||
return $this->CI->transactionservice->run(function () use ($journalId, $userId) {
|
||||
$journal = $this->lockedJournal($journalId, 'submitted');
|
||||
$request=$this->CI->approvalservice->pendingForEntity('journal',$journal->id);
|
||||
if(!$request) throw new BusinessException('Permintaan approval jurnal tidak ditemukan.');
|
||||
$roleId=$this->roleId($userId);
|
||||
$approval=$this->CI->approvalservice->act($request->id,'approved',$userId,$roleId);
|
||||
if($approval->status!=='approved') return $journal;
|
||||
$this->CI->fiscalperiodservice->assertOpen($journal->tanggal);
|
||||
$now=date('Y-m-d H:i:s');
|
||||
$this->CI->workflowJournalModel->updateStatus($journal->id, 'posted', array(
|
||||
'approved_at'=>$now,'approved_by'=>(int)$userId,'posted_at'=>$now,'posted_by'=>(int)$userId
|
||||
));
|
||||
$this->CI->workflowJournalModel->addStatusHistory($journal->id, 'submitted', 'approved', $userId);
|
||||
$this->CI->workflowJournalModel->addStatusHistory($journal->id, 'approved', 'posted', $userId, 'Otomatis diposting setelah approval final.');
|
||||
$after=$this->CI->workflowJournalModel->find($journal->id);
|
||||
$this->CI->auditservice->record('journal','journal',$journal->id,'approve_and_post',$journal,$after,$userId);
|
||||
return $after;
|
||||
});
|
||||
}
|
||||
|
||||
public function post($journalId, $userId)
|
||||
{
|
||||
return $this->CI->transactionservice->run(function () use ($journalId, $userId) {
|
||||
$journal = $this->lockedJournal($journalId, 'approved');
|
||||
$this->CI->fiscalperiodservice->assertOpen($journal->tanggal);
|
||||
$this->CI->workflowJournalModel->updateStatus($journal->id, 'posted', array(
|
||||
'posted_at' => date('Y-m-d H:i:s'), 'posted_by' => (int) $userId
|
||||
));
|
||||
$this->CI->workflowJournalModel->addStatusHistory($journal->id, 'approved', 'posted', $userId);
|
||||
$after=$this->CI->workflowJournalModel->find($journal->id);
|
||||
$this->CI->auditservice->record('journal','journal',$journal->id,'post',$journal,$after,$userId);
|
||||
return $after;
|
||||
});
|
||||
}
|
||||
|
||||
public function reject($journalId, $userId, $reason)
|
||||
{
|
||||
$reason = trim((string) $reason);
|
||||
if ($reason === '') {
|
||||
throw new BusinessException('Alasan penolakan wajib diisi.');
|
||||
}
|
||||
return $this->CI->transactionservice->run(function () use ($journalId, $userId, $reason) {
|
||||
$journal = $this->CI->workflowJournalModel->findForUpdate($journalId);
|
||||
if (!$journal || !in_array($journal->status, array('submitted', 'approved'), true)) {
|
||||
throw new BusinessException('Jurnal tidak berada pada status yang dapat ditolak.');
|
||||
}
|
||||
if($journal->status==='submitted') {
|
||||
$request=$this->CI->approvalservice->pendingForEntity('journal',$journal->id);
|
||||
if($request) $this->CI->approvalservice->act($request->id,'rejected',$userId,$this->roleId($userId),$reason);
|
||||
}
|
||||
$this->CI->workflowJournalModel->updateStatus($journal->id, 'rejected', array(
|
||||
'rejected_at' => date('Y-m-d H:i:s'), 'rejected_by' => (int) $userId, 'rejection_reason' => $reason
|
||||
));
|
||||
$this->CI->workflowJournalModel->addStatusHistory($journal->id, $journal->status, 'rejected', $userId, $reason);
|
||||
$after=$this->CI->workflowJournalModel->find($journal->id);
|
||||
$this->CI->auditservice->record('journal','journal',$journal->id,'reject',$journal,$after,$userId);
|
||||
return $after;
|
||||
});
|
||||
}
|
||||
|
||||
public function reverse($journalId, $date, $userId, $reason)
|
||||
{
|
||||
$reason = trim((string) $reason);
|
||||
if ($reason === '') {
|
||||
throw new BusinessException('Alasan reversal wajib diisi.');
|
||||
}
|
||||
return $this->CI->transactionservice->run(function () use ($journalId, $date, $userId, $reason) {
|
||||
$journal = $this->lockedJournal($journalId, 'posted');
|
||||
if ((int) $journal->is_reversed === 1) {
|
||||
throw new BusinessException('Jurnal sudah pernah direversal.');
|
||||
}
|
||||
$this->CI->fiscalperiodservice->assertOpen($date);
|
||||
$lines = array();
|
||||
foreach ($this->CI->workflowJournalModel->lines($journal->id) as $line) {
|
||||
$lines[] = array('account_id' => $line['account_id'], 'debit' => $line['kredit'], 'kredit' => $line['debit']);
|
||||
}
|
||||
$number = $this->CI->numberingservice->next('reversal', $date);
|
||||
$reversalId = $this->CI->postingservice->post(array(
|
||||
'tanggal' => $date,
|
||||
'no_ref' => $number,
|
||||
'keterangan' => 'Reversal ' . $journal->no_ref . ': ' . $reason,
|
||||
'ref_type' => 'journal_reversal',
|
||||
'ref_id' => $journal->id,
|
||||
'reversal_of' => $journal->id,
|
||||
'reversal_reason' => $reason,
|
||||
'created_by' => (int) $userId
|
||||
), $lines, false, true);
|
||||
$this->CI->workflowJournalModel->updateStatus($journal->id, 'reversed', array(
|
||||
'is_reversed' => 1, 'reversal_reason' => $reason, 'updated_by' => (int) $userId
|
||||
));
|
||||
$this->CI->workflowJournalModel->addStatusHistory($journal->id, 'posted', 'reversed', $userId, $reason);
|
||||
$this->CI->auditservice->record('journal','journal',$journal->id,'reverse',$journal,$this->CI->workflowJournalModel->find($journal->id),$userId);
|
||||
return array('journal' => $this->CI->workflowJournalModel->find($journal->id), 'reversal_id' => $reversalId, 'reversal_no' => $number);
|
||||
});
|
||||
}
|
||||
|
||||
private function transition($journalId, $from, $to, $userId, array $extra)
|
||||
{
|
||||
return $this->CI->transactionservice->run(function () use ($journalId, $from, $to, $userId, $extra) {
|
||||
$journal = $this->lockedJournal($journalId, $from);
|
||||
if ($from === 'draft' && (int) $journal->created_by !== (int) $userId && $this->CI->session->userdata('role') !== 'Admin') {
|
||||
throw new BusinessException('Anda hanya dapat mengajukan jurnal yang Anda buat.');
|
||||
}
|
||||
$this->CI->fiscalperiodservice->assertOpen($journal->tanggal);
|
||||
$this->CI->workflowJournalModel->updateStatus($journal->id, $to, $extra);
|
||||
$this->CI->workflowJournalModel->addStatusHistory($journal->id, $from, $to, $userId);
|
||||
return $this->CI->workflowJournalModel->find($journal->id);
|
||||
});
|
||||
}
|
||||
|
||||
private function lockedJournal($journalId, $expectedStatus)
|
||||
{
|
||||
$journal = $this->CI->workflowJournalModel->findForUpdate($journalId);
|
||||
if (!$journal) {
|
||||
throw new BusinessException('Jurnal tidak ditemukan.', array(), 404);
|
||||
}
|
||||
if ($journal->status !== $expectedStatus) {
|
||||
throw new BusinessException('Jurnal harus berstatus ' . $expectedStatus . ' untuk tindakan ini.');
|
||||
}
|
||||
return $journal;
|
||||
}
|
||||
|
||||
private function roleId($userId)
|
||||
{
|
||||
$roleId=(int)$this->CI->session->userdata('role_id');
|
||||
if(!$roleId) { $user=$this->CI->db->select('role_id')->get_where('users',array('id'=>(int)$userId))->row(); $roleId=$user?(int)$user->role_id:0; }
|
||||
return $roleId;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user