Last active
August 29, 2015 14:22
-
-
Save smurphy8/f373cfff4849f0507fc7 to your computer and use it in GitHub Desktop.
Invoice Template For QuickBooks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {--| | |
| # 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