From 06fc726d7a0a74ae4ba26be74da578686992d413 Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Sat, 30 Dec 2017 14:02:32 +0100 Subject: web: Use working online service for barcodes Replace webservice for generating Code 39 barcodes with a working one. --- templates/users/entry.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/users/entry.html b/templates/users/entry.html index 60d2dd3..065c4e7 100644 --- a/templates/users/entry.html +++ b/templates/users/entry.html @@ -11,7 +11,7 @@
Download
- Get HighRes Version (external) + Get HighRes Version (external) Firstname{{{FIRSTNAME}}} -- cgit v1.2.3 From 9c91c7390dde605424e0867ef18deb49473a0f0e Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Thu, 28 Dec 2017 14:06:27 +0100 Subject: README: Fix SQL syntax error --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 91a2ae3..e3e2984 100644 --- a/README +++ b/README @@ -76,6 +76,6 @@ but you need to modify a few things. === Database === * Create user - `sqlite3 shop.db "INSERT INTO users (id, email, firstname, lastname) VALUES (1, "test@tester", "Firstname", "Lastname");` + `sqlite3 shop.db "INSERT INTO users (id, email, firstname, lastname) VALUES (1, 'test@tester', 'Firstname', 'Lastname');"` * Setup user password `mdbus2 io.mainframe.shopsystem.Database /io/mainframe/shopsystem/database io.mainframe.shopsystem.Database.SetUserPassword 1 "password"` -- cgit v1.2.3 From 467607a8c6aca7bb97278007d43d704053a41401 Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Thu, 28 Dec 2017 14:14:10 +0100 Subject: README: Add missing dependencies --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index e3e2984..7fafe6d 100644 --- a/README +++ b/README @@ -33,7 +33,7 @@ The system consists of multiple daemons written in Vala, which communicate with each other using DBus. Build Dependencies: - * apt install build-essential valac libesmtp-dev libgpgme11-dev libncursesw5-dev libncurses5-dev libgee-0.8-dev libgmime-2.6-dev libarchive-dev libgstreamer1.0-dev libgtk2.0-dev librsvg2-dev libsoup2.4-dev libsqlite3-dev libpango1.0-dev libssl-dev dbus-x11 + * apt install build-essential valac libesmtp-dev libgpgme11-dev libncursesw5-dev libncurses5-dev libgee-0.8-dev libgmime-2.6-dev libarchive-dev libgstreamer1.0-dev libgtk2.0-dev librsvg2-dev libsoup2.4-dev libsqlite3-dev libpango1.0-dev libssl-dev dbus-x11 mdbus2 policykit-1 Additional runtime dependencies: * apt install fonts-lmodern gstreamer1.0-alsa gstreamer1.0-plugins-base -- cgit v1.2.3 From 7effa097b0cb2878ef012aea71b6b013498538a7 Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Fri, 29 Dec 2017 18:12:48 +0100 Subject: README: Use system DBus instead of session DBus --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 7fafe6d..29c498c 100644 --- a/README +++ b/README @@ -78,4 +78,4 @@ but you need to modify a few things. * Create user `sqlite3 shop.db "INSERT INTO users (id, email, firstname, lastname) VALUES (1, 'test@tester', 'Firstname', 'Lastname');"` * Setup user password - `mdbus2 io.mainframe.shopsystem.Database /io/mainframe/shopsystem/database io.mainframe.shopsystem.Database.SetUserPassword 1 "password"` + `mdbus2 -s io.mainframe.shopsystem.Database /io/mainframe/shopsystem/database io.mainframe.shopsystem.Database.SetUserPassword 1 "password"` -- cgit v1.2.3 From 16e73b8157e1bd1929d0e78d1347be14ab894a8d Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Fri, 29 Dec 2017 18:56:32 +0100 Subject: curses-ui: Load logo from file This loads the ASCII art logo shown in the curses UI from a file instead of having it hard-coded in the binary. --- README | 5 +++++ logo.txt | 6 ++++++ src/curses-ui/curses-ui.vala | 16 ++++++++-------- src/curses-ui/logo.vala | 27 ++++++++++++++++++++------- src/curses-ui/main.vala | 4 +++- 5 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 logo.txt diff --git a/README b/README index 29c498c..fdd141a 100644 --- a/README +++ b/README @@ -79,3 +79,8 @@ but you need to modify a few things. `sqlite3 shop.db "INSERT INTO users (id, email, firstname, lastname) VALUES (1, 'test@tester', 'Firstname', 'Lastname');"` * Setup user password `mdbus2 -s io.mainframe.shopsystem.Database /io/mainframe/shopsystem/database io.mainframe.shopsystem.Database.SetUserPassword 1 "password"` + +== Customize Your Shop == + +Edit the Logo in the logo.txt File. +A helpful tool you will found here [http://patorjk.com/software/taag/](http://patorjk.com/software/taag/) diff --git a/logo.txt b/logo.txt new file mode 100644 index 0000000..ee57aa1 --- /dev/null +++ b/logo.txt @@ -0,0 +1,6 @@ + _ ___ _____ ____ _ + | |/ / ||_ _| / ___|| |__ ___ _ __ + | ' /| __|| | \___ \| '_ \ / _ \| '_ \ + | . \| |_ | | ___) | | | | (_) | |_) ) + |_|\_\\__||_| |____/|_| |_|\___/| .__/ + |_| diff --git a/src/curses-ui/curses-ui.vala b/src/curses-ui/curses-ui.vala index ab34787..f7f6239 100644 --- a/src/curses-ui/curses-ui.vala +++ b/src/curses-ui/curses-ui.vala @@ -21,7 +21,7 @@ public class CursesUI { //StatusPanel statuswin; MessageBoxOverlay mbOverlay; - public CursesUI() { + public CursesUI(string binarylocation) { /* unicode support */ Intl.setlocale(LocaleCategory.CTYPE, ""); @@ -37,8 +37,8 @@ public class CursesUI { Curses.init_pair(1, Curses.Color.GREEN, Curses.Color.BLACK); Curses.init_pair(2, Curses.Color.WHITE, Curses.Color.RED); - /* initialize widgets */ - banner = new Logo(); + /* initialize widgets */ + banner = new Logo(binarylocation); //statuswin = new StatusPanel(); messages = new MessageBox(); clkwin = new ClockWindow(); @@ -68,18 +68,18 @@ public class CursesUI { //} public void log(MessageType type, string message) { - switch (type) { + switch (type) { case MessageType.WARNING: messages.add(message, MessageBox.WARN_COLOR); break; - case MessageType.ERROR: + case MessageType.ERROR: messages.add(message, MessageBox.ERROR_COLOR); break; default: messages.add(message, MessageBox.INFO_COLOR); break; } - + } public void log_overlay(string title, string message, int closeAfter) { @@ -87,7 +87,7 @@ public class CursesUI { Timeout.add_seconds(closeAfter, closeMbOverlay); } - public void dialog_open(string title, string message, int closeAfter=0) { + public void dialog_open(string title, string message, int closeAfter=0) { dialog = new Dialog(message, title, closeAfter); if (closeAfter > 0) { Timeout.add_seconds(closeAfter, close); @@ -102,7 +102,7 @@ public class CursesUI { return false; } - bool close() { + bool close() { dialog_close(); // just call me once return false; diff --git a/src/curses-ui/logo.vala b/src/curses-ui/logo.vala index dbc716d..c795981 100644 --- a/src/curses-ui/logo.vala +++ b/src/curses-ui/logo.vala @@ -18,17 +18,30 @@ using Curses; public class Logo { Window win; - public Logo() { + public Logo(string binarylocation) { win = new Window(8, COLS - 2, 0, 1); win.bkgdset(COLOR_PAIR(1) | Attribute.BOLD); win.addstr("\n"); - win.addstr(" _ ___ _____ ____ _ \n"); - win.addstr(" | |/ / ||_ _| / ___|| |__ ___ _ __ \n"); - win.addstr(" | ' /| __|| | \\___ \\| '_ \\ / _ \\| '_ \\ \n"); - win.addstr(" | . \\| |_ | | ___) | | | | (_) | |_) )\n"); - win.addstr(" |_|\\_\\\\__||_| |____/|_| |_|\\___/| .__/ \n"); - win.addstr(" |_| \n"); + + var file = File.new_for_path (binarylocation + "/../../logo.txt"); + + if (!file.query_exists ()) { + stderr.printf ("File '%s' doesn't exist.\n", file.get_path ()); + } + + try { + // Open file for reading and wrap returned FileInputStream into a + // DataInputStream, so we can read line by line + var dis = new DataInputStream (file.read ()); + string line; + // Read lines until end of file (null) is reached + while ((line = dis.read_line (null)) != null) { + win.addstr(line+"\n"); + } + } catch (Error e) { + error ("%s", e.message); + } win.clrtobot(); diff --git a/src/curses-ui/main.vala b/src/curses-ui/main.vala index da822a9..7020586 100644 --- a/src/curses-ui/main.vala +++ b/src/curses-ui/main.vala @@ -53,7 +53,9 @@ public static int main(string[] args) { error("IOError: %s\n", e.message); } - ui = new CursesUI(); + string binarylocation = File.new_for_path(args[0]).get_parent().get_path(); + + ui = new CursesUI(binarylocation); Log.set_default_handler(log_handler); -- cgit v1.2.3 From 14c4ab56c2a2aa12b316854a5765d075b9c2801a Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Fri, 29 Dec 2017 22:19:51 +0100 Subject: README: Add demo data --- README | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README b/README index fdd141a..8081e65 100644 --- a/README +++ b/README @@ -78,7 +78,10 @@ but you need to modify a few things. * Create user `sqlite3 shop.db "INSERT INTO users (id, email, firstname, lastname) VALUES (1, 'test@tester', 'Firstname', 'Lastname');"` * Setup user password - `mdbus2 -s io.mainframe.shopsystem.Database /io/mainframe/shopsystem/database io.mainframe.shopsystem.Database.SetUserPassword 1 "password"` + `mdbus2 -s io.mainframe.shopsystem.Database /io/mainframe/shopsystem/database io.mainframe.shopsystem.Database.SetUserPassword 1 "password"` + * Demo Data + `sqlite3 shop.db "INSERT INTO categories (name) VALUES ('Getränke')";` + `sqlite3 shop.db "INSERT INTO supplier (name,city,postal_code,street,phone,website) VALUES ('Demo Lieferant','Musterstadt','12345','Musterstraße 5','+49 1234 56789','https://www.ktt.de');"` == Customize Your Shop == -- cgit v1.2.3 From f07b648ce9b6f06200bdd0090d1fdac15fd3351d Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Sat, 30 Dec 2017 12:41:55 +0100 Subject: README: add superuser permission to example user --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 8081e65..830ae5b 100644 --- a/README +++ b/README @@ -79,6 +79,7 @@ but you need to modify a few things. `sqlite3 shop.db "INSERT INTO users (id, email, firstname, lastname) VALUES (1, 'test@tester', 'Firstname', 'Lastname');"` * Setup user password `mdbus2 -s io.mainframe.shopsystem.Database /io/mainframe/shopsystem/database io.mainframe.shopsystem.Database.SetUserPassword 1 "password"` + `sqlite3 shop.db "UPDATE authentication set superuser = 1, auth_users = 1, auth_products = 1, auth_cashbox = 1 where user = 1";` * Demo Data `sqlite3 shop.db "INSERT INTO categories (name) VALUES ('Getränke')";` `sqlite3 shop.db "INSERT INTO supplier (name,city,postal_code,street,phone,website) VALUES ('Demo Lieferant','Musterstadt','12345','Musterstraße 5','+49 1234 56789','https://www.ktt.de');"` -- cgit v1.2.3 From 207e77c7cbab87f3bf537dd11ca391f12df01129 Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Tue, 2 Jan 2018 13:58:11 +0100 Subject: all: replace hard-coded KtT branding with dynamic text * extend config file with general details * extend curves-ui makefile add config * Use name from config * replace static text with dynamic text * read short name and long name from config * replace SHORTNAME tags with the shortname * replace mail related branding information * add missing Replacement * make VAT (Umsatzsteuer) optional * make space name dynamic * make short name in treasuremail text dynamic * make pdf text more dynamic --- example.cfg | 11 +++++ invoice/invoice.final.html | 7 +--- invoice/invoice.final.txt | 6 +-- invoice/invoice.temporary.html | 7 +--- invoice/invoice.temporary.txt | 6 +-- invoice/pdf-template.txt | 4 +- invoice/treasurer.mail.txt | 2 +- invoice/vat.html | 4 ++ invoice/vat.txt | 3 ++ src/curses-ui/Makefile | 2 +- src/curses-ui/main.vala | 9 +++++ src/invoice/invoice.vala | 41 ++++++++++++++++--- src/pdf-invoice/pdf-invoice.vala | 37 ++++++++++++----- src/web/web.vala | 87 ++++++++++++++++++++++++++++------------ templates/index.html | 2 +- templates/menu.html | 2 +- 16 files changed, 165 insertions(+), 65 deletions(-) create mode 100644 invoice/vat.html create mode 100644 invoice/vat.txt diff --git a/example.cfg b/example.cfg index 1dbede7..628d73f 100644 --- a/example.cfg +++ b/example.cfg @@ -1,3 +1,7 @@ +[GENERAL] +longname = Kreativität trifft Technik e.V. +shortname = KTT +spacename = Mainframe [DATABASE] file = /path/to/shop.db [INPUT] @@ -9,6 +13,8 @@ port = 587 username = shop-system@server.example.com password = my_top_secret_password starttls = true +mailfromaddress = shop@kreativitaet-trifft-technik.de +treasurermailaddress = shop-einzug@kreativitaet-trifft-technik.de [AUDIO] path = /path/to/sounds/ [PGP] @@ -19,3 +25,8 @@ filepath = /path/to/web/templates/ port = 8080 [INVOICE] datadir = /path/to/invoice/ +vat = no +addressrow = Kreativität trifft Technik e.V., Bahnhofsplatz 10, 26122 Oldenburg +footer1 = Kreativität trifft Technik e.V.\nAmtsgericht Oldenburg VR 201044\n\nHackspace „Mainframe“\nFabLab „Fab-O-Lab“\nSchnittstelle „Schnittstelle“\n\nBahnhofsplatz 10 • 26122 Oldenburg +footer2 = Raiffeisenbank Oldenburg\nIBAN: DE34 2806 0228 0037 0185 00\nBIC: GENODEF1OL2\n\n\nFinanzamt Oldenburg\nAls gemeinnützig anerkannt.\nSteuer Nr.: 64/220/18413 +footer3 = Mail: vorstand@kreativitaet-trifft-technik.de\nWeb: www.kreativitaet-trifft-technik.de\n\n\n\nBGB-Vorstand:\nPatrick Günther, Jan Janssen, Andre Schäfer, Lars Hüsemann diff --git a/invoice/invoice.final.html b/invoice/invoice.final.html index 006321f..3856231 100644 --- a/invoice/invoice.final.html +++ b/invoice/invoice.final.html @@ -5,10 +5,7 @@ berechnen:

{{{INVOICE_TABLE}}} -

Umsatzsteuer wird nicht erhoben, da der Verein Kreativität trifft Technik e.V. -als Kleinunternehmen unter die Regelung des -§ 19 Abs. 1 UStG -fällt.

+{{{VAT}}} -

Grüße aus dem Mainframe,
+

Grüße aus dem {{{SPACENAME}}},
das Shop-System

diff --git a/invoice/invoice.final.txt b/invoice/invoice.final.txt index 80272f3..80e60b8 100644 --- a/invoice/invoice.final.txt +++ b/invoice/invoice.final.txt @@ -5,9 +5,7 @@ wie folgt zu berechnen: {{{INVOICE_TABLE}}} -Umsatzsteuer wird nicht erhoben, da der Verein Kreativität trifft -Technik e.V. als Kleinunternehmen unter die Regelung des § 19 -Abs. 1 UStG fällt. +{{{VAT}}} -Grüße aus dem Mainframe, +Grüße aus dem {{{SPACENAME}}}, das Shop-System diff --git a/invoice/invoice.temporary.html b/invoice/invoice.temporary.html index eb56443..26dc216 100644 --- a/invoice/invoice.temporary.html +++ b/invoice/invoice.temporary.html @@ -5,10 +5,7 @@ berechnen:

{{{INVOICE_TABLE}}} -

Umsatzsteuer wird nicht erhoben, da der Verein Kreativität trifft Technik e.V. -als Kleinunternehmen unter die Regelung des -§ 19 Abs. 1 UStG -fällt.

+{{{VAT}}}

Bei dieser Abrechnung handelt es sich lediglich um einen Zwischenstand. Die Hauptrechnung wird einmal monatlich getrennt zugestellt und der Gesamtbetrag @@ -16,5 +13,5 @@ wird dann vom angegebenen Bankkonto eingezogen.

Der Gesamtbetrag für den aktuellen Monat beträgt bisher:

{{{SUM_MONTH}}} € -

Grüße aus dem Mainframe,
+

Grüße aus dem {{{SPACENAME}}},
das Shop-System

diff --git a/invoice/invoice.temporary.txt b/invoice/invoice.temporary.txt index fcb8f25..bf21c51 100644 --- a/invoice/invoice.temporary.txt +++ b/invoice/invoice.temporary.txt @@ -5,9 +5,7 @@ wie folgt zu berechnen: {{{INVOICE_TABLE}}} -Umsatzsteuer wird nicht erhoben, da der Verein Kreativität trifft -Technik e.V. als Kleinunternehmen unter die Regelung des § 19 -Abs. 1 UStG fällt. +{{{VAT}}} Bei dieser Abrechnung handelt es sich lediglich um einen Zwischenstand. Die Hauptrechnung wird einmal monatlich getrennt zugestellt und der @@ -15,5 +13,5 @@ Gesamtbetrag wird dann vom angegebenen Bankkonto eingezogen. Der Gesamtbetrag für den aktuellen Monat beträgt bisher: {{{SUM_MONTH}}} € -Grüße aus dem Mainframe, +Grüße aus dem {{{SPACENAME}}}, das Shop-System diff --git a/invoice/pdf-template.txt b/invoice/pdf-template.txt index bb603b9..9da8a9a 100644 --- a/invoice/pdf-template.txt +++ b/invoice/pdf-template.txt @@ -4,9 +4,9 @@ wir erlauben uns, Ihnen für den Verzehr von Speisen und Getränken {{{SUM}}} Eine detaillierte Auflistung der einzelnen Posten befindet sich, mit genauer Zeitangabe des Einkaufs, auf den folgenden Seiten. -Umsatzsteuer wird nicht erhoben, da der Verein Kreativität trifft Technik e.V. als Kleinunternehmen unter die Regelung des § 19 Abs. 1 UStG fällt. +{{{VAT}}} Der Gesamtbetrag wird in 10 Tagen von dem angegebenen Bankkonto eingezogen. Mit freundlichen Grüßen -Kreativität trifft Technik e.V. +{{{ORGANIZATION}}} diff --git a/invoice/treasurer.mail.txt b/invoice/treasurer.mail.txt index 1e89991..6c9c6ac 100644 --- a/invoice/treasurer.mail.txt +++ b/invoice/treasurer.mail.txt @@ -5,4 +5,4 @@ and an additional csv-file in the attachment. The members' invoices are for your files and the csv-file can be used for automatic money collection. --- KtT Shopsystem +-- {{{SHORTNAME}}} Shopsystem diff --git a/invoice/vat.html b/invoice/vat.html new file mode 100644 index 0000000..245ec27 --- /dev/null +++ b/invoice/vat.html @@ -0,0 +1,4 @@ +

Umsatzsteuer wird nicht erhoben, da der Verein Kreativität trifft Technik e.V. +als Kleinunternehmen unter die Regelung des +§ 19 Abs. 1 UStG +fällt.

diff --git a/invoice/vat.txt b/invoice/vat.txt new file mode 100644 index 0000000..d1ee957 --- /dev/null +++ b/invoice/vat.txt @@ -0,0 +1,3 @@ +Umsatzsteuer wird nicht erhoben, da der Verein Kreativität trifft +Technik e.V. als Kleinunternehmen unter die Regelung des § 19 +Abs. 1 UStG fällt. diff --git a/src/curses-ui/Makefile b/src/curses-ui/Makefile index 1ca68cf..bfdea51 100644 --- a/src/curses-ui/Makefile +++ b/src/curses-ui/Makefile @@ -1,7 +1,7 @@ all: curses-ui @echo > /dev/null -curses-ui: *.vala ../audio/audio-interface.vala ../scanner-session/scannersession-interface.vala +curses-ui: *.vala ../audio/audio-interface.vala ../scanner-session/scannersession-interface.vala ../config/config-interface.vala valac -X -w -o $@ --pkg curses -X -lncursesw --pkg posix --pkg gio-2.0 $^ clean: diff --git a/src/curses-ui/main.vala b/src/curses-ui/main.vala index 7020586..47be40a 100644 --- a/src/curses-ui/main.vala +++ b/src/curses-ui/main.vala @@ -62,6 +62,15 @@ public static int main(string[] args) { scanner.msg.connect(msg_handler); scanner.msg_overlay.connect(msg_overlay_handler); + /* get configuration */ + Config config = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config"); + var shopname = "--SHOPNAME--"; + try { + shopname = config.get_string("GENERAL", "longname"); + } catch(KeyFileError e) { + shopname = "Missing in Config"; + } + ui.log(MessageType.INFO, "KtT Shop System has been started"); play("startup.ogg"); diff --git a/src/invoice/invoice.vala b/src/invoice/invoice.vala index 1e6dd58..68710ca 100644 --- a/src/invoice/invoice.vala +++ b/src/invoice/invoice.vala @@ -32,6 +32,11 @@ public class InvoiceImplementation { Database db; PDFInvoice pdf; string datadir; + string mailfromaddress; + string treasurermailaddress; + string shortname; + string spacename; + string vat; public InvoiceImplementation() throws IOError, KeyFileError { mailer = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", "/io/mainframe/shopsystem/mailer"); @@ -39,6 +44,11 @@ public class InvoiceImplementation { pdf = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.InvoicePDF", "/io/mainframe/shopsystem/invoicepdf"); Config cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config"); datadir = cfg.get_string("INVOICE", "datadir"); + mailfromaddress = cfg.get_string("MAIL", "mailfromaddress"); + treasurermailaddress = cfg.get_string("MAIL", "treasurermailaddress"); + shortname = cfg.get_string("GENERAL", "shortname"); + spacename = cfg.get_string("GENERAL", "spacename"); + vat = cfg.get_string("INVOICE", "vat"); } public void send_invoice(bool temporary, int64 timestamp, int user) throws IOError, InvoicePDFError, DatabaseError { @@ -67,9 +77,9 @@ public class InvoiceImplementation { string treasurer_path = mailer.create_mail(); Mail treasurer_mail = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", treasurer_path); - treasurer_mail.from = {"KtT Shopsystem", "shop@kreativitaet-trifft-technik.de"}; + treasurer_mail.from = {shortname + " Shopsystem", mailfromaddress}; treasurer_mail.subject = mailtitle; - treasurer_mail.add_recipient({"Schatzmeister", "shop-einzug@kreativitaet-trifft-technik.de"}, RecipientType.TO); + treasurer_mail.add_recipient({"Schatzmeister", treasurermailaddress}, RecipientType.TO); var csvinvoicedata = ""; foreach(var userid in users) { @@ -82,7 +92,7 @@ public class InvoiceImplementation { var invoicedata = generate_invoice(temporary, timestamp, userid, invoiceid); string mail_path = mailer.create_mail(); Mail mail = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", mail_path); - mail.from = {"KtT Shopsystem", "shop@kreativitaet-trifft-technik.de"}; + mail.from = {shortname + " Shopsystem", mailfromaddress}; mail.subject = mailtitle; mail.add_recipient({@"$(userdata.firstname) $(userdata.lastname)", userdata.email}, RecipientType.TO); @@ -135,9 +145,9 @@ public class InvoiceImplementation { string treasurer_path = mailer.create_mail(); Mail treasurer_mail = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", treasurer_path); - treasurer_mail.from = {"KtT Shopsystem", "shop@kreativitaet-trifft-technik.de"}; + treasurer_mail.from = {shortname + " Shopsystem", mailfromaddress}; treasurer_mail.subject = mailtitle; - treasurer_mail.add_recipient({"Schatzmeister", "shop-einzug@kreativitaet-trifft-technik.de"}, RecipientType.TO); + treasurer_mail.add_recipient({"Schatzmeister", treasurermailaddress}, RecipientType.TO); var csvinvoicedata = ""; foreach(var userid in users) { @@ -149,7 +159,7 @@ public class InvoiceImplementation { string mail_path = mailer.create_mail(); Mail mail = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Mail", mail_path); - mail.from = {"KtT Shopsystem", "shop@kreativitaet-trifft-technik.de"}; + mail.from = {shortname + " Shopsystem", mailfromaddress}; mail.subject = mailtitle; mail.add_recipient({@"$(userdata.firstname) $(userdata.lastname)", userdata.email}, RecipientType.TO); @@ -227,6 +237,8 @@ public class InvoiceImplementation { throw new IOError.FAILED("Could not open invoice template: %s", e.message); } + text = text.replace("{{{SHORTNAME}}}", shortname); + return text; } @@ -294,9 +306,26 @@ public class InvoiceImplementation { text = text.replace("{{{ADDRESS}}}", address); text = text.replace("{{{LASTNAME}}}", name); + text = text.replace("{{{SPACENAME}}}", spacename); text = text.replace("{{{INVOICE_TABLE}}}", table); text = text.replace("{{{SUM_MONTH}}}", "%d,%02d".printf(total_sum / 100, total_sum % 100)); + if(vat == "yes") { + text = text.replace("{{{VAT}}}", ""); + } else { + string vattext; + string vattextfilename; + vattextfilename = (type == MessageType.HTML) ? "vat.html" : "vat.txt"; + + try { + FileUtils.get_contents(datadir + "/" + vattextfilename, out vattext); + } catch(GLib.FileError e) { + throw new IOError.FAILED("Could not open VAT template: %s", e.message); + } + + text = text.replace("{{{VAT}}}", vattext); + } + return text; } diff --git a/src/pdf-invoice/pdf-invoice.vala b/src/pdf-invoice/pdf-invoice.vala index c50fe6c..6fd4383 100644 --- a/src/pdf-invoice/pdf-invoice.vala +++ b/src/pdf-invoice/pdf-invoice.vala @@ -15,6 +15,8 @@ [DBus (name = "io.mainframe.shopsystem.InvoicePDF")] public class InvoicePDF { + Config cfg; + /* A4 sizes (in points, 72 DPI) */ private const double width = 595.27559; /* 210mm */ private const double height = 841.88976; /* 297mm */ @@ -60,8 +62,14 @@ public class InvoicePDF { "Dezember" }; + string longname; + string vat; + public InvoicePDF(string datadir) { this.datadir = datadir; + cfg = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config"); + longname = cfg.get_string("GENERAL", "longname"); + vat = cfg.get_string("INVOICE", "vat"); } private void render_svg(Cairo.Context ctx, string file) { @@ -104,8 +112,7 @@ public class InvoicePDF { ctx.set_font_size(8.45); ctx.move_to(56.5, 142); - /* TODO: get string from config file */ - ctx.show_text("Kreativität trifft Technik e.V., Bahnhofsplatz 10, 26122 Oldenburg"); + ctx.show_text(cfg.get_string("INVOICE", "addressrow")); /* actually LMRoman12 */ ctx.select_font_face("LMSans10", Cairo.FontSlant.NORMAL, Cairo.FontWeight.NORMAL); @@ -194,7 +201,6 @@ public class InvoicePDF { ctx.move_to(56.5, 323); - /* TODO: get text from config file */ ctx.show_text(@"Rechnung Nr. $invoice_id"); ctx.restore(); @@ -224,8 +230,7 @@ public class InvoicePDF { /* set page width */ layout.set_width((int) 140 * Pango.SCALE); - /* TODO: get text from config file */ - var text = "Kreativität trifft Technik e.V.\nAmtsgericht Oldenburg VR 201044\n\nHackspace „Mainframe“\nFabLab „Fab-O-Lab“\nSchnittstelle „Schnittstelle“\n\nBahnhofsplatz 10 • 26122 Oldenburg"; + var text = cfg.get_string("INVOICE", "footer1"); /* write invoice date */ layout.set_markup(text, text.length); @@ -261,8 +266,7 @@ public class InvoicePDF { /* set page width */ layout.set_width((int) 190 * Pango.SCALE); - /* TODO: get text from config file */ - var text = "Mail: vorstand@kreativitaet-trifft-technik.de\nWeb: www.kreativitaet-trifft-technik.de\n\n\n\nBGB-Vorstand:\nPatrick Günther, Michael Pensler, Jan Janssen"; + var text = cfg.get_string("INVOICE", "footer2"); /* write invoice date */ layout.set_markup(text, text.length); @@ -298,8 +302,7 @@ public class InvoicePDF { /* set page width */ layout.set_width((int) 150 * Pango.SCALE); - /* TODO: get text from config file */ - var text = "Raiffeisenbank Oldenburg\nIBAN: DE34 2806 0228 0037 0185 00\nBIC: GENODEF1OL2\n\n\nFinanzamt Oldenburg\nAls gemeinnützig anerkannt.\nSteuer Nr.: 64/220/18413"; + var text = cfg.get_string("INVOICE", "footer3"); /* write invoice date */ layout.set_markup(text, text.length); @@ -362,6 +365,22 @@ public class InvoicePDF { text = text.replace("{{{ADDRESS}}}", address); text = text.replace("{{{LASTNAME}}}", invoice_recipient.lastname); text = text.replace("{{{SUM}}}", @"$sum"); + text = text.replace("{{{ORGANIZATION}}}", longname); + + if(vat == "yes") { + text = text.replace("{{{VAT}}}", ""); + } else { + string vattext; + + try { + FileUtils.get_contents(datadir + "/" + "vat.txt", out vattext); + } catch(GLib.FileError e) { + throw new IOError.FAILED("Could not open VAT template: %s", e.message); + } + + text = text.replace("{{{VAT}}}", vattext); + } + layout.set_markup(text, text.length); } catch(GLib.FileError e) { error("File Error: %s\n", e.message); diff --git a/src/web/web.vala b/src/web/web.vala index ea0c667..62cfb04 100644 --- a/src/web/web.vala +++ b/src/web/web.vala @@ -15,12 +15,15 @@ public class WebServer { private Soup.Server srv; + private string longname; + private string shortname; void handler_default(Soup.Server server, Soup.Message msg, string path, GLib.HashTable? query, Soup.ClientContext client) { try { var l = new WebSession(server, msg, path, query, client); var t = new WebTemplate("index.html", l); - t.replace("TITLE", "KtT Shop System"); + t.replace("TITLE", shortname + " Shop System"); + t.replace("SHORTNAME", shortname); t.menu_set_active("home"); msg.set_response("text/html", Soup.MemoryUse.COPY, t.data); msg.set_status(200); @@ -39,7 +42,8 @@ public class WebServer { var l = new WebSession(server, msg, path, query, client); l.logout(); var t = new WebTemplate("logout.html", l); - t.replace("TITLE", "KtT Shop System"); + t.replace("TITLE", shortname + " Shop System"); + t.replace("SHORTNAME", shortname); t.menu_set_active("home"); msg.set_response("text/html", Soup.MemoryUse.COPY, t.data); msg.set_status(200); @@ -96,7 +100,8 @@ public class WebServer { } var t = new WebTemplate("users/index.html", session); - t.replace("TITLE", "KtT Shop System: User"); + t.replace("TITLE", shortname + " Shop System: User"); + t.replace("SHORTNAME", shortname); t.menu_set_active("users"); var data = ""; foreach(var m in db.get_member_ids()) { @@ -130,7 +135,8 @@ public class WebServer { } var t = new WebTemplate("users/import-pgp.html", session); - t.replace("TITLE", "KtT Shop System: PGP Key Import"); + t.replace("TITLE", shortname + " Shop System: PGP Key Import"); + t.replace("SHORTNAME", shortname); t.menu_set_active("users"); Soup.Buffer filedata; @@ -182,7 +188,8 @@ public class WebServer { return; } var t = new WebTemplate("users/import.html", session); - t.replace("TITLE", "KtT Shop System: User Import"); + t.replace("TITLE", shortname + " Shop System: User Import"); + t.replace("SHORTNAME", shortname); t.menu_set_active("users"); Soup.Buffer filedata; @@ -327,7 +334,8 @@ public class WebServer { return; } var t = new WebTemplate("users/entry.html", session); - t.replace("TITLE", "KtT Shop System: User Info %llu".printf(id)); + t.replace("TITLE", shortname + " Shop System: User Info %llu".printf(id)); + t.replace("SHORTNAME", shortname); t.menu_set_active("users"); var userinfo = db.get_user_info(id); @@ -431,7 +439,8 @@ public class WebServer { return; } var t = new WebTemplate("users/invoice.html", l); - t.replace("TITLE", "KtT Shop System: User Invoice %llu".printf(id)); + t.replace("TITLE", shortname + " Shop System: User Invoice %llu".printf(id)); + t.replace("SHORTNAME", shortname); t.menu_set_active("users"); /* years, in which something has been purchased by the user */ @@ -553,7 +562,8 @@ public class WebServer { try { var l = new WebSession(server, msg, path, query, client); var t = new WebTemplate("products/index.html", l); - t.replace("TITLE", "KtT Shop System: Product List"); + t.replace("TITLE", shortname + " Shop System: Product List"); + t.replace("SHORTNAME", shortname); t.menu_set_active("products"); string table = ""; @@ -590,7 +600,8 @@ public class WebServer { try { var l = new WebSession(server, msg, path, query, client); var t = new WebTemplate("products/bestbefore.html", l); - t.replace("TITLE", "KtT Shop System: Best Before List"); + t.replace("TITLE", shortname + " Shop System: Best Before List"); + t.replace("SHORTNAME", shortname); t.menu_set_active("products"); string table = ""; @@ -645,7 +656,8 @@ public class WebServer { try { var l = new WebSession(server, msg, path, query, client); var t = new WebTemplate("products/entry.html", l); - t.replace("TITLE", "KtT Shop System: Product %llu".printf(id)); + t.replace("TITLE", shortname + " Shop System: Product %llu".printf(id)); + t.replace("SHORTNAME", shortname); t.menu_set_active("products"); /* ean */ @@ -725,7 +737,8 @@ public class WebServer { try { var session = new WebSession(server, msg, path, query, client); var template = new WebTemplate("products/new.html", session); - template.replace("TITLE", "KtT Shop System: New Product"); + template.replace("TITLE", shortname + " Shop System: New Product"); + template.replace("SHORTNAME", shortname); template.menu_set_active("products"); if(!session.superuser && !session.auth_products) { @@ -781,7 +794,8 @@ public class WebServer { } var template = new WebTemplate("products/restock.html", session); - template.replace("TITLE", "KtT Shop System: Restock Product %llu".printf(id)); + template.replace("TITLE", shortname + " Shop System: Restock Product %llu".printf(id)); + template.replace("SHORTNAME", shortname); template.replace("NAME", db.get_product_name(id)); template.menu_set_active("products"); @@ -839,7 +853,7 @@ public class WebServer { } var template = new WebTemplate("products/newprice.html", session); - template.replace("TITLE", "KtT Shop System: New Price for Product %llu".printf(id)); + template.replace("TITLE", shortname + " Shop System: New Price for Product %llu".printf(id)); template.replace("NAME", db.get_product_name(id)); template.menu_set_active("products"); @@ -878,7 +892,8 @@ public class WebServer { try { var l = new WebSession(server, msg, path, query, client); var t = new WebTemplate("aliases/index.html", l); - t.replace("TITLE", "KtT Shop System: Alias List"); + t.replace("TITLE", shortname + " Shop System: Alias List"); + t.replace("SHORTNAME", shortname); t.menu_set_active("aliases"); string table = ""; @@ -910,7 +925,8 @@ public class WebServer { try { var session = new WebSession(server, msg, path, query, client); var template = new WebTemplate("aliases/new.html", session); - template.replace("TITLE", "KtT Shop System: New Alias"); + template.replace("TITLE", shortname + " Shop System: New Alias"); + template.replace("SHORTNAME", shortname); template.menu_set_active("aliases"); if(!session.superuser && !session.auth_products) { @@ -958,7 +974,8 @@ public class WebServer { try { var l = new WebSession(server, msg, path, query, client); var t = new WebTemplate("stats/index.html", l); - t.replace("TITLE", "KtT Shop System: Statistics"); + t.replace("TITLE", shortname + " Shop System: Statistics"); + t.replace("SHORTNAME", shortname); t.menu_set_active("stats"); var stats = db.get_stats_info(); @@ -991,7 +1008,8 @@ public class WebServer { var t = new WebTemplate("stats/stock.html", l); string data = db.get_stats_stock().json; t.replace("DATA", data); - t.replace("TITLE", "KtT Shop System: Statistics: Stock"); + t.replace("SHORTNAME", shortname); + t.replace("TITLE", shortname + " Shop System: Statistics: Stock"); t.menu_set_active("stats"); msg.set_response("text/html", Soup.MemoryUse.COPY, t.data); msg.set_status(200); @@ -1007,7 +1025,8 @@ public class WebServer { var t = new WebTemplate("stats/profit_per_day.html", l); string data = db.get_stats_profit_per_day().json; t.replace("DATA", data); - t.replace("TITLE", "KtT Shop System: Statistics: Profit"); + t.replace("SHORTNAME", shortname); + t.replace("TITLE", shortname + " Shop System: Statistics: Profit"); t.menu_set_active("stats"); msg.set_response("text/html", Soup.MemoryUse.COPY, t.data); msg.set_status(200); @@ -1023,7 +1042,8 @@ public class WebServer { var t = new WebTemplate("stats/profit_per_weekday.html", l); string data = db.get_stats_profit_per_weekday().json; t.replace("DATA", data); - t.replace("TITLE", "KtT Shop System: Statistics: Profit/Weekday"); + t.replace("SHORTNAME", shortname); + t.replace("TITLE", shortname + " Shop System: Statistics: Profit/Weekday"); t.menu_set_active("stats"); msg.set_response("text/html", Soup.MemoryUse.COPY, t.data); msg.set_status(200); @@ -1039,7 +1059,8 @@ public class WebServer { var t = new WebTemplate("stats/profit_per_product.html", l); string data = db.get_stats_profit_per_products().json; t.replace("DATA", data); - t.replace("TITLE", "KtT Shop System: Statistics: Profit/Product"); + t.replace("SHORTNAME", shortname); + t.replace("TITLE", shortname + " Shop System: Statistics: Profit/Product"); t.menu_set_active("stats"); msg.set_response("text/html", Soup.MemoryUse.COPY, t.data); msg.set_status(200); @@ -1148,7 +1169,8 @@ public class WebServer { try { var session = new WebSession(server, msg, path, query, client); var template = new WebTemplate("errors/todo.html", session); - template.replace("TITLE", "KtT Shop System: ToDo"); + template.replace("TITLE", shortname + " Shop System: ToDo"); + template.replace("SHORTNAME", shortname); template.menu_set_active(""); msg.set_response("text/html", Soup.MemoryUse.COPY, template.data); msg.set_status(200); @@ -1193,7 +1215,8 @@ public class WebServer { hist += "\n"; } - template.replace("TITLE", "KtT Shop System: Cashbox"); + template.replace("TITLE", shortname + " Shop System: Cashbox"); + template.replace("SHORTNAME", shortname); template.replace("CASHBOX_STATUS", status); template.replace("CASHBOX_HISTORY", hist); template.menu_set_active("cashbox"); @@ -1219,7 +1242,8 @@ public class WebServer { } var template = new WebTemplate("cashbox/add.html", session); - template.replace("TITLE", "KtT Shop System: Cashbox Balance"); + template.replace("TITLE", shortname + " Shop System: Cashbox Balance"); + template.replace("SHORTNAME", shortname); template.menu_set_active("cashbox"); bool error = false; @@ -1291,7 +1315,8 @@ public class WebServer { try { var session = new WebSession(server, msg, path, query, client); var template = new WebTemplate("cashbox/selection.html", session); - template.replace("TITLE", "KtT Shop System: Cashbox Detail"); + template.replace("TITLE", shortname + " Shop System: Cashbox Detail"); + template.replace("SHORTNAME", shortname); template.menu_set_active("cashbox"); msg.set_response("text/html", Soup.MemoryUse.COPY, template.data); msg.set_status(200); @@ -1361,9 +1386,9 @@ public class WebServer { } var template = new WebTemplate("cashbox/detail.html", session); - template.replace("TITLE", "KtT Shop System: Cashbox Detail"); + template.replace("TITLE", shortname + " Shop System: Cashbox Detail"); template.menu_set_active("cashbox"); - + template.replace("SHORTNAME", shortname); template.replace("DATE", start.format("%B %Y")); template.replace("DEBIT", debit.to_string()); template.replace("LOSS", loss.to_string()); @@ -1387,6 +1412,16 @@ public class WebServer { } public WebServer(uint port = 8080, TlsCertificate? cert = null) throws Error { + /* get configuration */ + Config config = Bus.get_proxy_sync(BusType.SYSTEM, "io.mainframe.shopsystem.Config", "/io/mainframe/shopsystem/config"); + try { + longname = config.get_string("GENERAL", "longname"); + shortname = config.get_string("GENERAL", "shortname"); + } catch(KeyFileError e) { + longname = "Logname Missing in Config"; + shortname = "Shortname Missing in Config"; + } + srv = new Soup.Server("tls-certificate", cert); Soup.ServerListenOptions options = 0; diff --git a/templates/index.html b/templates/index.html index c7782bd..bee2d95 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1 +1 @@ -

Welcome to the new KtT Shop System.

+

Welcome to the new {{{SHORTNAME}}} Shop System.

diff --git a/templates/menu.html b/templates/menu.html index 764068a..01b61df 100644 --- a/templates/menu.html +++ b/templates/menu.html @@ -1,5 +1,5 @@