Compare commits
10
Commits
37801fca2a
...
263aefe9fc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
263aefe9fc
|
||
|
|
07666b30c9
|
||
|
|
65dd976bb4
|
||
|
|
0fb573552d
|
||
|
|
23c4c7ded0
|
||
|
|
c30d4cb34a
|
||
|
|
18b4199d0a
|
||
|
|
1a93fc739d
|
||
|
|
550750fe88
|
||
|
|
23173e79b2
|
@@ -0,0 +1,6 @@
|
||||
FROM python:3.12-alpine
|
||||
WORKDIR /app
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
COPY server.py receipt.py ./
|
||||
CMD ["python", "server.py"]
|
||||
@@ -0,0 +1,2 @@
|
||||
qrcode
|
||||
pillow
|
||||
+380
-519
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -6,7 +6,7 @@
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PID_FILE="$SCRIPT_DIR/data/server.pid"
|
||||
PORT=8989
|
||||
PORT=4566
|
||||
|
||||
# Proveri da li server već radi
|
||||
check_running() {
|
||||
|
||||
@@ -38,9 +38,19 @@ The goal is simple: everything the repair shop needs to track is located in one
|
||||
- Security HTTP headers (CSP, X-Frame-Options, Referrer-Policy, nosniff...)
|
||||
- Login attempt logging — history by user, IP, reason, date
|
||||
- Users and roles — admin panel, user management
|
||||
- Inventory — items, categories, filtering, critical stock levels
|
||||
- Service orders — intake, status bar, costs, receipt
|
||||
- Inventory — items, categories, filtering, critical stock levels, per-item stock card, supplier links, item transfers
|
||||
- Service orders:
|
||||
- Intake form, status bar, archive
|
||||
- Diagnostic workflow — fault description, technician notes, work done, diagnostic fee
|
||||
- Parts and services — used items deducted from stock; suggested items (proposal to client)
|
||||
- Client proposal approval — client receives a public link (QR code) to accept or reject a parts/service proposal with a comment
|
||||
- Public status page — client can check order status and receive notifications via a unique link
|
||||
- Documents — work order, pre-invoice (estimate), dispatch note, return slip, device label (QR + Code128 barcode)
|
||||
- Pickup with payment — tracks payment method and advance amount
|
||||
- Guarantee period, expected completion date, technician assignment, client notes
|
||||
- Sales orders — items, calculation, receipt with company and client details
|
||||
- Services catalog — service price list used for billing in service orders
|
||||
- Expenses — expense records with category and amount
|
||||
- Procurement — records of purchases from suppliers
|
||||
- Sales price calculation on procurement — markup (global, per category, per item), landed costs (customs, shipping...) allocated across items, two-way markup↔price computation; respects VAT-payer status
|
||||
- Price revaluation (nivelacija) — sales price changes with an audit trail (old→new, reason, source, user)
|
||||
@@ -50,7 +60,7 @@ The goal is simple: everything the repair shop needs to track is located in one
|
||||
- VAT rate code list
|
||||
- Clients and suppliers — contact database
|
||||
- Reminders — records with deadlines
|
||||
- Reports — revenue overview, inventory status
|
||||
- Reports — revenue overview, inventory status, inventory value report, stock movement list, stocktake (physical count)
|
||||
- Settings — company name, address, Tax ID (PIB), logo; theme toggle
|
||||
- Background images — login page and app, with blur, transparency and glass effect
|
||||
- Personal theme and background — each user can set their own theme and background image
|
||||
@@ -62,9 +72,12 @@ The goal is simple: everything the repair shop needs to track is located in one
|
||||
- Automated tests — unit and integration over a SQLite database (crypto, RBAC, login flows, form validators, reports)
|
||||
- **Demo mode** (`NTECH_ENV=demo`) — auto-created demo user, pre-filled login form, restricted backup count, blocked password/2FA changes
|
||||
|
||||
### In Progress
|
||||
|
||||
- **Fiscalization (ESIR/PFR)** — Teron L-PFR mock server included in `Fisk/`; Go client integration planned
|
||||
|
||||
### Planned
|
||||
|
||||
- Fiscalization (ESIR/PFR)
|
||||
- KPO book and double-entry bookkeeping (optional, later phase)
|
||||
- PostgreSQL support (for multi-user environments)
|
||||
- WebAuthn / Passkey login (database schema is already prepared)
|
||||
@@ -80,6 +93,7 @@ The goal is simple: everything the repair shop needs to track is located in one
|
||||
| [Go](https://go.dev) | backend language |
|
||||
| [chi](https://github.com/go-chi/chi) | HTTP router |
|
||||
| [html/template](https://pkg.go.dev/html/template) | server-side templates |
|
||||
| [HTMX](https://htmx.org) | dynamic HTML over HTTP |
|
||||
| [Alpine.js](https://alpinejs.dev) | client-side UI logic |
|
||||
| [SQLite](https://sqlite.org) + [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) | main database (pure Go, no CGO) |
|
||||
| [PostgreSQL](https://www.postgresql.org) + [pgx/v5](https://github.com/jackc/pgx) | optional production database |
|
||||
@@ -188,6 +202,78 @@ your.domain.com {
|
||||
}
|
||||
```
|
||||
|
||||
### With Teron L-PFR Mock (Fiscalization Testing)
|
||||
|
||||
The `Fisk/` directory contains a Python mock server that simulates a [Teron](https://teron.rs) L-PFR fiscal device (port 4566). It implements the Teron HTTP API — invoice signing, PDV calculation, QR code generation, and per-type counters — without requiring real hardware or a certificate.
|
||||
|
||||
Use it alongside NTech for fiscalization development and testing:
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
ntech:
|
||||
image: ghcr.io/dalibor31/ntech:latest
|
||||
container_name: ntech
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
NTECH_ENV: production
|
||||
NTECH_PORT: "8000"
|
||||
NTECH_SQLITE: /app/data/ntech.db
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- ./uploads:/app/web/static/uploads
|
||||
- ./logs:/var/log/ntech
|
||||
- ./backups:/app/backups
|
||||
networks:
|
||||
- ntech-net
|
||||
|
||||
teron-mock:
|
||||
image: ghcr.io/dalibor31/ntech-fisk:latest
|
||||
container_name: teron_mock
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- teron-data:/app/data
|
||||
networks:
|
||||
- ntech-net
|
||||
|
||||
volumes:
|
||||
teron-data:
|
||||
|
||||
networks:
|
||||
ntech-net:
|
||||
```
|
||||
|
||||
The `teron-mock` service is reachable from `ntech` at `http://teron-mock:4566` over the internal Docker network — the port is not exposed to the host.
|
||||
|
||||
To run the mock server locally (without Docker):
|
||||
|
||||
```bash
|
||||
cd Fisk
|
||||
pip install -r requirements.txt
|
||||
python server.py
|
||||
# or: ./start.sh
|
||||
```
|
||||
|
||||
#### Teron Mock Endpoints
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/status` | Device status and last invoice number |
|
||||
| GET | `/api/attention` | Active alerts |
|
||||
| POST | `/api/pin` | PIN verification (BE unlock) |
|
||||
| GET | `/api/settings` | Device settings |
|
||||
| POST | `/api/invoices` | Issue a fiscal invoice |
|
||||
| POST | `/api/invoices/final` | Finalize an advance invoice |
|
||||
| GET | `/api/invoices/last` | Last issued invoice |
|
||||
| GET | `/api/invoices/:invoiceNumber` | Invoice by number |
|
||||
| POST | `/api/invoices/search` | Search invoices |
|
||||
|
||||
Counters, signed receipts, QR codes, and JSON invoice data are persisted in `Fisk/data/`.
|
||||
|
||||
---
|
||||
|
||||
### Demo Mode
|
||||
|
||||
Demo mode runs a fully functional copy with a pre-created `Demo` / `Demo1234` admin account. Password and 2FA changes are blocked. Backup is limited to 2 copies.
|
||||
|
||||
+90
-4
@@ -38,9 +38,19 @@ Cilj je jednostavan: sve što servis treba da prati nalazi se na jednom mestu, b
|
||||
- Bezbednosni HTTP headeri (CSP, X-Frame-Options, Referrer-Policy, nosniff...)
|
||||
- Evidencija pokušaja prijave — istorija po korisniku, IP, razlog, datum
|
||||
- Korisnici i uloge — admin panel, upravljanje korisnicima
|
||||
- Magacin — artikli, kategorije, filtriranje, kritični nivoi zaliha
|
||||
- Servisni nalozi — prijem, statusna traka, troškovi, priznanica
|
||||
- Magacin — artikli, kategorije, filtriranje, kritični nivoi zaliha, magacinska kartica po artiklu, veza sa dobavljačima, premeštanje artikala
|
||||
- Servisni nalozi:
|
||||
- Forma prijema, statusna traka, arhiva
|
||||
- Tok dijagnostike — opis kvara, napomene servisera, urađeno, cena dijagnostike
|
||||
- Delovi i radovi — ugrađeni artikli se skidaju sa lagera; predloženi artikli (ponuda klijentu)
|
||||
- Odobravanje predloga — klijent dobija javni link (QR kod) da prihvati ili odbije predlog sa komentarom
|
||||
- Javna statusna stranica — klijent prati status naloga putem jedinstvenog linka
|
||||
- Dokumenti — radni nalog, predračun, otpremnica, revers, nalepnica za uređaj (QR + Code128 barkod)
|
||||
- Preuzimanje sa naplatom — način plaćanja i iznos avansa
|
||||
- Garancija, predviđen datum završetka, serviser, napomena klijentu
|
||||
- Prodajni nalozi — stavke, obračun, priznanica sa podacima firme i klijenta
|
||||
- Cenovnik usluga — šifarnik usluga za obračun u servisnim nalozima
|
||||
- Troškovi — evidencija troškova po kategoriji i iznosu
|
||||
- Nabavke — evidencija nabavki od dobavljača
|
||||
- Kalkulacija prodajne cene pri nabavci — marža (globalna, po kategoriji i po artiklu), zavisni troškovi (carina, prevoz...) sa raspodelom na stavke, dvosmerni izračun marža↔prodajna; poštuje status PDV obveznika
|
||||
- Nivelacija — promena prodajne cene uz trag (istorija promena: stara→nova, razlog, izvor, korisnik)
|
||||
@@ -50,7 +60,7 @@ Cilj je jednostavan: sve što servis treba da prati nalazi se na jednom mestu, b
|
||||
- Šifarnik PDV stopa
|
||||
- Klijenti i dobavljači — baza kontakata
|
||||
- Podsetnici — evidencija sa rokom
|
||||
- Izveštaji — pregled prihoda, stanje magacina
|
||||
- Izveštaji — pregled prihoda, stanje magacina, vrednost zaliha, prometni list, popis (inventura)
|
||||
- Podešavanja — naziv, adresa, PIB, logo firme; promena teme
|
||||
- Pozadinske slike — login stranica i aplikacija, sa zamućenjem, providnošću i glass efektom
|
||||
- Lična tema i pozadina — svaki korisnik može svoju temu i pozadinsku sliku
|
||||
@@ -62,9 +72,12 @@ Cilj je jednostavan: sve što servis treba da prati nalazi se na jednom mestu, b
|
||||
- Automatski testovi — jedinični i integracioni nad SQLite bazom (kripto, RBAC, tokovi prijave, validatori forme, izveštaji)
|
||||
- **Demo mod** (`NTECH_ENV=demo`) — automatski kreiran demo korisnik, pre-popunjeni login, ograničen bekap, blokirana promena lozinke i 2FA
|
||||
|
||||
### U toku
|
||||
|
||||
- **Fiskalizacija (ESIR/PFR)** — Teron L-PFR mock server dostupan u `Fisk/`; integracija Go klijenta u planu
|
||||
|
||||
### Planirano
|
||||
|
||||
- Fiskalizacija (ESIR/PFR)
|
||||
- KPO knjiga i dvojno knjigovodstvo (opciono, kasnija faza)
|
||||
- Podrška za PostgreSQL (za višekorisničko okruženje)
|
||||
- WebAuthn / Passkey prijava (šema baze je pripremljena)
|
||||
@@ -80,6 +93,7 @@ Cilj je jednostavan: sve što servis treba da prati nalazi se na jednom mestu, b
|
||||
| [Go](https://go.dev) | backend jezik |
|
||||
| [chi](https://github.com/go-chi/chi) | HTTP ruter |
|
||||
| [html/template](https://pkg.go.dev/html/template) | serverski šabloni |
|
||||
| [HTMX](https://htmx.org) | dinamički HTML preko HTTP-a |
|
||||
| [Alpine.js](https://alpinejs.dev) | UI logika na strani klijenta |
|
||||
| [SQLite](https://sqlite.org) + [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) | glavna baza (čisti Go, bez CGO) |
|
||||
| [PostgreSQL](https://www.postgresql.org) + [pgx/v5](https://github.com/jackc/pgx) | opciona baza za produkciju |
|
||||
@@ -188,6 +202,78 @@ tvoj.domen.com {
|
||||
}
|
||||
```
|
||||
|
||||
### Sa Teron L-PFR mokom (testiranje fiskalizacije)
|
||||
|
||||
Folder `Fisk/` sadrži Python mock server koji simulira [Teron](https://teron.rs) L-PFR fiskalni uređaj (port 4566). Implementira Teron HTTP API — potpisivanje računa, PDV obračun, generisanje QR koda i brojače po tipu računa — bez potrebe za pravim hardverom ili sertifikatom.
|
||||
|
||||
Koristi se uz NTech za razvoj i testiranje fiskalizacije:
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
ntech:
|
||||
image: ghcr.io/dalibor31/ntech:latest
|
||||
container_name: ntech
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
NTECH_ENV: production
|
||||
NTECH_PORT: "8000"
|
||||
NTECH_SQLITE: /app/data/ntech.db
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- ./uploads:/app/web/static/uploads
|
||||
- ./logs:/var/log/ntech
|
||||
- ./backups:/app/backups
|
||||
networks:
|
||||
- ntech-net
|
||||
|
||||
teron-mock:
|
||||
image: ghcr.io/dalibor31/ntech-fisk:latest
|
||||
container_name: teron_mock
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- teron-data:/app/data
|
||||
networks:
|
||||
- ntech-net
|
||||
|
||||
volumes:
|
||||
teron-data:
|
||||
|
||||
networks:
|
||||
ntech-net:
|
||||
```
|
||||
|
||||
Servis `teron-mock` je dostupan iz `ntech` kontejnera na adresi `http://teron-mock:4566` preko interne Docker mreže — port nije izložen spolja.
|
||||
|
||||
Za lokalno pokretanje moka (bez Dockera):
|
||||
|
||||
```bash
|
||||
cd Fisk
|
||||
pip install -r requirements.txt
|
||||
python server.py
|
||||
# ili: ./start.sh
|
||||
```
|
||||
|
||||
#### Teron Mock endpointi
|
||||
|
||||
| Metod | Putanja | Opis |
|
||||
|-------|---------|------|
|
||||
| GET | `/api/status` | Status uređaja i poslednji broj računa |
|
||||
| GET | `/api/attention` | Aktivna upozorenja |
|
||||
| POST | `/api/pin` | Verifikacija PIN-a (otključavanje BE) |
|
||||
| GET | `/api/settings` | Podešavanja uređaja |
|
||||
| POST | `/api/invoices` | Izdavanje fiskalnog računa |
|
||||
| POST | `/api/invoices/final` | Finalizacija avansnog računa |
|
||||
| GET | `/api/invoices/last` | Poslednji izdati račun |
|
||||
| GET | `/api/invoices/:invoiceNumber` | Račun po broju |
|
||||
| POST | `/api/invoices/search` | Pretraga računa |
|
||||
|
||||
Brojači, potpisane priznanice, QR kodovi i JSON podaci o računima čuvaju se u `Fisk/data/`.
|
||||
|
||||
---
|
||||
|
||||
### Demo mod
|
||||
|
||||
Demo mod pokreće potpuno funkcionalnu kopiju sa pre-kreiranim nalogom `Demo` / `Demo1234` (admin). Promena lozinke i 2FA su blokirani. Bekap je ograničen na 2 kopije.
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
services:
|
||||
teron-mock:
|
||||
image: ghcr.io/dalibor31/ntech-fisk:latest
|
||||
container_name: teron_mock
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "4566:4566"
|
||||
volumes:
|
||||
- teron-data:/app/data
|
||||
|
||||
volumes:
|
||||
teron-data:
|
||||
Reference in New Issue
Block a user