Add the dualpath-as-single-machine site toggle
Most facilities consider a Dualpath pair one physical dual-bay machine. New site setting dualpath_single_machine (default on): the machines list, dashboard counts, machines-by-type report, and floor map collapse each pair to its primary bay (lower assetnumber), with combined 2007 / 2008 labels; pagination totals stay honest. Detail pages remain per-bay and always show a dual-bay sibling banner linking the partner. Pair resolution lives in core services and joins the plugin contract surface (0.8.0 -> 0.9.0). On the WJ dataset: 31 pairs collapse, machine counts 262 -> 231, map 470 assets. Toggle verified live in both states, left on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -920,6 +920,18 @@ def get_assets_map():
|
||||
Asset.mapy.isnot(None)
|
||||
)
|
||||
|
||||
# Dualpath single-machine collapse: hide the secondary bay marker so a
|
||||
# dual-bay pair shows one marker; the primary carries the partner label.
|
||||
# Gated on the site setting (default on).
|
||||
from shopdb.core.services.dualpath import (
|
||||
resolve_dualpath_pairs, dualpath_single_machine_enabled)
|
||||
dualpath_collapse = None
|
||||
if dualpath_single_machine_enabled():
|
||||
dualpath_collapse = resolve_dualpath_pairs()
|
||||
if dualpath_collapse.secondaryassetids:
|
||||
query = query.filter(
|
||||
Asset.assetid.notin_(dualpath_collapse.secondaryassetids))
|
||||
|
||||
selected_assettype = request.args.get('assettype')
|
||||
|
||||
# Filter by asset type name
|
||||
@@ -1037,6 +1049,11 @@ def get_assets_map():
|
||||
if type_data:
|
||||
item['typedata'] = type_data
|
||||
|
||||
# combined-label partner for a collapsed dual-bay pair (label only)
|
||||
if dualpath_collapse:
|
||||
partner = dualpath_collapse.partnerbyasset.get(asset.assetid)
|
||||
item['dualpathpartner'] = partner['assetnumber'] if partner else None
|
||||
|
||||
data.append(item)
|
||||
|
||||
# Get filter options - these are small reference tables, no N+1 concern
|
||||
|
||||
@@ -19,10 +19,21 @@ _TYPE_CATEGORY = {
|
||||
|
||||
|
||||
def _count_by_type(assettype):
|
||||
return db.session.query(Asset).join(AssetType).filter(
|
||||
query = db.session.query(Asset).join(AssetType).filter(
|
||||
Asset.isactive == True,
|
||||
AssetType.assettype == assettype
|
||||
).count()
|
||||
)
|
||||
# Dualpath single-machine collapse: subtract the hidden secondary bays so a
|
||||
# dual-bay machine counts once. Only machines are ever Dualpath-paired, but
|
||||
# the AssetType filter above keeps this correct for any type. Default on.
|
||||
if assettype == 'machine':
|
||||
from shopdb.core.services.dualpath import (
|
||||
resolve_dualpath_pairs, dualpath_single_machine_enabled)
|
||||
if dualpath_single_machine_enabled():
|
||||
secondaryassetids = resolve_dualpath_pairs().secondaryassetids
|
||||
if secondaryassetids:
|
||||
query = query.filter(Asset.assetid.notin_(secondaryassetids))
|
||||
return query.count()
|
||||
|
||||
|
||||
@dashboard_bp.route('/summary', methods=['GET'])
|
||||
|
||||
@@ -64,6 +64,17 @@ def machines_by_type():
|
||||
if bu_id := request.args.get('businessunitid'):
|
||||
query = query.filter(Asset.businessunitid == int(bu_id))
|
||||
|
||||
# Dualpath single-machine collapse: exclude the secondary bay so a dual-bay
|
||||
# pair counts once per type bucket. Gated on the site setting (default on).
|
||||
from shopdb.core.services.dualpath import (
|
||||
resolve_dualpath_pairs, dualpath_single_machine_enabled)
|
||||
if dualpath_single_machine_enabled():
|
||||
secondaryassetids = resolve_dualpath_pairs().secondaryassetids
|
||||
if secondaryassetids:
|
||||
query = query.filter(
|
||||
db.or_(Machine.assetid.is_(None),
|
||||
Machine.assetid.notin_(secondaryassetids)))
|
||||
|
||||
query = query.group_by(
|
||||
MachineType.machinetypeid,
|
||||
MachineType.machinetype,
|
||||
|
||||
@@ -418,6 +418,13 @@ def build_default_settings():
|
||||
'category': 'site',
|
||||
'description': 'Regex a search term must match to be treated as an employee id. Invalid regex falls back to the default and never errors.'
|
||||
},
|
||||
{
|
||||
'key': 'dualpath_single_machine',
|
||||
'value': 'true',
|
||||
'valuetype': 'boolean',
|
||||
'category': 'site',
|
||||
'description': 'Treat a Dualpath pair (a dual-bay machine with one controller) as a single machine in lists, counts, and the floor map. The data model always keeps both bay records; detail pages stay per-bay with a sibling banner. Off = list and count both bays separately.'
|
||||
},
|
||||
{
|
||||
'key': 'printer_hostname_template',
|
||||
'value': 'Printer-{ip}.printer.geaerospace.net',
|
||||
|
||||
Reference in New Issue
Block a user