Files
2026-09-11 16:03:00 +07:00

35 lines
4.6 KiB
PHP

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/** Read-only integrity checker: php index.php fixedassetcheck */
class Fixedassetcheck extends CI_Controller
{
public function index()
{
if (!is_cli()) show_404();
$checks=array();
$checks['duplicate_asset_document']=$this->scalar("SELECT COUNT(*) FROM (SELECT company_id,document_no FROM assets GROUP BY company_id,document_no HAVING COUNT(*)>1)x");
$checks['duplicate_event_idempotency']=$this->scalar("SELECT COUNT(*) FROM (SELECT idempotency_key FROM asset_events WHERE idempotency_key IS NOT NULL GROUP BY idempotency_key HAVING COUNT(*)>1)x");
$checks['capitalized_without_event']=$this->scalar("SELECT COUNT(*) FROM assets a WHERE a.workflow_status='capitalized' AND NOT EXISTS(SELECT 1 FROM asset_events e WHERE e.asset_id=a.id AND e.company_id=a.company_id AND e.event_type IN('acquisition','capitalization'))");
$checks['active_below_residual']=$this->scalar("SELECT COUNT(*) FROM assets WHERE lifecycle_status IN('active','fully_depreciated') AND nilai_buku+0.005<nilai_residu");
$checks['duplicate_depreciation_period']=$this->scalar("SELECT COUNT(*) FROM (SELECT company_id,asset_id,period FROM asset_depreciation_schedule GROUP BY company_id,asset_id,period HAVING COUNT(*)>1)x");
$checks['unbalanced_asset_journals']=$this->scalar("SELECT COUNT(*) FROM (SELECT j.id FROM journals j JOIN journal_details d ON d.journal_id=j.id WHERE j.ref_type LIKE 'asset_%' AND j.status='posted' GROUP BY j.id HAVING ABS(SUM(d.debit)-SUM(d.kredit))>0.005)x");
$checks['cross_company_asset_attachment']=$this->scalar("SELECT COUNT(*) FROM transaction_attachments t JOIN assets a ON t.entity_type='asset' AND t.entity_id=a.id WHERE t.company_id IS NULL OR t.company_id<>a.company_id");
$checks['warehouse_capitalization_without_ledger']=$this->scalar("SELECT COUNT(*) FROM assets a WHERE a.source_type='warehouse' AND a.workflow_status='capitalized' AND a.idempotency_key NOT LIKE 'LEGACY-ASSET-%' AND NOT EXISTS(SELECT 1 FROM inventory_ledger l WHERE l.document_type='asset_capitalization' AND l.document_id=a.id)");
$checks['invalid_asset_posting_account']=$this->scalar("SELECT COUNT(*) FROM assets a LEFT JOIN accounts ac ON ac.id=a.asset_account_id AND ac.company_id=a.company_id AND ac.is_active=1 AND ac.allow_posting=1 WHERE a.workflow_status IN('draft','submitted','approved') AND (a.asset_account_id IS NULL OR ac.id IS NULL)");
$checks['invalid_accumulated_account_scope']=$this->scalar("SELECT COUNT(*) FROM assets a LEFT JOIN accounts ac ON ac.id=a.accumulated_depreciation_account_id AND ac.company_id=a.company_id WHERE a.workflow_status IN('draft','submitted','approved','capitalized') AND a.idempotency_key NOT LIKE 'LEGACY-ASSET-%' AND (a.accumulated_depreciation_account_id IS NULL OR ac.id IS NULL)");
$checks['invalid_expense_account_scope']=$this->scalar("SELECT COUNT(*) FROM assets a LEFT JOIN accounts ac ON ac.id=a.depreciation_expense_account_id AND ac.company_id=a.company_id WHERE a.workflow_status IN('draft','submitted','approved','capitalized') AND a.idempotency_key NOT LIKE 'LEGACY-ASSET-%' AND (a.depreciation_expense_account_id IS NULL OR ac.id IS NULL)");
$fail=0;foreach($checks as$name=>$count){$ok=(int)$count===0;if(!$ok)$fail++;echo($ok?'[OK] ':'[WARN] ').$name.': '.$count.PHP_EOL;}
$totals=$this->db->query("SELECT COUNT(*) total,COALESCE(SUM(IF(workflow_status='capitalized' AND lifecycle_status NOT IN('disposed','lost','damaged'),nilai_perolehan,0)),0) cost,COALESCE(SUM(IF(workflow_status='capitalized' AND lifecycle_status NOT IN('disposed','lost','damaged'),akumulasi_penyusutan,0)),0) accumulated FROM assets")->row();
echo 'Assets: '.$totals->total.' | Cost: '.$totals->cost.' | Accumulated: '.$totals->accumulated.PHP_EOL;
$statusColumn=$this->db->query("SHOW COLUMNS FROM assets WHERE Field='status'")->row();echo '[INFO] assets.status: '.($statusColumn->Type??'missing').PHP_EOL;
$this->load->model('FixedAssetModel','fixedasset');
foreach($this->db->select('id')->get('companies')->result() as$company){
$this->fixedasset->dashboard($company->id);$this->fixedasset->categories($company->id);$this->fixedasset->locations($company->id);$this->fixedasset->opnames($company->id);$this->fixedasset->registerPage($company->id,array(),0,5,'');
echo '[OK] model_query_smoke_company_'.$company->id.PHP_EOL;
}
echo $fail?'Integrity warnings: '.$fail.PHP_EOL:'Fixed asset integrity checks passed.'.PHP_EOL;
}
private function scalar($sql){return(int)$this->db->query($sql)->row_array()['COUNT(*)'];}
}