280 lines
8.1 KiB
PHP
280 lines
8.1 KiB
PHP
<?php
|
|
defined('BASEPATH') OR exit('No direct script access allowed');
|
|
|
|
class Dashboard extends CI_Controller {
|
|
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
$this->load->library('session');
|
|
|
|
// Cek apakah user sudah login
|
|
if (!$this->session->userdata('logged_in')) {
|
|
redirect('auth');
|
|
}
|
|
}
|
|
|
|
public function index()
|
|
{
|
|
$this->db->select('
|
|
accounts.id,
|
|
accounts.kode_akun,
|
|
accounts.nama_akun,
|
|
accounts.tipe,
|
|
COALESCE(SUM(journal_details.debit),0) as debit,
|
|
COALESCE(SUM(journal_details.kredit),0) as kredit
|
|
');
|
|
$this->db->from('accounts');
|
|
$this->db->join('journal_details','accounts.id = journal_details.account_id','left');
|
|
$this->db->where('accounts.kategori','laba_rugi');
|
|
$this->db->where('accounts.is_active',1);
|
|
$this->db->group_by('accounts.id');
|
|
$this->db->order_by('accounts.kode_akun','ASC');
|
|
|
|
$rows = $this->db->get()->result();
|
|
|
|
$revenue = 0;
|
|
$expense = 0;
|
|
|
|
foreach ($rows as $r) {
|
|
|
|
// 🔥 NORMALISASI SALDO BERDASARKAN POSISI
|
|
if ($r->tipe == 'revenue') {
|
|
$saldo = $r->kredit - $r->debit;
|
|
$revenue += $saldo;
|
|
}
|
|
|
|
if ($r->tipe == 'expense') {
|
|
$saldo = $r->debit - $r->kredit;
|
|
$expense += $saldo;
|
|
}
|
|
}
|
|
|
|
$summary = [
|
|
'total_revenue' => $revenue,
|
|
'total_expense' => $expense,
|
|
'net_profit' => $revenue - $expense
|
|
];
|
|
|
|
$today = date('Y-m');
|
|
$ai_insight = $this->db
|
|
->select('type, severity, message, meta, created_at')
|
|
->where('period', $today)
|
|
->order_by("
|
|
CASE severity
|
|
WHEN 'critical' THEN 1
|
|
WHEN 'warning' THEN 2
|
|
WHEN 'info' THEN 3
|
|
END
|
|
", '', false)
|
|
->order_by('created_at', 'DESC')
|
|
->limit(20)
|
|
->get('ai_insights')
|
|
->result();
|
|
|
|
$data = [
|
|
"active_menu" => "dashboard",
|
|
"summary" => $summary,
|
|
"ai_insight" => $ai_insight
|
|
];
|
|
|
|
$this->load->view('partials/header', $data);
|
|
$this->load->view('dashboard/layout', $data);
|
|
$this->load->view('partials/footer');
|
|
}
|
|
|
|
public function get_activity()
|
|
{
|
|
$this->db->select('activity_logs.*, users.nama');
|
|
$this->db->from('activity_logs');
|
|
$this->db->join('users','users.id = activity_logs.user_id','left');
|
|
|
|
if ($this->session->userdata('role') != 'Admin') {
|
|
$this->db->where('user_id',$this->session->userdata('user_id'));
|
|
}
|
|
|
|
$this->db->order_by('created_at','DESC');
|
|
$this->db->limit(10);
|
|
|
|
$data = $this->db->get()->result();
|
|
|
|
echo json_encode($data);
|
|
}
|
|
|
|
public function log_activity()
|
|
{
|
|
$data = [
|
|
"active_menu" => "dashboard"
|
|
];
|
|
|
|
$this->load->view('partials/header', $data);
|
|
$this->load->view('dashboard/activity_logs', $data);
|
|
$this->load->view('partials/footer');
|
|
|
|
}
|
|
|
|
public function get_activity_datatable()
|
|
{
|
|
$this->load->database();
|
|
|
|
$draw = $this->input->post('draw');
|
|
$start = $this->input->post('start');
|
|
$length = $this->input->post('length');
|
|
$search = $this->input->post('search')['value'] ?? '';
|
|
|
|
// =========================
|
|
// BASE QUERY
|
|
// =========================
|
|
$this->db->select('
|
|
activity_logs.*,
|
|
users.nama
|
|
');
|
|
$this->db->from('activity_logs');
|
|
$this->db->join('users', 'users.id = activity_logs.user_id', 'left');
|
|
|
|
// =========================
|
|
// SEARCH
|
|
// =========================
|
|
if (!empty($search)) {
|
|
$this->db->group_start();
|
|
$this->db->like('activity_logs.module', $search);
|
|
$this->db->or_like('activity_logs.action', $search);
|
|
$this->db->or_like('activity_logs.description', $search);
|
|
$this->db->or_like('activity_logs.status', $search);
|
|
$this->db->or_like('users.nama', $search);
|
|
$this->db->group_end();
|
|
}
|
|
|
|
// =========================
|
|
// COUNT FILTERED
|
|
// =========================
|
|
$filtered_query = clone $this->db;
|
|
$recordsFiltered = $filtered_query->count_all_results('', false);
|
|
|
|
// =========================
|
|
// ORDER
|
|
// =========================
|
|
$this->db->order_by('activity_logs.id', 'DESC');
|
|
|
|
// =========================
|
|
// LIMIT
|
|
// =========================
|
|
if ($length != -1) {
|
|
$this->db->limit($length, $start);
|
|
}
|
|
|
|
$query = $this->db->get();
|
|
$data = $query->result();
|
|
|
|
// =========================
|
|
// TOTAL RECORD
|
|
// =========================
|
|
$recordsTotal = $this->db->count_all('activity_logs');
|
|
|
|
// =========================
|
|
// FORMAT OUTPUT
|
|
// =========================
|
|
$result = [];
|
|
|
|
foreach ($data as $row) {
|
|
$result[] = [
|
|
'created_at' => $row->created_at,
|
|
'nama' => $row->nama ?? 'System',
|
|
'module' => $row->module,
|
|
'action' => $row->action,
|
|
'description' => $row->description,
|
|
'status' => $row->status,
|
|
'ip_address' => $row->ip_address
|
|
];
|
|
}
|
|
|
|
echo json_encode([
|
|
"draw" => intval($draw),
|
|
"recordsTotal" => $recordsTotal,
|
|
"recordsFiltered" => $recordsFiltered,
|
|
"data" => $result
|
|
]);
|
|
}
|
|
|
|
public function get_chart()
|
|
{
|
|
$year = $this->input->get('year');
|
|
|
|
// 🔥 DEFAULT: tahun berjalan
|
|
if (empty($year)) {
|
|
$year = date('Y');
|
|
}
|
|
|
|
$this->db->select('
|
|
journals.tanggal,
|
|
accounts.tipe,
|
|
SUM(journal_details.debit) as total_debit,
|
|
SUM(journal_details.kredit) as total_kredit
|
|
');
|
|
$this->db->from('journal_details');
|
|
$this->db->join('journals', 'journals.id = journal_details.journal_id', 'left');
|
|
$this->db->join('accounts', 'accounts.id = journal_details.account_id', 'left');
|
|
$this->db->where('accounts.kategori', 'laba_rugi');
|
|
$this->db->where('accounts.is_active', 1);
|
|
|
|
// 🔥 pakai tahun default / filter
|
|
$this->db->where('YEAR(journals.tanggal)', $year);
|
|
|
|
$this->db->group_by(['journals.tanggal', 'accounts.tipe']);
|
|
$this->db->order_by('journals.tanggal', 'ASC');
|
|
|
|
$rows = $this->db->get()->result();
|
|
|
|
$map = [];
|
|
|
|
foreach ($rows as $r) {
|
|
|
|
$date = $r->tanggal;
|
|
|
|
if (!isset($map[$date])) {
|
|
$map[$date] = [
|
|
'revenue' => 0,
|
|
'expense' => 0
|
|
];
|
|
}
|
|
|
|
if ($r->tipe == 'revenue') {
|
|
$map[$date]['revenue'] += ($r->total_kredit - $r->total_debit);
|
|
}
|
|
|
|
if ($r->tipe == 'expense') {
|
|
$map[$date]['expense'] += ($r->total_debit - $r->total_kredit);
|
|
}
|
|
}
|
|
|
|
$labels = [];
|
|
$revenue = [];
|
|
$expense = [];
|
|
|
|
foreach ($map as $date => $val) {
|
|
$labels[] = $date;
|
|
$revenue[] = (float)$val['revenue'];
|
|
$expense[] = (float)$val['expense'];
|
|
}
|
|
|
|
echo json_encode([
|
|
'year' => $year, // optional biar debugging enak
|
|
'labels' => $labels,
|
|
'revenue' => $revenue,
|
|
'expense' => $expense
|
|
]);
|
|
}
|
|
|
|
public function get_years()
|
|
{
|
|
$this->db->select('DISTINCT YEAR(tanggal) as year');
|
|
$this->db->from('journals');
|
|
$this->db->order_by('year', 'DESC');
|
|
|
|
$data = $this->db->get()->result();
|
|
|
|
echo json_encode($data);
|
|
}
|
|
|
|
}
|