"""Job cost and time estimation from STL geometry.""" import os # g/cm³ per material — used to convert volume → weight _DENSITY: dict[str, float] = { "PLA": 1.24, "PETG": 1.27, "ABS": 1.04, "ASA": 1.07, "TPU": 1.20, "Nylon": 1.14, "PC": 1.20, } _DEFAULT_DENSITY = 1.24 # Conservative average FDM print speed for weight-based time estimate _PRINT_SPEED_G_PER_HOUR = 20.0 def estimate(volume_ccm: float, material: str | None) -> dict: """ Returns a cost/time estimate dict for one job. Assumptions: - 20 % infill → material used = volume * 0.20 - filament density from _DENSITY (default 1.24 g/cm³) - print speed: 20 g/h (conservative FDM average) - filament cost: FILAMENT_PRICE_PER_KG EUR / kg (env, default 15) - misprint buffer: +20 % - gross profit margin: +30 % - VAT: VAT_RATE % (env, default 19) """ vat_rate = float(os.environ.get("VAT_RATE", 19)) price_per_kg = float(os.environ.get("FILAMENT_PRICE_PER_KG", 15)) density = _DENSITY.get(material or "", _DEFAULT_DENSITY) material_ccm = volume_ccm * 0.20 weight_g = material_ccm * density print_minutes = round((weight_g / _PRINT_SPEED_G_PER_HOUR) * 60) filament_cost = weight_g / 1000 * price_per_kg after_misprint = filament_cost * 1.20 net_price = after_misprint * 1.30 gross_price = net_price * (1 + vat_rate / 100) return { "material_ccm": round(material_ccm, 2), "weight_g": round(weight_g, 1), "print_minutes": print_minutes, "filament_cost": round(filament_cost, 2), "net_price": round(net_price, 2), "gross_price": round(gross_price, 2), "vat_rate": vat_rate, "price_per_kg": price_per_kg, }