From 6eb743a1bf4a4c7d3a5eb5428b70684ed9f24a85 Mon Sep 17 00:00:00 2001 From: odweta Date: Thu, 10 Sep 2026 17:04:41 +0200 Subject: [PATCH] Allow user-configurable invoice numbering start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a per-user invoice_starting_number setting (default 1) instead of always starting invoice numbering at 001. Adds /api/settings endpoints, a user_settings table, and a Číslování faktur panel in the account menu where the user can pick the starting number for a year with no invoices yet. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- app/src/app.js | 39 +++++++++++++++++++++++++++++++++-- app/src/db.js | 5 +++++ app/src/static/index.html | 17 ++++++++++++++++ app/src/static/script.js | 43 ++++++++++++++++++++++++++++++++++++++- app/src/static/style.css | 6 ++++++ 5 files changed, 107 insertions(+), 3 deletions(-) diff --git a/app/src/app.js b/app/src/app.js index 60693f6..c955f8e 100644 --- a/app/src/app.js +++ b/app/src/app.js @@ -227,6 +227,33 @@ app.put('/api/supplier', requireAuth, async (req, res, next) => { } }); +app.get('/api/settings', requireAuth, async (req, res, next) => { + try { + const result = await pool.query('SELECT invoice_starting_number FROM user_settings WHERE user_id = $1', [req.userId]); + res.json({ settings: { invoiceStartingNumber: result.rowCount ? result.rows[0].invoice_starting_number : 1 } }); + } catch (error) { + next(error); + } +}); + +app.put('/api/settings', requireAuth, async (req, res, next) => { + try { + const invoiceStartingNumber = Number.parseInt(req.body.invoiceStartingNumber, 10); + if (!Number.isInteger(invoiceStartingNumber) || invoiceStartingNumber < 1) { + res.status(400).json({ error: 'Počáteční číslo faktury musí být kladné celé číslo.' }); + return; + } + const result = await pool.query(` + INSERT INTO user_settings (user_id, invoice_starting_number) VALUES ($1, $2) + ON CONFLICT (user_id) DO UPDATE SET invoice_starting_number = EXCLUDED.invoice_starting_number + RETURNING invoice_starting_number + `, [req.userId, invoiceStartingNumber]); + res.json({ settings: { invoiceStartingNumber: result.rows[0].invoice_starting_number } }); + } catch (error) { + next(error); + } +}); + app.get('/api/clients', requireAuth, async (req, res, next) => { try { const result = await pool.query('SELECT * FROM clients WHERE user_id = $1 ORDER BY created_at, id', [req.userId]); @@ -376,13 +403,21 @@ app.post('/api/invoices', requireAuth, async (req, res, next) => { const invoiceYear = new Date().getFullYear(); await client.query('BEGIN'); + const settingsResult = await client.query( + 'SELECT invoice_starting_number FROM user_settings WHERE user_id = $1', + [req.userId] + ); + const invoiceStartingNumber = settingsResult.rowCount ? settingsResult.rows[0].invoice_starting_number : 1; await client.query(` INSERT INTO invoice_counters (user_id, invoice_year, last_number) - SELECT $1, $2, COALESCE(MAX((substring(invoice_number FROM '^F-[0-9]{4}-([0-9]+)$'))::integer), 0) + SELECT $1, $2, GREATEST( + COALESCE(MAX((substring(invoice_number FROM '^F-[0-9]{4}-([0-9]+)$'))::integer), 0), + $4 - 1 + ) FROM invoices WHERE user_id = $1 AND invoice_number LIKE $3 ON CONFLICT (user_id, invoice_year) DO NOTHING - `, [req.userId, invoiceYear, `F-${invoiceYear}-%`]); + `, [req.userId, invoiceYear, `F-${invoiceYear}-%`, invoiceStartingNumber]); const counterResult = await client.query(` UPDATE invoice_counters SET last_number = last_number + 1 diff --git a/app/src/db.js b/app/src/db.js index f1c8edb..4c4804a 100644 --- a/app/src/db.js +++ b/app/src/db.js @@ -65,6 +65,11 @@ const initializeDatabase = () => { PRIMARY KEY (user_id, invoice_year) ); + CREATE TABLE IF NOT EXISTS user_settings ( + user_id INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE, + invoice_starting_number INTEGER NOT NULL DEFAULT 1 CHECK (invoice_starting_number > 0) + ); + CREATE TABLE IF NOT EXISTS payment_presets ( id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, diff --git a/app/src/static/index.html b/app/src/static/index.html index 509cab9..0c96e72 100644 --- a/app/src/static/index.html +++ b/app/src/static/index.html @@ -65,11 +65,28 @@ + +