{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Tax.Canada.T1.Fix (fixT1) where
import Control.Applicative ((<|>))
import Data.Fixed (Centi)
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import Data.Time.Calendar (Year, dayPeriod)
import Rank2 qualified
import Tax.Canada.T1.Types
import Tax.Util (difference, fixEq, leastOf, nonNegativeDifference, totalOf)
fixT1 :: T1 Maybe -> T1 Maybe
fixT1 = fixEq $ \t1@T1{..}-> T1{page1 = fixPage1 page1,
page2 = fixPage2 page2,
page3 = fixPage3 page3,
page4 = fixPage4 t1 page4,
page5 = fixPage5 t1 page5,
page6 = fixPage6 t1 page6,
page7 = fixPage7 t1 page7,
page8 = fixPage8 t1 page8}
fixPage1 :: Page1 Maybe -> Page1 Maybe
fixPage1 = id
fixPage2 :: Page2 Maybe -> Page2 Maybe
fixPage2 = id
fixPage3 :: Page3 Maybe -> Page3 Maybe
fixPage3 = fixEq $ \page@Page3{..}-> page{
line_19 = totalOf [line_10100_EmploymentIncome ,
line_10400_OtherEmploymentIncome,
line_11300_OldAgeSecurityPension,
line_11400_CPP_QPP,
line_11500_OtherPensions,
line_11600_ElectedSplitPension,
line_11700_UCCB,
line_11900_EmploymentInsurance,
line_12000_TaxableDividends,
line_12100_InvestmentIncome,
line_12200_PartnershipIncome,
line_12500_RDSP,
line_12600_Amount,
line_12700_TaxableCapitalGains,
line_12800_Amount,
line_12900_RRSPIncome,
line_13000_OtherIncome,
line_13010_Taxablescholarship],
line_25_sum = totalOf [line_13500_Amount,
line_13700_Amount,
line_13900_Amount,
line_14100_Amount,
line_14300_Amount],
line_25_cont = line_25_sum,
line_26 = totalOf [line_19, line_25_cont],
line_14700_EqualsAmount = totalOf [line_14400_WorkersCompBen,
line_14500_SocialAssistPay,
line_14600_NetFedSupplements],
line_14700_PlusAmount = line_14700_EqualsAmount,
line_15000_TotalIncome = totalOf [line_26, line_14700_PlusAmount]}
fixPage4 :: T1 Maybe -> Page4 Maybe -> Page4 Maybe
fixPage4 t1 = fixEq $ \page@Page4{..}-> page{
line_15000_TotalIncome_2 = t1.page3.line_15000_TotalIncome,
line_23300_sum = totalOf [line_20700_RPPDeduction,
line_20800_RRSPDeduction,
line_21000_SplitPensionDeduction,
line_21200_Dues,
line_21300_UCCBRepayment,
line_21400_ChildCareExpenses,
line_21500_DisabilityDeduction,
line_21700_Amount,
line_21900_MovingExpenses,
line_22000_Amount,
line_22100_CarryingChargesInterest,
line_22200_CPP_QPP_Contributions,
line_22215_DeductionCPP_QPP,
line_22400_XplorationDevExpenses,
line_22900_OtherEmployExpenses,
line_23100_ClergyResDeduction,
line_23200_OtherDeductions,
line_23210],
line_23300_cont = line_23300_sum,
line_23400_NetBeforeAdjust = nonNegativeDifference line_15000_TotalIncome_2 line_23300_cont,
line_23600_NetIncome = nonNegativeDifference line_23400_NetBeforeAdjust line_23500_SocialBenefits}
fixPage5 :: T1 Maybe -> Page5 Maybe -> Page5 Maybe
fixPage5 t1 = fixEq $ \Page5{..}-> Page5{
step4_TaxableIncome = fixStep4 t1 step4_TaxableIncome,
partA_FederalTax = fixPage5PartA t1 partA_FederalTax,
partB_FederalTaxCredits = fixPage5PartB t1 partB_FederalTaxCredits}
fixPage6 :: T1 Maybe -> Page6 Maybe -> Page6 Maybe
fixPage6 t1 = fixEq $ \page@Page6{..}-> page{
line82 = t1.page5.partB_FederalTaxCredits.line_81,
line31260 = leastOf [Just 1287,
totalOf [t1.page3.line_10100_EmploymentIncome, t1.page3.line_10400_OtherEmploymentIncome]],
line94_sum = totalOf [line30800,
line31000,
line31200,
line31217,
line31220,
line31240,
line31260,
line31270,
line31285,
line31300,
line31350],
line94_cont = line94_sum,
line96 = totalOf [line82, line94_cont, line31400],
line99 = totalOf [line96, line31600, line31800],
line104 = totalOf [line99, line31900, line32300, line32400, line32600],
medical_expenses = fixMedicalExpenses t1 medical_expenses,
line33200_sum = totalOf [medical_expenses.difference, medical_expenses.otherDependants],
line33200_cont = line33200_sum,
line33500 = totalOf [line104, line33200_cont],
line33800 = (* 0.15) <$> line33500,
line35000 = totalOf [line33800, line34900]}
fixPage7 :: T1 Maybe -> Page7 Maybe -> Page7 Maybe
fixPage7 t1 = fixEq $ \Page7{partC_NetFederalTax, step6_RefundOrBalanceOwing}-> Page7{
partC_NetFederalTax = fixPage7PartC t1 partC_NetFederalTax,
step6_RefundOrBalanceOwing = fixPage7Step6 t1 step6_RefundOrBalanceOwing}
fixPage8 :: T1 Maybe -> Page8 Maybe -> Page8 Maybe
fixPage8 t1 = fixEq $ \page@Page8{..}-> Page8{
step6_RefundOrBalanceOwing = fixPage8Step6 t1 step6_RefundOrBalanceOwing,
line48400_Refund = step6_RefundOrBalanceOwing.line164_Refund_or_BalanceOwing
>>= \x-> if x < 0 then Just (negate x) else Nothing,
line48500_BalanceOwing = step6_RefundOrBalanceOwing.line164_Refund_or_BalanceOwing
>>= \x-> if x > 0 then Just x else Nothing,
line_46600 = (-) <$> line48400_Refund <*> line_46500,
..}
fixStep4 :: T1 Maybe -> Step4 Maybe -> Step4 Maybe
fixStep4 t1 = fixEq $ \step@Step4{..}-> step{
line_23600_NetIncome_2 = t1.page4.line_23600_NetIncome,
line_25700_AddLines_sum = totalOf [line_24400_MilitaryPoliceDeduction,
line_24900_SecurityDeductions,
line_25000_OtherPayDeductions,
line_25100_PartnershipLosses,
line_25200_NoncapitalLosses,
line_25300_NetCapitalLosses,
line_25400_CapitalGainsDeduction,
line_25500_NorthernDeductions,
line_25600_AdditionalDeductions_Amount],
line_25700_AddLines_cont = line_25700_AddLines_sum,
line_26000_TaxableIncome = nonNegativeDifference line_23600_NetIncome_2 line_25700_AddLines_cont}
fixPage5PartA :: T1 Maybe -> Page5PartA Maybe -> Page5PartA Maybe
fixPage5PartA t1 = fixEq $ \part@Page5PartA{..}-> part{
column1 = taxIncomeBracket 0 50197 0.15 0,
column2 = taxIncomeBracket 50197 100392 0.205 7529.55,
column3 = taxIncomeBracket 100392 155625 0.26 17819.53,
column4 = taxIncomeBracket 155625 221708 0.29 32180.11,
column5 = taxIncomeBracket 221708 (10^12) 0.33 51344.18} -- a trillion ought to be enough for anybody
where taxIncomeBracket threshold ceiling rate baseTax
| income > threshold && income <= ceiling = TaxIncomeBracket{
line67_income = Just income,
line69_overThreshold = Just (income - threshold),
line71_timesRate = Just ((income - threshold) * rate),
line73_equalsTax = Just ((income - threshold) * rate + baseTax)}
| otherwise = Rank2.pure Nothing
income = fromMaybe 0 t1.page5.step4_TaxableIncome.line_26000_TaxableIncome
fixPage5PartB :: T1 Maybe -> Page5PartB Maybe -> Page5PartB Maybe
fixPage5PartB t1 = fixEq $ \part@Page5PartB{..}-> part{
line30000 = let income = fromMaybe 0 t1.page4.line_23600_NetIncome
in if income <= 155625 then Just 14398
else if income >= 221708 then Just 12719
else Just $ 14398 - (14398 - 12719) * (income - 155625) / (221708 - 155625),
line30100 = if any ((<= (1957 :: Year)) . dayPeriod) t1.page1.identification.dateBirth
then Just 12719
else Nothing,
line30500 = ((* 2350) . fromIntegral) <$> line30499_ChildrenNum,
line_81 = totalOf [line30000,
line30100,
line30300,
line30400,
line30425,
line30450,
line30500]}
fixMedicalExpenses :: T1 Maybe -> MedicalExpenses Maybe -> MedicalExpenses Maybe
fixMedicalExpenses t1 = fixEq $ \expenses@MedicalExpenses{familyExpenses, taxableIncome,
taxableIncomeFraction, threshold}-> expenses{
taxableIncome = t1.page4.line_23600_NetIncome,
taxableIncomeFraction = (* 0.03) <$> taxableIncome,
threshold = min 2479 <$> taxableIncomeFraction,
difference = nonNegativeDifference familyExpenses threshold}
fixPage7PartC :: T1 Maybe -> Page7PartC Maybe -> Page7PartC Maybe
fixPage7PartC t1 = fixEq $ \part@Page7PartC{..}-> part{
line116 = let partA = t1.page5.partA_FederalTax
in partA.column1.line73_equalsTax
<|> partA.column2.line73_equalsTax
<|> partA.column3.line73_equalsTax
<|> partA.column4.line73_equalsTax
<|> partA.column5.line73_equalsTax,
line40400 = totalOf [line116, line40424],
line119 = t1.page6.line35000,
line40425,
line40427,
line122_sum = totalOf [line119, line40425, line40427],
line122_cont = line122_sum,
line123 = nonNegativeDifference line40400 line122_cont,
line125 = totalOf [line123, line124],
line127 = difference line125 line40500,
line129 = totalOf [line127, line128],
line131 = nonNegativeDifference line129 line130,
line41000 = case line40900
of Just x
| x <= 400 -> Just (x * 0.75)
| x <= 750 -> Just ((x - 400) * 0.5 + 300)
| otherwise-> Just ((x - 750) * 0.3333 + 475)
Nothing -> Nothing,
line41600_sum = totalOf [line41000, line41200, line41400],
line41600_cont = line41600_sum,
line41700 = nonNegativeDifference line131 line41600_cont,
line42000 = totalOf [line41700, line41500, line41800]}
fixPage7Step6 :: T1 Maybe -> Page7Step6 Maybe -> Page7Step6 Maybe
fixPage7Step6 t1 = fixEq $ \step@Page7Step6{..}-> step{
line140 = t1.page7.partC_NetFederalTax.line42000,
line_43500_TotalPayable = totalOf [line140, line_42100_CPPContributions, line_42120_EIPremiums,
line_42200_SocialBenefits, line_42800_ProvTerrTax]}
fixPage8Step6 :: T1 Maybe -> Page8Step6 Maybe -> Page8Step6 Maybe
fixPage8Step6 t1 = fixEq $ \step@Page8Step6{..}-> step{
line_43500_totalpayable = t1.page7.step6_RefundOrBalanceOwing.line_43500_TotalPayable,
line_46900 = (* 0.25) <$> line_46800,
line_48200_sum = totalOf [line_43700_Total_income_tax_ded,
line_44000,
line_44800_CPPOverpayment,
line_45000_EIOverpayment,
line_45200_MedicalExpense,
line_45300_CWB,
line_45350_CTC,
line_45400_InvestmentTaxCredit,
line_45600_TrustTaxCredit,
line_45700_GST_HST_Rebate,
line_46900,
line_47555_TaxPaid,
line_47556,
line_47557,
line_47600_TaxPaid,
line_47900_ProvTerrCredits],
line_48200_cont = line_48200_sum,
line164_Refund_or_BalanceOwing = difference line_43500_totalpayable line_48200_sum}