| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- from typing import List
- import db
- import config
- def calculate_estimated_price(material_id: int, file_sizes: List[int], file_quantities: List[int] = None, return_details=False) -> float:
- """
- Internal logic to estimate price per file based on file size (proxy for volume)
- and print time (proxy for machine wear/energy).
- """
- material = db.execute_query("""
- SELECT m.price_per_cm3,
- COALESCE(m.price_per_hour, s.price_per_hour, %s) as price_per_hour,
- m.speed_coeff
- FROM materials m
- LEFT JOIN services s ON m.service_id = s.id
- WHERE m.id = %s
- """, (config.DEFAULT_PRINTER_HOUR_PRICE, material_id))
- if not material:
- return (0.0, []) if return_details else 0.0
-
- price_per_cm3 = float(material[0]['price_per_cm3'])
- price_per_hour = float(material[0]['price_per_hour'])
- speed_coeff = float(material[0]['speed_coeff'] or 1.0)
-
- if file_quantities is None or len(file_quantities) != len(file_sizes):
- file_quantities = [1] * len(file_sizes)
-
- estimated_total = 0.0
- file_costs = []
- base_fee = 5.0 # Minimum setup fee per file
-
- for size, qty in zip(file_sizes, file_quantities):
- total_size_mb = size / (1024 * 1024)
- # Empirical conversion: ~8cm3 per 1MB of STL (binary)
- estimated_volume_cm3 = total_size_mb * 8.0
-
- # Estimate printing time (same logic as in slicer_utils.py: volume_mm3 / 10.0)
- # Apply speed_coeff to adjust time based on material difficulty
- estimated_hours = ((estimated_volume_cm3 * 100.0) / 3600.0) * speed_coeff
-
- material_cost = estimated_volume_cm3 * price_per_cm3
- operation_cost = estimated_hours * price_per_hour
-
- file_cost = round(base_fee + material_cost + operation_cost, 2)
- file_costs.append(file_cost)
- estimated_total += file_cost * qty
-
- if return_details:
- return round(estimated_total, 2), file_costs
- return round(estimated_total, 2)
|