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