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
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
"""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"
|
||||
Reference in New Issue
Block a user