update policy and fix other issues
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class BackfillReturningStudentYearStatus extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! $this->db->tableExists('student_year_status') || ! $this->db->tableExists('school_years')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$years = $this->db->table('school_years')
|
||||
->select('id, name, previous_school_year_id')
|
||||
->orderBy('id', 'ASC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
$yearsById = [];
|
||||
$yearsByName = [];
|
||||
foreach ($years as $year) {
|
||||
$id = (int) ($year['id'] ?? 0);
|
||||
$name = trim((string) ($year['name'] ?? ''));
|
||||
if ($id > 0 && preg_match('/^\d{4}-\d{4}$/', $name)) {
|
||||
$yearsById[$id] = $year;
|
||||
$yearsByName[$name] = $year;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($yearsById as $targetYear) {
|
||||
$targetName = trim((string) ($targetYear['name'] ?? ''));
|
||||
$sourceName = $this->sourceYearName($targetYear, $yearsById, $yearsByName);
|
||||
if ($sourceName === null || $sourceName === $targetName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($this->returningStudentIds($sourceName) as $studentId) {
|
||||
$this->upsertReturningStatus($studentId, $targetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// No rollback: this migration repairs source-of-truth status rows.
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $targetYear
|
||||
* @param array<int, array<string, mixed>> $yearsById
|
||||
* @param array<string, array<string, mixed>> $yearsByName
|
||||
*/
|
||||
private function sourceYearName(array $targetYear, array $yearsById, array $yearsByName): ?string
|
||||
{
|
||||
$previousId = (int) ($targetYear['previous_school_year_id'] ?? 0);
|
||||
if ($previousId > 0) {
|
||||
$name = trim((string) ($yearsById[$previousId]['name'] ?? ''));
|
||||
if (preg_match('/^\d{4}-\d{4}$/', $name)) {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
$targetName = trim((string) ($targetYear['name'] ?? ''));
|
||||
if (! preg_match('/^(\d{4})-(\d{4})$/', $targetName, $matches)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sourceName = ((int) $matches[1] - 1) . '-' . ((int) $matches[2] - 1);
|
||||
|
||||
return isset($yearsByName[$sourceName]) ? $sourceName : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<int>
|
||||
*/
|
||||
private function returningStudentIds(string $sourceSchoolYear): array
|
||||
{
|
||||
$ids = [];
|
||||
|
||||
foreach (['student_year_status', 'student_class', 'enrollments'] as $table) {
|
||||
if (! $this->db->tableExists($table) || ! $this->db->fieldExists('school_year', $table)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$rows = $this->db->table($table)
|
||||
->select('student_id')
|
||||
->where('school_year', $sourceSchoolYear)
|
||||
->where('student_id IS NOT NULL', null, false)
|
||||
->groupBy('student_id')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$studentId = (int) ($row['student_id'] ?? 0);
|
||||
if ($studentId > 0) {
|
||||
$ids[$studentId] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_keys($ids);
|
||||
}
|
||||
|
||||
private function upsertReturningStatus(int $studentId, string $targetSchoolYear): void
|
||||
{
|
||||
if ($studentId <= 0 || ! preg_match('/^\d{4}-\d{4}$/', $targetSchoolYear)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = date('Y-m-d H:i:s');
|
||||
$existing = $this->db->table('student_year_status')
|
||||
->select('id, is_new')
|
||||
->where('student_id', $studentId)
|
||||
->where('school_year', $targetSchoolYear)
|
||||
->get(1)
|
||||
->getRowArray();
|
||||
|
||||
if ($existing !== null) {
|
||||
if ((int) ($existing['is_new'] ?? 1) !== 0) {
|
||||
$this->db->table('student_year_status')
|
||||
->where('id', (int) $existing['id'])
|
||||
->update([
|
||||
'is_new' => 0,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->db->table('student_year_status')->insert([
|
||||
'student_id' => $studentId,
|
||||
'school_year' => $targetSchoolYear,
|
||||
'is_new' => 0,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user