diff --git a/app/services/scope_import.py b/app/services/scope_import.py index 7bb7ef0..eeb94bf 100644 --- a/app/services/scope_import.py +++ b/app/services/scope_import.py @@ -140,15 +140,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) @@ -160,9 +156,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: @@ -206,8 +200,7 @@ async def _link_fit( """Create a POSSIBLE fit from the scope's AP to the referenced part's first AP.""" if scope_ap is None: messages.append( - f"{scope_role}_fit '{target_sku}' skipped: scope has no " - f"{scope_role} attachment point" + f"{scope_role}_fit '{target_sku}' skipped: scope has no {scope_role} attachment point" ) return target = await augmented_part_crud.get_by_sku(db, target_sku) @@ -220,16 +213,13 @@ async def _link_fit( target_aps = await attachment_point_crud.list_for_augmented_part(db, target.id) if not target_aps: messages.append( - f"{scope_role}_fit '{target_sku}' skipped: referenced part has no " - "attachment points" + f"{scope_role}_fit '{target_sku}' skipped: referenced part has no attachment points" ) return 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: @@ -251,7 +241,7 @@ 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')} {row.get('model_suffix')}".strip() + 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() product_number = _text(row.get("product_number")) or default_product_number result = ScopeImportRowResult( row=row_num, product_number=product_number, status="skipped", messages=[] @@ -273,9 +263,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")) @@ -338,9 +326,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 @@ -366,8 +352,7 @@ async def import_scopes(db: AsyncSession, rows: list[dict]) -> ScopeImportResult ) if objective_ap is None: result.messages.append( - f"could not parse objective_thread " - f"'{objective_thread_spec}'" + f"could not parse objective_thread '{objective_thread_spec}'" ) staged.append((row, ocular_ap, objective_ap, part.id, result)) diff --git a/data/First 680 Riflescopes data for new fit guide - June 12 2026.xlsx b/data/First 680 Riflescopes data for new fit guide - June 12 2026.xlsx index 37d2c4b..83a65f4 100644 Binary files a/data/First 680 Riflescopes data for new fit guide - June 12 2026.xlsx and b/data/First 680 Riflescopes data for new fit guide - June 12 2026.xlsx differ