{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE OverloadedLists #-} {-# LANGUAGE OverloadedStrings #-} module Tests.Invoice where import Data.List qualified as List import Data.Text.Lazy qualified as Text.Lazy import Data.Time.Clock qualified as Time import Data.Time.LocalTime qualified as Time import Test.Syd (Spec, describe, goldenByteStringBuilderFile, it) import Tests.Utils.Tests (goldenPath) import Text.Blaze.Renderer.Text qualified as Blaze.Text import Text.Blaze.Renderer.Utf8 qualified as Blaze import Prelude ((*)) import Literate.Accounting (Amount, Unit (UnitName)) import Literate.Database import Literate.Document.HTML qualified as HTML import Literate.Invoice import Literate.Invoice.HTML (invoiceIdInline) import Literate.Invoice.HTML qualified as HTML import Literate.Prelude import Tests.Organization import Tests.Work spec :: HasCallStack => Spec spec = describe "Invoice" do forM_ invoices \invId -> do let inv = invId & get @(Invoice ScopeId ActionId EntityId InvoiceId) idS = inv & invoiceIdInline & HTML.toHtml & Blaze.Text.renderMarkup & Text.Lazy.unpack outPath <- goldenPath idS "html" it idS do goldenByteStringBuilderFile outPath do inv & HTML.htmlIO <&> Blaze.renderMarkupBuilder data InvoiceId = Invoice_0 | Invoice_org3sale1 | Invoice_org3sale2 | Invoice_org3sale3 deriving (Eq, Ord, Show, Generic, Enum, NFData) instance Get (Invoice ScopeId ActionId EntityId InvoiceId) InvoiceId where get invoiceId = case invoiceId of Invoice_0 -> Invoice { invoiceId , invoiceType = InvoiceTypeSale , invoiceOrders = [] , invoiceEmittedOn , invoicePaymentDueBefore = invoiceEmittedOn & Time.addLocalTime (31 * Time.nominalDay) , invoiceIssuer = EntityJulmInfo , invoiceRecipient = EntityJulmInfo , invoiceRates = [Action_Development := 0] , invoiceMentions = [ InvoiceMentionTVANonApplicable , InvoiceMentionIndemnitéForfaitaire , InvoiceMentionIndemnitéTaux (12.15 :: Amount 100 (UnitName "%")) ] , invoiceWorks = [ Work { workDate = "2000-01-01" , workDuration = 1 , workAction = Action_Development , workScope = [] , workReferences = [] , workDescription = "" } ] } where invoiceEmittedOn = "2026-01-22" Invoice_org3sale1 -> Invoice { invoiceId , invoiceType = InvoiceTypeSale , invoiceOrders = ["Contract n°2025-24"] , invoiceEmittedOn , invoicePaymentDueBefore = invoiceEmittedOn & Time.addLocalTime (31 * Time.nominalDay) , invoiceIssuer = EntityJulmInfo , invoiceRecipient = EntityNixOSFoundationNGITeam , invoiceRates = [ Action_Organization := 31.25 , Action_Development := 31.25 , Action_Documentation := 31.25 , Action_Review := 31.25 ] , invoiceMentions = [ InvoiceMentionTVANonApplicable , InvoiceMentionIndemnitéForfaitaire , InvoiceMentionIndemnitéTaux (12.15 :: Amount 100 (UnitName "%")) ] , invoiceWorks = works & List.filter \work -> and $ list [ work & workDate & (>= "2025-11-06") , work & workDate & (<= "2025-12-22") , work & workScope & (/= [Scope_NGIpkgs_Manuals]) ] } where invoiceEmittedOn = "2026-01-22" Invoice_org3sale2 -> Invoice { invoiceId , invoiceType = InvoiceTypeSale , invoiceOrders = ["contract n°2026-03"] , invoiceEmittedOn , invoicePaymentDueBefore = invoiceEmittedOn & Time.addLocalTime (31 * Time.nominalDay) , invoiceIssuer = EntityJulmInfo , invoiceRecipient = EntityNixOSFoundationNGITeam , invoiceRates = [ Action_Organization := 31.25 , Action_Development := 31.25 , Action_Documentation := 31.25 , Action_Review := 31.25 ] , invoiceMentions = [ InvoiceMentionTVANonApplicable , InvoiceMentionIndemnitéForfaitaire , InvoiceMentionIndemnitéTaux (12.15 :: Amount 100 (UnitName "%")) ] , invoiceWorks = works & List.filter \work -> and $ [ work & workDate & (>= "2025-12-23") , work & workDate & (<= "2026-12-31") , work & workScope & (/= [Scope_NGIpkgs_Manuals]) , work & workScope & (/= [Scope_NGIpkgs, Scope_Funkwhale]) , not $ and $ [ work & workDate & (>= "2026-01-09") , work & workDate & (<= "2026-01-28") , work & workAction & (== Action_Organization) , work & workScope & (== [Scope_NGIpkgs]) ] & list ] & list } where invoiceEmittedOn = "2026-01-27" Invoice_org3sale3 -> Invoice { invoiceId , invoiceType = InvoiceTypeSale , invoiceOrders = ["contract n°2026-FixMe"] , invoiceEmittedOn , invoicePaymentDueBefore = invoiceEmittedOn & Time.addLocalTime (31 * Time.nominalDay) , invoiceIssuer = EntityJulmInfo , invoiceRecipient = EntityNixOSFoundationNGITeam , invoiceRates = [ Action_Organization := 31.25 , Action_Development := 31.25 , Action_Documentation := 31.25 , Action_Review := 31.25 ] , invoiceMentions = [ InvoiceMentionTVANonApplicable , InvoiceMentionIndemnitéForfaitaire , InvoiceMentionIndemnitéTaux (12.15 :: Amount 100 (UnitName "%")) ] , invoiceWorks = works & List.filter \work -> or $ [ and $ [ work & workDate & (>= "2026-01-21") , work & workDate & (<= "2026-12-31") , work & workScope & (== [Scope_NGIpkgs_Manuals]) ] & list , and $ [ work & workDate & (>= "2025-12-29") , work & workDate & (<= "2026-12-31") , work & workScope & (== [Scope_NGIpkgs, Scope_Funkwhale]) ] & list , and $ [ work & workDate & (>= "2026-01-09") , work & workDate & (<= "2026-01-28") , work & workAction & (== Action_Organization) , work & workScope & (== [Scope_NGIpkgs]) ] & list ] & list } where invoiceEmittedOn = "2026-01-28" invoices :: [InvoiceId] invoices = enumAll