Migrationen 003–009, Kundaufträge mit Lieferschein, Abräumen mit Urteil, ntfy/Backup/Zeitfenster, Live-Stream und Mobile-Mehr-Menü.
49 lines
1.6 KiB
Python
49 lines
1.6 KiB
Python
"""Auftrags-Status und Angebotsrechnung."""
|
|
|
|
import unittest
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
from grotti.cost import offer_from_file
|
|
from grotti.orders import ORDER_STATUSES, IDEA_TO_ORDER, PROJECT_TO_ORDER, normalize_status
|
|
|
|
|
|
class OrderStatusTests(unittest.TestCase):
|
|
def test_all_status_values(self):
|
|
for s in ("idee", "angebot", "bestaetigt", "druckt", "fertig", "geliefert", "bezahlt"):
|
|
self.assertIn(s, ORDER_STATUSES)
|
|
self.assertEqual(normalize_status(s), s)
|
|
|
|
def test_unknown_status(self):
|
|
with self.assertRaises(ValueError):
|
|
normalize_status("xyz")
|
|
|
|
def test_legacy_project_map(self):
|
|
self.assertEqual(PROJECT_TO_ORDER["bereit"], "angebot")
|
|
self.assertEqual(PROJECT_TO_ORDER["druckt"], "druckt")
|
|
|
|
def test_legacy_idea_map(self):
|
|
self.assertEqual(IDEA_TO_ORDER["erledigt"], "fertig")
|
|
self.assertEqual(IDEA_TO_ORDER["spaeter"], "idee")
|
|
|
|
|
|
class OfferFromFileTests(unittest.TestCase):
|
|
def test_basic_offer(self):
|
|
file_row = {"weight_g": 50, "estimated_s": 3600}
|
|
out = offer_from_file(file_row, material_price=20, machine_rate_per_h=10, setup_min=15, margin=20)
|
|
self.assertAlmostEqual(out["material_cost"], 1.0)
|
|
self.assertAlmostEqual(out["hours"], 1.0)
|
|
self.assertAlmostEqual(out["machine_cost"], 10 + 2.5)
|
|
self.assertAlmostEqual(out["total"], out["subtotal"] * 1.2)
|
|
|
|
def test_empty_file(self):
|
|
out = offer_from_file({}, 0, 0, 0, 0)
|
|
self.assertEqual(out["total"], 0.0)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|