Skip to content

Instantly share code, notes, and snippets.

@smurphy8
Last active August 29, 2015 14:22
Show Gist options
  • Select an option

  • Save smurphy8/f373cfff4849f0507fc7 to your computer and use it in GitHub Desktop.

Select an option

Save smurphy8/f373cfff4849f0507fc7 to your computer and use it in GitHub Desktop.
Invoice Template For QuickBooks
{--|
# Invoice and Spreadsheet template system for Kiosk
# The system should:
##* Allow a template to be specified that has holes which can be filled
in from a [TemplateTableStore + DataTemplateEntry]
## Primary goals
* Be translated into a quickbooks invoice
* Contain everything needed to marshall the data
* Be abstracted to the point that no specific quick books references
are contained in the template (transforms should add them in)
## Secondary goals
* Be translated into an excel spreadsheet
* Capability to add transforms on invidual incoming records
|--}
-- | An Example Template
zero07QuickbooksTemplate = InvoiceTemplate invoiceHeaders items
where
invoiceHeaders = InvoiceHeaderTemplate headerLabels headerLabelMap
headerLabels = ["Billing Address", "DueDate", "InvoiceDate","PO Number","Sales Rep"]
headerLabelMap = fromList [ ("Billing Address" , \_ formTemplate -> getAddressFromFormTemplate formTemplate )
, ("Due Date" , \time _ -> formatInvoiceTime time )
, ("Invoice Date" , \time _ -> formatInvoiceTime . addFiveDays $ time)
, ("PO Number", const EmptyInvoiceField )
, ("Sales Rep", const EmptyInvoiceField )]
items = InvoiceItemTemplate itemLabels itemLabelMap
itemLabels = ["Product/Service","Description","Qty","Rate","Amount"]
itemLabelMap = [("Product/Service", \_ dataTemplate -> getAndFormatCompanyName dataTemplate)
,("Description",\_ dataTemplate -> getMultipleFieldsAndPutThemTogetherInADescription dataTemplate)
,("Qty", \_ dataTemplate -> getQty dataTemplate)
,("Rate", \_ dataTemplate -> getRateAndConvertToAnInt 0.0 dataTemplate)
,("Amount", \_ dataTemplate -> getAmountFromTemplate dataTemplate)]
-- | Possible DataTypes
-- Invoices also contain numbers which should
-- auto-populate
-- | The top level 'InvoiceTemplate' should represent a
-- complete description of the invoice
data InvoiceTemplate = InvoiceTemplate {
invoiceHeaders :: [InvoiceHeaderTemplate]
, invoiceItems :: [InvoiceItemTemplate]
}
-- | Here is a description of the 'InvoiceHeaderTemplate'
data InvoiceHeaderTemplate = InvoiceHeaderTemplate {
invoiceHeaderLabel :: [InvoiceHeaderLabel]
, valueRetrievalFunction :: InvoiceHeaderRetrievalMap
}
type ItemRetrievalMap = Map InvoiceHeaderLabel (CurrentTime -> FormTemplate -> InvoiceItemHeader)
-- | InvoiceItemTemplate renders to a list of DataTemplate
-- Constrained to a subset of DataTemplate fields
{--| It would be very nice if the Length of the invoice item list
and the size of the invoice item map were forced constrained
also if the map entries had to match the invoice item labels
so that an invoice item like:
>>> InvoiceItemTemplate ["One label"] (fromList [("wrong label",foo)])
could be excluded by smart constructors (or something fancier)
|--}
------------
data InvoiceItemTemplate = InvoiceItemTemplate {
invoiceItemLabels :: [InvoiceItemLabel]
, invoiceItemLabelRetrievalFunctions :: ItemRetrievalMap
}
type ItemRetrievalMap = Map InvoiceItemLabel (CurrentTime -> DataTemplate -> InvoiceItemValue)
-- Utility Functions would then render
renderQuickBooksInvoice :: InvoiceItemTemplate -> TemplateTable -> WhateverTheQuickbooksRetrievalTypeIs
-- Then later
renderExcelInvoice :: InvoiceItemTemplate -> TemplateTable -> AnExcelFile
---------------------------------------------------------
-- Maybe someday even more generic for all the situations where we have a table with headers
data ReportTemplate header rowtype = ReportTemplate {
reportHeader :: [ReportHeaderTemplate header]
, reportRows :: [ReportRowTemplate rowtype]}
data ReportHeaderTemplate header = ReportHeaderTemplate {
reportHeaderLabel :: [ReportHeaderLabel]
, valueRetrievalFunctions :: [ReportHeaderRetrievalMap header]
}
type ReportHeaderRetrievalMap header = Map ReportHeaderLabel (CurrentTime -> header -> ReportHeaderValueTypes)
data ReportRowTemplate rowtype = ReportRowTemplate {
reportRowLabels :: [ReportRowLabel]
, reportRowRetrievalFunctions :: ReportRowRetrievalMap rowtype
}
type ReportRowRetrievalMap rowtype = Map ReportRowLabel (CurrentTime -> rowtype -> ReportRowValueTypes)
-- Then you can write
type InvoiceTemplate = ReportTemlate Form DataTemplate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment