1 {-# LANGUAGE OverloadedLists #-}
3 module Literate.Invoice where
5 import Country qualified
6 import Literate.Accounting.Amount
7 import Literate.Accounting.Math
8 import Literate.Accounting.Unit
9 import Literate.Document qualified as Doc
10 import Literate.Document.HTML qualified as HTML
11 import Literate.Organization
12 import Literate.Prelude
15 data InvoiceId = InvoiceId
16 { invoiceIdRecipient :: Organization
17 , invoiceIdType :: InvoiceType
18 , invoiceIdCount :: Natural
20 deriving (Eq, Ord, Show)
21 instance Doc.ToInline InvoiceId where
24 , i & invoiceIdRecipient & orgEntity & entityId & Doc.toInline
25 , case i & invoiceIdType of
26 InvoiceTypeProForma -> "pro-forma"
27 InvoiceTypeSale -> "sale"
28 InvoiceTypeVoucher -> "voucher"
29 , i & invoiceIdCount & show & Doc.toInline
33 type Invoices = Map InvoiceId Invoice
34 type InvoiceAction = [Text]
35 type InvoiceScope = [Text]
37 data Invoice = Invoice
38 { invoiceEmittedOn :: LocalTime
39 , invoiceOrders :: [Doc.Inline]
40 , invoicePaymentDueBefore :: LocalTime
41 , invoiceIssuer :: Organization
42 , invoiceRecipient :: Organization
43 , -- , invoiceItems :: [InvoiceItem (UnitName "€" :/: UnitName "h") (UnitName "h")]
44 invoiceRates :: Map InvoiceAction (Amount 100 (UnitName "€" :/: UnitName "h"))
45 , invoiceMentions :: [InvoiceMention]
46 , invoiceWorks :: [Work]
51 { invoiceEmittedOn = "2000-01-01"
53 , invoicePaymentDueBefore = "2000-01-31"
54 , invoiceIssuer = organization
55 , invoiceRecipient = organization
57 , invoiceMentions = []
61 { workDescription :: Doc.Inline
62 , workDate :: LocalTime
63 , workDuration :: Amount 100 (UnitName "h")
64 , workAction :: [Text]
66 , workReferences :: [URL]
73 deriving (Eq, Ord, Show)
75 = InvoiceMentionTVANonApplicable
76 | InvoiceMentionIndemnitéForfaitaire
77 | InvoiceMentionIndemnitéTaux (Amount 100 (UnitName "%"))
78 deriving (Eq, Ord, Show)
80 data InvoiceItem rate qty = InvoiceItem
81 { invoiceItemScope :: [Text]
82 , invoiceItemAction :: [Text]
83 , invoiceItemType :: InvoiceItemType
84 , invoiceItemPeriod :: Period
85 , invoiceItemRate :: Amount 100 rate
86 , invoiceItemQuantity :: Amount 100 qty
90 invoiceItemTotal :: InvoiceItem rate qty -> Euro
91 invoiceItemTotal InvoiceItem{..} =
92 let (res, _actualFrac) =
95 & fraction (invoiceItemQuantity & amountQuantity & quantityToRatio)
99 { invoiceItemScope = []
100 , invoiceItemAction = []
101 , invoiceItemType = InvoiceItemTypeItem
102 , invoiceItemPeriod = Period{periodBeginning = "2000-01-01", periodEnd = "2000-01-01"}
103 , invoiceItemRate = 0
104 , invoiceItemQuantity = 0
108 = InvoiceItemTypeItem
109 | InvoiceItemTypeService
110 deriving (Eq, Ord, Show)
113 { periodBeginning :: LocalTime
114 , periodEnd :: LocalTime
116 deriving (Eq, Ord, Show)