From c5d3019e3f34f7c81e3cb8287d6c2b57fc113e4c Mon Sep 17 00:00:00 2001 From: kbenestad Date: Tue, 19 May 2026 00:54:22 +0700 Subject: [PATCH] Add project specification for kbenestad/invoice Added detailed specification for the kbenestad/invoice project, including goals, planned structure, features, and configuration file details. --- docs/devdocs/Specs.md | 167 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 docs/devdocs/Specs.md diff --git a/docs/devdocs/Specs.md b/docs/devdocs/Specs.md new file mode 100644 index 0000000..ea43a85 --- /dev/null +++ b/docs/devdocs/Specs.md @@ -0,0 +1,167 @@ +# 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 fields**`Line 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.