]> Git — Sourcephile - tmp/julm/literate-invoice.git/blob - tests/Tests/Invoice.hs
user/completeness(Invoice): display Seller and Buyer as Organization not Entity
[tmp/julm/literate-invoice.git] / tests / Tests / Invoice.hs
1 {-# LANGUAGE DeriveAnyClass #-}
2 {-# LANGUAGE OverloadedLists #-}
3 {-# LANGUAGE OverloadedStrings #-}
4
5 module Tests.Invoice where
6
7 import Data.List qualified as List
8 import Data.Text.Lazy qualified as Text.Lazy
9 import Data.Time.Clock qualified as Time
10 import Data.Time.LocalTime qualified as Time
11 import Test.Syd (Spec, describe, goldenByteStringBuilderFile, it)
12 import Tests.Utils.Tests (goldenPath)
13 import Text.Blaze.Renderer.Text qualified as Blaze.Text
14 import Text.Blaze.Renderer.Utf8 qualified as Blaze
15 import Prelude ((*))
16
17 import Literate.Accounting (Amount, Unit (UnitName))
18 import Literate.Database
19 import Literate.Document.HTML qualified as HTML
20 import Literate.Invoice
21 import Literate.Invoice.HTML (invoiceIdInline)
22 import Literate.Invoice.HTML qualified as HTML
23 import Literate.Prelude
24
25 import Tests.Organization
26 import Tests.Work
27
28 spec :: HasCallStack => Spec
29 spec =
30 describe "Invoice" do
31 forM_ invoices \invId -> do
32 let
33 inv = invId & get @(Invoice ScopeId ActionId EntityId InvoiceId)
34 idS =
35 inv
36 & invoiceIdInline
37 & HTML.toHtml
38 & Blaze.Text.renderMarkup
39 & Text.Lazy.unpack
40 outPath <- goldenPath idS "html"
41 it idS do
42 goldenByteStringBuilderFile outPath do
43 inv & HTML.htmlIO <&> Blaze.renderMarkupBuilder
44
45 data InvoiceId
46 = Invoice_0
47 | Invoice_org3sale1
48 | Invoice_org3sale2
49 | Invoice_org3sale3
50 | Invoice_org3sale4
51 deriving (Eq, Ord, Show, Generic, Enum, NFData)
52
53 instance Get (Invoice ScopeId ActionId EntityId InvoiceId) InvoiceId where
54 get invoiceId = case invoiceId of
55 Invoice_0 ->
56 Invoice
57 { invoiceId
58 , invoiceType = InvoiceTypeSale
59 , invoiceOrders = []
60 , invoiceEmittedOn
61 , invoicePaymentDueBefore = invoiceEmittedOn & Time.addLocalTime (31 * Time.nominalDay)
62 , invoiceIssuer = EntityJulmInfo
63 , invoiceRecipient = EntityJulmInfo
64 , invoiceRates = [Action_Develop := 0]
65 , invoiceMentions =
66 [ InvoiceMentionTVANonApplicable
67 , InvoiceMentionIndemnitéForfaitaire
68 , InvoiceMentionIndemnitéTaux (12.15 :: Amount 100 (UnitName "%"))
69 ]
70 , invoiceWorks =
71 [ Work
72 { workDate = "2000-01-01"
73 , workDuration = 1
74 , workAction = Action_Develop
75 , workScope = []
76 , workReferences = []
77 , workDescription = ""
78 }
79 ]
80 }
81 where
82 invoiceEmittedOn = "2026-01-22"
83 Invoice_org3sale1 ->
84 Invoice
85 { invoiceId
86 , invoiceType = InvoiceTypeSale
87 , invoiceOrders = ["Contract n°2025-24"]
88 , invoiceEmittedOn
89 , invoicePaymentDueBefore = invoiceEmittedOn & Time.addLocalTime (31 * Time.nominalDay)
90 , invoiceIssuer = EntityJulmInfo
91 , invoiceRecipient = EntityNixOSFoundationNGITeam
92 , invoiceRates =
93 [ Action_Debug := 31.25
94 , Action_Organize := 31.25
95 , Action_Develop := 31.25
96 , Action_Document := 31.25
97 , Action_Review := 31.25
98 ]
99 , invoiceMentions =
100 [ InvoiceMentionTVANonApplicable
101 , InvoiceMentionIndemnitéForfaitaire
102 , InvoiceMentionIndemnitéTaux (12.15 :: Amount 100 (UnitName "%"))
103 ]
104 , invoiceWorks =
105 works
106 & List.filter \work ->
107 and $
108 list
109 [ work & workDate & (>= "2025-11-06")
110 , work & workDate & (<= "2025-12-22")
111 , work & workScope & (/= [Scope_NGIpkgs_Manuals])
112 ]
113 }
114 where
115 invoiceEmittedOn = "2026-01-22"
116 Invoice_org3sale2 ->
117 Invoice
118 { invoiceId
119 , invoiceType = InvoiceTypeSale
120 , invoiceOrders = ["contract n°2026-03"]
121 , invoiceEmittedOn
122 , invoicePaymentDueBefore = invoiceEmittedOn & Time.addLocalTime (31 * Time.nominalDay)
123 , invoiceIssuer = EntityJulmInfo
124 , invoiceRecipient = EntityNixOSFoundationNGITeam
125 , invoiceRates =
126 [ Action_Debug := 31.25
127 , Action_Organize := 31.25
128 , Action_Develop := 31.25
129 , Action_Document := 31.25
130 , Action_Review := 31.25
131 ]
132 , invoiceMentions =
133 [ InvoiceMentionTVANonApplicable
134 , InvoiceMentionIndemnitéForfaitaire
135 , InvoiceMentionIndemnitéTaux (12.15 :: Amount 100 (UnitName "%"))
136 ]
137 , invoiceWorks =
138 works
139 & List.filter \work ->
140 and $
141 [ work & workDate & (>= "2025-12-23")
142 , work & workDate & (<= "2026-12-31")
143 , work & workScope & (/= [Scope_NGIpkgs_Manuals])
144 , work & workScope & (/= [Scope_NGIpkgs, Scope_Funkwhale])
145 , not $
146 and $
147 [ work & workDate & (>= "2026-01-09")
148 , work & workDate & (<= "2026-01-28")
149 , work & workAction & (== Action_Organize)
150 , work & workScope & (== [Scope_NGIpkgs])
151 ]
152 & list
153 ]
154 & list
155 }
156 where
157 invoiceEmittedOn = "2026-01-27"
158 Invoice_org3sale3 ->
159 Invoice
160 { invoiceId
161 , invoiceType = InvoiceTypeSale
162 , invoiceOrders = ["contract n°2026-07, February 2026"]
163 , invoiceEmittedOn
164 , invoicePaymentDueBefore = invoiceEmittedOn & Time.addLocalTime (31 * Time.nominalDay)
165 , invoiceIssuer = EntityJulmInfo
166 , invoiceRecipient = EntityNixOSFoundationNGITeam
167 , invoiceRates =
168 [ Action_Debug := 31.25
169 , Action_Develop := 31.25
170 , Action_Document := 31.25
171 , Action_Organize := 31.25
172 , Action_Review := 31.25
173 ]
174 , invoiceMentions =
175 [ InvoiceMentionTVANonApplicable
176 , InvoiceMentionIndemnitéForfaitaire
177 , InvoiceMentionIndemnitéTaux (12.15 :: Amount 100 (UnitName "%"))
178 ]
179 , invoiceWorks =
180 works
181 & List.filter \work ->
182 or $
183 [ and $
184 [ work & workDate & (> "2026-01-28")
185 , work & workDate & (< "2026-03-01")
186 ]
187 & list
188 ]
189 & list
190 }
191 where
192 invoiceEmittedOn = "2026-03-31"
193 Invoice_org3sale4 ->
194 Invoice
195 { invoiceId
196 , invoiceType = InvoiceTypeSale
197 , invoiceOrders = ["contract n°2026-07, Mars 2026"]
198 , invoiceEmittedOn
199 , invoicePaymentDueBefore = invoiceEmittedOn & Time.addLocalTime (31 * Time.nominalDay)
200 , invoiceIssuer = EntityJulmInfo
201 , invoiceRecipient = EntityNixOSFoundationNGITeam
202 , invoiceRates =
203 [ Action_Debug := 31.25
204 , Action_Develop := 31.25
205 , Action_Document := 31.25
206 , Action_Organize := 31.25
207 , Action_Review := 31.25
208 ]
209 , invoiceMentions =
210 [ InvoiceMentionTVANonApplicable
211 , InvoiceMentionIndemnitéForfaitaire
212 , InvoiceMentionIndemnitéTaux (12.15 :: Amount 100 (UnitName "%"))
213 ]
214 , invoiceWorks =
215 works
216 & List.filter \work ->
217 or $
218 [ and $
219 [ work & workDate & (>= "2026-03-01")
220 , work & workDate & (<= "2026-04-01")
221 ]
222 & list
223 ]
224 & list
225 }
226 where
227 invoiceEmittedOn = "2026-03-31"
228
229 invoices :: [InvoiceId]
230 invoices = enumAll