feat: extract workflow material services phase 3
This commit is contained in:
@@ -16,7 +16,9 @@ from app.domains.orders.models import Order, OrderLine, OrderStatus
|
||||
from app.domains.products.models import CadFile, Product
|
||||
from app.domains.rendering.models import OutputType, RenderTemplate
|
||||
from app.domains.rendering.workflow_runtime_services import (
|
||||
auto_populate_materials_for_cad,
|
||||
prepare_order_line_render_context,
|
||||
resolve_order_line_material_map,
|
||||
resolve_order_line_template_context,
|
||||
)
|
||||
|
||||
@@ -216,3 +218,150 @@ def test_resolve_order_line_template_context_uses_exact_template_and_override(sy
|
||||
"InnerRing": "HARTOMAT_OVERRIDE",
|
||||
"OuterRing": "HARTOMAT_OVERRIDE",
|
||||
}
|
||||
|
||||
|
||||
def test_resolve_order_line_material_map_disables_materials_when_template_blocks_replacement(
|
||||
sync_session,
|
||||
tmp_path,
|
||||
monkeypatch,
|
||||
):
|
||||
from app.config import settings
|
||||
|
||||
monkeypatch.setattr(settings, "upload_dir", str(tmp_path / "uploads"))
|
||||
line = _seed_order_line_graph(sync_session, tmp_path)
|
||||
template = RenderTemplate(
|
||||
id=uuid.uuid4(),
|
||||
name="Lighting Only",
|
||||
category_key="bearings",
|
||||
blend_file_path="/templates/lighting-only.blend",
|
||||
original_filename="lighting-only.blend",
|
||||
target_collection="Product",
|
||||
material_replace_enabled=False,
|
||||
lighting_only=True,
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
result = resolve_order_line_material_map(
|
||||
line,
|
||||
line.product.cad_file,
|
||||
line.product.cad_part_materials,
|
||||
material_library="/libraries/materials.blend",
|
||||
template=template,
|
||||
)
|
||||
|
||||
assert result.use_materials is False
|
||||
assert result.material_map is None
|
||||
assert result.override_material is None
|
||||
|
||||
|
||||
def test_resolve_order_line_material_map_prefers_line_override_over_output_override(
|
||||
sync_session,
|
||||
tmp_path,
|
||||
monkeypatch,
|
||||
):
|
||||
from app.config import settings
|
||||
|
||||
monkeypatch.setattr(settings, "upload_dir", str(tmp_path / "uploads"))
|
||||
line = _seed_order_line_graph(sync_session, tmp_path)
|
||||
line.material_override = "LINE_OVERRIDE"
|
||||
line.output_type.material_override = "OUTPUT_OVERRIDE"
|
||||
sync_session.commit()
|
||||
|
||||
result = resolve_order_line_material_map(
|
||||
line,
|
||||
line.product.cad_file,
|
||||
line.product.cad_part_materials,
|
||||
material_library="/libraries/materials.blend",
|
||||
template=None,
|
||||
)
|
||||
|
||||
assert result.override_material == "LINE_OVERRIDE"
|
||||
assert result.use_materials is True
|
||||
assert result.material_map == {
|
||||
"InnerRing": "LINE_OVERRIDE",
|
||||
"OuterRing": "LINE_OVERRIDE",
|
||||
}
|
||||
|
||||
|
||||
def test_auto_populate_materials_for_cad_updates_only_blank_products_and_queues_once(sync_session, tmp_path):
|
||||
line = _seed_order_line_graph(sync_session, tmp_path)
|
||||
cad_file = line.product.cad_file
|
||||
assert cad_file is not None
|
||||
|
||||
line.product.components = [
|
||||
{"part_name": "InnerRing", "material": "Steel"},
|
||||
{"part_name": "OuterRing", "material": "Rubber"},
|
||||
]
|
||||
line.product.cad_part_materials = []
|
||||
|
||||
second_product = Product(
|
||||
id=uuid.uuid4(),
|
||||
pim_id="P-2000",
|
||||
name="Bearing B",
|
||||
category_key="bearings",
|
||||
cad_file_id=cad_file.id,
|
||||
cad_file=cad_file,
|
||||
components=[
|
||||
{"part_name": "InnerRing", "material": "Brass"},
|
||||
{"part_name": "OuterRing", "material": "Copper"},
|
||||
],
|
||||
cad_part_materials=[{"part_name": "InnerRing", "material": "Existing"}],
|
||||
)
|
||||
sync_session.add(second_product)
|
||||
sync_session.commit()
|
||||
|
||||
queued: list[tuple[str, dict[str, str]]] = []
|
||||
|
||||
result = auto_populate_materials_for_cad(
|
||||
sync_session,
|
||||
str(cad_file.id),
|
||||
enqueue_thumbnail=lambda current_cad_file_id, part_colors: queued.append(
|
||||
(current_cad_file_id, part_colors)
|
||||
),
|
||||
)
|
||||
|
||||
sync_session.refresh(line.product)
|
||||
sync_session.refresh(second_product)
|
||||
|
||||
assert result.updated_product_ids == [str(line.product.id)]
|
||||
assert result.queued_thumbnail_regeneration is True
|
||||
assert result.part_colors == {"InnerRing": "Steel", "OuterRing": "Rubber"}
|
||||
assert queued == [(str(cad_file.id), {"InnerRing": "Steel", "OuterRing": "Rubber"})]
|
||||
assert line.product.cad_part_materials == [
|
||||
{"part_name": "InnerRing", "material": "Steel"},
|
||||
{"part_name": "OuterRing", "material": "Rubber"},
|
||||
]
|
||||
assert second_product.cad_part_materials == [{"part_name": "InnerRing", "material": "Existing"}]
|
||||
|
||||
|
||||
def test_auto_populate_materials_for_cad_skips_when_materials_already_present(sync_session, tmp_path):
|
||||
line = _seed_order_line_graph(sync_session, tmp_path)
|
||||
cad_file = line.product.cad_file
|
||||
assert cad_file is not None
|
||||
|
||||
line.product.components = [
|
||||
{"part_name": "InnerRing", "material": "Steel"},
|
||||
{"part_name": "OuterRing", "material": "Rubber"},
|
||||
]
|
||||
sync_session.commit()
|
||||
|
||||
queued: list[tuple[str, dict[str, str]]] = []
|
||||
|
||||
result = auto_populate_materials_for_cad(
|
||||
sync_session,
|
||||
str(cad_file.id),
|
||||
enqueue_thumbnail=lambda current_cad_file_id, part_colors: queued.append(
|
||||
(current_cad_file_id, part_colors)
|
||||
),
|
||||
)
|
||||
|
||||
sync_session.refresh(line.product)
|
||||
|
||||
assert result.updated_product_ids == []
|
||||
assert result.queued_thumbnail_regeneration is False
|
||||
assert result.part_colors is None
|
||||
assert queued == []
|
||||
assert line.product.cad_part_materials == [
|
||||
{"part_name": "InnerRing", "material": "Steel raw"},
|
||||
{"part_name": "OuterRing", "material": "Steel raw"},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user