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); } }