proc group_benefit_units_with_tags {household} { array set incomePriority { ODSP 1 OW 2 CPPD 3 Support 4 CPP 5 Employment 6 PartTimeJob 7 EI 8 } array set personMap {} array set grouped {} set units {} # Step 1: Index everyone and initialize tags foreach person $household { array set p $person set name $p(name) set age $p(age) # Determine age category if {$age < 18} { set ageCategory "child" } elseif {$age < 65} { set ageCategory "adult" } else { set ageCategory "senior" } set incomeList $p(incomes) set bestIncomeType "" set bestPriority 999 foreach income $incomeList { if {[info exists incomePriority($income)] && $incomePriority($income) < $bestPriority} { set bestIncomeType $income set bestPriority $incomePriority($income) } } # Social assistance flag set isSocialAssistanceUnit [expr {$bestIncomeType eq "ODSP" || $bestIncomeType eq "OW"}] # Student-based exemption set studentStatus [expr {[info exists p(studentStatus)] ? $p(studentStatus) : "none"}] set incomeExempt 0 if {$age < 18 || ($age < 21 && $studentStatus eq "fulltime")} { set incomeExempt 1 } # Tag info set tagged [list \ name $name \ age $age \ ageCategory $ageCategory \ incomes $incomeList \ incomeExempt $incomeExempt \ studentStatus $studentStatus \ spouse [expr {[info exists p(spouse)] ? $p(spouse) : ""}] \ dependentsOf [expr {[info exists p(dependentsOf)] ? $p(dependentsOf) : ""}] \ isSocialAssistanceUnit $isSocialAssistanceUnit \ relationship [expr {$ageCategory eq "child" ? "child" : ([info exists p(spouse)] && $p(spouse) ne "" ? "spouse" : "single")}] ] set personMap($name) $tagged } # Step 2: Group benefit units (use logic from prior version) foreach name [array names personMap] { if {[info exists grouped($name)]} { continue } array set p $personMap($name) if {$p(isSocialAssistanceUnit)} { lappend units [list $personMap($name)] set grouped($name) 1 continue } # Try to group with spouse if {$p(spouse) ne "" && [info exists personMap($p(spouse))] && ![info exists grouped($p(spouse))]} { set spouseInfo $personMap($p(spouse)) lappend units [list $personMap($name) $spouseInfo] set grouped($name) 1 set grouped($p(spouse)) 1 continue } # Fallback: single unit lappend units [list $personMap($name)] set grouped($name) 1 } # Step 3: Attach dependents foreach name [array names personMap] { array set p $personMap($name) if {$p(dependentsOf) ne ""} { set parent $p(dependentsOf) foreach i $units { foreach j $i { array set pj $j if {$pj(name) eq $parent} { # Attach dependent to this unit set idx [lsearch -exact $units $i] set newUnit [concat $i $personMap($name)] set units [lreplace $units $idx $idx $newUnit] break } } } set grouped($name) 1 } } return $units } proc calculate_afni_and_rent {unit} { set annualIncome 0 set hasEmployment 0 set exemptIncome 0 foreach person $unit { array set p $person if {$p(incomeExempt)} { continue } foreach income $p(incomes) { if {$income eq "Employment"} { set hasEmployment 1 } } # Simulate: each person earns $X per year (placeholder — replace with real Line 23600) set simulatedLine23600 20000 incr annualIncome $simulatedLine23600 } set deduction [expr {$hasEmployment ? ([llength $unit] > 1 ? 150 * 12 : 75 * 12) : 0}] set adjustedAnnual [expr {$annualIncome - $deduction}] set monthlyAFNI [expr {$adjustedAnnual / 12.0}] set baseRent [expr {0.30 * $monthlyAFNI}] set rent [expr {max($baseRent, 129)}] ;# Assume $129 minimum rent return [list \ annualIncome $annualIncome \ deduction $deduction \ adjustedAnnual $adjustedAnnual \ monthlyAFNI $monthlyAFNI \ rent [format "%.2f" $rent] \ ] } proc calculate_utility_adjustment {unitSize utilityConfig} { array set utilityTable { "Bachelor" {Hydro 44 Heat 37 Water 12 HotWater 26} "1BR" {Hydro 44 Heat 37 Water 12 HotWater 26} "2BR" {Hydro 62 Heat 42 Water 23 HotWater 37} "3BR" {Hydro 73 Heat 44 Water 28 HotWater 46} "4BR" {Hydro 77 Heat 44 Water 31 HotWater 56} "5BR" {Hydro 77 Heat 44 Water 31 HotWater 56} } # Retrieve the utility allowances for the given unit size if {![info exists utilityTable($unitSize)]} { error "Unknown unit size: $unitSize" } array set allowances $utilityTable($unitSize) # Calculate total adjustment set totalAdjustment 0 foreach utility [array names utilityConfig] { if {$utilityConfig($utility) && [info exists allowances($utility)]} { set totalAdjustment [expr {$totalAdjustment + $allowances($utility)}] } } return $totalAdjustment } #------------------------------------------------------------------------------- # Define which utilities the tenant pays for array set utilityConfig {Hydro 1 Heat 0 Water 1 HotWater 0} # Calculate the utility adjustment for a 2-bedroom unit set adjustment [calculate_utility_adjustment "2BR" utilityConfig] puts "Total Utility Adjustment: $adjustment" #------------------------------------------------------------------------------- set totalRentBeforeUtilities 1000 ;# Example total rent set utilityAdjustment [calculate_utility_adjustment "2BR" utilityConfig] set finalRent [expr {$totalRentBeforeUtilities - $utilityAdjustment}] puts "Final Rent After Utility Adjustment: $finalRent" #------------------------------------------------------------------------------- array set utilityAllowances { "Toronto:2BR" {Hydro 62 Heat 42 Water 23 HotWater 37} "Peel:2BR" {Hydro 60 Heat 40 Water 20 HotWater 35} # Add more entries as needed } #------------------------------------------------------------------------------- proc calculate_utility_adjustment {serviceManager unitSize utilityConfig} { global utilityAllowances set key "$serviceManager:$unitSize" if {![info exists utilityAllowances($key)]} { error "Unknown utility allowances for $serviceManager and $unitSize" } array set allowances $utilityAllowances($key) set totalAdjustment 0 foreach utility [array names utilityConfig] { if {$utilityConfig($utility) && [info exists allowances($utility)]} { set totalAdjustment [expr {$totalAdjustment + $allowances($utility)}] } } return $totalAdjustment } #=============================================================================== proc calculate_utility_adjustment {unitSize utilityConfig} { array set utilityTable { "Bachelor" {Hydro 44 Heat 37 Water 12 HotWater 26} "1BR" {Hydro 44 Heat 37 Water 12 HotWater 26} "2BR" {Hydro 62 Heat 42 Water 23 HotWater 37} "3BR" {Hydro 73 Heat 44 Water 28 HotWater 46} "4BR" {Hydro 77 Heat 44 Water 31 HotWater 56} "5BR" {Hydro 77 Heat 44 Water 31 HotWater 56} } # Retrieve the utility allowances for the given unit size if {![info exists utilityTable($unitSize)]} { error "Unknown unit size: $unitSize" } array set allowances $utilityTable($unitSize) # Calculate total adjustment set totalAdjustment 0 foreach utility [array names utilityConfig] { if {$utilityConfig($utility) && [info exists allowances($utility)]} { set totalAdjustment [expr {$totalAdjustment + $allowances($utility)}] } } return $totalAdjustment } #------------------------------------------------------------------------------- # Define which utilities the tenant pays for array set utilityConfig {Hydro 1 Heat 0 Water 1 HotWater 0} # Calculate the utility adjustment for a 2-bedroom unit set adjustment [calculate_utility_adjustment "2BR" utilityConfig] puts "Total Utility Adjustment: $adjustment" #------------------------------------------------------------------------------- set totalRentBeforeUtilities 1000 ;# Example total rent set utilityAdjustment [calculate_utility_adjustment "2BR" utilityConfig] set finalRent [expr {$totalRentBeforeUtilities - $utilityAdjustment}] puts "Final Rent After Utility Adjustment: $finalRent" #------------------------------------------------------------------------------- array set utilityAllowances { "Toronto:2BR" {Hydro 62 Heat 42 Water 23 HotWater 37} "Peel:2BR" {Hydro 60 Heat 40 Water 20 HotWater 35} # Add more entries as needed } #------------------------------------------------------------------------------- proc calculate_utility_adjustment {serviceManager unitSize utilityConfig} { global utilityAllowances set key "$serviceManager:$unitSize" if {![info exists utilityAllowances($key)]} { error "Unknown utility allowances for $serviceManager and $unitSize" } array set allowances $utilityAllowances($key) set totalAdjustment 0 foreach utility [array names utilityConfig] { if {$utilityConfig($utility) && [info exists allowances($utility)]} { set totalAdjustment [expr {$totalAdjustment + $allowances($utility)}] } } return $totalAdjustment } #------------------------------------------------------------------------------- /* { set testHouseholds { ;# 1. Single person, employment income only (default case) { {name John age 32 incomes {Employment} spouse "" dependents {}} } ;# 2. Married couple, both earning employment income - grouped { {name Anna age 28 incomes {Employment} spouse Mark dependents {}} {name Mark age 30 incomes {Employment} spouse Anna dependents {}} } ;# 3. ODSP recipient - forms own unit even with spouse { {name Laura age 45 incomes {ODSP Employment} spouse Steve dependents {}} {name Steve age 47 incomes {Employment} spouse Laura dependents {}} } ;# 4. OW recipient - forms separate unit { {name Daniel age 22 incomes {OW} spouse "" dependents {}} } ;# 5. CPPD recipient with support income - may form own unit { {name Sandra age 53 incomes {CPPD Support} spouse "" dependents {}} } ;# 6. Couple with one on CPP, other on employment - grouped { {name Judy age 66 incomes {CPP} spouse Albert dependents {}} {name Albert age 65 incomes {Employment} spouse Judy dependents {}} } ;# 7. Lone parent with child - child under 18, no income { {name Maria age 34 incomes {Employment} spouse "" dependents {Lily}} {name Lily age 12 incomes {} dependentsOf Maria} } ;# 8. Lone parent, child with part-time job - child is FT student under 21 ? exempt { {name Rachel age 39 incomes {Employment} spouse "" dependents {Zoe}} {name Zoe age 17 incomes {PartTimeJob} studentStatus fulltime dependentsOf Rachel} } ;# 9. Same as above, but child is *not* a student ? income counted { {name Brian age 41 incomes {Employment} spouse "" dependents {Eli}} {name Eli age 18 incomes {PartTimeJob} studentStatus notEnrolled dependentsOf Brian} } ;# 10. Shared custody, both parents present, one pays support { {name Karen age 40 incomes {Employment SupportPaid} spouse Mike dependents {Olivia}} {name Mike age 42 incomes {Employment} spouse Karen dependents {}} {name Olivia age 9 incomes {} dependentsOf Karen} } ;# 11. Independent adult child living at home with own income - separate unit { {name Claire age 55 incomes {Employment} spouse Tom dependents {}} {name Tom age 58 incomes {CPP} spouse Claire dependents {}} {name Alex age 22 incomes {Employment} spouse "" dependents {}} } ;# 12. Two unrelated adults, both on OW - two units { {name Nina age 35 incomes {OW} spouse "" dependents {}} {name Fiona age 40 incomes {OW} spouse "" dependents {}} } ;# 13. Spouse deceased, widow receiving CPP survivor + employment - single unit { {name Evelyn age 68 incomes {CPP Employment} spouse "" dependents {}} } ;# 14. Couple, one receiving CPPD + Employment + Support - test trumping { {name Leo age 49 incomes {CPPD Employment Support} spouse Erin dependents {}} {name Erin age 46 incomes {Employment} spouse Leo dependents {}} } ;# 15. Complex mixed household - ODSP, student with income, senior, support income { {name Omar age 50 incomes {ODSP} spouse "" dependents {}} {name Tessa age 19 incomes {PartTimeJob} studentStatus fulltime dependentsOf Omar} {name Nora age 76 incomes {CPP} spouse "" dependents {}} {name Dylan age 38 incomes {Employment Support} spouse "" dependents {}} } } */} /* { */}