Dashboard cards: rebuild deployable dists
This commit is contained in:
@@ -994,3 +994,73 @@ def dashboard_quiet():
|
||||
# down the list, not the order the rows came out of the table.
|
||||
rows.sort(key=lambda r: (r['quietdays'] is not None, -(r['quietdays'] or 0)))
|
||||
return success_response(rows[:50])
|
||||
|
||||
|
||||
@computers_bp.route('/dashboard/sharedmachines', methods=['GET'])
|
||||
@jwt_required()
|
||||
@require_permission('computers.view')
|
||||
def dashboard_sharedmachines():
|
||||
"""Machine numbers claimed by more than one PC, with nothing filed under
|
||||
them.
|
||||
|
||||
Several devices genuinely sharing a number is legitimate - part markers do
|
||||
it - and those are modelled: each device is its own asset filed `partof` the
|
||||
operation, so the operation has CHILD ASSETS. Two PCs carrying the same
|
||||
machine number by mistake looks identical from a count and has none. That
|
||||
distinction is the whole card; without it this would list correct data
|
||||
alongside faults and get ignored.
|
||||
|
||||
Promoted from `flask relationships check-shared-machines`, which answers the
|
||||
same question and which nobody will remember to run. This one found seven
|
||||
mis-numbered bays that had been that way for weeks.
|
||||
"""
|
||||
from shopdb.api import AssetRelationship, RelationshipType
|
||||
from sqlalchemy.orm import aliased
|
||||
|
||||
controls = RelationshipType.query.filter_by(
|
||||
relationshiptype='controls').first()
|
||||
partof = RelationshipType.query.filter_by(relationshiptype='partof').first()
|
||||
if not controls:
|
||||
return success_response([])
|
||||
|
||||
pcasset = aliased(Asset)
|
||||
machineasset = aliased(Asset)
|
||||
|
||||
rows = (db.session.query(machineasset.assetid, machineasset.assetnumber,
|
||||
pcasset.assetnumber)
|
||||
.select_from(AssetRelationship)
|
||||
.join(pcasset, AssetRelationship.sourceassetid == pcasset.assetid)
|
||||
.join(machineasset,
|
||||
AssetRelationship.targetassetid == machineasset.assetid)
|
||||
.filter(AssetRelationship.relationshiptypeid ==
|
||||
controls.relationshiptypeid,
|
||||
AssetRelationship.label == 'collector:machine',
|
||||
AssetRelationship.isactive.is_(True))
|
||||
.all())
|
||||
|
||||
bymachine = {}
|
||||
for assetid, machinenumber, pcnumber in rows:
|
||||
bymachine.setdefault((assetid, machinenumber), []).append(pcnumber)
|
||||
|
||||
out = []
|
||||
for (assetid, machinenumber), pcs in bymachine.items():
|
||||
if len(pcs) < 2:
|
||||
continue
|
||||
children = 0
|
||||
if partof:
|
||||
children = (AssetRelationship.query
|
||||
.filter_by(targetassetid=assetid,
|
||||
relationshiptypeid=partof.relationshiptypeid,
|
||||
isactive=True)
|
||||
.count())
|
||||
if children:
|
||||
continue # modelled: the devices are assets in their own right
|
||||
out.append({
|
||||
'assetid': assetid,
|
||||
'machinenumber': machinenumber,
|
||||
'pccount': len(pcs),
|
||||
'pcs': ', '.join(sorted(p for p in pcs if p)),
|
||||
})
|
||||
|
||||
out.sort(key=lambda r: -r['pccount'])
|
||||
return success_response(out)
|
||||
|
||||
Reference in New Issue
Block a user