Files
cantarire-etichetare/cantarire/units.py
T
ske087 bff6d70b17 Initial commit: aplicatie de cantarire si etichetare
Aplicatie Flask + SQLite pentru productie alimentara: cantarirea
componentelor unui produs finit si tiparirea etichetei prin QZ Tray.

- produse finite (retete) formate din componente cantarite
- designer vizual de etichete (mm/px, zona sigura, campuri variabile,
  cod QR cu continut din mai multe bucati)
- legare produs finit -> sablon de eticheta
- navigare pe doua taburi: Cantarire / Setari
- administrare: componente, produse finite, sabloane, campuri, istoric
- backup, resetare baza de date, checklist de pregatire, /healthz
- CLI de administrare si serviciu systemd pentru productie
- vendor/syncpulse-scale-bridge (GPL-3.0-or-later) pentru citirea cantarului
2026-10-18 23:38:45 +03:00

59 lines
1.8 KiB
Python

"""Unitati de masa, normalizare si conversii.
Etichetele de produs finit sunt exprimate de obicei in grame, iar cantarul
poate raporta kilograme. Toate cantaririle sunt convertite in unitatea retetei
inainte de a fi salvate.
"""
from __future__ import annotations
from typing import Optional
# Unitati acceptate, in ordinea afisata in interfata.
UNITS: tuple[str, ...] = ("g", "kg", "mg", "t", "lb", "oz")
GRAMS_PER: dict[str, float] = {
"g": 1.0,
"kg": 1000.0,
"mg": 0.001,
"t": 1_000_000.0,
"lb": 453.59237,
"oz": 28.349523125,
}
ALIASES: dict[str, str] = {
"gr": "g", "gram": "g", "grame": "g", "grams": "g",
"kg": "kg", "kgs": "kg", "kilogram": "kg", "kilograme": "kg",
"mg": "mg", "miligram": "mg", "miligrame": "mg",
"t": "t", "tona": "t", "ton": "t", "to": "t",
"lb": "lb", "lbs": "lb", "pound": "lb",
"oz": "oz", "ounce": "oz",
}
def normalize_unit(value: object, default: str = "g") -> str:
text = str(value or "").strip().lower()
if not text:
return default
return ALIASES.get(text, text if text in GRAMS_PER else default)
def convert(value: float, from_unit: str, to_unit: str) -> Optional[float]:
"""Converteste intre unitati de masa; None daca una nu este unitate de masa."""
source = GRAMS_PER.get(from_unit)
target = GRAMS_PER.get(to_unit)
if source is None or target is None:
return None
return value * source / target
def format_weight(value: object, decimals: int = 3) -> str:
"""Formatare pentru etichete: fara zerouri finale inutile."""
try:
number = float(value) # type: ignore[arg-type]
except (TypeError, ValueError):
return str(value)
text = f"{number:.{int(decimals)}f}"
if "." in text:
text = text.rstrip("0").rstrip(".")
return text or "0"