{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
module Tax.Canada (completeForms, completeRelevantForms, formFileNames) where
import Data.CAProvinceCodes qualified as Province
import Data.Functor.Const (Const)
import Data.Functor.Product (Product (Pair))
import Data.Kind (Type)
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Set qualified as Set
import Data.Text (Text)
import Rank2 qualified
import Tax.Canada.Federal qualified as Federal
import Tax.Canada.Federal (fixFederalForms, relevantFormKeys)
import Tax.Canada.FormKey qualified as FormKey
import Tax.Canada.FormKey (FormKey)
import Tax.Canada.Province.AB qualified as AB
import Tax.Canada.Province.BC qualified as BC
import Tax.Canada.Province.MB qualified as MB
import Tax.Canada.Province.ON qualified as ON
import Tax.Canada.T1 as T1 (T1, fixT1, t1FieldsForProvince, fileNameForProvince)
import Tax.FDF (FDFs)
import Tax.FDF qualified as FDF
completeForms :: Province.Code -> Federal.InputForms Maybe -> FDFs FormKey -> Either String (FDFs FormKey)
completeForms :: Code
-> InputForms Maybe -> FDFs FormKey -> Either String (FDFs FormKey)
completeForms Code
Province.AB = Product Forms AB428 FieldConst
-> (Product Forms AB428 Maybe -> Product Forms AB428 Maybe)
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall (form :: (* -> *) -> *) a.
(Apply form, Traversable form, Ord a, Read a, Show a) =>
form FieldConst
-> (form Maybe -> form Maybe) -> FDFs a -> Either String (FDFs a)
FDF.mapForms Product Forms AB428 FieldConst
AB.returnFields ((Product Forms AB428 Maybe -> Product Forms AB428 Maybe)
-> FDFs FormKey -> Either String (FDFs FormKey))
-> (InputForms Maybe
-> Product Forms AB428 Maybe -> Product Forms AB428 Maybe)
-> InputForms Maybe
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputForms Maybe
-> Product Forms AB428 Maybe -> Product Forms AB428 Maybe
AB.fixReturns
completeForms Code
Province.BC = Returns FieldConst
-> (Returns Maybe -> Returns Maybe)
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall (form :: (* -> *) -> *) a.
(Apply form, Traversable form, Ord a, Read a, Show a) =>
form FieldConst
-> (form Maybe -> form Maybe) -> FDFs a -> Either String (FDFs a)
FDF.mapForms Returns FieldConst
BC.returnFields ((Returns Maybe -> Returns Maybe)
-> FDFs FormKey -> Either String (FDFs FormKey))
-> (InputForms Maybe -> Returns Maybe -> Returns Maybe)
-> InputForms Maybe
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputForms Maybe -> Returns Maybe -> Returns Maybe
BC.fixReturns
completeForms Code
Province.MB = Product Forms MB428 FieldConst
-> (Product Forms MB428 Maybe -> Product Forms MB428 Maybe)
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall (form :: (* -> *) -> *) a.
(Apply form, Traversable form, Ord a, Read a, Show a) =>
form FieldConst
-> (form Maybe -> form Maybe) -> FDFs a -> Either String (FDFs a)
FDF.mapForms Product Forms MB428 FieldConst
MB.returnFields ((Product Forms MB428 Maybe -> Product Forms MB428 Maybe)
-> FDFs FormKey -> Either String (FDFs FormKey))
-> (InputForms Maybe
-> Product Forms MB428 Maybe -> Product Forms MB428 Maybe)
-> InputForms Maybe
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputForms Maybe
-> Product Forms MB428 Maybe -> Product Forms MB428 Maybe
MB.fixReturns
completeForms Code
Province.ON = Returns FieldConst
-> (Returns Maybe -> Returns Maybe)
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall (form :: (* -> *) -> *) a.
(Apply form, Traversable form, Ord a, Read a, Show a) =>
form FieldConst
-> (form Maybe -> form Maybe) -> FDFs a -> Either String (FDFs a)
FDF.mapForms Returns FieldConst
ON.returnFields ((Returns Maybe -> Returns Maybe)
-> FDFs FormKey -> Either String (FDFs FormKey))
-> (InputForms Maybe -> Returns Maybe -> Returns Maybe)
-> InputForms Maybe
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputForms Maybe -> Returns Maybe -> Returns Maybe
ON.fixReturns
completeForms Code
p = Forms FieldConst
-> (Forms Maybe -> Forms Maybe)
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall (form :: (* -> *) -> *) a.
(Apply form, Traversable form, Ord a, Read a, Show a) =>
form FieldConst
-> (form Maybe -> form Maybe) -> FDFs a -> Either String (FDFs a)
FDF.mapForms (Code -> Forms FieldConst
Federal.formFieldsForProvince Code
p) ((Forms Maybe -> Forms Maybe)
-> FDFs FormKey -> Either String (FDFs FormKey))
-> (InputForms Maybe -> Forms Maybe -> Forms Maybe)
-> InputForms Maybe
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Code -> InputForms Maybe -> Forms Maybe -> Forms Maybe
fixFederalForms Code
p
completeRelevantForms :: Province.Code -> Federal.InputForms Maybe -> FDFs FormKey -> Either String (FDFs FormKey)
completeRelevantForms :: Code
-> InputForms Maybe -> FDFs FormKey -> Either String (FDFs FormKey)
completeRelevantForms Code
Province.AB =
(Either String (T1 Maybe, FDFs FormKey)
-> Either String (FDFs FormKey))
-> (FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall a b. (a -> b) -> (FDFs FormKey -> a) -> FDFs FormKey -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((T1 Maybe -> FDFs FormKey -> FDFs FormKey)
-> (T1 Maybe, FDFs FormKey) -> FDFs FormKey
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry T1 Maybe -> FDFs FormKey -> FDFs FormKey
filterRelevant ((T1 Maybe, FDFs FormKey) -> FDFs FormKey)
-> Either String (T1 Maybe, FDFs FormKey)
-> Either String (FDFs FormKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)
((FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> FDFs FormKey -> Either String (FDFs FormKey))
-> (InputForms Maybe
-> FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> InputForms Maybe
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Product Forms AB428 FieldConst
-> (Product Forms AB428 Maybe -> T1 Maybe)
-> (Product Forms AB428 Maybe -> Product Forms AB428 Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
forall (form :: (* -> *) -> *).
(Apply form, Traversable form) =>
form FieldConst
-> (form Maybe -> T1 Maybe)
-> (form Maybe -> form Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
mapFormsWithT1 Product Forms AB428 FieldConst
AB.returnFields ((.t1) (Forms Maybe -> T1 Maybe)
-> (Product Forms AB428 Maybe -> Forms Maybe)
-> Product Forms AB428 Maybe
-> T1 Maybe
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Product Forms AB428 Maybe -> Forms Maybe
forall {k} (g :: k -> *) (h :: k -> *) (p :: k).
Product g h p -> g p
Rank2.fst :: Rank2.Product Federal.Forms AB.AB428 Maybe -> T1 Maybe)
((Product Forms AB428 Maybe -> Product Forms AB428 Maybe)
-> FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> (InputForms Maybe
-> Product Forms AB428 Maybe -> Product Forms AB428 Maybe)
-> InputForms Maybe
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputForms Maybe
-> Product Forms AB428 Maybe -> Product Forms AB428 Maybe
AB.fixReturns
completeRelevantForms Code
Province.BC =
(Either String (T1 Maybe, FDFs FormKey)
-> Either String (FDFs FormKey))
-> (FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall a b. (a -> b) -> (FDFs FormKey -> a) -> FDFs FormKey -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((T1 Maybe -> FDFs FormKey -> FDFs FormKey)
-> (T1 Maybe, FDFs FormKey) -> FDFs FormKey
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry T1 Maybe -> FDFs FormKey -> FDFs FormKey
filterRelevant ((T1 Maybe, FDFs FormKey) -> FDFs FormKey)
-> Either String (T1 Maybe, FDFs FormKey)
-> Either String (FDFs FormKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)
((FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> FDFs FormKey -> Either String (FDFs FormKey))
-> (InputForms Maybe
-> FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> InputForms Maybe
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Returns FieldConst
-> (Returns Maybe -> T1 Maybe)
-> (Returns Maybe -> Returns Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
forall (form :: (* -> *) -> *).
(Apply form, Traversable form) =>
form FieldConst
-> (form Maybe -> T1 Maybe)
-> (form Maybe -> form Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
mapFormsWithT1 Returns FieldConst
BC.returnFields ((.federal.t1) :: BC.Returns Maybe -> T1 Maybe)
((Returns Maybe -> Returns Maybe)
-> FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> (InputForms Maybe -> Returns Maybe -> Returns Maybe)
-> InputForms Maybe
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputForms Maybe -> Returns Maybe -> Returns Maybe
BC.fixReturns
completeRelevantForms Code
Province.MB =
(Either String (T1 Maybe, FDFs FormKey)
-> Either String (FDFs FormKey))
-> (FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall a b. (a -> b) -> (FDFs FormKey -> a) -> FDFs FormKey -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((T1 Maybe -> FDFs FormKey -> FDFs FormKey)
-> (T1 Maybe, FDFs FormKey) -> FDFs FormKey
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry T1 Maybe -> FDFs FormKey -> FDFs FormKey
filterRelevant ((T1 Maybe, FDFs FormKey) -> FDFs FormKey)
-> Either String (T1 Maybe, FDFs FormKey)
-> Either String (FDFs FormKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)
((FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> FDFs FormKey -> Either String (FDFs FormKey))
-> (InputForms Maybe
-> FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> InputForms Maybe
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Product Forms MB428 FieldConst
-> (Product Forms MB428 Maybe -> T1 Maybe)
-> (Product Forms MB428 Maybe -> Product Forms MB428 Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
forall (form :: (* -> *) -> *).
(Apply form, Traversable form) =>
form FieldConst
-> (form Maybe -> T1 Maybe)
-> (form Maybe -> form Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
mapFormsWithT1 Product Forms MB428 FieldConst
MB.returnFields ((.t1) (Forms Maybe -> T1 Maybe)
-> (Product Forms MB428 Maybe -> Forms Maybe)
-> Product Forms MB428 Maybe
-> T1 Maybe
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Product Forms MB428 Maybe -> Forms Maybe
forall {k} (g :: k -> *) (h :: k -> *) (p :: k).
Product g h p -> g p
Rank2.fst :: Rank2.Product Federal.Forms MB.MB428 Maybe -> T1 Maybe)
((Product Forms MB428 Maybe -> Product Forms MB428 Maybe)
-> FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> (InputForms Maybe
-> Product Forms MB428 Maybe -> Product Forms MB428 Maybe)
-> InputForms Maybe
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputForms Maybe
-> Product Forms MB428 Maybe -> Product Forms MB428 Maybe
MB.fixReturns
completeRelevantForms Code
Province.ON =
(Either String (T1 Maybe, FDFs FormKey)
-> Either String (FDFs FormKey))
-> (FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall a b. (a -> b) -> (FDFs FormKey -> a) -> FDFs FormKey -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((T1 Maybe -> FDFs FormKey -> FDFs FormKey)
-> (T1 Maybe, FDFs FormKey) -> FDFs FormKey
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry T1 Maybe -> FDFs FormKey -> FDFs FormKey
filterRelevant ((T1 Maybe, FDFs FormKey) -> FDFs FormKey)
-> Either String (T1 Maybe, FDFs FormKey)
-> Either String (FDFs FormKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)
((FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> FDFs FormKey -> Either String (FDFs FormKey))
-> (InputForms Maybe
-> FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> InputForms Maybe
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Returns FieldConst
-> (Returns Maybe -> T1 Maybe)
-> (Returns Maybe -> Returns Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
forall (form :: (* -> *) -> *).
(Apply form, Traversable form) =>
form FieldConst
-> (form Maybe -> T1 Maybe)
-> (form Maybe -> form Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
mapFormsWithT1 Returns FieldConst
ON.returnFields ((.federal.t1) :: ON.Returns Maybe -> T1 Maybe)
((Returns Maybe -> Returns Maybe)
-> FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> (InputForms Maybe -> Returns Maybe -> Returns Maybe)
-> InputForms Maybe
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InputForms Maybe -> Returns Maybe -> Returns Maybe
ON.fixReturns
completeRelevantForms Code
p =
(Either String (T1 Maybe, FDFs FormKey)
-> Either String (FDFs FormKey))
-> (FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall a b. (a -> b) -> (FDFs FormKey -> a) -> FDFs FormKey -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((T1 Maybe -> FDFs FormKey -> FDFs FormKey)
-> (T1 Maybe, FDFs FormKey) -> FDFs FormKey
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry T1 Maybe -> FDFs FormKey -> FDFs FormKey
filterRelevant ((T1 Maybe, FDFs FormKey) -> FDFs FormKey)
-> Either String (T1 Maybe, FDFs FormKey)
-> Either String (FDFs FormKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)
((FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> FDFs FormKey -> Either String (FDFs FormKey))
-> (InputForms Maybe
-> FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> InputForms Maybe
-> FDFs FormKey
-> Either String (FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Forms FieldConst
-> (Forms Maybe -> T1 Maybe)
-> (Forms Maybe -> Forms Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
forall (form :: (* -> *) -> *).
(Apply form, Traversable form) =>
form FieldConst
-> (form Maybe -> T1 Maybe)
-> (form Maybe -> form Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
mapFormsWithT1 (Code -> Forms FieldConst
Federal.formFieldsForProvince Code
p) (.t1)
((Forms Maybe -> Forms Maybe)
-> FDFs FormKey -> Either String (T1 Maybe, FDFs FormKey))
-> (InputForms Maybe -> Forms Maybe -> Forms Maybe)
-> InputForms Maybe
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Code -> InputForms Maybe -> Forms Maybe -> Forms Maybe
fixFederalForms Code
p
filterRelevant :: T1 Maybe -> FDFs FormKey -> FDFs FormKey
filterRelevant :: T1 Maybe -> FDFs FormKey -> FDFs FormKey
filterRelevant T1 Maybe
t1 = (FDFs FormKey -> Set FormKey -> FDFs FormKey)
-> Set FormKey -> FDFs FormKey -> FDFs FormKey
forall a b c. (a -> b -> c) -> b -> a -> c
flip FDFs FormKey -> Set FormKey -> FDFs FormKey
forall k a. Ord k => Map k a -> Set k -> Map k a
Map.restrictKeys (T1 Maybe -> Set FormKey
relevantFormKeys T1 Maybe
t1 Set FormKey -> Set FormKey -> Set FormKey
forall a. Semigroup a => a -> a -> a
<> Set FormKey
alwaysRelevant)
where alwaysRelevant :: Set FormKey
alwaysRelevant = [FormKey] -> Set FormKey
forall a. Ord a => [a] -> Set a
Set.fromList [FormKey
FormKey.Provincial428, FormKey
FormKey.Provincial479, FormKey
FormKey.T1]
mapFormsWithT1 :: (Rank2.Apply form, Rank2.Traversable form)
=> form FDF.FieldConst -> (form Maybe -> T1 Maybe) -> (form Maybe -> form Maybe) -> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
mapFormsWithT1 :: forall (form :: (* -> *) -> *).
(Apply form, Traversable form) =>
form FieldConst
-> (form Maybe -> T1 Maybe)
-> (form Maybe -> form Maybe)
-> FDFs FormKey
-> Either String (T1 Maybe, FDFs FormKey)
mapFormsWithT1 form FieldConst
fields form Maybe -> T1 Maybe
getT1 form Maybe -> form Maybe
f FDFs FormKey
fdfs = do
forms <- form FieldConst -> FDFs FormKey -> Either String (form Maybe)
forall (form :: (* -> *) -> *) a.
(Apply form, Traversable form, Ord a, Read a, Show a) =>
form FieldConst -> FDFs a -> Either String (form Maybe)
FDF.loadAll form FieldConst
fields FDFs FormKey
fdfs
let forms' = form Maybe -> form Maybe
f form Maybe
forms
t1' = form Maybe -> T1 Maybe
getT1 form Maybe
forms'
(,) t1' <$> FDF.storeAll fields fdfs forms'
formFileNames :: Province.Code -> Map FormKey Text
formFileNames :: Code -> Map FormKey Text
formFileNames Code
Province.AB = Map FormKey Text
AB.formFileNames Map FormKey Text -> Map FormKey Text -> Map FormKey Text
forall a. Semigroup a => a -> a -> a
<> Map FormKey Text
Federal.formFileNames
formFileNames Code
Province.BC = Map FormKey Text
BC.formFileNames Map FormKey Text -> Map FormKey Text -> Map FormKey Text
forall a. Semigroup a => a -> a -> a
<> Map FormKey Text
Federal.formFileNames
formFileNames Code
Province.MB = Map FormKey Text
MB.formFileNames Map FormKey Text -> Map FormKey Text -> Map FormKey Text
forall a. Semigroup a => a -> a -> a
<> Map FormKey Text
Federal.formFileNames
formFileNames Code
Province.ON = Map FormKey Text
ON.formFileNames Map FormKey Text -> Map FormKey Text -> Map FormKey Text
forall a. Semigroup a => a -> a -> a
<> Map FormKey Text
Federal.formFileNames
formFileNames Code
p = [(FormKey, Text)] -> Map FormKey Text
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(FormKey
FormKey.T1, Code -> Text
T1.fileNameForProvince Code
p)] Map FormKey Text -> Map FormKey Text -> Map FormKey Text
forall a. Semigroup a => a -> a -> a
<> Map FormKey Text
Federal.formFileNames