Skip to content

Latest commit

 

History

228 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Trafcom DXF Calculate

Python Flask PostgreSQL UI language

A Flask app for a CNC/laser cutting company (Trafcom): upload a DXF drawing and get its cutting price calculated automatically from geometry (area, cut length, pierce count), build a catalog of reusable "Details" and "Products" from priced drawings, track stock via delivery notes, and run customer orders through production tracking. The UI is in Bulgarian.

Contents

Features

  • DXF pricing — upload a DXF file, get area/cut-length/pierce-count extracted from the geometry and run through a time-based pricing engine: material supplies the raw-stock area cost plus its cutting/pierce speed, and one or more billable Services (see below) supply the EUR/hour rate — a job can be priced against several services at once (e.g. a combined cut+engrave pass), plus a flat setup fee.
  • Services & Operations — admins define billable Service types (e.g. laser cutting, 3-axis milling) with an EUR/hour rate and the machines that can run them; extra post-processing steps on a catalog Detail (Operation — milling, deburring, welding, ...) are costed by duration × the linked service's rate.
  • Catalog — admin-curated Detail (single part) and Product (assembled from multiple Details + extra costs like paint/assembly, with markup) records, each with stock tracking and a printable barcode label.
  • Orders & production tracking — customer orders (Order / OrderItem) roll up completion status per-component as production reports units produced, driven off frozen recipe snapshots so later catalog edits don't retroactively change placed orders.
  • Production wizard — separately from order tracking above, plan a standalone "produce N of this Detail" job ahead of demand; it's clamped so it can never drive the chosen material batch's stock negative, and completing/deleting one properly moves (or reverses) real stock.
  • Delivery notes / stock intake — recording goods received from a Supplier bumps stock on the referenced material/detail/product. Material requests raise the restock ask on the other end, from the storage dashboard, when stock runs low.
  • Clients & deliverers — lightweight lookup catalogs (with Bulgarian company legal fields — ЕИК, ДДС №, address, МОЛ) an order can reference.
  • Label printing — Code128 barcode labels (rendered as inline SVG, no external service) for any catalog entry or produced batch.
  • Role-based accessregular_user, worker, admin, web_designer, with a scoped-down content editor for non-pricing public-page text; new registrations can be locked from /admin/users without affecting existing accounts.
  • Two-factor auth & email verification — optional per-user TOTP 2FA (QR-code setup, no image file written to disk) and email verification/ password-reset links, both signed & time-limited rather than stored as a token column.
  • Quotes (Offers) — pre-order quotes with product/detail/text-only lines, an optional whole-quote discount and expiry date, per-line photos, and one click to turn the checked lines into a real Order.
  • Offer / protocol / certificate documents — browser-print pages (Ctrl+P to PDF), no server-side PDF library.
  • Panel Generator — a parametric panel/hole-pattern DXF tool (square, hexagon, triangle, rhombus, hex-cluster), with save/reload presets and a server-side (ezdxf) export that real CAD software can open cleanly.
  • AI chat assistant (optional) — a chat widget backed by Claude, with read-only tools to look up catalog items, stock, orders, and prices in plain Bulgarian; degrades to a friendly "unavailable" message if no API key is configured.
  • Activity log — every state-changing admin/worker action is recorded (who, what, when), exportable to .xlsx.
  • Missing-stock dashboard — every open order that doesn't currently have enough Detail/Product stock to fulfill it, recomputed live rather than stored.
  • DXF revision history per Detail — the original uploaded .dxf files behind a catalog Detail are kept and downloadable (admins only), not just the geometry extracted from them.
  • Order-time customization — a standalone-detail order line can carry its own ad-hoc operations (independent of any Operation permanently attached to the Detail catalog row) and an optional reference PDF (drawing/spec), both picked at order-creation time and frozen into that line's price and paperwork.
  • Live power monitoring — a real-time dashboard (/admin/power) polling Shelly energy meters on the shop LAN (both Gen1 and Gen2 devices supported), plus a background poller that logs readings locally every minute so historical charts are available for both generations — not just the roughly 45-day on-device retention Gen2 meters offer natively; see docs/SHELLY_API.md.

Requirements

  • Python 3
  • PostgreSQL (reachable via DATABASE_URL)

Installation

pip install -r requirements.txt

Copy .env.example to .env and fill in real values:

SECRET_KEY=
DATABASE_URL=postgresql+psycopg2://user:password@localhost:5432/cnc_calculator_db
FLASK_DEBUG=0

SECRET_KEY and DATABASE_URL are required — the app raises an error on import if either is missing. .env is loaded automatically via python-dotenv and is gitignored.

Everything else in .env.example is optional, each feature just degrades gracefully without it: ANTHROPIC_API_KEY (+ optional ANTHROPIC_WORKSPACE_ID) powers the AI chat assistant; SMTP_HOST / PORT / USER / PASSWORD / FROM control outgoing password-reset and email-verification mail (defaults to a local localhost:25 transport with no auth if unset).

Running it

python app.py

This also creates any missing database tables (db.create_all() — it does not migrate existing ones, see Schema changes below) and seeds default material prices and machine cards on first run, then opens http://127.0.0.1:5000/ in your browser. Set FLASK_DEBUG=1 for the interactive debugger and auto-reload during local dev — never in a public deployment.

There is no auto-created admin account. To create or reset one:

python -m migration.change_admin_password

For production, serve wsgi.py with gunicorn/waitress instead of running app.py directly (the WSGI entrypoint never runs the dev-server initialization block above, so run python app.py once by hand first to set up the database).

Project structure

Click to expand
  • app.py — models, DXF geometry/pricing logic, and all routes (single file)
  • wsgi.py — production entrypoint (gunicorn/waitress)
  • gunicorn.conf.py — bumps the worker timeout to 120s (/admin/power/history can take ~25s per day-chunk fetched, close to gunicorn's 30s default)
  • requirements.txt
  • .env.example
  • uploads/ — private scratch folder for in-flight DXF uploads (not on GitHub — gitignored)
templates/ — Jinja2 templates, one per page/route
partials/ — shared chrome (navbar, footer, CSRF field, editable-text blocks)
- [`navbar.html`](https://github.com/protoknight12/Trafcom_Website/blob/main/templates/partials/navbar.html)
- [`footer.html`](https://github.com/protoknight12/Trafcom_Website/blob/main/templates/partials/footer.html) — also renders the AI chat widget for logged-in users
- [`editable.html`](https://github.com/protoknight12/Trafcom_Website/blob/main/templates/partials/editable.html)
- [`csrf_field.html`](https://github.com/protoknight12/Trafcom_Website/blob/main/templates/partials/csrf_field.html)
- [`material_options.html`](https://github.com/protoknight12/Trafcom_Website/blob/main/templates/partials/material_options.html)
- [`legal_fields.html`](https://github.com/protoknight12/Trafcom_Website/blob/main/templates/partials/legal_fields.html) — shared ЕИК/ДДС №/address/МОЛ fields (Client/Deliverer/Supplier)
- [`favicon.html`](https://github.com/protoknight12/Trafcom_Website/blob/main/templates/partials/favicon.html)
- [`breadcrumbs.html`](https://github.com/protoknight12/Trafcom_Website/blob/main/templates/partials/breadcrumbs.html)
- [`local_business_schema.html`](https://github.com/protoknight12/Trafcom_Website/blob/main/templates/partials/local_business_schema.html) — LocalBusiness JSON-LD for the public pages
- [`sticky_cta.html`](https://github.com/protoknight12/Trafcom_Website/blob/main/templates/partials/sticky_cta.html) — mobile call/contact bar for anonymous visitors
static/ — CSS, client-side JS, images, and web-accessible uploads
migration/ — one-off migration/backfill/seed scripts (see below)
testing/ — test scripts (see below)
docs/ — reference docs

Schema changes

db.create_all() only creates tables that don't exist yet — it never alters existing ones (there's no Alembic in this project). Any model field change needs either a fresh dev database or a hand-written migration script in migration/, run as a module from the repo root, e.g.:

python -m migration.migrate_add_supplier_vat

See each script's module docstring for what it does and when to run it.

Tests

Most tests are plain assert-based scripts, run as modules from the repo root, e.g.:

python -m testing.test_label_barcode

A few use pytest instead, where the thing being tested needs real request/response behavior (redirects, status codes, session auth):

pip install pytest flask-wtf
pytest testing/test_security_fixes.py -v

Configuration notes

  • Rate limiting (flask-limiter) defaults to 300 requests/hour per IP, with tighter limits on /login and /register. Storage is in-memory — per-process only. If running more than one gunicorn/waitress worker, switch to a shared store (e.g. Redis) or limits won't be enforced correctly across workers.
  • All state-changing requests require a CSRF token (flask-wtf).
  • Shelly energy meters are managed from the /admin/power dashboard itself (add/rename/delete/relink a machine there, no restart needed). The SHELLY_DEVICES env var in .env.example is legacy, one-time-use only — it's read once on first startup after upgrading, to migrate whatever was configured there into the database; leave it blank on a fresh install. See docs/SHELLY_API.md.

About

Website for TRAFCOM

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages