invoice/docs/devdocs/Specs.md
kbenestad c5d3019e3f
Add project specification for kbenestad/invoice
Added detailed specification for the kbenestad/invoice project, including goals, planned structure, features, and configuration file details.
2026-05-19 00:54:22 +07:00

7.1 KiB

kbenestad/invoice - specification

(C) 2026 Kristian Benestad. Licensed under the Apache 2 license.

Goal

kbenestad/invoice solves an important financial question for many small entities relying on freelancers and others who are not used to charging for their services by providing a static web app that produces ready-to-submit PDF invoices with prepared lines and rates if so defined in the configuration file.

This app works well together with kbenestad/reimburse, a static web app that provides structured reimbursement requests with built-in currency conversion and receipt references.

Planned structure for development

  • app/index.html -- app file that consists of a form capturing user data which generates a PDF invoice.
  • app/config.yml -- configuration file
  • docs/ -- documentation for project
    • docs/devdocs/ -- development documentation
      • docs/devdocs/spec.md -- this document
      • docs/devdocs/sampletheme.yml -- sample theme from MD-CMS
      • docs/devdocs/reference-theme.md -- MD-CMS documentation for theme files

Invoice features

The invoice form -- both input and output -- is a standard classic invoice. The form is multilingual, and if more than one language is defined, the user selects language at the top of the form. The form always prints in the default language.


Suggested layout for input form - output derives from this:

                                                       [ICON] Language: [SELECT]
--------------------------------------------------------------------------------

                                                       INVOICE
                                                       
--------------------------------------------------------------------------------
[SENDER NAME - TEXT                    ]    Phone: [SENDER PHONE - TEXT        ]
[SENDER ADDRESS1 - TEXT                ]    Email: [SENDER EMAIL - TEXT        ]
[SENDER ADDRESS2 - TEXT                ]
[SENDER ADDRESS3 - TEXT                ]             
[SENDER ADDRESS4 - TEXT                ]           
[SENDER COUNTRY - SELECT               ]             

Charge to: [SELECT OR OTHER            ]
----------------------------------------
[CHARGE TO NAME - TEXT                 ]    Phone: [CHARGE TO PHONE - TEXT     ]
[CHARGE TO ADDRESS1 - TEXT             ]    Email: [CHARGE TO EMAIL - TEXT     ]
[CHARGE TO ADDRESS2 - TEXT             ]               VAT/Tax ID: [TEXT       ]
[CHARGE TO ADDRESS3 - TEXT             ]             Invoice date: [MONTHPICKER]
[CHARGE TO ADDRESS4 - TEXT             ]             Project code: [SELECT     ]
[CHARGE TO COUNTRY - SELECT            ]              Invoice no.: [ALFANUMERIC]

      [CHARGE TO EMAIL ADDRESS - TEXT ] • [CHARGE TO TELEPHONE NUMBER - TEXT]

  QTY  |  UOM  | DESCRIPTION                           |      PRICE | LINE TOTAL
-------|-------|---------------------------------------|------------|-----------
[NUM. ]|[SLCT ]|[SELECT OR TEXT                       ]| 999,999.00 | 999,999.00
       |       | Foreign currency: [NO]                |            |
-------|-------|---------------------------------------|------------|-----------
       |       | [+] Add new line                      |            | 

** If Foreign currency = Yes, input: **       
-------|-------|---------------------------------------|------------|-----------
[NUM. ]|[SLCT ]|[SELECT OR TEXT                       ]| 999,999.00 | 999,999.00
       |       |   Foreign currency:     [YES       ]  |            |
       |       |   Currency code:        [SELECT    ]  |            |
       |       |   Exchange rate:        [NUMBER    ]  |            | 
       |       |   Per item:             [999,999.00]  |            |
       |       |   Total local currency: [999,999.00]  |            |
-------|-------|---------------------------------------|------------|-----------
       |       | [+] Add new line                      |            | 
       
 ** End of form **
 
--------------------------------------------------------------------|-----------
                                                          Subtotal: |[CALCULATE]
                                                 [SELECT] Tax X.X%: |[CALCULATE]
                                                              Paid: |[NUMBER   ]
--------------------------------------------------------------------|-----------
                                                            To pay: |[CALCULATE] 
--------------------------------------------------------------------|-----------

[ GENERATE INVOICE ]

Features

  • [ICON] Language: [SELECT]: Languages and icons are defined in config.yml. This affects only the layout of the input form.
  • Sender name: Text input fields. Saved in local storage and retrieved next time.
  • Charge to: Select a predefined recipient, or select Other and fill in all fields manually. Empty fields are not shown on invoice.
  • Invoice date: Date picker. Default to today.
  • Project code: List of predefined project codes. If Other field becomes a text field.
  • Invoice number: User sets an alfanumeric value. It is stored in local storage and retreived and bumped with 1 next time the user visits after having clicked Generate invoice. Invoice lines: After the user clicks [+] Add new line, a new line appears.
    • Description: The user selects either a predefined product already; Description and UoM are then prefilled.
    • Qty: Numeric field. Multiply with Price to get Line total.
    • UoM: Prefilled if selected an existing product, if Other
    • Price: If selecting an exsisting product, Price is prefilled but can be altered.
    • Calculated fieldsLine total, Subtotal, and To pay are calculated bassed on the values provide.
    • Tax/VAT is set in the config.yml.
  • Foreign currency: Yes/no. Yes opens further options that must be defined. The form calculates the total price based ion the line items.

Configuration file

ICON is an SVG icon - either a name for a Material Icon hosted by Google, or the filename of an icon hosted in assets/icons.

Language is defined in config.yml:

default-code: en
default-name: English
default-direction: ltr

Languages are defined with lang-code, lang-name, and lang-direction.

Each piece of information is defined in config.yml, e.g.,:

language
  default-lang: Language
  de: Sprache

invoice
  default-lang: Invoice
  de: Faktura

sender-name
  default-lang: Sender name
  de: Aussteller

charge-to allows the app owner to predefine recipients:

charge-to: Organisation Name
  charge-to-name: Legal Organisation Name
  charge-to-address1: Address Line 1
  charge-to-address2: Address Line 2
  charge-to-address3: Address Line 3
  charge-to-address4: Address Line 4
  charge-to-phone: +66-(0)94 251 7500
  charge-to-email: email@example.org
  charge-to-vat-id: Text field

Project code is a list of available project codes.

project-codes:
  Project 100
  Project 110
  Project 230

Units of measures are defined by config.yml:

uom
  Each: EA
  Hour: HR
  Day: DY

Agent instructions

Build app/index.html and config.yml.

Use a neutral, authoritative colour scheme.