37241-vm/includes/journal_helpers.php
2026-01-03 08:40:36 +00:00

62 lines
2.7 KiB
PHP

<?php
require_once __DIR__ . '/uuid.php';
require_once __DIR__ . '/audit_helpers.php';
function post_journal_entry(PDO $pdo, array $payload): array
{
try {
if (empty($payload['entry_date']) || empty($payload['description']) || empty($payload['lines'])) {
return ['error' => 'Missing required fields for journal entry'];
}
// --- Accounting Period Control ---
$stmt_period_check = $pdo->prepare(
"SELECT COUNT(*) FROM accounting_periods WHERE status = 'closed' AND :entry_date BETWEEN start_date AND end_date"
);
$stmt_period_check->execute([':entry_date' => $payload['entry_date']]);
if ($stmt_period_check->fetchColumn() > 0) {
return ['error' => 'Cannot post transaction to a closed accounting period.'];
}
// --- End Control ---
$total_debits = 0;
$total_credits = 0;
foreach ($payload['lines'] as $line) {
$debit = isset($line['debit']) ? $line['debit'] : 0;
$credit = isset($line['credit']) ? $line['credit'] : 0;
$total_debits += $debit;
$total_credits += $credit;
}
if (round($total_debits, 2) !== round($total_credits, 2) || $total_debits === 0) {
return ['error' => 'Debits and credits must balance and not be zero.'];
}
$journal_entry_id = uuid_v4();
$stmt_je = $pdo->prepare("INSERT INTO journal_entries (id, entry_date, description, status) VALUES (?, ?, ?, 'posted')");
$stmt_je->execute([$journal_entry_id, $payload['entry_date'], $payload['description']]);
$stmt_lines = $pdo->prepare("INSERT INTO journal_lines (id, journal_entry_id, account_code, debit_amount, credit_amount) VALUES (?, ?, ?, ?, ?)");
$stmt_subledger = $pdo->prepare("INSERT INTO journal_line_subledgers (journal_line_id, subledger_id) VALUES (?, ?)");
foreach ($payload['lines'] as $line) {
$journal_line_id = uuid_v4();
$debit = $line['debit'] ?? 0;
$credit = $line['credit'] ?? 0;
$stmt_lines->execute([$journal_line_id, $journal_entry_id, $line['account_code'], $debit, $credit]);
if (!empty($line['subledger_id'])) {
$stmt_subledger->execute([$journal_line_id, $line['subledger_id']]);
}
}
// Log audit trail
log_audit_trail($pdo, 'post_journal_entry', ['journal_entry_id' => $journal_entry_id, 'description' => $payload['description']]);
return ['success' => true, 'journal_entry_id' => $journal_entry_id];
} catch (PDOException $e) {
return ['error' => 'Database error in post_journal_entry: ' . $e->getMessage()];
}
}