Card refinements
This commit is contained in:
@@ -399,13 +399,16 @@ def warranty_report():
|
||||
def dashboard_expiring():
|
||||
"""Warranties running out, and ones that already have.
|
||||
|
||||
Already-expired first, then soonest. Expired stays on the list rather than
|
||||
dropping off: a machine out of warranty is a purchasing decision someone
|
||||
still has to make, and silently removing it the day it lapses is how it gets
|
||||
missed entirely.
|
||||
Identified the way the floor identifies them: the PC's hostname and the
|
||||
MACHINE it drives. Nobody walks out looking for an asset number, and a
|
||||
warranty row for a bay PC is only actionable if you know which bay.
|
||||
|
||||
Horizon is a setting because 90 days suits a site that budgets quarterly and
|
||||
nobody else (ADR-015).
|
||||
No dates. "Expired" or "expiring" is the whole decision - the exact day
|
||||
matters when you are placing the order, which is what the warranty report
|
||||
is for, not when you are scanning a board.
|
||||
|
||||
Already-expired stays listed rather than dropping off the day it lapses,
|
||||
which is how one gets missed entirely.
|
||||
"""
|
||||
from shopdb.api import Setting
|
||||
|
||||
@@ -421,7 +424,7 @@ def dashboard_expiring():
|
||||
horizon = today + timedelta(days=days)
|
||||
|
||||
rows = []
|
||||
query = (db.session.query(Warranty, WarrantyAsset, Asset)
|
||||
query = (db.session.query(Warranty, Asset)
|
||||
.join(WarrantyAsset, WarrantyAsset.warrantyid == Warranty.warrantyid)
|
||||
.join(Asset, Asset.assetid == WarrantyAsset.assetid)
|
||||
.filter(Warranty.isactive.is_(True),
|
||||
@@ -429,16 +432,33 @@ def dashboard_expiring():
|
||||
Warranty.enddate <= horizon,
|
||||
Asset.isactive.is_(True)))
|
||||
|
||||
for warranty, _link, asset in query.all():
|
||||
for warranty, asset in query.all():
|
||||
remaining = (warranty.enddate - today).days
|
||||
# Reuses the machine lookup behind the warranty page's machine column,
|
||||
# so the board and the report agree about which bay a PC belongs to.
|
||||
machine = _related_machine(asset)
|
||||
rows.append({
|
||||
'assetid': asset.assetid,
|
||||
'assetnumber': asset.assetnumber or asset.name or str(asset.assetid),
|
||||
'enddate': warranty.enddate.isoformat(),
|
||||
'provider': warranty.provider,
|
||||
'daysleft': remaining,
|
||||
'hostname': _hostname(asset) or asset.assetnumber or asset.name,
|
||||
'machinenumber': machine['machinenumber'] if machine else None,
|
||||
'state': 'expired' if remaining < 0 else 'expiring',
|
||||
'daysleft': remaining,
|
||||
})
|
||||
|
||||
rows.sort(key=lambda r: r['daysleft'])
|
||||
return success_response(rows[:50])
|
||||
|
||||
|
||||
def _hostname(asset):
|
||||
"""The PC's hostname, when the covered asset is a PC.
|
||||
|
||||
Optional import: a lean site may not install the computers plugin, and a
|
||||
warranty on a printer or a machine has no hostname at all. Falls back to
|
||||
the asset number, which is what the row shows either way.
|
||||
"""
|
||||
try:
|
||||
from plugins.computers.models import Computer
|
||||
except ImportError:
|
||||
return None
|
||||
computer = Computer.query.filter_by(assetid=asset.assetid).first()
|
||||
return computer.hostname if computer else None
|
||||
|
||||
@@ -133,12 +133,13 @@ class WarrantyPlugin(BasePlugin):
|
||||
'empty': 'hide',
|
||||
'position': 50,
|
||||
'map': {
|
||||
'title': 'assetnumber',
|
||||
'title': 'hostname',
|
||||
'detail': 'state',
|
||||
'meta': [
|
||||
{'key': 'enddate', 'label': 'ends', 'format': 'date'},
|
||||
{'key': 'provider'},
|
||||
],
|
||||
# The bay, which is how the floor identifies the PC. No
|
||||
# date: expired or expiring is the whole decision when
|
||||
# scanning a board, and the exact day belongs on the report
|
||||
# you order from.
|
||||
'meta': [{'key': 'machinenumber', 'label': 'machine'}],
|
||||
'link': '/assets/{assetid}',
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user