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 data InvoiceId entId = InvoiceId
19 { invoiceIdRecipient :: entId
20 , invoiceIdType :: InvoiceType
21 , invoiceIdCount :: Natural
23 deriving (Eq, Ord, Show, Generic, NFData)
25 ( GetOrganization entId
29 Doc.ToInline (InvoiceId entId)
40 , case i & invoiceIdType of
41 InvoiceTypeProForma -> "pro-forma"
42 InvoiceTypeSale -> "sale"
43 InvoiceTypeVoucher -> "voucher"
44 , i & invoiceIdCount & show & Doc.toInline
48 type Invoices entId = Map (InvoiceId entId) (Invoice entId)
49 type InvoiceAction = [Text]
50 type InvoiceScope = [Text]
52 data Invoice entId = Invoice
53 { invoiceEmittedOn :: LocalTime
54 , invoiceOrders :: [Doc.Inline]
55 , invoicePaymentDueBefore :: LocalTime
56 , invoiceIssuer :: entId
57 , invoiceRecipient :: entId
58 , -- , invoiceItems :: [InvoiceItem (UnitName "€" :/: UnitName "h") (UnitName "h")]
59 invoiceRates :: Map InvoiceAction (Amount 100 (UnitName "€" :/: UnitName "h"))
60 , invoiceMentions :: [InvoiceMention]
61 , invoiceWorks :: [Work]
65 invoice :: Enum entId => Invoice entId
68 { invoiceEmittedOn = "2000-01-01"
70 , invoicePaymentDueBefore = "2000-01-31"
71 , invoiceIssuer = toEnum 0
72 , invoiceRecipient = toEnum 0
74 , invoiceMentions = []
78 { workDescription :: Doc.Inline
79 , workDate :: LocalTime
80 , workDuration :: Amount 100 (UnitName "h")
81 , workAction :: [Text]
83 , workReferences :: [URL]
90 deriving (Eq, Ord, Show, Generic, NFData)
92 = InvoiceMentionTVANonApplicable
93 | InvoiceMentionIndemnitéForfaitaire
94 | InvoiceMentionIndemnitéTaux (Amount 100 (UnitName "%"))
95 deriving (Eq, Ord, Show, Generic, NFData)
97 data InvoiceItem rate qty = InvoiceItem
98 { invoiceItemScope :: [Text]
99 , invoiceItemAction :: [Text]
100 , invoiceItemType :: InvoiceItemType
101 , invoiceItemPeriod :: Period
102 , invoiceItemRate :: Amount 100 rate
103 , invoiceItemQuantity :: Amount 100 qty
106 type Euro = Amount 100 (UnitName "€")
108 invoiceItemTotal :: InvoiceItem rate qty -> Euro
109 invoiceItemTotal InvoiceItem{..} =
110 let (res, _actualFrac) =
113 & fraction (invoiceItemQuantity & amountQuantity & quantityToRatio)
117 { invoiceItemScope = []
118 , invoiceItemAction = []
119 , invoiceItemType = InvoiceItemTypeItem
120 , invoiceItemPeriod = Period{periodBeginning = "2000-01-01", periodEnd = "2000-01-01"}
121 , invoiceItemRate = 0
122 , invoiceItemQuantity = 0
126 = InvoiceItemTypeItem
127 | InvoiceItemTypeService
128 deriving (Eq, Ord, Show)
131 { periodBeginning :: LocalTime
132 , periodEnd :: LocalTime
134 deriving (Eq, Ord, Show, Generic, NFData)