From 34d538f9a0df3b2116cf2a2ff4dbdffc3c768b3f Mon Sep 17 00:00:00 2001 From: Ian Roddis <31021769+iroddis@users.noreply.github.com> Date: Tue, 18 Aug 2026 16:19:03 -0300 Subject: [PATCH] Adjusting default product name --- app/services/scope_import.py | 84 +++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/app/services/scope_import.py b/app/services/scope_import.py index 038519e..c50423b 100644 --- a/app/services/scope_import.py +++ b/app/services/scope_import.py @@ -138,15 +138,11 @@ def parse_workbook(data: bytes) -> list[dict]: wb.close() -async def _static_ap( - db: AsyncSession, *, augmented_part_id: int, label: str, od_mm: float -): +async def _static_ap(db: AsyncSession, *, augmented_part_id: int, label: str, od_mm: float): """Create an attachment point carrying a StaticConnection for ``od_mm``.""" sc = await static_connection_crud.get_by_od_mm(db, od_mm) if sc is None: - sc = await static_connection_crud.create( - db, od_mm=od_mm, od_in=od_mm / MM_PER_INCH - ) + sc = await static_connection_crud.create(db, od_mm=od_mm, od_in=od_mm / MM_PER_INCH) apn = await apn_crud.get_by_name(db, label) if apn is None: apn = await apn_crud.create(db, name=label) @@ -158,9 +154,7 @@ async def _static_ap( ) -async def _thread_ap( - db: AsyncSession, *, augmented_part_id: int, label: str, spec: str -): +async def _thread_ap(db: AsyncSession, *, augmented_part_id: int, label: str, spec: str): """Create an attachment point for a parsed ISO/UNC thread, or None.""" parsed = _parse_thread_attribute(spec) if parsed is None: @@ -223,9 +217,7 @@ async def _link_fit( target_ap = target_aps[0] existing = await fit_crud.get_by_attachment_points(db, scope_ap, target_ap) if existing is None: - await fit_crud.create( - db, ap_a=scope_ap, ap_b=target_ap, label=FitLabel.POSSIBLE - ) + await fit_crud.create(db, ap_a=scope_ap, ap_b=target_ap, label=FitLabel.POSSIBLE) async def import_scopes(db: AsyncSession, rows: list[dict]) -> ScopeImportResult: @@ -247,7 +239,21 @@ async def import_scopes(db: AsyncSession, rows: list[dict]) -> ScopeImportResult # +2: 1-based, and the header occupies row 1. row_num = offset + 2 model_suffix = _text(row.get("model_suffix")) - default_product_number = f"{_text(row.get('model'))} {row.get('magnification_min')}-{row.get('magnification_max')}x{row.get('objective_lens_diameter_mm')} {row.get('model_suffix')}".strip() + model = _text(row.get("model")) + magnification_min = _num(row.get("magnification_min")) + magnification_max = _num(row.get("magnification_max")) + objective_lens_diameter_mm = _num(row.get("objective_lens_diameter_mm")) or _num( + row.get("objective_lens") + ) + + # Construct the model number + default_product_number = model + if magnification_min: + default_product_number += f" {magnification_min}-{magnification_max}" + if objective_lens_diameter_mm: + default_product_number += f"x{objective_lens_diameter_mm}" + if model_suffix: + default_product_number += " {model_suffix}" product_number = _text(row.get("product_number")) or default_product_number result = ScopeImportRowResult( row=row_num, product_number=product_number, status="skipped", messages=[] @@ -269,9 +275,7 @@ async def import_scopes(db: AsyncSession, rows: list[dict]) -> ScopeImportResult manufacturer = await manufacturer_crud.get_by_name(db, manufacturer_name) if manufacturer is None: - manufacturer = await manufacturer_crud.create( - db, name=manufacturer_name, url="" - ) + manufacturer = await manufacturer_crud.create(db, name=manufacturer_name, url="") model_name = _text(row.get("model")) url = _text(row.get("url")) @@ -333,9 +337,7 @@ async def import_scopes(db: AsyncSession, rows: list[dict]) -> ScopeImportResult # Rebuild attachment points from scratch so re-imports stay idempotent # (cascades delete any fits that referenced the old points). - for old_ap in await attachment_point_crud.list_for_augmented_part( - db, part.id - ): + for old_ap in await attachment_point_crud.list_for_augmented_part(db, part.id): await attachment_point_crud.delete(db, old_ap) ocular_ap = None @@ -377,24 +379,36 @@ async def import_scopes(db: AsyncSession, rows: list[dict]) -> ScopeImportResult try: ocular_fit = _text(row.get("ocular_fit")) if ocular_fit: - await _link_fit( - db, - scope_ap=ocular_ap, - scope_role=OCULAR_LABEL.lower(), - target_sku=ocular_fit, - scope_part_id=part_id, - messages=result.messages, - ) + fits = ocular_fit + if "/" in fits: + fits = [x.strip() for x in fits.split("/")] + else: + fits = [fits] + for ocular_fit in fits: + await _link_fit( + db, + scope_ap=ocular_ap, + scope_role=OCULAR_LABEL.lower(), + target_sku=ocular_fit, + scope_part_id=part_id, + messages=result.messages, + ) objective_fit = _text(row.get("objective_fit")) if objective_fit: - await _link_fit( - db, - scope_ap=objective_ap, - scope_role=OBJECTIVE_LABEL.lower(), - target_sku=objective_fit, - scope_part_id=part_id, - messages=result.messages, - ) + fits = objective_fit + if "/" in fits: + fits = [x.strip() for x in fits.split("/")] + else: + fits = [fits] + for objective_fit in fits: + await _link_fit( + db, + scope_ap=objective_ap, + scope_role=OBJECTIVE_LABEL.lower(), + target_sku=objective_fit, + scope_part_id=part_id, + messages=result.messages, + ) except Exception as exc: # noqa: BLE001 result.messages.append(f"fit resolution error: {exc}")