{-# LANGUAGE DisambiguateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NoFieldSelectors #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Tax.Canada.Federal (InputForms, Forms(..), loadInputForms, fixFederalForms,
formFieldsForProvince, formFileNames, relevantFormKeys) where
import Control.Applicative ((<|>))
import Control.Monad ((=<<))
import Data.CAProvinceCodes qualified as Province
import Data.Fixed (Centi)
import Data.Foldable (find)
import Data.Functor.Compose (Compose(Compose))
import Data.List.NonEmpty (NonEmpty((:|)), nonEmpty)
import Data.Maybe (isJust)
import Data.Map (Map, fromList)
import Data.Set (Set)
import Data.Set qualified as Set
import Data.Semigroup (Any (Any, getAny), Sum(Sum, getSum))
import Data.Text (Text)
import Data.Text qualified as Text
import Data.Time (Day)
import GHC.Stack (HasCallStack)
import Rank2 qualified
import Rank2.TH qualified
import Transformation.Shallow.TH qualified
import Text.FDF (FDF)
import Tax.Canada.Federal.Schedule6 qualified as Schedule6
import Tax.Canada.Federal.Schedule6 (Schedule6, fixSchedule6, schedule6Fields)
import Tax.Canada.Federal.Schedule7 qualified
import Tax.Canada.Federal.Schedule7 (Schedule7, fixSchedule7, schedule7Fields)
import Tax.Canada.Federal.Schedule8 qualified as Schedule8
import Tax.Canada.Federal.Schedule8 (Schedule8(page4, page5, page6, page7, page8, page9, page10),
fixSchedule8, schedule8Fields,
Page4(line_50339_totalPensionableEarnings,
line_50340_totalContributions,
line_50341_totalSecondContributions),
Page6(line1_netSelfEmploymentEarnings),
Page7(line1_netSelfEmploymentEarnings))
import Tax.Canada.Federal.Schedule9 (Schedule9(page1), Page1(line23_sum), fixSchedule9, schedule9Fields)
import Tax.Canada.Federal.Schedule11 (Schedule11(page1), Page1(line5_trainingClaim, line17_sum), fixSchedule11, schedule11Fields)
import Tax.Canada.FormKey (FormKey)
import Tax.Canada.FormKey qualified as FormKey
import Tax.Canada.T1 (fixT1, t1FieldsForProvince)
import Tax.Canada.T1.Types (T1(page3, page4, page5, page6, page7, page8),
Page3(line_10100_EmploymentIncome, line_10120_Commissions, line_12200_PartnershipIncome,
line29_sum),
Page4(line_20600_PensionAdjustment, line_20700_RPPDeduction, line_20800_RRSPDeduction,
line_21200_Dues, line_22200_CPP_QPP_Contributions, line_22215_DeductionCPP_QPP,
line_22900_OtherEmployExpenses),
Page5(step4_TaxableIncome),
Step4(line_24400_MilitaryPoliceDeduction, line_24900_SecurityDeductions),
Page6(line_30800, line_31000, line_31200, line_31205, line_32300, line_34900),
Page7(step6_RefundOrBalanceOwing),
Page7Step6(line_42100_CPPContributions),
Page8(step6_RefundOrBalanceOwing),
Page8Step6(line_43700_Total_income_tax_ded, line_44800_CPPOverpayment,
line_45300_CWB, line_45350_CTC),
LanguageOfCorrespondence, MaritalStatus)
import Tax.Canada.T4 (T4, t4Fields, T4Slip(box16_employeeCPP, box26_pensionableEarnings))
import Tax.Canada.T4 qualified as T4
import Tax.Canada.Shared (SubCalculation(result))
import Tax.FDF (Entry (Amount), FieldConst (Field), load, within)
import Tax.Util (fixEq, totalOf)
data InputForms line = InputForms{
forall (line :: * -> *).
InputForms line -> Maybe (NonEmpty (T4 line))
t4 :: Maybe (NonEmpty (T4 line))}
deriving instance Show (InputForms Maybe)
instance Semigroup (InputForms Maybe) where
InputForms Maybe (NonEmpty (T4 Maybe))
x <> :: InputForms Maybe -> InputForms Maybe -> InputForms Maybe
<> InputForms Maybe (NonEmpty (T4 Maybe))
y = Maybe (NonEmpty (T4 Maybe)) -> InputForms Maybe
forall (line :: * -> *).
Maybe (NonEmpty (T4 line)) -> InputForms line
InputForms (Maybe (NonEmpty (T4 Maybe)) -> InputForms Maybe)
-> Maybe (NonEmpty (T4 Maybe)) -> InputForms Maybe
forall a b. (a -> b) -> a -> b
$ Maybe (NonEmpty (T4 Maybe))
x Maybe (NonEmpty (T4 Maybe))
-> Maybe (NonEmpty (T4 Maybe)) -> Maybe (NonEmpty (T4 Maybe))
forall a. Semigroup a => a -> a -> a
<> Maybe (NonEmpty (T4 Maybe))
y
instance Monoid (InputForms Maybe) where
mempty :: InputForms Maybe
mempty = Maybe (NonEmpty (T4 Maybe)) -> InputForms Maybe
forall (line :: * -> *).
Maybe (NonEmpty (T4 line)) -> InputForms line
InputForms Maybe (NonEmpty (T4 Maybe))
forall a. Maybe a
Nothing
data Forms line = Forms{
forall (line :: * -> *). Forms line -> T1 line
t1 :: T1 line,
forall (line :: * -> *). Forms line -> Schedule6 line
schedule6 :: Schedule6 line,
forall (line :: * -> *). Forms line -> Schedule7 line
schedule7 :: Schedule7 line,
forall (line :: * -> *). Forms line -> Schedule8 line
schedule8 :: Schedule8 line,
forall (line :: * -> *). Forms line -> Schedule9 line
schedule9 :: Schedule9 line,
forall (line :: * -> *). Forms line -> Schedule11 line
schedule11 :: Schedule11 line}
deriving instance (Show (line Bool), Show (line Centi), Show (line Word), Show (line Int), Show (line Text),
Show (line Rational), Show (line Province.Code), Show (line Day),
Show (line LanguageOfCorrespondence), Show (line MaritalStatus))
=> Show (Forms line)
deriving instance (Eq (line Bool), Eq (line Centi), Eq (line Word), Eq (line Int), Eq (line Text),
Eq (line Rational), Eq (line Province.Code), Eq (line Day),
Eq (line LanguageOfCorrespondence), Eq (line MaritalStatus))
=> Eq (Forms line)
Rank2.TH.deriveAll ''Forms
Transformation.Shallow.TH.deriveAll ''Forms
loadInputForms :: [(FormKey, FDF)] -> Either String (InputForms Maybe)
loadInputForms :: [(FormKey, FDF)] -> Either String (InputForms Maybe)
loadInputForms [(FormKey, FDF)]
forms = Maybe (NonEmpty (T4 Maybe)) -> InputForms Maybe
forall (line :: * -> *).
Maybe (NonEmpty (T4 line)) -> InputForms line
InputForms (Maybe (NonEmpty (T4 Maybe)) -> InputForms Maybe)
-> ([T4 Maybe] -> Maybe (NonEmpty (T4 Maybe)))
-> [T4 Maybe]
-> InputForms Maybe
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [T4 Maybe] -> Maybe (NonEmpty (T4 Maybe))
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty ([T4 Maybe] -> InputForms Maybe)
-> Either String [T4 Maybe] -> Either String (InputForms Maybe)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((FormKey, FDF) -> Either String (T4 Maybe))
-> [(FormKey, FDF)] -> Either String [T4 Maybe]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (T4 FieldConst -> FDF -> Either String (T4 Maybe)
forall (form :: (* -> *) -> *).
(Apply form, Traversable form) =>
form FieldConst -> FDF -> Either String (form Maybe)
load T4 FieldConst
T4.t4Fields (FDF -> Either String (T4 Maybe))
-> ((FormKey, FDF) -> FDF)
-> (FormKey, FDF)
-> Either String (T4 Maybe)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FormKey, FDF) -> FDF
forall a b. (a, b) -> b
snd) [(FormKey, FDF)]
forms
fixFederalForms :: Province.Code -> InputForms Maybe -> Forms Maybe -> Forms Maybe
fixFederalForms :: Code -> InputForms Maybe -> Forms Maybe -> Forms Maybe
fixFederalForms Code
province InputForms{Maybe (NonEmpty (T4 Maybe))
t4 :: forall (line :: * -> *).
InputForms line -> Maybe (NonEmpty (T4 line))
t4 :: Maybe (NonEmpty (T4 Maybe))
t4} = (Forms Maybe -> Forms Maybe) -> Forms Maybe -> Forms Maybe
forall a. Eq a => (a -> a) -> a -> a
fixEq ((Forms Maybe -> Forms Maybe) -> Forms Maybe -> Forms Maybe)
-> (Forms Maybe -> Forms Maybe) -> Forms Maybe -> Forms Maybe
forall a b. (a -> b) -> a -> b
$ \Forms{T1 Maybe
t1 :: forall (line :: * -> *). Forms line -> T1 line
t1 :: T1 Maybe
t1, Schedule6 Maybe
schedule6 :: forall (line :: * -> *). Forms line -> Schedule6 line
schedule6 :: Schedule6 Maybe
schedule6, Schedule7 Maybe
schedule7 :: forall (line :: * -> *). Forms line -> Schedule7 line
schedule7 :: Schedule7 Maybe
schedule7, Schedule8 Maybe
schedule8 :: forall (line :: * -> *). Forms line -> Schedule8 line
schedule8 :: Schedule8 Maybe
schedule8, Schedule9 Maybe
schedule9 :: forall (line :: * -> *). Forms line -> Schedule9 line
schedule9 :: Schedule9 Maybe
schedule9, Schedule11 Maybe
schedule11 :: forall (line :: * -> *). Forms line -> Schedule11 line
schedule11 :: Schedule11 Maybe
schedule11}->
let fromT4s' :: (T4 Maybe -> Maybe Centi)
-> (Maybe Centi -> form -> form) -> form -> form
fromT4s' = Maybe (NonEmpty (T4 Maybe))
-> (T4 Maybe -> Maybe Centi)
-> (Maybe Centi -> form -> form)
-> form
-> form
forall form.
Maybe (NonEmpty (T4 Maybe))
-> (T4 Maybe -> Maybe Centi)
-> (Maybe Centi -> form -> form)
-> form
-> form
fromT4s Maybe (NonEmpty (T4 Maybe))
t4 in Forms{
t1 :: T1 Maybe
t1 = HasCallStack => T1 Maybe -> T1 Maybe
T1 Maybe -> T1 Maybe
fixT1 T1 Maybe
t1{
page3 = fromT4s' (.slip1.box14_employmentIncome) (\Maybe Centi
amt Page3 Maybe
pg-> Page3 Maybe
pg{line_10100_EmploymentIncome = amt}) $
fromT4s' (additionalT4 ["42"]) (\Maybe Centi
amt Page3 Maybe
pg-> Page3 Maybe
pg{line_10120_Commissions = amt}) $
t1.page3,
page4 = fromT4s' (.slip1.box52_pensionAdjustment) (\Maybe Centi
amt Page4 Maybe
pg-> Page4 Maybe
pg{line_20600_PensionAdjustment = amt}) $
fromT4s' (.slip1.box20_employeeRPP) (\Maybe Centi
amt Page4 Maybe
pg-> Page4 Maybe
pg{line_20700_RPPDeduction = amt}) $
fromT4s' (.slip1.box44_unionDues) (\Maybe Centi
amt Page4 Maybe
pg-> Page4 Maybe
pg{line_21200_Dues = amt}) $
fromT4s' (additionalT4 ["77"]) (\Maybe Centi
amt Page4 Maybe
step-> Page4 Maybe
step{line_22900_OtherEmployExpenses = amt}) $
t1.page4{line_20800_RRSPDeduction = schedule7.page3.partC.line20_deduction,
line_22200_CPP_QPP_Contributions = schedule8.page6.line17_sum <|>
schedule8.page10.line97_sum,
line_22215_DeductionCPP_QPP = schedule8.page5.part3a.line30_sum <|>
schedule8.page5.part3b.line43_sum <|>
schedule8.page9.line77_sum},
page5 = t1.page5{
step4_TaxableIncome =
fromT4s' (additionalT4 ["39", "41", "91", "92"])
(\Maybe Centi
amt Step4 Maybe
step-> Step4 Maybe
step{line_24900_SecurityDeductions = amt}) $
fromT4s' (additionalT4 ["43"]) (\Maybe Centi
amt Step4 Maybe
step-> Step4 Maybe
step{line_24400_MilitaryPoliceDeduction = amt}) $
t1.page5.step4_TaxableIncome},
page6 = (case province
of Code
Province.QC ->
(T4 Maybe -> Maybe Centi)
-> (Maybe Centi -> Page6 Maybe -> Page6 Maybe)
-> Page6 Maybe
-> Page6 Maybe
forall {form}.
(T4 Maybe -> Maybe Centi)
-> (Maybe Centi -> form -> form) -> form -> form
fromT4s' (.slip1.box18_employeeEI) (\Maybe Centi
amt Page6 Maybe
pg-> Page6 Maybe
pg{line_31200 = amt}) (Page6 Maybe -> Page6 Maybe) -> Page6 Maybe -> Page6 Maybe
forall a b. (a -> b) -> a -> b
$
(T4 Maybe -> Maybe Centi)
-> (Maybe Centi -> Page6 Maybe -> Page6 Maybe)
-> Page6 Maybe
-> Page6 Maybe
forall {form}.
(T4 Maybe -> Maybe Centi)
-> (Maybe Centi -> form -> form) -> form -> form
fromT4s' (.slip1.box55_premiumPPIP) (\Maybe Centi
amt Page6 Maybe
pg-> Page6 Maybe
pg{line_31205 = amt}) T1 Maybe
t1.page6
Code
_ -> (T4 Maybe -> Maybe Centi)
-> (Maybe Centi -> Page6 Maybe -> Page6 Maybe)
-> Page6 Maybe
-> Page6 Maybe
forall {form}.
(T4 Maybe -> Maybe Centi)
-> (Maybe Centi -> form -> form) -> form -> form
fromT4s' (\T4 Maybe
t4-> [Maybe Centi] -> Maybe Centi
forall (f :: * -> *) a.
(Foldable f, Num a) =>
f (Maybe a) -> Maybe a
totalOf [T4 Maybe
t4.slip1.box18_employeeEI, T4 Maybe
t4.slip1.box55_premiumPPIP])
(\Maybe Centi
amt Page6 Maybe
pg-> Page6 Maybe
pg{line_31200 = amt}) T1 Maybe
t1.page6)
{line_30800 = if any hasAnyField t4
then schedule8.page5.part3a.line27_copy <|>
schedule8.page5.part3b.line32_join <|>
schedule8.page9.line60_least
else t1.page6.line_30800,
line_31000 = if any hasAnyField t4
then schedule8.page6.line15_half.result <|>
schedule8.page9.line78_half.result
else t1.page6.line_31000,
line_32300 = schedule11.page1.line17_sum,
line_34900 = schedule9.page1.line23_sum},
page7 = t1.page7{
step6_RefundOrBalanceOwing = t1.page7.step6_RefundOrBalanceOwing{
line_42100_CPPContributions = schedule8.page6.line14_sum <|>
find (> 0) schedule8.page8.line55_difference}},
page8 = t1.page8{
step6_RefundOrBalanceOwing =
(fromT4s' (.slip1.box22_incomeTaxDeducted) (\Maybe Centi
amt Page8Step6 Maybe
pt-> Page8Step6 Maybe
pt{line_43700_Total_income_tax_ded = amt})
t1.page8.step6_RefundOrBalanceOwing)
{line_44800_CPPOverpayment = schedule8.page5.part3a.line31_copy <|> schedule8.page9.line56_half.result,
line_45300_CWB = schedule6.page4.step3.line42_sum <|>
schedule6.page4.step2.line28_difference,
line_45350_CTC = schedule11.page1.line5_trainingClaim}}},
schedule6 :: Schedule6 Maybe
schedule6 = Maybe (T1 Maybe) -> T1 Maybe -> Schedule6 Maybe -> Schedule6 Maybe
fixSchedule6 Maybe (T1 Maybe)
forall a. Maybe a
Nothing T1 Maybe
t1 Schedule6 Maybe
schedule6,
schedule7 :: Schedule7 Maybe
schedule7 = T1 Maybe -> Schedule7 Maybe -> Schedule7 Maybe
fixSchedule7 T1 Maybe
t1 Schedule7 Maybe
schedule7,
schedule8 :: Schedule8 Maybe
schedule8 = Schedule8 Maybe -> Schedule8 Maybe
fixSchedule8 Schedule8 Maybe
schedule8{
page4 = schedule8.page4{
line_50339_totalPensionableEarnings =
totalOf . (liftA2 (<|>) (.slip1.box26_pensionableEarnings) (.slip1.box14_employmentIncome) <$>) =<< t4,
line_50340_totalContributions = totalOf . fmap (.slip1.box16_employeeCPP) =<< t4},
page6 = schedule8.page6{
line1_netSelfEmploymentEarnings = totalOf [t1.page3.line_12200_PartnershipIncome,
t1.page3.line29_sum.result]},
page7 = schedule8.page7{
line1_netSelfEmploymentEarnings = totalOf [t1.page3.line_12200_PartnershipIncome,
t1.page3.line29_sum.result]}},
schedule9 :: Schedule9 Maybe
schedule9 = T1 Maybe -> Schedule9 Maybe -> Schedule9 Maybe
fixSchedule9 T1 Maybe
t1 Schedule9 Maybe
schedule9,
schedule11 :: Schedule11 Maybe
schedule11 = T1 Maybe -> Schedule11 Maybe -> Schedule11 Maybe
fixSchedule11 T1 Maybe
t1 Schedule11 Maybe
schedule11}
formFieldsForProvince :: Province.Code -> Forms FieldConst
formFieldsForProvince :: Code -> Forms FieldConst
formFieldsForProvince Code
p = Forms{
t1 :: T1 FieldConst
t1 = Text -> FieldConst a -> FieldConst a
forall x. Text -> FieldConst x -> FieldConst x
within (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormKey -> String
forall a. Show a => a -> String
show FormKey
FormKey.T1) (forall {a}. FieldConst a -> FieldConst a)
-> T1 FieldConst -> T1 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) -> T1 p -> T1 q
Rank2.<$> Code -> T1 FieldConst
t1FieldsForProvince Code
p,
schedule6 :: Schedule6 FieldConst
schedule6 = Text -> FieldConst a -> FieldConst a
forall x. Text -> FieldConst x -> FieldConst x
within (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormKey -> String
forall a. Show a => a -> String
show FormKey
FormKey.Schedule6) (forall {a}. FieldConst a -> FieldConst a)
-> Schedule6 FieldConst -> Schedule6 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) -> Schedule6 p -> Schedule6 q
Rank2.<$> Schedule6 FieldConst
schedule6Fields,
schedule7 :: Schedule7 FieldConst
schedule7 = Text -> FieldConst a -> FieldConst a
forall x. Text -> FieldConst x -> FieldConst x
within (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormKey -> String
forall a. Show a => a -> String
show FormKey
FormKey.Schedule7) (forall {a}. FieldConst a -> FieldConst a)
-> Schedule7 FieldConst -> Schedule7 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) -> Schedule7 p -> Schedule7 q
Rank2.<$> Schedule7 FieldConst
schedule7Fields,
schedule8 :: Schedule8 FieldConst
schedule8 = Text -> FieldConst a -> FieldConst a
forall x. Text -> FieldConst x -> FieldConst x
within (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormKey -> String
forall a. Show a => a -> String
show FormKey
FormKey.Schedule8) (forall {a}. FieldConst a -> FieldConst a)
-> Schedule8 FieldConst -> Schedule8 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) -> Schedule8 p -> Schedule8 q
Rank2.<$> Schedule8 FieldConst
schedule8Fields,
schedule9 :: Schedule9 FieldConst
schedule9 = Text -> FieldConst a -> FieldConst a
forall x. Text -> FieldConst x -> FieldConst x
within (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormKey -> String
forall a. Show a => a -> String
show FormKey
FormKey.Schedule9) (forall {a}. FieldConst a -> FieldConst a)
-> Schedule9 FieldConst -> Schedule9 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) -> Schedule9 p -> Schedule9 q
Rank2.<$> Schedule9 FieldConst
schedule9Fields,
schedule11 :: Schedule11 FieldConst
schedule11 = Text -> FieldConst a -> FieldConst a
forall x. Text -> FieldConst x -> FieldConst x
within (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ FormKey -> String
forall a. Show a => a -> String
show FormKey
FormKey.Schedule11) (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 FieldConst
schedule11Fields}
formFileNames :: Map FormKey Text
formFileNames :: Map FormKey Text
formFileNames = [(FormKey, Text)] -> Map FormKey Text
forall k a. Ord k => [(k, a)] -> Map k a
fromList [
(FormKey
FormKey.Schedule6, Text
"5000-s6"),
(FormKey
FormKey.Schedule7, Text
"5000-s7"),
(FormKey
FormKey.Schedule8, Text
"5000-s8"),
(FormKey
FormKey.Schedule9, Text
"5000-s9"),
(FormKey
FormKey.Schedule11, Text
"5000-s11")]
relevantFormKeys :: T1 Maybe -> Set FormKey
relevantFormKeys :: T1 Maybe -> Set FormKey
relevantFormKeys T1 Maybe
t1 = [FormKey] -> Set FormKey
forall a. Ord a => [a] -> Set a
Set.fromList ([FormKey] -> Set FormKey) -> [FormKey] -> Set FormKey
forall a b. (a -> b) -> a -> b
$
[FormKey
FormKey.Provincial428 | Maybe Centi -> Bool
forall a. Maybe a -> Bool
isJust T1 Maybe
t1.page8.step6_RefundOrBalanceOwing.line_45300_CWB] [FormKey] -> [FormKey] -> [FormKey]
forall a. Semigroup a => a -> a -> a
<>
[FormKey
FormKey.Schedule6 | Maybe Centi -> Bool
forall a. Maybe a -> Bool
isJust T1 Maybe
t1.page8.step6_RefundOrBalanceOwing.line_45300_CWB] [FormKey] -> [FormKey] -> [FormKey]
forall a. Semigroup a => a -> a -> a
<>
[FormKey
FormKey.Schedule7 | Maybe Centi -> Bool
forall a. Maybe a -> Bool
isJust T1 Maybe
t1.page4.line_20800_RRSPDeduction] [FormKey] -> [FormKey] -> [FormKey]
forall a. Semigroup a => a -> a -> a
<>
[FormKey
FormKey.Schedule8 | Maybe Centi -> Bool
forall a. Maybe a -> Bool
isJust (T1 Maybe
t1.page4.line_22200_CPP_QPP_Contributions
Maybe Centi -> Maybe Centi -> Maybe Centi
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> T1 Maybe
t1.page4.line_22215_DeductionCPP_QPP
Maybe Centi -> Maybe Centi -> Maybe Centi
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> T1 Maybe
t1.page6.line_30800
Maybe Centi -> Maybe Centi -> Maybe Centi
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> T1 Maybe
t1.page6.line_31000
Maybe Centi -> Maybe Centi -> Maybe Centi
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> T1 Maybe
t1.page7.step6_RefundOrBalanceOwing.line_42100_CPPContributions
Maybe Centi -> Maybe Centi -> Maybe Centi
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> T1 Maybe
t1.page8.step6_RefundOrBalanceOwing.line_44800_CPPOverpayment)] [FormKey] -> [FormKey] -> [FormKey]
forall a. Semigroup a => a -> a -> a
<>
[FormKey
FormKey.Schedule9 | Maybe Centi -> Bool
forall a. Maybe a -> Bool
isJust T1 Maybe
t1.page6.line_34900] [FormKey] -> [FormKey] -> [FormKey]
forall a. Semigroup a => a -> a -> a
<>
[FormKey
FormKey.Schedule11 | Maybe Centi -> Bool
forall a. Maybe a -> Bool
isJust (T1 Maybe
t1.page6.line_32300 Maybe Centi -> Maybe Centi -> Maybe Centi
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> T1 Maybe
t1.page8.step6_RefundOrBalanceOwing.line_45350_CTC)] [FormKey] -> [FormKey] -> [FormKey]
forall a. Semigroup a => a -> a -> a
<>
[FormKey
FormKey.T1]
hasAnyField :: Foldable f => f (T4 Maybe) -> Bool
hasAnyField :: forall (f :: * -> *). Foldable f => f (T4 Maybe) -> Bool
hasAnyField = Any -> Bool
getAny (Any -> Bool) -> (f (T4 Maybe) -> Any) -> f (T4 Maybe) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (T4 Maybe -> Any) -> f (T4 Maybe) -> Any
forall m a. Monoid m => (a -> m) -> f a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((forall a. Maybe a -> Any) -> T4 Maybe -> Any
forall m (p :: * -> *).
Monoid m =>
(forall a. p a -> m) -> T4 p -> m
forall {k} (g :: (k -> *) -> *) m (p :: k -> *).
(Foldable g, Monoid m) =>
(forall (a :: k). p a -> m) -> g p -> m
Rank2.foldMap (Bool -> Any
Any (Bool -> Any) -> (Maybe a -> Bool) -> Maybe a -> Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe a -> Bool
forall a. Maybe a -> Bool
isJust))
fromT4s :: Maybe (NonEmpty (T4 Maybe)) -> (T4 Maybe -> Maybe Centi) -> (Maybe Centi -> form -> form) -> form -> form
fromT4s :: forall form.
Maybe (NonEmpty (T4 Maybe))
-> (T4 Maybe -> Maybe Centi)
-> (Maybe Centi -> form -> form)
-> form
-> form
fromT4s Maybe (NonEmpty (T4 Maybe))
t4 T4 Maybe -> Maybe Centi
field Maybe Centi -> form -> form
set
| Compose Maybe NonEmpty (T4 Maybe) -> Bool
forall (f :: * -> *). Foldable f => f (T4 Maybe) -> Bool
hasAnyField (Maybe (NonEmpty (T4 Maybe)) -> Compose Maybe NonEmpty (T4 Maybe)
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose Maybe (NonEmpty (T4 Maybe))
t4) = Maybe Centi -> form -> form
set (Maybe Centi -> form -> form) -> Maybe Centi -> form -> form
forall a b. (a -> b) -> a -> b
$ Compose Maybe NonEmpty (Maybe Centi) -> Maybe Centi
forall (f :: * -> *) a.
(Foldable f, Num a) =>
f (Maybe a) -> Maybe a
totalOf (Compose Maybe NonEmpty (Maybe Centi) -> Maybe Centi)
-> Compose Maybe NonEmpty (Maybe Centi) -> Maybe Centi
forall a b. (a -> b) -> a -> b
$ T4 Maybe -> Maybe Centi
field (T4 Maybe -> Maybe Centi)
-> Compose Maybe NonEmpty (T4 Maybe)
-> Compose Maybe NonEmpty (Maybe Centi)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (NonEmpty (T4 Maybe)) -> Compose Maybe NonEmpty (T4 Maybe)
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose Maybe (NonEmpty (T4 Maybe))
t4
| Bool
otherwise = form -> form
forall a. a -> a
id
additionalT4 :: [Text] -> T4 Maybe -> Maybe Centi
additionalT4 :: [Text] -> T4 Maybe -> Maybe Centi
additionalT4 [Text]
codes T4 Maybe
t4 = Sum Centi -> Centi
forall a. Sum a -> a
getSum (Sum Centi -> Centi) -> Maybe (Sum Centi) -> Maybe Centi
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Product (Only Text) (Only Centi) Maybe -> Maybe (Sum Centi))
-> ZipList (Product (Only Text) (Only Centi) Maybe)
-> Maybe (Sum Centi)
forall m a. Monoid m => (a -> m) -> ZipList a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Product (Only Text) (Only Centi) Maybe -> Maybe (Sum Centi)
forall {a}. Product (Only Text) (Only a) Maybe -> Maybe (Sum a)
findCode T4 Maybe
t4.slip1.otherInformation
where findCode :: Product (Only Text) (Only a) Maybe -> Maybe (Sum a)
findCode (Rank2.Pair (Rank2.Only (Just Text
code)) (Rank2.Only (Just a
amt)))
| Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem Text
code [Text]
codes = Sum a -> Maybe (Sum a)
forall a. a -> Maybe a
Just (a -> Sum a
forall a. a -> Sum a
Sum a
amt)
findCode Product (Only Text) (Only a) Maybe
_ = Maybe (Sum a)
forall a. Maybe a
Nothing