]> Git — Sourcephile - tmp/julm/literate-invoice.git/blob - src/Literate/Invoice.hs
maint/correctness(Invoice): use sum type for InvoiceId
[tmp/julm/literate-invoice.git] / src / Literate / Invoice.hs
1 {-# LANGUAGE DeriveAnyClass #-}
2 {-# LANGUAGE OverloadedLists #-}
3 {-# LANGUAGE QuantifiedConstraints #-}
4 {-# LANGUAGE UndecidableInstances #-}
5
6 module Literate.Invoice where
7
8 import Country qualified
9 import Literate.Accounting.Amount
10 import Literate.Accounting.Quantity
11 import Literate.Accounting.Unit
12 import Literate.Document qualified as Doc
13 import Literate.Document.HTML qualified as HTML
14 import Literate.Organization
15 import Literate.Prelude
16 import Literate.Time
17
18 -- type Invoices entId = Map (InvoiceId entId) (Invoice entId)
19 type InvoiceAction = [Text]
20 type InvoiceScope = [Text]
21
22 data Invoice entId invId = Invoice
23 { invoiceId :: invId
24 , invoiceType :: InvoiceType
25 , invoiceEmittedOn :: LocalTime
26 , invoiceOrders :: [Doc.Inline]
27 , invoicePaymentDueBefore :: LocalTime
28 , invoiceIssuer :: entId
29 , invoiceRecipient :: entId
30 , -- , invoiceItems :: [InvoiceItem (UnitName "€" :/: UnitName "h") (UnitName "h")]
31 invoiceRates :: Map InvoiceAction (Amount 100 (UnitName "€" :/: UnitName "h"))
32 , invoiceMentions :: [InvoiceMention]
33 , invoiceWorks :: [Work]
34 }
35 deriving (Eq, Show)
36
37 invoice :: Enum entId => invId -> Invoice entId invId
38 invoice invoiceId =
39 Invoice
40 { invoiceId
41 , invoiceType = InvoiceTypeSale
42 , invoiceEmittedOn = "2000-01-01"
43 , invoiceOrders = []
44 , invoicePaymentDueBefore = "2000-01-31"
45 , invoiceIssuer = toEnum 0
46 , invoiceRecipient = toEnum 0
47 , invoiceRates = []
48 , invoiceMentions = []
49 , invoiceWorks = []
50 }
51
52 class GetInvoice entId invId where
53 getInvoice :: invId -> Invoice entId invId
54
55 data Work = Work
56 { workDescription :: Doc.Inline
57 , workDate :: LocalTime
58 , workDuration :: Amount 100 (UnitName "h")
59 , workAction :: [Text]
60 , workScope :: [Text]
61 , workReferences :: [URL]
62 }
63 deriving (Eq, Show)
64 data InvoiceType
65 = InvoiceTypeSale
66 | InvoiceTypeProForma
67 | InvoiceTypeVoucher
68 deriving (Eq, Ord, Show, Generic, NFData)
69 data InvoiceMention
70 = InvoiceMentionTVANonApplicable
71 | InvoiceMentionIndemnitéForfaitaire
72 | InvoiceMentionIndemnitéTaux (Amount 100 (UnitName "%"))
73 deriving (Eq, Ord, Show, Generic, NFData)
74
75 data InvoiceItem rate qty = InvoiceItem
76 { invoiceItemScope :: [Text]
77 , invoiceItemAction :: [Text]
78 , invoiceItemType :: InvoiceItemType
79 , invoiceItemPeriod :: Period
80 , invoiceItemRate :: Amount 100 rate
81 , invoiceItemQuantity :: Amount 100 qty
82 }
83 deriving (Eq, Show)
84 type Euro = Amount 100 (UnitName "€")
85
86 invoiceItemTotal :: InvoiceItem rate qty -> Euro
87 invoiceItemTotal InvoiceItem{..} =
88 let (res, _actualFrac) =
89 invoiceItemRate
90 & amountQuantity
91 & fraction (invoiceItemQuantity & amountQuantity & quantityToRatio)
92 in Amount res
93 invoiceItem =
94 InvoiceItem
95 { invoiceItemScope = []
96 , invoiceItemAction = []
97 , invoiceItemType = InvoiceItemTypeItem
98 , invoiceItemPeriod = Period{periodBeginning = "2000-01-01", periodEnd = "2000-01-01"}
99 , invoiceItemRate = 0
100 , invoiceItemQuantity = 0
101 }
102
103 data InvoiceItemType
104 = InvoiceItemTypeItem
105 | InvoiceItemTypeService
106 deriving (Eq, Ord, Show)
107
108 data Period = Period
109 { periodBeginning :: LocalTime
110 , periodEnd :: LocalTime
111 }
112 deriving (Eq, Ord, Show, Generic, NFData)