Update besar apk finance
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
class Jurnal extends CI_Controller {
|
||||
class Jurnal extends MY_Controller {
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->model('DynamicModel', 'dm');
|
||||
$this->load->library('JournalService');
|
||||
$this->load->library('NumberingService');
|
||||
$this->load->library('JournalWorkflowService');
|
||||
|
||||
if (!$this->session->userdata('logged_in')) {
|
||||
redirect('auth');
|
||||
@@ -37,10 +40,10 @@ class Jurnal extends CI_Controller {
|
||||
$search = $_POST['search']['value'];
|
||||
|
||||
// ================= TOTAL ALL
|
||||
$totalAll = $this->db->count_all('journals');
|
||||
$totalAll = $this->db->where('company_id',$this->companycontext->id())->count_all_results('journals');
|
||||
|
||||
// ================= QUERY FILTERED (HITUNG)
|
||||
$this->db->from('journals');
|
||||
$this->db->from('journals')->where('company_id',$this->companycontext->id());
|
||||
|
||||
if(!empty($search)){
|
||||
$this->db->group_start();
|
||||
@@ -58,11 +61,14 @@ class Jurnal extends CI_Controller {
|
||||
journals.tanggal,
|
||||
journals.no_ref,
|
||||
journals.keterangan,
|
||||
journals.status,
|
||||
journals.is_reversed,
|
||||
COALESCE(SUM(journal_details.debit),0) as total_debit,
|
||||
COALESCE(SUM(journal_details.kredit),0) as total_kredit
|
||||
');
|
||||
$this->db->from('journals');
|
||||
$this->db->join('journal_details','journal_details.journal_id = journals.id','LEFT');
|
||||
$this->db->where('journals.company_id',$this->companycontext->id());
|
||||
|
||||
if(!empty($search)){
|
||||
$this->db->group_start();
|
||||
@@ -86,19 +92,22 @@ class Jurnal extends CI_Controller {
|
||||
foreach ($query as $row) {
|
||||
$no++;
|
||||
|
||||
if($this->session->userdata('role') != 'Admin'){
|
||||
|
||||
$aksi = '
|
||||
<button class="btn btn-sm btn-info btn-detail" data-id="'.$row->id.'">Detail</button>
|
||||
';
|
||||
|
||||
$isAdmin = $this->session->userdata('role') === 'Admin';
|
||||
$aksi = '<button class="btn btn-sm btn-info btn-detail" data-id="'.$row->id.'">Detail</button> ';
|
||||
if ($row->status === 'draft') {
|
||||
$aksi .= '<button class="btn btn-sm btn-primary btn-submit" data-id="'.$row->id.'">Submit</button> ';
|
||||
if ($isAdmin) $aksi .= '<button class="btn btn-sm btn-danger btn-delete" data-id="'.$row->id.'">Hapus</button> ';
|
||||
}
|
||||
else {
|
||||
$aksi = '
|
||||
<button class="btn btn-sm btn-info btn-detail" data-id="'.$row->id.'">Detail</button>
|
||||
<button class="btn btn-sm btn-danger btn-delete" data-id="'.$row->id.'">Delete</button>
|
||||
';
|
||||
if ($isAdmin && $row->status === 'submitted') {
|
||||
$aksi .= '<button class="btn btn-sm btn-success btn-approve" data-id="'.$row->id.'">Approve</button> ';
|
||||
$aksi .= '<button class="btn btn-sm btn-outline-danger btn-reject" data-id="'.$row->id.'">Reject</button> ';
|
||||
}
|
||||
if ($isAdmin && $row->status === 'posted') {
|
||||
$aksi .= '<button class="btn btn-sm btn-outline-warning btn-reverse" data-id="'.$row->id.'">Reverse</button>';
|
||||
}
|
||||
|
||||
$statusClass = array('draft'=>'secondary','submitted'=>'info','approved'=>'primary','posted'=>'success','rejected'=>'danger','reversed'=>'warning');
|
||||
$badge = '<span class="badge bg-'.(isset($statusClass[$row->status]) ? $statusClass[$row->status] : 'secondary').'">'.htmlspecialchars(strtoupper($row->status), ENT_QUOTES, 'UTF-8').'</span>';
|
||||
|
||||
$data[] = [
|
||||
$no,
|
||||
@@ -107,6 +116,7 @@ class Jurnal extends CI_Controller {
|
||||
$row->keterangan,
|
||||
number_format($row->total_debit,0,',','.'),
|
||||
number_format($row->total_kredit,0,',','.'),
|
||||
$badge,
|
||||
$aksi
|
||||
];
|
||||
}
|
||||
@@ -124,7 +134,7 @@ class Jurnal extends CI_Controller {
|
||||
// =========================
|
||||
public function get_accounts()
|
||||
{
|
||||
$data = $this->db->order_by('kode_akun','ASC')->get('accounts')->result();
|
||||
$data = $this->db->where(['company_id'=>$this->companycontext->id(),'is_active'=>1,'allow_posting'=>1])->order_by('kode_akun','ASC')->get('accounts')->result();
|
||||
echo json_encode($data);
|
||||
}
|
||||
|
||||
@@ -133,68 +143,59 @@ class Jurnal extends CI_Controller {
|
||||
// =========================
|
||||
public function save()
|
||||
{
|
||||
$tanggal = $this->input->post('tanggal');
|
||||
$no_ref = 'JR-' . date('YmdHis');
|
||||
$keterangan = $this->input->post('keterangan');
|
||||
$tanggal = (string) $this->input->post('tanggal', true);
|
||||
$keterangan = trim((string) $this->input->post('keterangan', true));
|
||||
$accounts = (array) $this->input->post('account_id');
|
||||
$debit = (array) $this->input->post('debit');
|
||||
$kredit = (array) $this->input->post('kredit');
|
||||
|
||||
$accounts = $this->input->post('account_id');
|
||||
$debit = $this->input->post('debit');
|
||||
$kredit = $this->input->post('kredit');
|
||||
try {
|
||||
$noRef = $this->numberingservice->next('journal', $tanggal);
|
||||
$lines = array();
|
||||
foreach ($accounts as $index => $accountId) {
|
||||
$lineDebit = isset($debit[$index]) ? $this->parseNominal($debit[$index]) : 0;
|
||||
$lineCredit = isset($kredit[$index]) ? $this->parseNominal($kredit[$index]) : 0;
|
||||
if ($lineDebit <= 0 && $lineCredit <= 0) continue;
|
||||
$lines[] = array(
|
||||
'account_id' => $accountId,
|
||||
'debit' => $lineDebit,
|
||||
'kredit' => $lineCredit
|
||||
);
|
||||
}
|
||||
|
||||
if (array_sum($debit) != array_sum($kredit)) {
|
||||
echo json_encode([
|
||||
'status'=>false,
|
||||
'message'=>'Debit & Kredit tidak balance!'
|
||||
]);
|
||||
return;
|
||||
}
|
||||
$journalId = $this->journalservice->create(array(
|
||||
'tanggal' => $tanggal,
|
||||
'no_ref' => $noRef,
|
||||
'keterangan' => $keterangan,
|
||||
'ref_type' => 'manual_journal',
|
||||
'created_by' => (int) $this->session->userdata('user_id')
|
||||
), $lines);
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
$this->db->insert('journals', [
|
||||
'tanggal' => $tanggal,
|
||||
'no_ref' => $no_ref,
|
||||
'keterangan' => $keterangan,
|
||||
'created_by' => $this->session->userdata('user_id')
|
||||
]);
|
||||
|
||||
$journal_id = $this->db->insert_id();
|
||||
|
||||
for ($i=0; $i<count($accounts); $i++) {
|
||||
if ($accounts[$i] == '') continue;
|
||||
|
||||
$this->db->insert('journal_details', [
|
||||
'journal_id' => $journal_id,
|
||||
'account_id' => $accounts[$i],
|
||||
'debit' => $debit[$i] ?: 0,
|
||||
'kredit' => $kredit[$i] ?: 0
|
||||
]);
|
||||
log_activity('Jurnal', 'create', 'Membuat jurnal No Ref: ' . $noRef, 'success');
|
||||
return json_response(true, 'Jurnal berhasil disimpan.', array(
|
||||
'journal_id' => $journalId,
|
||||
'no_ref' => $noRef
|
||||
));
|
||||
} catch (Throwable $exception) {
|
||||
return business_exception_response($exception);
|
||||
}
|
||||
}
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
if ($this->db->trans_status() === FALSE) {
|
||||
|
||||
echo json_encode([
|
||||
'status'=>false,
|
||||
'message'=>'Gagal simpan jurnal'
|
||||
]);
|
||||
return;
|
||||
|
||||
/** Menerima nominal raw maupun berformat 20,000 / 20.000 / 20.000,50. */
|
||||
private function parseNominal($value)
|
||||
{
|
||||
$value = trim(str_ireplace(array('Rp', ' '), '', (string) $value));
|
||||
if ($value === '') return 0.0;
|
||||
$comma = strrpos($value, ','); $dot = strrpos($value, '.');
|
||||
if ($comma !== false && $dot !== false) {
|
||||
$value = $comma > $dot ? str_replace(',', '.', str_replace('.', '', $value)) : str_replace(',', '', $value);
|
||||
} elseif ($comma !== false) {
|
||||
$decimal = strlen($value) - $comma - 1;
|
||||
$value = $decimal > 0 && $decimal <= 2 ? str_replace(',', '.', $value) : str_replace(',', '', $value);
|
||||
} elseif ($dot !== false && strlen($value) - $dot - 1 === 3) {
|
||||
$value = str_replace('.', '', $value);
|
||||
}
|
||||
|
||||
// ================= LOG ACTIVITY =================
|
||||
log_activity(
|
||||
'Jurnal',
|
||||
'create',
|
||||
'Membuat jurnal No Ref: '.$no_ref,
|
||||
'success'
|
||||
);
|
||||
|
||||
echo json_encode([
|
||||
'status'=>true,
|
||||
'message'=>'Jurnal berhasil disimpan'
|
||||
]);
|
||||
return is_numeric($value) ? round((float) $value, 2) : 0.0;
|
||||
}
|
||||
|
||||
// =========================
|
||||
@@ -202,7 +203,8 @@ class Jurnal extends CI_Controller {
|
||||
// =========================
|
||||
public function detail($id)
|
||||
{
|
||||
$header = $this->db->get_where('journals',['id'=>$id])->row();
|
||||
$header = $this->db->get_where('journals',['id'=>$id,'company_id'=>$this->companycontext->id()])->row();
|
||||
if (!$header) return json_response(false, 'Jurnal tidak ditemukan.', array(), 404);
|
||||
|
||||
$detail = $this->db
|
||||
->select('accounts.kode_akun, accounts.nama_akun, journal_details.*')
|
||||
@@ -220,10 +222,19 @@ class Jurnal extends CI_Controller {
|
||||
->get('users')
|
||||
->row();
|
||||
|
||||
$history = $this->db
|
||||
->select('journal_status_histories.*, users.nama changed_by_name')
|
||||
->from('journal_status_histories')
|
||||
->join('users', 'users.id = journal_status_histories.changed_by', 'left')
|
||||
->where('journal_id', $id)
|
||||
->order_by('journal_status_histories.id', 'ASC')
|
||||
->get()->result();
|
||||
|
||||
echo json_encode([
|
||||
'header'=>$header,
|
||||
'detail'=>$detail,
|
||||
'user' =>$user
|
||||
'user' =>$user,
|
||||
'history'=>$history
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -232,6 +243,10 @@ class Jurnal extends CI_Controller {
|
||||
// =========================
|
||||
public function delete($id)
|
||||
{
|
||||
if (strtoupper($this->input->method()) !== 'POST') {
|
||||
return json_response(false, 'Metode request tidak diizinkan.', array(), 405);
|
||||
}
|
||||
$this->requireAdmin();
|
||||
$journal = $this->db->get_where('journals', ['id' => $id])->row();
|
||||
|
||||
// VALIDASI
|
||||
@@ -243,6 +258,10 @@ class Jurnal extends CI_Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in_array($journal->status, array('draft', 'rejected'), true)) {
|
||||
return json_response(false, 'Hanya jurnal draft atau rejected yang dapat dihapus.', array(), 422);
|
||||
}
|
||||
|
||||
$this->db->trans_start();
|
||||
|
||||
// =========================
|
||||
@@ -301,6 +320,62 @@ class Jurnal extends CI_Controller {
|
||||
]);
|
||||
}
|
||||
|
||||
public function submit($id)
|
||||
{
|
||||
return $this->workflowAction(function () use ($id) {
|
||||
return $this->journalworkflowservice->submit($id, $this->session->userdata('user_id'));
|
||||
}, 'Jurnal berhasil diajukan.');
|
||||
}
|
||||
|
||||
public function approve($id)
|
||||
{
|
||||
$this->requireAdmin();
|
||||
return $this->workflowAction(function () use ($id) {
|
||||
return $this->journalworkflowservice->approve($id, $this->session->userdata('user_id'));
|
||||
}, 'Approval jurnal berhasil diproses. Setelah approval final, jurnal otomatis diposting.');
|
||||
}
|
||||
|
||||
public function post($id)
|
||||
{
|
||||
$this->requireAdmin();
|
||||
return $this->workflowAction(function () use ($id) {
|
||||
return $this->journalworkflowservice->post($id, $this->session->userdata('user_id'));
|
||||
}, 'Jurnal berhasil diposting.');
|
||||
}
|
||||
|
||||
public function reject($id)
|
||||
{
|
||||
$this->requireAdmin();
|
||||
$reason = $this->input->post('reason', true);
|
||||
return $this->workflowAction(function () use ($id, $reason) {
|
||||
return $this->journalworkflowservice->reject($id, $this->session->userdata('user_id'), $reason);
|
||||
}, 'Jurnal berhasil ditolak.');
|
||||
}
|
||||
|
||||
public function reverse($id)
|
||||
{
|
||||
$this->requireAdmin();
|
||||
$date = $this->input->post('date', true);
|
||||
$reason = $this->input->post('reason', true);
|
||||
return $this->workflowAction(function () use ($id, $date, $reason) {
|
||||
return $this->journalworkflowservice->reverse($id, $date, $this->session->userdata('user_id'), $reason);
|
||||
}, 'Reversal jurnal berhasil dibuat.');
|
||||
}
|
||||
|
||||
private function workflowAction(callable $callback, $message)
|
||||
{
|
||||
if (strtoupper($this->input->method()) !== 'POST') {
|
||||
return json_response(false, 'Metode request tidak diizinkan.', array(), 405);
|
||||
}
|
||||
try {
|
||||
$result = $callback();
|
||||
log_activity('Jurnal', 'workflow', $message, 'success');
|
||||
return json_response(true, $message, array('result' => $result));
|
||||
} catch (Throwable $exception) {
|
||||
return business_exception_response($exception);
|
||||
}
|
||||
}
|
||||
|
||||
public function get_base_jurnal()
|
||||
{
|
||||
echo json_encode(
|
||||
@@ -330,4 +405,4 @@ class Jurnal extends CI_Controller {
|
||||
'stok' => $stok
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user