set('dead.income_mode', 'percent'); $settings->set('dead.income_value', 10); $settings->set('dead.transaction_mode', 'fixed'); $settings->set('dead.transaction_value', 1); $budget->savePlan('2026-01', 1000, 0, true, 'Self-test'); $categoryId = $budget->addCategory('Utilities', '#49a8ff', 200); $itemId = $budget->addBudgetItem('2026-01', $categoryId, 'Internet', 55, '2026-01-20', 'monthly', ''); $transactionId = $budget->addTransaction('2026-01', $itemId, null, 'Internet payment', 10, '2026-01-10', ''); $january = $budget->summary('2026-01'); $assert(abs($january['remaining'] - 889) < 0.001, 'January remaining balance is incorrect.'); $assert(abs($budget->budgetItems('2026-01')[0]['remaining_amount'] - 45) < 0.001, 'Target progress is incorrect.'); $budget->updateTransaction($transactionId, '2026-01', $itemId, null, 'Internet payment', 20, '2026-01-10', ''); $budget->moveDeadAccount('2026-01', 'restore', 50, '', 'item', $itemId); $january = $budget->summary('2026-01'); $assert(abs($january['remaining'] - 929) < 0.001, 'Dormant restoration accounting is incorrect.'); $assert(abs($budget->deadBalance() - 51) < 0.001, 'Dormant balance is incorrect.'); $february = $budget->ensureMonth('2026-02'); $februaryItems = $budget->budgetItems('2026-02'); $assert(abs((float) $february['rollover_in'] - 929) < 0.001, 'Rolling budget did not carry the remainder forward.'); $assert(count($februaryItems) === 1 && $februaryItems[0]['name'] === 'Internet', 'Recurring target was not materialized.'); $year = $budget->yearlySummary(2026); $assert(abs($year['totals']['fresh_income'] - 1000) < 0.001, 'Yearly income double-counted rollover.'); $exporter = new ExportService($pdo, $settings, $budget); $package = json_decode($exporter->package(), true); $assert(($package['format'] ?? null) === 'neon-ledger/budget-planner', 'JSON package format is invalid.'); $assert(str_contains($exporter->html('2026-01'), 'Internet'), 'HTML export is missing target data.'); $assert(str_starts_with($exporter->pdf('2026-01'), '%PDF-1.4'), 'PDF export is invalid.'); echo "Neon Ledger self-test passed.\n";