#!/usr/bin/env python3 """ Fix Equipment Data from Equipment Names Extracts correct vendor/model/type from Equipment_Name column instead of PC/Controller columns """ import csv import re import pymysql DB_CONFIG = { 'host': 'localhost', 'user': '570005354', 'password': '570005354', 'database': 'shopdb', 'charset': 'utf8mb4', 'cursorclass': pymysql.cursors.DictCursor } # Vendor/Model extraction from equipment names EQUIPMENT_PATTERNS = [ # OKUMA machines { 'pattern': r'(?i)OKUMA\s+(&\s+HOWA\s+)?2SP\s+V\d+', 'vendor': 'Okuma', 'model': '2SP V80', 'type': 'Vertical Lathe' }, { 'pattern': r'(?i)OKUMA\s+VTM\s+\d+', 'vendor': 'Okuma', 'model': 'VTM 100', 'type': 'Vertical Lathe' }, { 'pattern': r'(?i)OKUMA\s+LOC\s+650.*4.?Axis.*SimulTurn', 'vendor': 'Okuma', 'model': 'LOC 650', 'type': 'Mill Turn' }, { 'pattern': r'(?i)OKUMA\s+LB\s*\d+', 'vendor': 'Okuma', 'model_extract': r'LB\s*\d+[A-Z]*', 'type': 'Lathe' }, # HWACHEON machines { 'pattern': r'(?i)HWACHEON\s+VT[L]?\s*\d+', 'vendor': 'Hwacheon', 'model_extract': r'VT[L]?\s*\d+[A-Z]*', 'type': 'Vertical Lathe' }, # HEXAGON/Brown&Sharpe CMMs { 'pattern': r'(?i)(Brown.?Sharpe|HEXAGON).*CMM', 'vendor': 'Hexagon Metrology', 'model_extract': r'(?:GLOBAL\s+)?(?:ADVANTAGE\s+)?(?:FX\s+)?[\d\s\.]+(?:SF)?', 'type': 'CMM' }, # Mitutoyo CMMs { 'pattern': r'(?i)Mitutoyo\s+C\s*\d+', 'vendor': 'Mitutoyo', 'model': 'C 4500', 'type': 'CMM' }, # KEYENCE Vision Systems { 'pattern': r'(?i)KEYENCE\s+(VHX|VR)\s*\d+', 'vendor': 'KEYENCE', 'model_extract': r'V[HR]X?\s*\d+', 'type': 'Measuring Machine' }, # OKK Mills { 'pattern': r'(?i)OKK\s+VP\d+.*5.*AXIS', 'vendor': 'OKK', 'model_extract': r'VP\d+', 'type': '5-axis Mill' }, ] def connect_db(): conn = pymysql.connect(**DB_CONFIG) print(f"āœ“ Connected to database: {DB_CONFIG['database']}") return conn def get_or_create_vendor(cursor, vendor_name): if not vendor_name: return None cursor.execute("SELECT vendorid FROM vendors WHERE vendor = %s", (vendor_name,)) result = cursor.fetchone() if result: return result['vendorid'] cursor.execute("INSERT INTO vendors (vendor, isactive, ismachine) VALUES (%s, 1, 1)", (vendor_name,)) return cursor.lastrowid def get_or_create_model(cursor, model_name, vendor_id): if not model_name or not vendor_id: return None cursor.execute("SELECT modelnumberid FROM models WHERE modelnumber = %s AND vendorid = %s", (model_name, vendor_id)) result = cursor.fetchone() if result: return result['modelnumberid'] cursor.execute("INSERT INTO models (modelnumber, vendorid, isactive) VALUES (%s, %s, 1)", (model_name, vendor_id)) return cursor.lastrowid def get_machine_type_id(cursor, machine_type_name): cursor.execute("SELECT machinetypeid FROM machinetypes WHERE machinetype = %s", (machine_type_name,)) result = cursor.fetchone() return result['machinetypeid'] if result else None def extract_equipment_info(equipment_name): """Extract vendor, model, and type from equipment name""" if not equipment_name: return None, None, None for pattern_info in EQUIPMENT_PATTERNS: match = re.search(pattern_info['pattern'], equipment_name) if match: vendor = pattern_info.get('vendor') # Extract model if 'model_extract' in pattern_info: model_match = re.search(pattern_info['model_extract'], equipment_name, re.IGNORECASE) model = model_match.group(0).strip() if model_match else pattern_info.get('model') else: model = pattern_info.get('model') machine_type = pattern_info.get('type') return vendor, model, machine_type return None, None, None def main(): print("="*70) print("FIX EQUIPMENT FROM EQUIPMENT NAMES") print("="*70) conn = connect_db() cursor = conn.cursor() # Read inventory with open('/tmp/inventory_restructured.csv', 'r', encoding='utf-8') as f: reader = csv.DictReader(f) equipment_rows = [row for row in reader if row.get('Row_Type') == 'Equipment'] print(f"āœ“ Found {len(equipment_rows)} equipment records\n") updates = 0 skipped = 0 for row in equipment_rows: machine_number = row.get('Machine_Number', '').strip() equipment_name = row.get('Equipment_Name', '').strip() if not machine_number or not equipment_name: continue # Check if machine exists cursor.execute("SELECT machineid, machinetypeid FROM machines WHERE machinenumber = %s", (machine_number,)) machine = cursor.fetchone() if not machine: continue # Extract equipment info from name vendor_name, model_name, machine_type_name = extract_equipment_info(equipment_name) if not vendor_name: skipped += 1 continue # Get/create vendor and model vendor_id = get_or_create_vendor(cursor, vendor_name) model_id = get_or_create_model(cursor, model_name, vendor_id) if model_name else None type_id = get_machine_type_id(cursor, machine_type_name) if machine_type_name else None # Build UPDATE update_parts = [] values = [] if model_id: update_parts.append("modelnumberid = %s") values.append(model_id) if type_id: update_parts.append("machinetypeid = %s") values.append(type_id) if update_parts: update_parts.append("lastupdated = NOW()") values.append(machine['machineid']) sql = f"UPDATE machines SET {', '.join(update_parts)} WHERE machineid = %s" cursor.execute(sql, tuple(values)) conn.commit() print(f"āœ“ {machine_number}: {equipment_name[:50]}") print(f" Vendor: {vendor_name}, Model: {model_name}, Type: {machine_type_name}") updates += 1 else: skipped += 1 # Summary print("\n" + "="*70) print("SUMMARY") print("="*70) print(f"Equipment updated: {updates}") print(f"Equipment skipped: {skipped}") # Show LocationOnly count cursor.execute(""" SELECT COUNT(*) as count FROM machines m JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid WHERE mt.machinetype = 'LocationOnly' AND m.isactive = 1 """) location_only = cursor.fetchone()['count'] print(f"\nLocationOnly remaining: {location_only}") cursor.close() conn.close() print("\nāœ“ Complete!") if __name__ == '__main__': main()