fix enrollment, invoice, payment and financila aid
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace App\Commands;
|
||||
|
||||
use App\Support\Enrollment\DeliberationDecision;
|
||||
use CodeIgniter\CLI\BaseCommand;
|
||||
use CodeIgniter\CLI\CLI;
|
||||
use CodeIgniter\Database\BaseConnection;
|
||||
|
||||
class EnrollmentDataAuditCommand extends BaseCommand
|
||||
{
|
||||
protected $group = 'Registration';
|
||||
protected $name = 'registration:enrollment-data-audit';
|
||||
protected $description = 'Audit withdrawn terminology normalization and duplicate enrollment rows per student/year.';
|
||||
protected $usage = 'php spark registration:enrollment-data-audit [--school-year=2026-2027] [--json]';
|
||||
protected $options = [
|
||||
'--school-year' => 'Optional school year filter for duplicate enrollment detection.',
|
||||
'--json' => 'Print machine-readable JSON.',
|
||||
];
|
||||
|
||||
private BaseConnection $db;
|
||||
|
||||
public function run(array $params)
|
||||
{
|
||||
$this->db = \Config\Database::connect();
|
||||
$schoolYear = trim((string) (CLI::getOption('school-year') ?? ''));
|
||||
|
||||
$report = [
|
||||
'generated_at' => date('Y-m-d H:i:s'),
|
||||
'school_year_filter' => $schoolYear !== '' ? $schoolYear : null,
|
||||
'withdrawn_normalization' => $this->auditWithdrawnValues(),
|
||||
'duplicate_enrollments' => $this->auditDuplicateEnrollments($schoolYear),
|
||||
];
|
||||
|
||||
if (CLI::getOption('json') !== null) {
|
||||
CLI::write(json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CLI::write('Enrollment Data Audit', 'green');
|
||||
CLI::newLine();
|
||||
CLI::write('Withdrawn / misspelling findings: ' . count($report['withdrawn_normalization']), 'yellow');
|
||||
foreach ($report['withdrawn_normalization'] as $row) {
|
||||
CLI::write(sprintf(
|
||||
' [%s] %s.%s = %s',
|
||||
$row['table'],
|
||||
$row['column'],
|
||||
$row['id'] ?? $row['student_id'] ?? '?',
|
||||
$row['value']
|
||||
));
|
||||
}
|
||||
CLI::newLine();
|
||||
CLI::write('Duplicate enrollment groups: ' . count($report['duplicate_enrollments']), 'yellow');
|
||||
foreach ($report['duplicate_enrollments'] as $group) {
|
||||
CLI::write(sprintf(
|
||||
' student=%d year=%s rows=%d ids=[%s]',
|
||||
$group['student_id'],
|
||||
$group['school_year'],
|
||||
$group['row_count'],
|
||||
implode(',', $group['enrollment_ids'])
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array<string, mixed>>
|
||||
*/
|
||||
private function auditWithdrawnValues(): array
|
||||
{
|
||||
$findings = [];
|
||||
$patterns = ['widthrawan', 'widthrwan', 'withdraw'];
|
||||
|
||||
if ($this->db->tableExists('enrollments')) {
|
||||
$rows = $this->db->table('enrollments')
|
||||
->select('id, student_id, school_year, enrollment_status')
|
||||
->get()
|
||||
->getResultArray();
|
||||
foreach ($rows as $row) {
|
||||
$status = strtolower(trim((string) ($row['enrollment_status'] ?? '')));
|
||||
foreach ($patterns as $pattern) {
|
||||
if ($status === $pattern || str_contains($status, $pattern)) {
|
||||
$findings[] = [
|
||||
'table' => 'enrollments',
|
||||
'column' => 'enrollment_status',
|
||||
'id' => (int) ($row['id'] ?? 0),
|
||||
'student_id' => (int) ($row['student_id'] ?? 0),
|
||||
'school_year' => (string) ($row['school_year'] ?? ''),
|
||||
'value' => (string) ($row['enrollment_status'] ?? ''),
|
||||
'recommended' => 'withdrawn',
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->db->tableExists('student_decisions')) {
|
||||
$rows = $this->db->table('student_decisions')
|
||||
->select('id, student_id, school_year, decision, deliberation_decision_standard')
|
||||
->get()
|
||||
->getResultArray();
|
||||
foreach ($rows as $row) {
|
||||
foreach (['decision', 'deliberation_decision_standard'] as $column) {
|
||||
$raw = (string) ($row[$column] ?? '');
|
||||
$normalized = DeliberationDecision::normalize($raw);
|
||||
if ($raw !== '' && $normalized === DeliberationDecision::WITHDRAWN && strtoupper($raw) !== DeliberationDecision::WITHDRAWN) {
|
||||
$findings[] = [
|
||||
'table' => 'student_decisions',
|
||||
'column' => $column,
|
||||
'id' => (int) ($row['id'] ?? 0),
|
||||
'student_id' => (int) ($row['student_id'] ?? 0),
|
||||
'school_year' => (string) ($row['school_year'] ?? ''),
|
||||
'value' => $raw,
|
||||
'recommended' => DeliberationDecision::WITHDRAWN,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $findings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array<string, mixed>>
|
||||
*/
|
||||
private function auditDuplicateEnrollments(string $schoolYear): array
|
||||
{
|
||||
if (! $this->db->tableExists('enrollments')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$builder = $this->db->table('enrollments')
|
||||
->select('student_id, school_year, COUNT(*) AS row_count, GROUP_CONCAT(id ORDER BY updated_at DESC, id DESC) AS enrollment_ids', false)
|
||||
->groupBy('student_id, school_year')
|
||||
->having('row_count >', 1);
|
||||
|
||||
if ($schoolYear !== '') {
|
||||
$builder->where('school_year', $schoolYear);
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
foreach ($builder->get()->getResultArray() as $row) {
|
||||
$ids = array_values(array_filter(array_map('intval', explode(',', (string) ($row['enrollment_ids'] ?? '')))));
|
||||
$groups[] = [
|
||||
'student_id' => (int) ($row['student_id'] ?? 0),
|
||||
'school_year' => (string) ($row['school_year'] ?? ''),
|
||||
'row_count' => (int) ($row['row_count'] ?? 0),
|
||||
'enrollment_ids' => $ids,
|
||||
];
|
||||
}
|
||||
|
||||
return $groups;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user