]> Git — Sourcephile - tmp/julm/literate-invoice.git/blob - src/Literate/Invoice/Invoice.hs
feat(invoice): add what I need
[tmp/julm/literate-invoice.git] / src / Literate / Invoice / Invoice.hs
1 {-# LANGUAGE OverloadedLists #-}
2
3 module Literate.Invoice.Invoice where
4
5 import Data.Text qualified as Text
6 import Literate.Accounting.Math
7 import Literate.Document qualified as Doc
8 import Literate.Document.HTML qualified as HTML
9 import Literate.Prelude
10 import Literate.Time
11
12 data Id = Id {unId :: Natural}
13 deriving (Eq, Ord, Show)
14 instance HTML.ToMarkup Id where
15 toMarkup i = i & unId & HTML.toHtml
16 instance Doc.ToInline Id where
17 toInline i = i & unId & show & Doc.toInline
18
19 data InvoiceId = InvoiceId
20 { invoiceIdBuyer :: Entity
21 , invoiceIdCount :: Natural
22 }
23 deriving (Eq, Ord, Show)
24 instance Doc.ToInline InvoiceId where
25 toInline i =
26 Doc.Inlines
27 [ "ent"
28 , i & invoiceIdBuyer & entityId & Doc.toInline
29 , "inv"
30 , i & invoiceIdCount & show & Doc.toInline
31 ]
32 instance HTML.ToMarkup InvoiceId where
33 toMarkup InvoiceId{..} =
34 "ent"
35 <> (invoiceIdBuyer & entityId & HTML.toMarkup)
36 <> "inv"
37 <> (invoiceIdCount & HTML.toMarkup)
38
39 type Invoices = Map InvoiceId Invoice
40
41 type EntityId = Id
42 type Email = Text
43 data Entity = Entity
44 { entityId :: EntityId
45 , entityName :: Text
46 , entityEmail :: Maybe Email
47 , entityAddress :: Address
48 , entitySIREN :: Maybe Text
49 }
50 deriving (Eq, Ord, Show)
51 entity =
52 Entity
53 { entityId = Id 0
54 , entityName = ""
55 , entityAddress = address
56 , entityEmail = Nothing
57 , entitySIREN = Nothing
58 }
59
60 data Address = Address
61 { addressText :: [Text]
62 , addressZipCode :: ZipCode
63 , addressCity :: City
64 , addressCountry :: Country
65 }
66 deriving (Eq, Ord, Show)
67
68 address =
69 Address
70 { addressText = []
71 , addressZipCode = ""
72 , addressCity = ""
73 , addressCountry = ""
74 }
75
76 type ZipCode = Text
77 type City = Text
78 type Country = Text
79
80 data Invoice = Invoice
81 { invoiceCreation :: LocalTime
82 , invoiceIssuer :: Entity
83 , invoiceRecipient :: Entity
84 , invoiceCustomer :: Entity
85 , invoiceObjet :: Text
86 , invoiceDetails :: Text
87 , invoiceItems :: [InvoiceItem (UnitName "€" :/: UnitName "h") (UnitName "h")]
88 , invoiceMentions :: [InvoiceMention]
89 }
90 invoice =
91 Invoice
92 { invoiceCreation = "2000-01-01"
93 , invoiceIssuer = entity
94 , invoiceRecipient = entity
95 , invoiceCustomer = entity
96 , invoiceObjet = ""
97 , invoiceDetails = ""
98 , invoiceItems = []
99 , invoiceMentions = []
100 }
101
102 data InvoiceMention
103 = InvoiceMentionTVANonApplicable
104 deriving (Eq, Ord, Show)
105
106 data InvoiceItem rate qty = InvoiceItem
107 { invoiceItemDescription :: Doc.Block
108 , invoiceItemPeriod :: Period
109 , invoiceItemRate :: Amount 100 rate
110 , invoiceItemQuantity :: Amount 100 qty
111 }
112 deriving (Eq, Show)
113 invoiceItemTotal :: InvoiceItem rate qty -> Amount 100 (UnitName "€")
114 invoiceItemTotal InvoiceItem{..} =
115 let (res, _actualFrac) =
116 invoiceItemRate
117 & amountQuantity
118 & fraction (invoiceItemQuantity & amountQuantity & quantityToRatio)
119 in Amount res
120
121 data Period = Period
122 { periodBegin :: LocalTime
123 , periodEnd :: LocalTime
124 }
125 deriving (Eq, Ord, Show)