feat: add repair parts tracking
This commit is contained in:
1 parent
6e550c1c13
commit
eab9646960
23 files changed
+2386
-4
No files matched your search
@@ -597,6 +597,184 @@ class RepairRepository:
|
||||
row = cur.fetchone()
|
||||
return dict(row)
|
||||
|
||||
def lock_component_for_update(self, component_id: UUID) -> dict | None:
|
||||
with self._connection_scope() as connection:
|
||||
with connection.cursor(row_factory=dict_row) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT
|
||||
id,
|
||||
component_type,
|
||||
asset_id,
|
||||
manufacturer,
|
||||
model,
|
||||
manufacturer_serial
|
||||
FROM components
|
||||
WHERE id = %s
|
||||
FOR UPDATE
|
||||
""",
|
||||
(component_id,),
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
def create_repair_part(
|
||||
self,
|
||||
*,
|
||||
repair_part_id: UUID,
|
||||
repair_id: UUID,
|
||||
consumable_description: str | None,
|
||||
quantity: object | None,
|
||||
unit: str | None,
|
||||
component: Mapping[str, Any] | None,
|
||||
notes: str | None,
|
||||
recorded_event: Mapping[str, Any],
|
||||
) -> dict:
|
||||
with self._connection_scope(write=True) as connection:
|
||||
with connection.cursor(row_factory=dict_row) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
INSERT INTO repair_parts (
|
||||
id,
|
||||
repair_id,
|
||||
consumable_description,
|
||||
quantity,
|
||||
unit,
|
||||
component_id,
|
||||
component_type_snapshot,
|
||||
component_asset_id_snapshot,
|
||||
component_manufacturer_snapshot,
|
||||
component_model_snapshot,
|
||||
component_manufacturer_serial_snapshot,
|
||||
notes,
|
||||
recorded_by,
|
||||
recorded_at,
|
||||
recorded_event_id
|
||||
)
|
||||
VALUES (
|
||||
%s, %s, %s, %s, %s, %s, %s, %s,
|
||||
%s, %s, %s, %s, %s, %s, %s
|
||||
)
|
||||
RETURNING *
|
||||
""",
|
||||
(
|
||||
repair_part_id,
|
||||
repair_id,
|
||||
consumable_description,
|
||||
quantity,
|
||||
unit,
|
||||
component.get("id") if component else None,
|
||||
component.get("component_type") if component else None,
|
||||
component.get("asset_id") if component else None,
|
||||
component.get("manufacturer") if component else None,
|
||||
component.get("model") if component else None,
|
||||
component.get("manufacturer_serial") if component else None,
|
||||
notes,
|
||||
recorded_event["created_by"],
|
||||
recorded_event["created_at"],
|
||||
recorded_event["id"],
|
||||
),
|
||||
)
|
||||
return dict(cur.fetchone())
|
||||
|
||||
def get_repair_part(
|
||||
self,
|
||||
repair_id: UUID,
|
||||
repair_part_id: UUID,
|
||||
) -> dict | None:
|
||||
with self._connection_scope() as connection:
|
||||
with connection.cursor(row_factory=dict_row) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT part.*, event.sequence AS recorded_event_sequence
|
||||
FROM repair_parts AS part
|
||||
JOIN repair_events AS event
|
||||
ON event.id = part.recorded_event_id
|
||||
WHERE part.repair_id = %s AND part.id = %s
|
||||
""",
|
||||
(repair_id, repair_part_id),
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
def get_repair_parts(self, repair_id: UUID) -> list[dict] | None:
|
||||
with self._connection_scope() as connection:
|
||||
with connection.cursor(row_factory=dict_row) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT
|
||||
repair.id AS existing_repair_id,
|
||||
part.*,
|
||||
event.sequence AS recorded_event_sequence
|
||||
FROM repairs AS repair
|
||||
LEFT JOIN repair_parts AS part
|
||||
ON part.repair_id = repair.id
|
||||
LEFT JOIN repair_events AS event
|
||||
ON event.id = part.recorded_event_id
|
||||
WHERE repair.id = %s
|
||||
ORDER BY event.sequence ASC, part.id ASC
|
||||
""",
|
||||
(repair_id,),
|
||||
)
|
||||
rows = [dict(row) for row in cur.fetchall()]
|
||||
|
||||
if not rows:
|
||||
return None
|
||||
return [row for row in rows if row.get("id") is not None]
|
||||
|
||||
def lock_repair_part_for_update(
|
||||
self,
|
||||
repair_id: UUID,
|
||||
repair_part_id: UUID,
|
||||
) -> dict | None:
|
||||
with self._connection_scope() as connection:
|
||||
with connection.cursor(row_factory=dict_row) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT *
|
||||
FROM repair_parts
|
||||
WHERE repair_id = %s AND id = %s
|
||||
FOR UPDATE
|
||||
""",
|
||||
(repair_id, repair_part_id),
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
def void_repair_part(
|
||||
self,
|
||||
repair_id: UUID,
|
||||
repair_part_id: UUID,
|
||||
*,
|
||||
reason: str,
|
||||
void_event: Mapping[str, Any],
|
||||
) -> dict | None:
|
||||
with self._connection_scope(write=True) as connection:
|
||||
with connection.cursor(row_factory=dict_row) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
UPDATE repair_parts
|
||||
SET voided_by = %s,
|
||||
voided_at = %s,
|
||||
void_reason = %s,
|
||||
void_event_id = %s
|
||||
WHERE repair_id = %s
|
||||
AND id = %s
|
||||
AND voided_at IS NULL
|
||||
RETURNING *
|
||||
""",
|
||||
(
|
||||
void_event["created_by"],
|
||||
void_event["created_at"],
|
||||
reason,
|
||||
void_event["id"],
|
||||
repair_id,
|
||||
repair_part_id,
|
||||
),
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return dict(row) if row else None
|
||||
|
||||
def get_repair_detail(self, repair_id: UUID) -> dict | None:
|
||||
with self._connection_scope() as connection:
|
||||
with connection.cursor(row_factory=dict_row) as cur:
|
||||
|
||||
Reference in new issue
Block a user