load->database(); // ONLY CLI ACCESS if (!$this->input->is_cli_request()) { exit('No direct access allowed'); } } public function generate_insight() { $period = date('Y-m'); // ===================================================== // 🔥 REPLACE MODE (hapus data lama dulu) // ===================================================== $this->db->where('period', $period); $this->db->delete('ai_insights'); // ===================================================== // 1. FINANCE - OVERDUE INVOICE // ===================================================== $overdue = $this->db->query(" SELECT COUNT(*) as total FROM invoices WHERE status != 'paid' AND jatuh_tempo < CURDATE() AND deleted_at IS NULL ")->row()->total; if ($overdue > 0) { $this->db->insert('ai_insights', [ 'type' => 'finance', 'severity' => 'warning', 'message' => "$overdue invoice sudah melewati jatuh tempo", 'meta' => json_encode([ 'overdue_count' => (int)$overdue ]), 'period' => $period ]); } // ===================================================== // 2. FINANCE - CASHFLOW BULAN INI // ===================================================== $cash = $this->db->query(" SELECT COALESCE(SUM(jd.debit),0) as cash_in FROM journal_details jd JOIN journals j ON j.id = jd.journal_id WHERE MONTH(j.tanggal) = MONTH(CURDATE()) AND YEAR(j.tanggal) = YEAR(CURDATE()) ")->row()->cash_in; if ($cash > 0) { $this->db->insert('ai_insights', [ 'type' => 'finance', 'severity' => ($cash > 10000000) ? 'info' : 'warning', 'message' => "Cashflow bulan ini Rp " . number_format($cash), 'meta' => json_encode([ 'cash_in' => (float)$cash ]), 'period' => $period ]); } // ===================================================== // 3. STOCK - KRITIS // ===================================================== $stocks = $this->db->query(" SELECT i.kode_id, k.nama_barang, SUM(i.stok) as total_stok, k.limit_stock FROM items i JOIN kode_barang k ON k.id = i.kode_id GROUP BY i.kode_id, k.nama_barang, k.limit_stock HAVING total_stok <= k.limit_stock ")->result(); foreach ($stocks as $s) { $this->db->insert('ai_insights', [ 'type' => 'stock', 'severity' => 'critical', 'message' => "Stok {$s->nama_barang} kritis ({$s->total_stok})", 'meta' => json_encode([ 'kode_id' => $s->kode_id, 'item' => $s->nama_barang, 'stok' => (int)$s->total_stok, 'limit' => (int)$s->limit_stock ]), 'period' => $period ]); } // ===================================================== // 4. CUSTOMER - PAYMENT RISK // ===================================================== $lateCustomers = $this->db->query(" SELECT c.nama, COUNT(i.id) as total_invoice FROM invoices i JOIN customers c ON c.id = i.customer_id WHERE i.status != 'paid' AND i.jatuh_tempo < CURDATE() GROUP BY i.customer_id HAVING total_invoice > 2 ")->result(); foreach ($lateCustomers as $c) { $this->db->insert('ai_insights', [ 'type' => 'customer', 'severity' => 'warning', 'message' => "Customer {$c->nama} memiliki {$c->total_invoice} invoice overdue", 'meta' => json_encode([ 'customer' => $c->nama, 'overdue_invoice' => (int)$c->total_invoice ]), 'period' => $period ]); } // ===================================================== // RESPONSE // ===================================================== echo json_encode([ 'status' => true, 'message' => 'AI Insight generated (REPLACE MODE)', 'period' => $period ]); } }