--- /dev/null
+#!/bin/sh
+# Copyright (c) 2023 Jakub Czajka <jakub@ekhem.eu.org>
+# License: GPL-3.0 or later.
+
+. /etc/environment
+
+request_body=$(echo "${REQUEST_BODY}" | /usr/bin/python3 -c "\
+import sys;
+from urllib.parse import unquote_plus;
+print(unquote_plus(sys.stdin.read()));")
+
+get_query_param() {
+ echo "${request_body}" | sed "s/^.*${1}=// ; s/\&.*$//"
+}
+
+query_db() {
+ /usr/bin/psql --user=payments_tracker --dbname="${PAYMENTS_DB}" \
+ --tuples-only --no-align --command="${1}"
+}
+
+insert_into() {
+ query_db "\
+ WITH new_id AS (
+ INSERT INTO ${1} (name)
+ VALUES ('${2}')
+ ON CONFLICT DO NOTHING
+ RETURNING id
+ )
+ SELECT *
+ FROM new_id
+ UNION
+ SELECT id
+ FROM ${1}
+ WHERE name='${2}'"
+}
+
+shop=$(get_query_param "shop")
+shop_id=$(insert_into "shops" "${shop}")
+
+product=$(get_query_param "product")
+product_id=$(insert_into "products" "${product}")
+
+purchase_date=$(get_query_param "date")
+
+price=$(get_query_param "price")
+
+currency=$(get_query_param "currency")
+currency_id=$(insert_into "currencies" "${currency}")
+
+unit=$(get_query_param "unit")
+unit_id=$(insert_into "units" "${unit}")
+
+payment_method=$(get_query_param "payment_method")
+payment_method_id=$(insert_into "payment_methods" "${payment_method}")
+
+if [ "$(get_query_param "discount")" = "on" ]
+then
+ discount="TRUE"
+else
+ discount="FALSE"
+fi
+
+purchase_id=$(query_db "\
+WITH new_purchase_id AS (
+ INSERT INTO purchases (
+ shop_id,
+ product_id,
+ payment_method_id,
+ date,
+ price,
+ currency_id,
+ unit_id,
+ discount
+ )
+ VALUES (
+ ${shop_id},
+ ${product_id},
+ ${payment_method_id},
+ '${purchase_date}',
+ ${price},
+ ${currency_id},
+ ${unit_id},
+ ${discount}
+ )
+ RETURNING id
+)
+SELECT *
+FROM new_purchase_id;")
+
+PAGE="
+<!DOCTYPE html>
+<html>
+<meta name='viewport' content='width=device-width'>
+<head>
+ <title>Purchase</title>
+ <style>
+ body {
+ white-space: pre-wrap;
+ font-size: 1.2em;
+ }
+ </style>
+</head>
+<body>
+Recorded new purchase (id=${purchase_id}) of ${product} \
+(id=${product_id}) on ${purchase_date} in ${shop} (id=${shop_id}). Payed \
+${price} ${currency} (id=${currency_id}) for ${unit} (id=${unit_id}) with \
+${payment_method} (id=${payment_method_id}) (discount=${discount}).
+</body>
+</html>"
+
+echo "HTTP/1.1 200 OK"
+echo "Content-Type: text/html"
+echo "${PAGE}" | sed 's/^[ \t]*//g'
--- /dev/null
+#!/bin/sh
+# Copyright (c) 2023 Jakub Czajka <jakub@ekhem.eu.org>
+# License: GPL-3.0 or later.
+
+. /etc/environment
+
+query_db() {
+ /usr/bin/psql --user=payments_tracker --dbname="${PAYMENTS_DB}" \
+ --tuples-only --no-align --command="${1}"
+}
+
+as_options() {
+ xargs --replace={} echo "<option value='{}'>{}</option>"
+}
+
+PAGE="
+<!DOCTYPE html>
+<html>
+<meta name='viewport' content='width=device-width'>
+<head>
+ <title>Payments</title>
+ <style>
+ body {
+ background-color: #7fa99b;
+ }
+ form {
+ width: min(400px, 100%);
+ }
+ fieldset {
+ background-color: #f1d18a;
+ display: flex;
+ flex-direction: column;
+ row-gap: 5px;
+ }
+ label {
+ column-gap: 5px;
+ display: flex;
+ }
+ input[type=date] {
+ width: 100%;
+ }
+ </style>
+</head>
+<body>
+ <form method='post' action='/payment'>
+ <fieldset>
+ <legend>Payment</legend>
+
+ <input list='shops' id='shop' name='shop' placeholder='Shop' required />
+ <datalist id='shops'>
+ $(query_db "SELECT name FROM shops" | as_options)
+ </datalist>
+
+ <input list='products' id='product' name='product' placeholder='Product'
+ required />
+ <datalist id='products'>
+ $(query_db "SELECT name FROM products" | as_options)
+ </datalist>
+
+ <label>
+ 📅<input type='date' id='date' name='date' required />
+ </label>
+
+ <input type='number' id='price' name='price' min='0.00' step='0.01'
+ placeholder='0.00' required />
+
+ <input list='currencies' id='currency' name='currency'
+ placeholder='Currency' required />
+ <datalist id='currency'>
+ $(query_db "SELECT name FROM currencies" | as_options)
+ </datalist>
+
+ <input list='units' id='unit' name='unit' placeholder='Unit' required />
+ <datalist id='units'>
+ $(query_db "SELECT name FROM units" | as_options)
+ </datalist>
+
+ <input list='payment_methods' id='payment_method' name='payment_method'
+ placeholder='Payment method' />
+ <datalist id='payment_methods'>
+ $(query_db "SELECT name FROM payment_methods" | as_options)
+ </datalist>
+
+ <label for='discount'>
+ <input id='discount' name='discount' type='checkbox' />Discount?
+ </label>
+
+ <button type='submit'>Record</>
+ </fieldset>
+ </form>
+</body>
+</html>"
+
+echo "HTTP/1.1 200 OK"
+echo "Content-Type: text/html"
+echo "${PAGE}" | sed 's/^[ \t]*//g'