prepare('SELECT id FROM tenants WHERE slug = ?'); $stmt->execute([$slug]); $tenantId = $stmt->fetchColumn(); if ($tenantId === false) { throw new RuntimeException("Tenant '{$slug}' not found."); } return (int)$tenantId; } /** * @return array{total_payments_cents: int, total_costs_cents: int, total_marks: int, balance_cents: int, year_payments_cents: int, year_costs_cents: int, year_marks: int} */ function m4_service_totals_from_summaries(array $summaries): array { $totals = ledger_empty_totals(); foreach ($summaries as $summary) { $totals['total_payments_cents'] += (int)$summary['total_payments_cents']; $totals['total_costs_cents'] += (int)$summary['total_costs_cents']; $totals['total_marks'] += (int)$summary['total_marks']; $totals['balance_cents'] += (int)$summary['balance_cents']; $totals['year_payments_cents'] += (int)$summary['year_payments_cents']; $totals['year_costs_cents'] += (int)$summary['year_costs_cents']; $totals['year_marks'] += (int)$summary['year_marks']; } return $totals; } $pdo = dev_pdo(); dev_apply_schema($pdo); $tenantSlug = m4_service_env('M4_DEFAULT_TENANT_SLUG', m4_service_env('M3_DEFAULT_TENANT_SLUG', 'default')); $tenantId = m4_service_fetch_tenant_id($pdo, $tenantSlug); $expected = gm_expected_summaries(); $emails = array_keys($expected); $failures = []; $passes = 0; $summaries = ledger_fetch_participant_summaries($pdo, $tenantId, [ 'email_norms' => $emails, 'year' => gm_current_year(), ]); $summariesByEmail = []; foreach ($summaries as $summary) { if ($summary['email_norm'] !== null) { $summariesByEmail[$summary['email_norm']] = $summary; } } m4_service_assert_equal('ledger service summary count', count($expected), count($summariesByEmail), $failures, $passes); $keyMap = [ 'total_payments' => 'total_payments_cents', 'total_costs' => 'total_costs_cents', 'total_marks' => 'total_marks', 'balance' => 'balance_cents', 'year_payments' => 'year_payments_cents', 'year_costs' => 'year_costs_cents', 'year_marks' => 'year_marks', ]; foreach ($expected as $email => $expectedSummary) { m4_service_assert("ledger service summary exists {$email}", isset($summariesByEmail[$email]), $failures, $passes); if (!isset($summariesByEmail[$email])) { continue; } m4_service_assert( "ledger service {$email} keeps legacy member id", $summariesByEmail[$email]['legacy_mitarbeiter_id'] !== null, $failures, $passes ); foreach ($keyMap as $expectedKey => $actualKey) { m4_service_assert_equal( "ledger service {$email} {$expectedKey}", $expectedSummary[$expectedKey], $summariesByEmail[$email][$actualKey], $failures, $passes ); } } $allSummaries = ledger_fetch_participant_summaries($pdo, $tenantId, [ 'year' => gm_current_year(), ]); $tenantTotals = ledger_fetch_tenant_totals($pdo, $tenantId, gm_current_year()); foreach (m4_service_totals_from_summaries($allSummaries) as $key => $value) { m4_service_assert_equal("ledger service tenant total {$key}", $value, $tenantTotals[$key], $failures, $passes); } $stmt = $pdo->prepare('SELECT COUNT(*) FROM participants WHERE tenant_id = ? AND active = 1'); $stmt->execute([$tenantId]); $activeExpectedCount = (int)$stmt->fetchColumn(); $activeSummaries = ledger_fetch_participant_summaries($pdo, $tenantId, ['active_only' => true]); m4_service_assert_equal('ledger service active participant count', $activeExpectedCount, count($activeSummaries), $failures, $passes); $paypalSummary = $summariesByEmail['gm-paypal@test.local'] ?? null; m4_service_assert('ledger service paypal summary is present', $paypalSummary !== null, $failures, $passes); if ($paypalSummary !== null) { $singleSummary = ledger_fetch_participant_summary($pdo, $tenantId, $paypalSummary['participant_id'], gm_current_year()); m4_service_assert('ledger service single participant summary is present', $singleSummary !== null, $failures, $passes); if ($singleSummary !== null) { m4_service_assert_equal('ledger service single participant email', 'gm-paypal@test.local', $singleSummary['email_norm'], $failures, $passes); m4_service_assert_equal('ledger service single participant balance', 650, $singleSummary['balance_cents'], $failures, $passes); } $legacySummary = ledger_fetch_participant_summary_by_legacy_id( $pdo, $tenantId, (int)$paypalSummary['legacy_mitarbeiter_id'], gm_current_year() ); m4_service_assert('ledger service legacy participant summary is present', $legacySummary !== null, $failures, $passes); if ($legacySummary !== null) { m4_service_assert_equal('ledger service legacy participant id matches', $paypalSummary['participant_id'], $legacySummary['participant_id'], $failures, $passes); m4_service_assert_equal('ledger service legacy participant balance', 650, $legacySummary['balance_cents'], $failures, $passes); } $paypalEntries = ledger_fetch_recent_entries($pdo, $tenantId, [ 'participant_id' => $paypalSummary['participant_id'], 'limit' => 100, ]); m4_service_assert_equal('ledger service paypal entry count', 2, count($paypalEntries), $failures, $passes); foreach ($paypalEntries as $entry) { m4_service_assert_equal('ledger service paypal entry tenant', $tenantId, $entry['tenant_id'], $failures, $passes); m4_service_assert_equal('ledger service paypal entry participant', $paypalSummary['participant_id'], $entry['participant_id'], $failures, $passes); } } $recentEntries = ledger_fetch_recent_entries($pdo, $tenantId, ['limit' => 5]); m4_service_assert_equal('ledger service recent entry limit', 5, count($recentEntries), $failures, $passes); $previousBookedAt = null; foreach ($recentEntries as $entry) { m4_service_assert_equal('ledger service recent entry tenant', $tenantId, $entry['tenant_id'], $failures, $passes); m4_service_assert('ledger service recent entry has amount', $entry['amount_cents'] !== 0, $failures, $passes); if ($previousBookedAt !== null) { m4_service_assert('ledger service recent entries are sorted', $previousBookedAt >= $entry['booked_at'], $failures, $passes); } $previousBookedAt = $entry['booked_at']; } $legacyConsumptionCount = (int)$pdo->query('SELECT COUNT(*) FROM kl_Kaffeeverbrauch')->fetchColumn(); $consumptionEntries = ledger_fetch_recent_entries($pdo, $tenantId, [ 'type' => 'consumption', 'limit' => 100, ]); m4_service_assert_equal('ledger service consumption entry count', $legacyConsumptionCount, count($consumptionEntries), $failures, $passes); m4_service_assert_equal('ledger service empty participant id filter', [], ledger_fetch_participant_summaries($pdo, $tenantId, [ 'participant_ids' => [], ]), $failures, $passes); m4_service_assert_equal('ledger service empty legacy id filter', [], ledger_fetch_participant_summaries($pdo, $tenantId, [ 'legacy_mitarbeiter_ids' => [], ]), $failures, $passes); m4_service_assert_equal('ledger service unknown legacy summary', null, ledger_fetch_participant_summary_by_legacy_id($pdo, $tenantId, 0), $failures, $passes); m4_service_assert_equal('ledger service unknown tenant summaries', [], ledger_fetch_participant_summaries($pdo, 0), $failures, $passes); m4_service_assert_equal('ledger service unknown tenant entries', [], ledger_fetch_recent_entries($pdo, 0), $failures, $passes); m4_service_assert_equal('ledger service unknown tenant totals', ledger_empty_totals(), ledger_fetch_tenant_totals($pdo, 0), $failures, $passes); if ($failures !== []) { echo "\nM4 ledger service check failed with " . count($failures) . " failure(s):\n"; foreach ($failures as $failure) { echo "- {$failure}\n"; } exit(1); } echo "\nM4 ledger service check passed with {$passes} assertions.\n";