CI =& get_instance(); $this->CI->load->library('AuditService'); } public function save(array $input, $id = null, $userId = null) { $code = trim(isset($input['kode_akun']) ? $input['kode_akun'] : ''); $name = trim(isset($input['nama_akun']) ? $input['nama_akun'] : ''); $type = isset($input['tipe']) ? $input['tipe'] : ''; $parentId = !empty($input['parent_id']) ? (int) $input['parent_id'] : null; $isHeader = !empty($input['is_header']) ? 1 : 0; $allowPosting = $isHeader ? 0 : (!empty($input['allow_posting']) ? 1 : 0); if ($code === '' || $name === '') { throw new BusinessException('Kode dan nama akun wajib diisi.'); } if (!preg_match('/^[0-9]{4}$/', $code)) { throw new BusinessException('Kode akun wajib terdiri dari tepat 4 angka.'); } if (!in_array($type, array('asset', 'liability', 'equity', 'revenue', 'expense'), true)) { throw new BusinessException('Tipe akun tidak valid.'); } $duplicateQuery = $this->CI->db->where('kode_akun', $code); if ($id) $duplicateQuery->where('id !=', (int) $id); if ($duplicateQuery->count_all_results('accounts') > 0) { throw new BusinessException('Kode akun sudah digunakan.'); } if ($parentId) { if ($id && $parentId === (int) $id) { throw new BusinessException('Akun tidak dapat menjadi parent untuk dirinya sendiri.'); } $parent = $this->CI->db->get_where('accounts', array('id' => $parentId))->row(); if (!$parent) { throw new BusinessException('Parent akun tidak ditemukan.'); } if ($id && $this->wouldCreateCycle((int) $id, $parentId)) { throw new BusinessException('Parent akun tersebut akan membentuk hierarki melingkar.'); } } if ($id && $isHeader && $this->CI->db->where('account_id', (int) $id)->count_all_results('journal_details') > 0) { throw new BusinessException('Akun yang sudah mempunyai transaksi tidak dapat diubah menjadi akun header.'); } $data = array( 'kode_akun' => $code, 'nama_akun' => $name, 'tipe' => $type, 'posisi' => in_array($type, array('asset', 'expense'), true) ? 'debit' : 'kredit', 'kategori' => in_array($type, array('asset', 'liability', 'equity'), true) ? 'neraca' : 'laba_rugi', 'parent_id' => $parentId, 'priority' => isset($input['priority']) && $input['priority'] !== '' ? (int) $input['priority'] : null, 'is_header' => $isHeader, 'allow_posting' => $allowPosting, 'is_active' => isset($input['is_active']) ? (!empty($input['is_active']) ? 1 : 0) : 1, 'is_hidden' => !empty($input['is_hidden']) ? 1 : 0, 'updated_at' => date('Y-m-d H:i:s'), 'updated_by' => $userId ? (int) $userId : null ); if ($id) { $before = $this->CI->db->get_where('accounts', array('id'=>(int)$id))->row(); $this->CI->db->where('id', (int) $id)->update('accounts', $data); $this->CI->auditservice->record('chart_of_accounts','account',(int)$id,'update',$before,$this->CI->db->get_where('accounts',array('id'=>(int)$id))->row(),$userId); return (int) $id; } $this->CI->db->insert('accounts', $data); $newId=(int)$this->CI->db->insert_id(); $this->CI->auditservice->record('chart_of_accounts','account',$newId,'create',null,$this->CI->db->get_where('accounts',array('id'=>$newId))->row(),$userId); return $newId; } public function delete($id, $userId = null) { $id = (int) $id; if ($this->CI->db->where('parent_id', $id)->count_all_results('accounts') > 0) { throw new BusinessException('Akun memiliki child dan tidak dapat dihapus.'); } if ($this->CI->db->where('account_id', $id)->count_all_results('journal_details') > 0) { throw new BusinessException('Akun sudah mempunyai transaksi dan tidak dapat dihapus. Nonaktifkan akun sebagai gantinya.'); } if ($this->CI->db->where('account_id', $id)->count_all_results('system_account_mappings') > 0) { throw new BusinessException('Akun masih digunakan sebagai mapping akun sistem.'); } $before=$this->CI->db->get_where('accounts',array('id'=>$id))->row(); $result=$this->CI->db->where('id', $id)->delete('accounts'); if($result) $this->CI->auditservice->record('chart_of_accounts','account',$id,'delete',$before,null,$userId); return $result; } private function wouldCreateCycle($accountId, $parentId) { $visited = array(); while ($parentId) { if ($parentId === $accountId || isset($visited[$parentId])) return true; $visited[$parentId] = true; $row = $this->CI->db->select('parent_id')->get_where('accounts', array('id' => $parentId))->row(); $parentId = $row && $row->parent_id ? (int) $row->parent_id : null; } return false; } }