module Literate.Invoice.Invoice where import Literate.Accounting.Math import Literate.Prelude import Literate.Time import Data.Text qualified as Text import Literate.Document.HTML qualified as HTML data Id = Id {unId :: Natural} deriving (Eq, Ord, Show) instance HTML.ToMarkup Id where toMarkup (Id idt) = idt & HTML.toHtml data InvoiceId = InvoiceId { invoiceIdBuyer :: Entity , invoiceIdCount :: Natural } deriving (Eq, Ord, Show) instance HTML.ToMarkup InvoiceId where toMarkup InvoiceId{..} = "ent" <> (invoiceIdBuyer & entityId & HTML.toMarkup) <> "inv" <> (invoiceIdCount & HTML.toMarkup) type Invoices = Map InvoiceId Invoice type EntityId = Id type Email = Text data Entity = Entity { entityId :: EntityId , entityName :: Text , entityEmail :: Maybe Email , entityAddress :: Address , entitySIREN :: Maybe Text } deriving (Eq, Ord, Show) data Address = Address { addressText :: [Text] , addressZipCode :: ZipCode , addressCity :: City , addressCountry :: Country } deriving (Eq, Ord, Show) type ZipCode = Text type City = Text type Country = Text data Invoice = Invoice { invoiceCreation :: LocalTime , invoiceIssuer :: Entity , invoiceRecipient :: Entity , invoiceCustomer :: Entity , invoiceObjet :: Text , invoiceDetails :: Text , invoiceItems :: [InvoiceItem (UnitName "€" :/: UnitName "h") (UnitName "h")] , invoiceRate :: Double } data InvoiceItem rate qty = InvoiceItem { invoiceItemDescription :: Text , invoiceItemRate :: Amount 100 rate , invoiceItemQuantity :: Amount 100 qty } invoiceItemTotal :: InvoiceItem rate qty -> Amount 100 (UnitName "€") invoiceItemTotal InvoiceItem{..} = let (res, _actualFrac) = invoiceItemRate & amountQuantity & fraction (invoiceItemQuantity & amountQuantity & quantityToRatio) in Amount res