1 {-# LANGUAGE DeriveAnyClass #-}
2 {-# LANGUAGE OverloadedLists #-}
4 module Literate.Invoice where
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
16 data InvoiceId = InvoiceId
17 { invoiceIdRecipient :: Organization
18 , invoiceIdType :: InvoiceType
19 , invoiceIdCount :: Natural
21 deriving (Eq, Ord, Show, Generic, NFData)
22 instance Doc.ToInline InvoiceId where
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
34 type Invoices = Map InvoiceId Invoice
35 type InvoiceAction = [Text]
36 type InvoiceScope = [Text]
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]
52 { invoiceEmittedOn = "2000-01-01"
54 , invoicePaymentDueBefore = "2000-01-31"
55 , invoiceIssuer = organization
56 , invoiceRecipient = organization
58 , invoiceMentions = []
62 { workDescription :: Doc.Inline
63 , workDate :: LocalTime
64 , workDuration :: Amount 100 (UnitName "h")
65 , workAction :: [Text]
67 , workReferences :: [URL]
74 deriving (Eq, Ord, Show, Generic, NFData)
76 = InvoiceMentionTVANonApplicable
77 | InvoiceMentionIndemnitéForfaitaire
78 | InvoiceMentionIndemnitéTaux (Amount 100 (UnitName "%"))
79 deriving (Eq, Ord, Show, Generic, NFData)
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
90 type Euro = Amount 100 (UnitName "€")
92 invoiceItemTotal :: InvoiceItem rate qty -> Euro
93 invoiceItemTotal InvoiceItem{..} =
94 let (res, _actualFrac) =
97 & fraction (invoiceItemQuantity & amountQuantity & quantityToRatio)
101 { invoiceItemScope = []
102 , invoiceItemAction = []
103 , invoiceItemType = InvoiceItemTypeItem
104 , invoiceItemPeriod = Period{periodBeginning = "2000-01-01", periodEnd = "2000-01-01"}
105 , invoiceItemRate = 0
106 , invoiceItemQuantity = 0
110 = InvoiceItemTypeItem
111 | InvoiceItemTypeService
112 deriving (Eq, Ord, Show)
115 { periodBeginning :: LocalTime
116 , periodEnd :: LocalTime
118 deriving (Eq, Ord, Show)