{-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ImportQualifiedPost #-} {-# LANGUAGE InstanceSigs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoFieldSelectors #-} {-# LANGUAGE NumericUnderscores #-} {-# LANGUAGE OverloadedRecordDot #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} module Tax.Canada.Federal.Schedule11 where import Data.Fixed (Centi) import Data.Text (Text) import Language.Haskell.TH qualified as TH import Rank2 qualified import Rank2.TH qualified import Transformation.Shallow.TH qualified import Tax.Canada.Shared (SubCalculation(result), fixSubCalculation, subCalculationFields) import Tax.Canada.T1.Types (T1) import Tax.Canada.T1.Types qualified import Tax.FDF (Entry (Amount, Checkbox, Count), FieldConst (Field), within) import Tax.Util (fixEq, fractionOf, difference, nonNegativeDifference, totalOf) data Schedule11 line = Schedule11{ forall (line :: * -> *). Schedule11 line -> Page1 line page1 :: Page1 line, forall (line :: * -> *). Schedule11 line -> Page2 line page2 :: Page2 line} data Page1 line = Page1{ forall (line :: * -> *). Page1 line -> line Centi line_32000_tuition :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line2_copy :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line2_fraction :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line3_limit :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line4_min :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line5_trainingClaim :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line6_difference :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line_32001_eligible :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line8_sum :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line9_pastUnused :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line10_sum :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line11_copy :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line11_numerator :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line12_copy :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line13_difference :: line Centi, forall (line :: * -> *). Page1 line -> SubCalculation line line14_minUnused :: SubCalculation line, forall (line :: * -> *). Page1 line -> line Centi line15_difference :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line16_min :: line Centi, forall (line :: * -> *). Page1 line -> line Centi line17_sum :: line Centi} data Page2 line = Page2{ forall (line :: * -> *). Page2 line -> line Bool line_32005_diability :: line Bool, forall (line :: * -> *). Page2 line -> line Word line_32010_partTimeMonths :: line Word, forall (line :: * -> *). Page2 line -> line Word line_32020_fullTimeMonths :: line Word, forall (line :: * -> *). Page2 line -> line Centi line18_copy :: line Centi, forall (line :: * -> *). Page2 line -> line Centi line19_copy :: line Centi, forall (line :: * -> *). Page2 line -> line Centi line20_difference :: line Centi, forall (line :: * -> *). Page2 line -> line Centi line21_copy :: line Centi, forall (line :: * -> *). Page2 line -> line Centi line22_copy :: line Centi, forall (line :: * -> *). Page2 line -> line Centi line23_difference :: line Centi, forall (line :: * -> *). Page2 line -> line Centi line24_transferred :: line Centi, forall (line :: * -> *). Page2 line -> line Centi line25_difference :: line Centi} $(foldMap (\t-> concat <$> sequenceA [ [d| deriving instance (Show (line Bool), Show (line Centi), Show (line Rational), Show (line Word)) => Show ($(TH.conT t) line) deriving instance (Eq (line Bool), Eq (line Centi), Eq (line Rational), Eq (line Word)) => Eq ($(TH.conT t) line) |], Rank2.TH.deriveAll t, Transformation.Shallow.TH.deriveAll t]) [''Schedule11, ''Page1, ''Page2]) fixSchedule11 :: T1 Maybe -> Schedule11 Maybe -> Schedule11 Maybe fixSchedule11 :: T1 Maybe -> Schedule11 Maybe -> Schedule11 Maybe fixSchedule11 T1 Maybe t1 = (Schedule11 Maybe -> Schedule11 Maybe) -> Schedule11 Maybe -> Schedule11 Maybe forall a. Eq a => (a -> a) -> a -> a fixEq ((Schedule11 Maybe -> Schedule11 Maybe) -> Schedule11 Maybe -> Schedule11 Maybe) -> (Schedule11 Maybe -> Schedule11 Maybe) -> Schedule11 Maybe -> Schedule11 Maybe forall a b. (a -> b) -> a -> b $ \Schedule11{$sel:page1:Schedule11 :: forall (line :: * -> *). Schedule11 line -> Page1 line page1 = page1 :: Page1 Maybe page1@Page1{Maybe Centi SubCalculation Maybe $sel:line_32000_tuition:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line2_copy:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line2_fraction:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line3_limit:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line4_min:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line5_trainingClaim:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line6_difference:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line_32001_eligible:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line8_sum:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line9_pastUnused:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line10_sum:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line11_copy:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line11_numerator:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line12_copy:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line13_difference:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line14_minUnused:Page1 :: forall (line :: * -> *). Page1 line -> SubCalculation line $sel:line15_difference:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line16_min:Page1 :: forall (line :: * -> *). Page1 line -> line Centi $sel:line17_sum:Page1 :: forall (line :: * -> *). Page1 line -> line Centi line_32000_tuition :: Maybe Centi line2_copy :: Maybe Centi line2_fraction :: Maybe Centi line3_limit :: Maybe Centi line4_min :: Maybe Centi line5_trainingClaim :: Maybe Centi line6_difference :: Maybe Centi line_32001_eligible :: Maybe Centi line8_sum :: Maybe Centi line9_pastUnused :: Maybe Centi line10_sum :: Maybe Centi line11_copy :: Maybe Centi line11_numerator :: Maybe Centi line12_copy :: Maybe Centi line13_difference :: Maybe Centi line14_minUnused :: SubCalculation Maybe line15_difference :: Maybe Centi line16_min :: Maybe Centi line17_sum :: Maybe Centi ..}, $sel:page2:Schedule11 :: forall (line :: * -> *). Schedule11 line -> Page2 line page2 = page2 :: Page2 Maybe page2@Page2{Maybe Bool Maybe Word Maybe Centi $sel:line_32005_diability:Page2 :: forall (line :: * -> *). Page2 line -> line Bool $sel:line_32010_partTimeMonths:Page2 :: forall (line :: * -> *). Page2 line -> line Word $sel:line_32020_fullTimeMonths:Page2 :: forall (line :: * -> *). Page2 line -> line Word $sel:line18_copy:Page2 :: forall (line :: * -> *). Page2 line -> line Centi $sel:line19_copy:Page2 :: forall (line :: * -> *). Page2 line -> line Centi $sel:line20_difference:Page2 :: forall (line :: * -> *). Page2 line -> line Centi $sel:line21_copy:Page2 :: forall (line :: * -> *). Page2 line -> line Centi $sel:line22_copy:Page2 :: forall (line :: * -> *). Page2 line -> line Centi $sel:line23_difference:Page2 :: forall (line :: * -> *). Page2 line -> line Centi $sel:line24_transferred:Page2 :: forall (line :: * -> *). Page2 line -> line Centi $sel:line25_difference:Page2 :: forall (line :: * -> *). Page2 line -> line Centi line_32005_diability :: Maybe Bool line_32010_partTimeMonths :: Maybe Word line_32020_fullTimeMonths :: Maybe Word line18_copy :: Maybe Centi line19_copy :: Maybe Centi line20_difference :: Maybe Centi line21_copy :: Maybe Centi line22_copy :: Maybe Centi line23_difference :: Maybe Centi line24_transferred :: Maybe Centi line25_difference :: Maybe Centi ..}} -> Schedule11{ $sel:page1:Schedule11 :: Page1 Maybe page1 = Page1 Maybe page1{ line2_copy = line_32000_tuition, line2_fraction = (0.5 *) <$> line2_copy, line4_min = minimum [line2_fraction, line3_limit], line6_difference = difference line_32000_tuition line5_trainingClaim, line8_sum = totalOf [line6_difference, line_32001_eligible], line10_sum = totalOf [line9_pastUnused, line8_sum], line11_copy = if taxableIncomeUnderThreshold then Nothing else t1.page7.partC_NetFederalTax.line116, line11_numerator = if taxableIncomeUnderThreshold then taxableIncome else (/ 0.15) <$> line11_copy, line12_copy = t1.page6.line99, line13_difference = nonNegativeDifference line11_numerator line12_copy, line14_minUnused = fixSubCalculation $ minimum [line9_pastUnused, line13_difference], line15_difference = difference line13_difference line14_minUnused.result, line16_min = minimum [line8_sum, line15_difference], line17_sum = totalOf [line14_minUnused.result, line16_min]}, $sel:page2:Schedule11 :: Page2 Maybe page2 = Page2 Maybe page2{ line18_copy = line10_sum, line19_copy = line17_sum, line20_difference = difference line18_copy line19_copy, line21_copy = min 5000 <$> line8_sum, line22_copy = line16_min, line23_difference = nonNegativeDifference line21_copy line22_copy, line25_difference = nonNegativeDifference line20_difference line24_transferred}} where taxableIncome :: Maybe Centi taxableIncome = T1 Maybe t1.page5.step4_TaxableIncome.line_26000_TaxableIncome taxableIncomeUnderThreshold :: Bool taxableIncomeUnderThreshold = Maybe Centi taxableIncome Maybe Centi -> Maybe Centi -> Bool forall a. Ord a => a -> a -> Bool <= Centi -> Maybe Centi forall a. a -> Maybe a Just Centi 50_197 schedule11Fields :: Schedule11 FieldConst schedule11Fields :: Schedule11 FieldConst schedule11Fields = Text -> FieldConst a -> FieldConst a forall x. Text -> FieldConst x -> FieldConst x within Text "form1" (forall {a}. FieldConst a -> FieldConst a) -> Schedule11 FieldConst -> Schedule11 FieldConst forall {k} (g :: (k -> *) -> *) (p :: k -> *) (q :: k -> *). Functor g => (forall (a :: k). p a -> q a) -> g p -> g q forall (p :: * -> *) (q :: * -> *). (forall a. p a -> q a) -> Schedule11 p -> Schedule11 q Rank2.<$> Schedule11 { $sel:page1:Schedule11 :: Page1 FieldConst page1 = Page1 FieldConst page1Fields, $sel:page2:Schedule11 :: Page2 FieldConst page2 = Page2 FieldConst page2Fields} page1Fields :: Page1 FieldConst page1Fields :: Page1 FieldConst page1Fields = Text -> FieldConst a -> FieldConst a forall x. Text -> FieldConst x -> FieldConst x within Text "Page1" (FieldConst a -> FieldConst a) -> (FieldConst a -> FieldConst a) -> FieldConst a -> FieldConst a forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> FieldConst a -> FieldConst a forall x. Text -> FieldConst x -> FieldConst x within Text "YourTuition" (forall {a}. FieldConst a -> FieldConst a) -> Page1 FieldConst -> Page1 FieldConst forall {k} (g :: (k -> *) -> *) (p :: k -> *) (q :: k -> *). Functor g => (forall (a :: k). p a -> q a) -> g p -> g q forall (p :: * -> *) (q :: * -> *). (forall a. p a -> q a) -> Page1 p -> Page1 q Rank2.<$> Page1 { $sel:line_32000_tuition:Page1 :: FieldConst Centi line_32000_tuition = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line1", Text "Amount2"] Entry Centi Amount, $sel:line2_copy:Page1 :: FieldConst Centi line2_copy = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line2", Text "Amount1"] Entry Centi Amount, $sel:line2_fraction:Page1 :: FieldConst Centi line2_fraction = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line2", Text "Amount2"] Entry Centi Amount, $sel:line3_limit:Page1 :: FieldConst Centi line3_limit = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line3", Text "Amount4"] Entry Centi Amount, $sel:line4_min:Page1 :: FieldConst Centi line4_min = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line4", Text "Amount5"] Entry Centi Amount, $sel:line5_trainingClaim:Page1 :: FieldConst Centi line5_trainingClaim = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line5", Text "Amount6"] Entry Centi Amount, $sel:line6_difference:Page1 :: FieldConst Centi line6_difference = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line6", Text "Amount7"] Entry Centi Amount, $sel:line_32001_eligible:Page1 :: FieldConst Centi line_32001_eligible = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line7", Text "Amount8"] Entry Centi Amount, $sel:line8_sum:Page1 :: FieldConst Centi line8_sum = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line8", Text "Amount1"] Entry Centi Amount, $sel:line9_pastUnused:Page1 :: FieldConst Centi line9_pastUnused = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line9", Text "Amount1"] Entry Centi Amount, $sel:line10_sum:Page1 :: FieldConst Centi line10_sum = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line10", Text "Amount10"] Entry Centi Amount, $sel:line11_copy:Page1 :: FieldConst Centi line11_copy = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line11", Text "Line11", Text "Amount11"] Entry Centi Amount, $sel:line11_numerator:Page1 :: FieldConst Centi line11_numerator = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line11", Text "Amount11"] Entry Centi Amount, $sel:line12_copy:Page1 :: FieldConst Centi line12_copy = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line12", Text "Amount12"] Entry Centi Amount, $sel:line13_difference:Page1 :: FieldConst Centi line13_difference = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line13", Text "Amount13"] Entry Centi Amount, $sel:line14_minUnused:Page1 :: SubCalculation FieldConst line14_minUnused = Text -> [Text] -> [Text] -> SubCalculation FieldConst subCalculationFields Text "Line14" [Text "Amount1"] [Text "Amount14"], $sel:line15_difference:Page1 :: FieldConst Centi line15_difference = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line15", Text "Amount15"] Entry Centi Amount, $sel:line16_min:Page1 :: FieldConst Centi line16_min = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line16", Text "Amount16"] Entry Centi Amount, $sel:line17_sum:Page1 :: FieldConst Centi line17_sum = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Line17", Text "Amount17"] Entry Centi Amount} page2Fields :: Page2 FieldConst page2Fields :: Page2 FieldConst page2Fields = Text -> FieldConst a -> FieldConst a forall x. Text -> FieldConst x -> FieldConst x within Text "Page2" (forall {a}. FieldConst a -> FieldConst a) -> Page2 FieldConst -> Page2 FieldConst forall {k} (g :: (k -> *) -> *) (p :: k -> *) (q :: k -> *). Functor g => (forall (a :: k). p a -> q a) -> g p -> g q forall (p :: * -> *) (q :: * -> *). (forall a. p a -> q a) -> Page2 p -> Page2 q Rank2.<$> Page2 { $sel:line_32005_diability:Page2 :: FieldConst Bool line_32005_diability = [Text] -> Entry Bool -> FieldConst Bool forall a. [Text] -> Entry a -> FieldConst a Field [Text "Enrolment", Text "Line32005", Text "CheckBox"] Entry Bool Checkbox, $sel:line_32010_partTimeMonths:Page2 :: FieldConst Word line_32010_partTimeMonths = [Text] -> Entry Word -> FieldConst Word forall a. [Text] -> Entry a -> FieldConst a Field [Text "Enrolment", Text "Line32010", Text "parttime_Months"] Entry Word Count, $sel:line_32020_fullTimeMonths:Page2 :: FieldConst Word line_32020_fullTimeMonths = [Text] -> Entry Word -> FieldConst Word forall a. [Text] -> Entry a -> FieldConst a Field [Text "Enrolment", Text "Line32020", Text "Fulltime_Months"] Entry Word Count, $sel:line18_copy:Page2 :: FieldConst Centi line18_copy = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Transfer_CF", Text "Line18", Text "Amount18"] Entry Centi Amount, $sel:line19_copy:Page2 :: FieldConst Centi line19_copy = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Transfer_CF", Text "Line19", Text "Amount19"] Entry Centi Amount, $sel:line20_difference:Page2 :: FieldConst Centi line20_difference = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Transfer_CF", Text "Line20", Text "Amount20"] Entry Centi Amount, $sel:line21_copy:Page2 :: FieldConst Centi line21_copy = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Transfer_CF", Text "Line21", Text "Amount21"] Entry Centi Amount, $sel:line22_copy:Page2 :: FieldConst Centi line22_copy = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Transfer_CF", Text "Line22", Text "Amount22"] Entry Centi Amount, $sel:line23_difference:Page2 :: FieldConst Centi line23_difference = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Transfer_CF", Text "Line23", Text "Amount22"] Entry Centi Amount, $sel:line24_transferred:Page2 :: FieldConst Centi line24_transferred = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Transfer_CF", Text "Line24", Text "Amount24"] Entry Centi Amount, $sel:line25_difference:Page2 :: FieldConst Centi line25_difference = [Text] -> Entry Centi -> FieldConst Centi forall a. [Text] -> Entry a -> FieldConst a Field [Text "Transfer_CF", Text "Line25", Text "Amount25"] Entry Centi Amount}