Update besar apk finance
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
require_once APPPATH . 'exceptions/BusinessException.php';
|
||||
|
||||
class FiscalPeriodService
|
||||
{
|
||||
private $CI;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->CI =& get_instance();
|
||||
$this->CI->load->model('FiscalPeriodModel', 'fiscalPeriodModel');
|
||||
$this->CI->load->library('TransactionService');
|
||||
$this->CI->load->library('AuditService');
|
||||
}
|
||||
|
||||
public function periodForDate($date)
|
||||
{
|
||||
$parsed = DateTime::createFromFormat('Y-m-d', (string) $date);
|
||||
if (!$parsed || $parsed->format('Y-m-d') !== $date) {
|
||||
throw new BusinessException('Tanggal periode accounting tidak valid.');
|
||||
}
|
||||
|
||||
$period = $this->CI->fiscalPeriodModel->findByDate($date);
|
||||
if (!$period) {
|
||||
throw new BusinessException('Periode accounting untuk tanggal ' . $date . ' belum tersedia.');
|
||||
}
|
||||
return $period;
|
||||
}
|
||||
|
||||
public function assertOpen($date)
|
||||
{
|
||||
$period = $this->periodForDate($date);
|
||||
if ($period->status !== 'open') {
|
||||
throw new BusinessException('Periode ' . $period->name . ' berstatus ' . $period->status . ' dan tidak menerima transaksi.');
|
||||
}
|
||||
return $period;
|
||||
}
|
||||
|
||||
public function changeStatus($periodId, $targetStatus, $userId, $reason = '')
|
||||
{
|
||||
$allowed = array('open', 'soft_closed', 'closed');
|
||||
if (!in_array($targetStatus, $allowed, true)) {
|
||||
throw new BusinessException('Status periode tidak valid.');
|
||||
}
|
||||
|
||||
return $this->CI->transactionservice->run(function () use ($periodId, $targetStatus, $userId, $reason) {
|
||||
$period = $this->CI->db->query('SELECT * FROM accounting_periods WHERE id = ? FOR UPDATE', array((int) $periodId))->row();
|
||||
if (!$period) {
|
||||
throw new BusinessException('Periode accounting tidak ditemukan.', array(), 404);
|
||||
}
|
||||
if ($period->status === $targetStatus) {
|
||||
return $period;
|
||||
}
|
||||
|
||||
$transitions = array(
|
||||
'open' => array('soft_closed', 'closed'),
|
||||
'soft_closed' => array('open', 'closed'),
|
||||
'closed' => array('open')
|
||||
);
|
||||
if (!in_array($targetStatus, $transitions[$period->status], true)) {
|
||||
throw new BusinessException('Perubahan status periode tidak diizinkan.');
|
||||
}
|
||||
if ($targetStatus === 'open' && $period->status !== 'open' && trim($reason) === '') {
|
||||
throw new BusinessException('Alasan membuka kembali periode wajib diisi.');
|
||||
}
|
||||
if (in_array($targetStatus, array('soft_closed', 'closed'), true)) {
|
||||
$pending = $this->CI->db
|
||||
->where('tanggal >=', $period->start_date)
|
||||
->where('tanggal <=', $period->end_date)
|
||||
->where_in('status', array('draft', 'submitted', 'approved'))
|
||||
->count_all_results('journals');
|
||||
if ($pending > 0) {
|
||||
throw new BusinessException('Periode masih mempunyai ' . $pending . ' jurnal yang belum diposting atau ditolak.');
|
||||
}
|
||||
}
|
||||
|
||||
$update = array('status' => $targetStatus, 'updated_at' => date('Y-m-d H:i:s'));
|
||||
if ($targetStatus === 'closed') {
|
||||
$update['closed_at'] = date('Y-m-d H:i:s');
|
||||
$update['closed_by'] = (int) $userId;
|
||||
} elseif ($targetStatus === 'open') {
|
||||
$update['reopened_at'] = date('Y-m-d H:i:s');
|
||||
$update['reopened_by'] = (int) $userId;
|
||||
}
|
||||
$this->CI->db->where('id', $period->id)->update('accounting_periods', $update);
|
||||
$this->CI->db->insert('accounting_period_logs', array(
|
||||
'accounting_period_id' => $period->id,
|
||||
'from_status' => $period->status,
|
||||
'to_status' => $targetStatus,
|
||||
'reason' => trim($reason) ?: null,
|
||||
'changed_by' => (int) $userId,
|
||||
'changed_at' => date('Y-m-d H:i:s')
|
||||
));
|
||||
$notClosed = $this->CI->db
|
||||
->where('fiscal_year_id', $period->fiscal_year_id)
|
||||
->where('status !=', 'closed')
|
||||
->count_all_results('accounting_periods');
|
||||
$this->CI->db->where('id', $period->fiscal_year_id)->update('fiscal_years', array(
|
||||
'status' => $notClosed === 0 ? 'closed' : 'open'
|
||||
));
|
||||
$after=$this->CI->fiscalPeriodModel->find($period->id);
|
||||
$this->CI->auditservice->record('accounting_period','accounting_period',$period->id,'change_status',$period,$after,$userId);
|
||||
return $after;
|
||||
});
|
||||
}
|
||||
|
||||
public function createCalendarYear($year, $userId)
|
||||
{
|
||||
$year = (int) $year;
|
||||
if ($year < 2000 || $year > 2200) {
|
||||
throw new BusinessException('Tahun buku tidak valid.');
|
||||
}
|
||||
return $this->CI->transactionservice->run(function () use ($year, $userId) {
|
||||
$start = $year . '-01-01';
|
||||
$end = $year . '-12-31';
|
||||
$overlap = $this->CI->db
|
||||
->where('start_date <=', $end)
|
||||
->where('end_date >=', $start)
|
||||
->count_all_results('fiscal_years');
|
||||
if ($overlap > 0) {
|
||||
throw new BusinessException('Tahun buku tersebut sudah tersedia atau bertumpang tindih.');
|
||||
}
|
||||
$this->CI->db->insert('fiscal_years', array(
|
||||
'name' => 'Tahun Buku ' . $year,
|
||||
'start_date' => $start,
|
||||
'end_date' => $end,
|
||||
'status' => 'open',
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'created_by' => (int) $userId
|
||||
));
|
||||
$fiscalId = (int) $this->CI->db->insert_id();
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$periodStart = sprintf('%04d-%02d-01', $year, $month);
|
||||
$this->CI->db->insert('accounting_periods', array(
|
||||
'fiscal_year_id' => $fiscalId,
|
||||
'period_number' => $month,
|
||||
'name' => date('F Y', strtotime($periodStart)),
|
||||
'start_date' => $periodStart,
|
||||
'end_date' => date('Y-m-t', strtotime($periodStart)),
|
||||
'status' => 'open'
|
||||
));
|
||||
}
|
||||
$this->CI->auditservice->record('fiscal_year','fiscal_year',$fiscalId,'create',null,array('year'=>$year),$userId);
|
||||
return $fiscalId;
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user