Adding UAC Diameter Range MM to augmented parts
This commit is contained in:
1 parent
597cf68157
commit
d23f5b9e82
7 files changed
+263
-2
No files matched your search
@@ -22,6 +22,17 @@ async def list_all(
|
||||
return list(result.scalars().all())
|
||||
|
||||
|
||||
async def get_by_values(
|
||||
db: AsyncSession, *, min_mm: float | None, max_mm: float | None
|
||||
) -> ClampConnection | None:
|
||||
result = await db.execute(
|
||||
select(ClampConnection).where(
|
||||
ClampConnection.min_mm == min_mm, ClampConnection.max_mm == max_mm
|
||||
)
|
||||
)
|
||||
return result.scalars().first()
|
||||
|
||||
|
||||
async def create(
|
||||
db: AsyncSession,
|
||||
*,
|
||||
|
||||
@@ -38,6 +38,11 @@ class AugmentedPart(Base):
|
||||
nullable=True,
|
||||
default=None,
|
||||
)
|
||||
# "##.##-##.##" mm, derived from ImportedPart.UACDiameterRangemm by the sync
|
||||
# service. Read-only — never set outside app/services/augmented_part_sync.py.
|
||||
uac_diameter_range_mm: Mapped[str | None] = mapped_column(
|
||||
String, nullable=True, default=None
|
||||
)
|
||||
# Set instead of deleting the row when the last backing ImportedPart is
|
||||
# removed, so fit/attachment-point history is preserved. Hidden from list
|
||||
# views by default.
|
||||
|
||||
@@ -67,6 +67,7 @@ class AugmentedPartRead(AugmentedPartBase):
|
||||
|
||||
id: int
|
||||
archived: bool
|
||||
uac_diameter_range_mm: str | None
|
||||
colour: PartColourRead
|
||||
manufacturer: ManufacturerRead
|
||||
scope_model: ScopeModelRead | None
|
||||
|
||||
@@ -25,6 +25,12 @@ Phase 2 – create entries for new ImportedParts
|
||||
unit is missing is derived via mm/in conversion) if the
|
||||
thread attribute is absent or unparseable
|
||||
Skipped entirely if none of those fields are usable.
|
||||
UAC diameter range ← ImportedPart.UACDiameterRangemm, an 8-digit string with
|
||||
no separators (2 leading digits + 2 decimal digits for the
|
||||
minimum, then the same for the maximum) reformatted as
|
||||
AugmentedPart.uac_diameter_range_mm = "##.##-##.##". When
|
||||
present, also adds a second attachment point named
|
||||
"Objective" with a ClampConnection spanning that range.
|
||||
"""
|
||||
|
||||
import re
|
||||
@@ -49,6 +55,7 @@ from app.models.unc_thread import UncSeries
|
||||
from app.schemas.augmented_part import AugmentedPartSyncResult
|
||||
|
||||
ATTACHMENT_POINT_NAME = "Ocular"
|
||||
UAC_ATTACHMENT_POINT_NAME = "Objective"
|
||||
MM_PER_INCH = 25.4
|
||||
|
||||
# e.g.
|
||||
@@ -118,6 +125,49 @@ def _parse_thread_attribute(value: str) -> tuple[str, dict] | None:
|
||||
return None
|
||||
|
||||
|
||||
def _parse_uac_diameter_range(value: str | None) -> tuple[str, float, float] | None:
|
||||
"""Parse an 8-digit UACDiameterRangemm value into ("##.##-##.##", min, max).
|
||||
|
||||
The source field is 8 digits with no separators: the first 4 are the
|
||||
minimum diameter (2 whole + 2 decimal), the last 4 the maximum, e.g.
|
||||
"03505500" -> ("03.50-55.00", 3.5, 55.0).
|
||||
"""
|
||||
if not value:
|
||||
return None
|
||||
digits = "".join(re.findall(r"\d", value))
|
||||
if len(digits) != 8:
|
||||
return None
|
||||
min_str = f"{digits[0:2]}.{digits[2:4]}"
|
||||
max_str = f"{digits[4:6]}.{digits[6:8]}"
|
||||
return f"{min_str}-{max_str}", float(min_str), float(max_str)
|
||||
|
||||
|
||||
async def _add_uac_clamp_attachment_point(
|
||||
db: AsyncSession, ap: AugmentedPart, ip: ImportedPart
|
||||
) -> None:
|
||||
"""Add a second, "Objective"-named clamp attachment point derived from
|
||||
ImportedPart.UACDiameterRangemm, if that field is populated."""
|
||||
parsed = _parse_uac_diameter_range(ip.UACDiameterRangemm)
|
||||
if parsed is None:
|
||||
return
|
||||
_, min_mm, max_mm = parsed
|
||||
min_in = min_mm / MM_PER_INCH
|
||||
max_in = max_mm / MM_PER_INCH
|
||||
|
||||
apn = await _get_or_create_attachment_point_name(db, UAC_ATTACHMENT_POINT_NAME)
|
||||
clamp = await clamp_connection_crud.get_by_values(db, min_mm=min_mm, max_mm=max_mm)
|
||||
if clamp is None:
|
||||
clamp = await clamp_connection_crud.create(
|
||||
db, min_mm=min_mm, max_mm=max_mm, min_in=min_in, max_in=max_in
|
||||
)
|
||||
await attachment_point_crud.create(
|
||||
db,
|
||||
augmented_part_id=ap.id,
|
||||
attachment_point_name_id=apn.id,
|
||||
clamp_connection_id=clamp.id,
|
||||
)
|
||||
|
||||
|
||||
async def _get_or_create_attachment_point_name(db: AsyncSession, name: str):
|
||||
apn = await attachment_point_name_crud.get_by_name(db, name)
|
||||
if apn is None:
|
||||
@@ -233,6 +283,8 @@ async def sync_one(
|
||||
if manufacturer is None:
|
||||
manufacturer = await manufacturer_crud.create(db, name="Armament", url="")
|
||||
|
||||
uac_range = _parse_uac_diameter_range(ip.UACDiameterRangemm)
|
||||
|
||||
ap = AugmentedPart(
|
||||
sku=ip.InventoryID,
|
||||
description=description,
|
||||
@@ -241,6 +293,7 @@ async def sync_one(
|
||||
scope_model_id=None,
|
||||
part_type_id=part_type_id,
|
||||
sub_part_type_id=sub_part_type_id,
|
||||
uac_diameter_range_mm=uac_range[0] if uac_range else None,
|
||||
)
|
||||
db.add(ap)
|
||||
await db.flush()
|
||||
@@ -252,6 +305,7 @@ async def sync_one(
|
||||
)
|
||||
)
|
||||
await _add_attachment_point(db, ap, ip)
|
||||
await _add_uac_clamp_attachment_point(db, ap, ip)
|
||||
await db.commit()
|
||||
return ap
|
||||
|
||||
@@ -416,6 +470,8 @@ async def sync(db: AsyncSession) -> AugmentedPartSyncResult:
|
||||
if colour is None:
|
||||
colour = await part_colour_crud.create(db, name=colour_name)
|
||||
|
||||
uac_range = _parse_uac_diameter_range(ip.UACDiameterRangemm)
|
||||
|
||||
ap = AugmentedPart(
|
||||
sku=ip.InventoryID,
|
||||
description=description,
|
||||
@@ -424,6 +480,7 @@ async def sync(db: AsyncSession) -> AugmentedPartSyncResult:
|
||||
scope_model_id=None,
|
||||
part_type_id=part_type.id,
|
||||
sub_part_type_id=None,
|
||||
uac_diameter_range_mm=uac_range[0] if uac_range else None,
|
||||
)
|
||||
db.add(ap)
|
||||
await db.flush()
|
||||
@@ -435,6 +492,7 @@ async def sync(db: AsyncSession) -> AugmentedPartSyncResult:
|
||||
)
|
||||
)
|
||||
await _add_attachment_point(db, ap, ip)
|
||||
await _add_uac_clamp_attachment_point(db, ap, ip)
|
||||
created += 1
|
||||
|
||||
await db.commit()
|
||||
|
||||
Reference in new issue
Block a user