1 {-# LANGUAGE OverloadedLists #-}
3 module Literate.Invoice.Invoice where
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
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
19 data InvoiceId = InvoiceId
20 { invoiceIdBuyer :: Entity
21 , invoiceIdCount :: Natural
23 deriving (Eq, Ord, Show)
24 instance Doc.ToInline InvoiceId where
28 , i & invoiceIdBuyer & entityId & Doc.toInline
30 , i & invoiceIdCount & show & Doc.toInline
32 instance HTML.ToMarkup InvoiceId where
33 toMarkup InvoiceId{..} =
35 <> (invoiceIdBuyer & entityId & HTML.toMarkup)
37 <> (invoiceIdCount & HTML.toMarkup)
39 type Invoices = Map InvoiceId Invoice
44 { entityId :: EntityId
46 , entityEmail :: Maybe Email
47 , entityAddress :: Address
48 , entitySIREN :: Maybe Text
50 deriving (Eq, Ord, Show)
55 , entityAddress = address
56 , entityEmail = Nothing
57 , entitySIREN = Nothing
60 data Address = Address
61 { addressText :: [Text]
62 , addressZipCode :: ZipCode
64 , addressCountry :: Country
66 deriving (Eq, Ord, Show)
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]
92 { invoiceCreation = "2000-01-01"
93 , invoiceIssuer = entity
94 , invoiceRecipient = entity
95 , invoiceCustomer = entity
99 , invoiceMentions = []
103 = InvoiceMentionTVANonApplicable
104 deriving (Eq, Ord, Show)
106 data InvoiceItem rate qty = InvoiceItem
107 { invoiceItemDescription :: Doc.Block
108 , invoiceItemPeriod :: Period
109 , invoiceItemRate :: Amount 100 rate
110 , invoiceItemQuantity :: Amount 100 qty
113 invoiceItemTotal :: InvoiceItem rate qty -> Amount 100 (UnitName "€")
114 invoiceItemTotal InvoiceItem{..} =
115 let (res, _actualFrac) =
118 & fraction (invoiceItemQuantity & amountQuantity & quantityToRatio)
122 { periodBegin :: LocalTime
123 , periodEnd :: LocalTime
125 deriving (Eq, Ord, Show)