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