1 {-# LANGUAGE OverloadedLists #-}
3 module Literate.Invoice.Invoice where
5 import Country qualified
6 import Literate.Accounting.Math
7 import Literate.Document qualified as Doc
8 import Literate.Document.HTML qualified as HTML
9 import Literate.Organization
10 import Literate.Prelude
13 data InvoiceId = InvoiceId
14 { invoiceIdRecipient :: Organization
15 , invoiceIdType :: InvoiceType
16 , invoiceIdCount :: Natural
18 deriving (Eq, Ord, Show)
19 instance Doc.ToInline InvoiceId where
22 , i & invoiceIdRecipient & orgEntity & entityId & Doc.toInline
23 , case i & invoiceIdType of
24 InvoiceTypeProForma -> "pro-forma"
25 InvoiceTypeSale -> "sale"
26 InvoiceTypeVoucher -> "voucher"
27 , i & invoiceIdCount & show & Doc.toInline
31 type Invoices = Map InvoiceId Invoice
32 type InvoiceAction = [Text]
33 type InvoiceScope = [Text]
35 data Invoice = Invoice
36 { invoiceEmittedOn :: LocalTime
37 , invoiceOrders :: [Doc.Inline]
38 , invoicePaymentDueBefore :: LocalTime
39 , invoiceIssuer :: Organization
40 , invoiceRecipient :: Organization
41 , -- , invoiceItems :: [InvoiceItem (UnitName "€" :/: UnitName "h") (UnitName "h")]
42 invoiceRates :: Map InvoiceAction (Amount 100 (UnitName "€" :/: UnitName "h"))
43 , invoiceMentions :: [InvoiceMention]
44 , invoiceLogs :: [InvoiceLog]
49 { invoiceEmittedOn = "2000-01-01"
51 , invoicePaymentDueBefore = "2000-01-31"
52 , invoiceIssuer = organization
53 , invoiceRecipient = organization
55 , invoiceMentions = []
58 data InvoiceLog = InvoiceLog
59 { invoiceLogDescription :: Doc.Inline
60 , invoiceLogDate :: LocalTime
61 , invoiceLogDuration :: Amount 100 (UnitName "h")
62 , invoiceLogAction :: [Text]
63 , invoiceLogScope :: [Text]
64 , invoiceLogReferences :: [URL]
71 deriving (Eq, Ord, Show)
73 = InvoiceMentionTVANonApplicable
74 | InvoiceMentionIndemnitéForfaitaire
75 | InvoiceMentionIndemnitéTaux (Amount 100 (UnitName "%"))
76 deriving (Eq, Ord, Show)
78 data InvoiceItem rate qty = InvoiceItem
79 { invoiceItemScope :: [Text]
80 , invoiceItemAction :: [Text]
81 , invoiceItemType :: InvoiceItemType
82 , invoiceItemPeriod :: Period
83 , invoiceItemRate :: Amount 100 rate
84 , invoiceItemQuantity :: Amount 100 qty
87 invoiceItemTotal :: InvoiceItem rate qty -> Amount 100 (UnitName "€")
88 invoiceItemTotal InvoiceItem{..} =
89 let (res, _actualFrac) =
92 & fraction (invoiceItemQuantity & amountQuantity & quantityToRatio)
96 { invoiceItemScope = []
97 , invoiceItemAction = []
98 , invoiceItemType = InvoiceItemTypeItem
99 , invoiceItemPeriod = Period{periodBeginning = "2000-01-01", periodEnd = "2000-01-01"}
100 , invoiceItemRate = 0
101 , invoiceItemQuantity = 0
105 = InvoiceItemTypeItem
106 | InvoiceItemTypeService
107 deriving (Eq, Ord, Show)
110 { periodBeginning :: LocalTime
111 , periodEnd :: LocalTime
113 deriving (Eq, Ord, Show)