1 {-# LANGUAGE DeriveAnyClass #-}
2 {-# LANGUAGE OverloadedLists #-}
3 {-# LANGUAGE QuantifiedConstraints #-}
4 {-# LANGUAGE UndecidableInstances #-}
6 module Literate.Invoice where
8 import Country qualified
9 import Literate.Accounting.Amount
10 import Literate.Accounting.Quantity
11 import Literate.Accounting.Unit
12 import Literate.Document qualified as Doc
13 import Literate.Document.HTML qualified as HTML
14 import Literate.Organization
15 import Literate.Prelude
18 -- type Invoices entId = Map (InvoiceId entId) (Invoice entId)
19 type InvoiceAction = [Text]
20 type InvoiceScope = [Text]
22 data Invoice entId invId = Invoice
24 , invoiceType :: InvoiceType
25 , invoiceEmittedOn :: LocalTime
26 , invoiceOrders :: [Doc.Inline]
27 , invoicePaymentDueBefore :: LocalTime
28 , invoiceIssuer :: entId
29 , invoiceRecipient :: entId
30 , -- , invoiceItems :: [InvoiceItem (UnitName "€" :/: UnitName "h") (UnitName "h")]
31 invoiceRates :: Map InvoiceAction (Amount 100 (UnitName "€" :/: UnitName "h"))
32 , invoiceMentions :: [InvoiceMention]
33 , invoiceWorks :: [Work]
37 invoice :: Enum entId => invId -> Invoice entId invId
41 , invoiceType = InvoiceTypeSale
42 , invoiceEmittedOn = "2000-01-01"
44 , invoicePaymentDueBefore = "2000-01-31"
45 , invoiceIssuer = toEnum 0
46 , invoiceRecipient = toEnum 0
48 , invoiceMentions = []
52 class GetInvoice entId invId where
53 getInvoice :: invId -> Invoice entId invId
56 { workDescription :: Doc.Inline
57 , workDate :: LocalTime
58 , workDuration :: Amount 100 (UnitName "h")
59 , workAction :: [Text]
61 , workReferences :: [URL]
68 deriving (Eq, Ord, Show, Generic, NFData)
70 = InvoiceMentionTVANonApplicable
71 | InvoiceMentionIndemnitéForfaitaire
72 | InvoiceMentionIndemnitéTaux (Amount 100 (UnitName "%"))
73 deriving (Eq, Ord, Show, Generic, NFData)
75 data InvoiceItem rate qty = InvoiceItem
76 { invoiceItemScope :: [Text]
77 , invoiceItemAction :: [Text]
78 , invoiceItemType :: InvoiceItemType
79 , invoiceItemPeriod :: Period
80 , invoiceItemRate :: Amount 100 rate
81 , invoiceItemQuantity :: Amount 100 qty
84 type Euro = Amount 100 (UnitName "€")
86 invoiceItemTotal :: InvoiceItem rate qty -> Euro
87 invoiceItemTotal InvoiceItem{..} =
88 let (res, _actualFrac) =
91 & fraction (invoiceItemQuantity & amountQuantity & quantityToRatio)
95 { invoiceItemScope = []
96 , invoiceItemAction = []
97 , invoiceItemType = InvoiceItemTypeItem
98 , invoiceItemPeriod = Period{periodBeginning = "2000-01-01", periodEnd = "2000-01-01"}
100 , invoiceItemQuantity = 0
104 = InvoiceItemTypeItem
105 | InvoiceItemTypeService
106 deriving (Eq, Ord, Show)
109 { periodBeginning :: LocalTime
110 , periodEnd :: LocalTime
112 deriving (Eq, Ord, Show, Generic, NFData)