warranty: show the machine a covered PC drives, with a map on hover
A shopfloor PC is bought, warranted and replaced as a PC, but it is FOUND by the machine it drives - nobody walks the floor looking for an asset number. The warranty tables listed the covered asset and left the reader to work out where that is. Both tables gain a Machine # column. The payload resolves it by walking the asset relationship graph in BOTH directions: the canonical edge is PC --controls--> machine, but a dual-bay pair carries controls on both bays and hand-made links are not reliably oriented. Hovering the chip shows the floor map with the machine marked, so the row answers "where do I go" without opening anything. The blueprint follows the viewer's theme and the marker is placed from mapx/mapy as a percentage of the configured map dimensions, since the preview is a few hundred pixels wide rather than the full plan. It renders only while hovered, so a long table does not build a blueprint per row. A machine with no map position still gets its chip and says so, rather than being dropped: against real data 142 PCs resolve to a machine and 125 of those are placed, so 17 rows would otherwise have silently lost their number. The chip is deliberately not a link. /machines/:id is keyed by machineid, not assetid, and resolving one to the other here would make the warranty plugin import the machines plugin (ADR-014). Worth noting separately: the existing assetLink() in these tables already sends machine-type assets to /machines/<assetid>, which is that same mismatch and predates this change.
This commit is contained in:
@@ -33,12 +33,57 @@ def _parse_date(value):
|
||||
return None
|
||||
|
||||
|
||||
def _related_machine(asset):
|
||||
"""The machine a covered asset is associated with, or None.
|
||||
|
||||
A shopfloor PC is bought, warranted and replaced as a PC, but it is FOUND
|
||||
by the machine it drives - nobody walks the floor looking for an asset
|
||||
number. So a warranty row for a PC carries the machine's number, and its
|
||||
map position so the row can point at where to go.
|
||||
|
||||
Walks the asset relationship graph in BOTH directions: the canonical edge is
|
||||
PC --controls--> machine, but a dual-bay pair carries controls on both bays
|
||||
and hand-made links are not guaranteed to be oriented. Returns the first
|
||||
active related asset whose type is 'machine'.
|
||||
"""
|
||||
from shopdb.api import Asset as CoreAsset
|
||||
|
||||
related = []
|
||||
for rel in (getattr(asset, 'outgoing_relationships', None) or []):
|
||||
if rel.isactive and rel.targetasset:
|
||||
related.append(rel.targetasset)
|
||||
for rel in (getattr(asset, 'incoming_relationships', None) or []):
|
||||
if rel.isactive and rel.sourceasset:
|
||||
related.append(rel.sourceasset)
|
||||
|
||||
for candidate in related:
|
||||
typename = candidate.assettype.assettype if candidate.assettype else None
|
||||
if typename != 'machine':
|
||||
continue
|
||||
return {
|
||||
'assetid': candidate.assetid,
|
||||
'machinenumber': candidate.assetnumber,
|
||||
'name': candidate.name,
|
||||
# Map position for the hover preview. Either may be None: a machine
|
||||
# that has never been placed on the floor map still has a number
|
||||
# worth showing, so the caller decides what to do with a missing
|
||||
# position rather than the row being dropped.
|
||||
'mapx': candidate.mapx,
|
||||
'mapy': candidate.mapy,
|
||||
'locationid': candidate.locationid,
|
||||
'locationname': (candidate.location.locationname
|
||||
if candidate.location else None),
|
||||
}
|
||||
return None
|
||||
|
||||
|
||||
def _asset_summary(asset):
|
||||
return {
|
||||
'assetid': asset.assetid,
|
||||
'assetnumber': asset.assetnumber,
|
||||
'name': asset.name,
|
||||
'assettypename': asset.assettype.assettype if asset.assettype else None,
|
||||
'machine': _related_machine(asset),
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user