Commit cc929837 authored by Mahmoud Aglan's avatar Mahmoud Aglan

fix(subscriptions): improve orphan matching to include archived dependents

When matching orphaned person_ids, also search archived/inactive records
since subscriptions may reference people who were active at creation time.
Validate method also checks ALL records, not just active ones.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 4806bcdc
......@@ -75,9 +75,9 @@ final class SubscriptionDataMigration
);
foreach ($orphanedSpouses as $os) {
// Try to match by name
// Try to match by name (check active first, then archived)
$match = $this->db->selectOne(
"SELECT id FROM spouses WHERE member_id = ? AND full_name_ar = ? AND is_archived = 0",
"SELECT id FROM spouses WHERE member_id = ? AND full_name_ar = ? ORDER BY is_archived ASC LIMIT 1",
[(int)$os['member_id'], $os['person_name']]
);
if (!$match) {
......@@ -120,7 +120,7 @@ final class SubscriptionDataMigration
foreach ($orphanedChildren as $oc) {
$match = $this->db->selectOne(
"SELECT id FROM children WHERE member_id = ? AND full_name_ar = ? AND is_archived = 0",
"SELECT id FROM children WHERE member_id = ? AND full_name_ar = ? ORDER BY is_archived ASC LIMIT 1",
[(int)$oc['member_id'], $oc['person_name']]
);
if (!$match) {
......@@ -162,7 +162,7 @@ final class SubscriptionDataMigration
foreach ($orphanedTemps as $ot) {
$match = $this->db->selectOne(
"SELECT id FROM temporary_members WHERE member_id = ? AND full_name_ar = ? AND is_archived = 0",
"SELECT id FROM temporary_members WHERE member_id = ? AND full_name_ar = ? ORDER BY is_archived ASC LIMIT 1",
[(int)$ot['member_id'], $ot['person_name']]
);
if ($match && !$dryRun) {
......@@ -489,13 +489,13 @@ final class SubscriptionDataMigration
$issues[] = ['type' => 'duplicates', 'count' => count($dupes), 'details' => $dupes];
}
// Check 5: Orphaned person_ids
// Check 5: Orphaned person_ids (check ALL records including archived)
$orphans = $this->db->select(
"SELECT s.id, s.member_id, s.person_type, s.person_id, s.financial_year
FROM subscriptions s
WHERE (s.person_type = 'spouse' AND s.person_id NOT IN (SELECT id FROM spouses WHERE member_id = s.member_id))
OR (s.person_type = 'child' AND s.person_id NOT IN (SELECT id FROM children WHERE member_id = s.member_id))
OR (s.person_type = 'temporary' AND s.person_id NOT IN (SELECT id FROM temporary_members WHERE member_id = s.member_id))"
WHERE (s.person_type = 'spouse' AND NOT EXISTS (SELECT 1 FROM spouses WHERE id = s.person_id AND member_id = s.member_id))
OR (s.person_type = 'child' AND NOT EXISTS (SELECT 1 FROM children WHERE id = s.person_id AND member_id = s.member_id))
OR (s.person_type = 'temporary' AND NOT EXISTS (SELECT 1 FROM temporary_members WHERE id = s.person_id AND member_id = s.member_id))"
);
if (!empty($orphans)) {
$issues[] = ['type' => 'orphaned_person_ids', 'count' => count($orphans), 'details' => $orphans];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment