WJ import loader: route LocationOnly by the islocationonly bit, not machinetypeid
Of the 158 machinetypeid=1 rows, only 24 carry the islocationonly bit (real named areas: DT Office, IT Closet, Materials, ...). The other 134 are active, modelled shop machines just left untyped - routing all 158 to Locations dropped those 134 real assets. Route on the bit instead; the 134 untyped rows import as machines with a null subtype (machinetypeid=1 is not a real machine subtype, so catalog skips seeding one). Also process asset routes in richness order (computer > measuringtool > network > machine) so on a duplicate machinenumber the PC - which carries installs + IP a bare untyped machine does not - wins first-come. Result on the scratch target: 933 assets (computer 663, machine 76, network 58, measuringtool 136), 24 locations (was mis-routing 158), installs 850 (was 653 - PCs no longer lose their numbers to bare machines), warranties 464, comms 461. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -54,15 +54,23 @@ MEASURING_MTYPES = {3, 5, 8, 23, 47, 48} # CMM, Wax, Eddy, Measuring, Inspe
|
|||||||
MEASURING_PCTYPES = {5, 6, 7, 8} # PC subtypes: CMM, Wax/Trace, Keyence, Genspect
|
MEASURING_PCTYPES = {5, 6, 7, 8} # PC subtypes: CMM, Wax/Trace, Keyence, Genspect
|
||||||
COMPUTER_MTYPES = {33, 20} # PC, Server
|
COMPUTER_MTYPES = {33, 20} # PC, Server
|
||||||
NETWORK_MTYPES = {16, 17, 18, 19, 46} # Access, IDF, Camera, Switch, Firewall
|
NETWORK_MTYPES = {16, 17, 18, 19, 46} # Access, IDF, Camera, Switch, Firewall
|
||||||
LOCATION_MTYPES = {1} # LocationOnly -> core Locations
|
|
||||||
SKIP_MTYPES = {15, 44} # Printer (printers table), USB (cmmc source)
|
SKIP_MTYPES = {15, 44} # Printer (printers table), USB (cmmc source)
|
||||||
|
# LocationOnly is the islocationonly BIT, not machinetypeid=1: of the 158 type-1
|
||||||
|
# rows only 24 carry the bit (real named areas). The other 134 are active,
|
||||||
|
# modelled shop machines just left untyped - they must become assets, not
|
||||||
|
# Locations.
|
||||||
|
|
||||||
|
|
||||||
|
def _truthy_bit(value):
|
||||||
|
"""MySQL bit(1) comes back from pymysql as bytes b'\\x00'/b'\\x01'."""
|
||||||
|
return value not in (0, None, False, b'\x00', b'', '0', '')
|
||||||
# classic controllertypeid -> (vendor, model) hand split; 1=TBD dropped
|
# classic controllertypeid -> (vendor, model) hand split; 1=TBD dropped
|
||||||
CONTROLLER_SPLIT = {2: ('Fanuc', '31i-MB'), 6: ('Fanuc', None),
|
CONTROLLER_SPLIT = {2: ('Fanuc', '31i-MB'), 6: ('Fanuc', None),
|
||||||
7: ('Okuma', None), 8: ('Makino', None)}
|
7: ('Okuma', None), 8: ('Makino', None)}
|
||||||
|
|
||||||
|
|
||||||
def _route(machinetypeid, pctypeid):
|
def _route(machinetypeid, pctypeid, islocationonly=False):
|
||||||
if machinetypeid in LOCATION_MTYPES:
|
if islocationonly:
|
||||||
return 'location'
|
return 'location'
|
||||||
if machinetypeid in SKIP_MTYPES:
|
if machinetypeid in SKIP_MTYPES:
|
||||||
return 'skip'
|
return 'skip'
|
||||||
@@ -74,7 +82,7 @@ def _route(machinetypeid, pctypeid):
|
|||||||
if machinetypeid == 33 and pctypeid in MEASURING_PCTYPES:
|
if machinetypeid == 33 and pctypeid in MEASURING_PCTYPES:
|
||||||
return 'measuringtool'
|
return 'measuringtool'
|
||||||
return 'computer'
|
return 'computer'
|
||||||
return 'machine'
|
return 'machine' # includes the 134 untyped (machinetypeid=1) shop machines
|
||||||
|
|
||||||
|
|
||||||
def _modeltype_category(machinetypeid):
|
def _modeltype_category(machinetypeid):
|
||||||
@@ -153,9 +161,11 @@ def stage_catalog(h):
|
|||||||
'SELECT machinetypeid, machinetype FROM machinetypes')
|
'SELECT machinetypeid, machinetype FROM machinetypes')
|
||||||
for mt in mtypes:
|
for mt in mtypes:
|
||||||
name = (mt['machinetype'] or '').strip()
|
name = (mt['machinetype'] or '').strip()
|
||||||
if not name:
|
|
||||||
continue
|
|
||||||
mtid = mt['machinetypeid']
|
mtid = mt['machinetypeid']
|
||||||
|
# machinetypeid=1 (LocationOnly) is not a real machine subtype - the
|
||||||
|
# untyped shop machines that carry it import with a null subtype.
|
||||||
|
if not name or mtid == 1:
|
||||||
|
continue
|
||||||
# modeltype (types the models catalog)
|
# modeltype (types the models catalog)
|
||||||
modeltypeid = _upsert(h, '/api/modeltypes',
|
modeltypeid = _upsert(h, '/api/modeltypes',
|
||||||
{'modeltype': name, 'category': _modeltype_category(mtid)},
|
{'modeltype': name, 'category': _modeltype_category(mtid)},
|
||||||
@@ -236,8 +246,15 @@ def stage_assets(h):
|
|||||||
if isinstance(row, dict) and row.get('assetnumber'):
|
if isinstance(row, dict) and row.get('assetnumber'):
|
||||||
seen_assetnumbers.add(row['assetnumber'].strip().lower())
|
seen_assetnumbers.add(row['assetnumber'].strip().lower())
|
||||||
|
|
||||||
|
# On a duplicate machinenumber, first-wins - so process the richer asset
|
||||||
|
# types first (a PC carries installs/IP a bare untyped machine does not).
|
||||||
|
route_rank = {'computer': 0, 'measuringtool': 1, 'network': 2, 'machine': 3}
|
||||||
|
machines = sorted(machines, key=lambda m: route_rank.get(
|
||||||
|
_route(m['machinetypeid'], m['pctypeid'], _truthy_bit(m['islocationonly'])), 4))
|
||||||
|
|
||||||
for m in machines:
|
for m in machines:
|
||||||
route = _route(m['machinetypeid'], m['pctypeid'])
|
route = _route(m['machinetypeid'], m['pctypeid'],
|
||||||
|
_truthy_bit(m['islocationonly']))
|
||||||
if route == 'location':
|
if route == 'location':
|
||||||
counts['skip_location'] += 1
|
counts['skip_location'] += 1
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user