# Scanner Service und Frontend Software (Kugelstoßmeeting Rochlitz)
- Geschrieben von Mario Voigt (2024 - 2025)
- License: MIT

## WARNUNG: UGLY SOFTWARE. Das ist ein "works for me" Projekt

## Konzept
- ein eigenständiger Scan-Service läuft permanent und speichert alle gescannten Barcodes, die von einem Eyoyo Barcode Scanner per USB-Anschluss kommen, in eine SQLite DB ab. 
  - der Scan-Service (usb-scanner.py) basiert auf https://github.com/vpatron/barcode_scanner_python/tree/master
  - läuft nur, wenn der Scanner angeschlossen und aktiv ist. Anderfalls gibt es Fehlermeldungen
  - wird als systemd Service installiert
- ein separat gestartetes Frontend (GUI) greift auf diese Datenbank zu und prüft die Eingaben bzw. reichert sie an
  - Frontend (sqlite.py) basiert auf https://github.com/tonypdavis/Raspberry-Pi-Barcode-Scanner-/blob/master/ipad_bs_v1.2.py
  - ruft die gleiche Datenbank auf und liest/schreibt Änderungen

**Achtung: Frontend und Scan-Service müssen auf die gleiche Datenbankdatei konfiguriert werden!**

## Installation
Siehe auch https://pypi.org/project/cysystemd/

Fedora:
```
dnf install -y systemd-devel python3-venv
sudo usermod -G dialout -a $USER #den aktuellen User zu dialout hinzufügen
```
Ubuntu:
```
apt install build-essential libsystemd-dev systemd-dev python3-venv
sudo usermod -G dialout -a $USER #den aktuellen User zu dialout hinzufügen
```

```
cd /opt/
git clone https://gitea.fablabchemnitz.de/vmario/kugelstossmeeting-ticketing.git
cd kugelstossmeeting-ticketing/
python3 -m venv venv
venv/bin/pip install -r requirements.txt
```

## USB Scanner betriebsbereit machen

USB-Geräte anzeigen und nach Scanner prüfen:
```
lsusb -v
#idVendor           0x0581 Racal Data Group
#idProduct          0x0115 Tera 5100
lsusb
#Bus 003 Device 003: ID 0581:0115 Racal Data Group Tera 5100
```

USB-Gerät Berechtigungen anpassen:
```
vim /etc/udev/rules.d/55-barcode-scanner.rules
```
```
# Set permissions to let anyone use barcode scanner
SUBSYSTEM=="usb", ATTR{idVendor}=="0581", ATTR{idProduct}=="0115", MODE="666"
```

Änderungen übernehmen:
```
udevadm control --reload-rules && udevadm trigger
```

Dienst starten und prüfen:
```
ln -sf /etc/systemd/system/usb-scanner.service /opt/kugelstossmeeting-ticketing/usb-scanner.service
systemctl enable usb-scanner.service --now
journalctl -f -u usb-scanner.service
```

## Codes scannen
Folgende Codes scannen wir ein, um den Scanner korrekt zu konfigurieren:
![QR Code Config](qrcodes.png)

**Der Scanner kann zurückgesetzt werden, indem wir ihn per QR Code ausschalten und vom USB-Port trennen.**

## Datenbankoperationen

**SQLite installieren:**

Fedora:
```
sudo dnf install sqlite3
```
Ubuntu:
```
sudo apt install sqlite3
```

**Datenbank per Shell leeren:**

```
sqlite3 kugelstossmeeting-prod.db "DELETE FROM tickets;"
sqlite3 kugelstossmeeting-prod.db "DELETE FROM scans;"
sqlite3 kugelstossmeeting-prod.db "VACUUM;"
```

**Datenbank per DB Browser for SQLite bearbeiten/ansehen:**

Fedora:
```
sudo dnf install sqlitebrowser
```
Ubuntu:
```
sudo apt install sqlitebrowser
```
![DB Browser for SQLite](db1.png)
![DB Browser for SQLite](db2.png)
![DB Browser for SQLite](db3.png)


**Bestehende Tabelle mit neuem Inhalt aus CSV Datei überschreiben:**
![DB Browser for SQLite](db4.png)

**Datenbankstruktur erzeugen:**

**Wichtig:** Die Reihenfolge der Spalten in den Tabellen darf nicht verändert werden, da die GUI TreeViews fest zugewiesen sind!

```
CREATE TABLE "tickets" (
	"BarcodeContent" TEXT,                 /* Barcode (5-stellig) {str} */
	"Nr" INTEGER,                          /* Ticket Nummer {int} */
	"VIP" TEXT,                            /* VIP Status {y/n} - VIPs bekommen kostenfreie Verköstigung und Parkplatz */
	"Medium" TEXT,                         /* {Kartonage; Online-Ticket (PDF) */
	"Aushändigung" TEXT,                   /* {Barverkauf/Tageskasse; Persönliche Aushänding; Email} */
	"Bestellnummer/Verwendungszweck" TEXT, /* Bestellnummer Online (6-stellig) {str} */
	"Bezahlt am" TEXT,                     /* {TT.MM.JJJJ} */
	"Hinweise" TEXT,                       /* {str} - etwaige Bemerkungen */
	"Besteller" TEXT,                      /* {str} - Vor- und Zuname des Käufers */
	"Typ" TEXT                             /* {E = Erwachsen; K = Kind; 0 = kostenfrei} */
);
```

```
CREATE TABLE "scans" (
	"unixtimestamp_created"INTEGER NOT NULL, /* Zeitstempel, wann der Barcode gescannt wurde */
	"barcode" TEXT NOT NULL,                 /* Der 5-stellige Barcode */
	"validated" INTEGER,                     /* {0;1} - Barcode entwertet? */
	"hint"	TEXT,                            /* Der beim Scannen optional eingetragene Kommentar */
	"unixtimestamp_checked"	INTEGER,         /* Zeitstempel, wann der Barcode entwertet wurde */
	"skipped"	INTEGER                      /* {0;1} - Barcode übersprungen? */
);
```

**Datenbankstruktur ändern (Spalten):**

Die Reihenfolge der Spalten in der Tabelle ist entscheidend, da diese statisch im Quellcode referenziert wird. Anpassungen (Löschen) zum Beispiel wie folgt:
```
ALTER TABLE tickets DROP COLUMN 'BarcodeFile';
ALTER TABLE tickets DROP COLUMN 'Ticketbeschriftung';
```

**Test-Scan mit Pseudo-Barcode und Zeitstempel erzeugen:**

```
INSERT 
	INTO scans(unixtimestamp_created,barcode,validated,hint,unixtimestamp_checked,skipped) 
	VALUES(CAST(unixepoch('now') AS FLOAT)*1e9,'12345',0,'None',CAST(unixepoch('now') AS FLOAT)*1e9,0)
;
```

## GUI starten
```
/opt/kugelstossmeeting-ticketing/venv/bin/python3 /opt/kugelstossmeeting-ticketing/sqlite.py
```

... oder
```
/opt/kugelstossmeeting-ticketing/sqlite.py #siehe python3 Header
```

... oder die .desktop-Verknüpfung benutzen

![GUI](gui.png)

## Notwendig für den Betrieb
- Notebook mit Netzteil
- USB Scanner mit USB-C Kabel
- Stempel + Stempelfarbe
- Alle Tickets als PDF-Backup (falls Was nicht klappt)
- eine aktuell befüllte SQ-Lite Datenbank

## FAQs
**Der Barcode auf dem Ticket ist schwer oder nicht scanbar. Was nun?**

In diesem Fall kann die Klarnummer des Tickets verwendet werden und manuell in der Liste ausgewählt werden. Dort wird auch der Barcode angezeigt. Dieser müsste sich mit dem gedruckten Ticket oder Online-PDF decken.

## Mögliche Verbesserungen der Software
- SQLite DB gegen netzwerkfähige MySQL/PGSQL tauschen und multimandantenfähig machen (2 Rechner, 2 Barcode Scanner)
- Programm so beschränken, dass es nicht mehrfach gestartet werden kann (PID Kontrolle o.ä.)
- siehe Code-Kommentare
- TK GUI modernisieren