""" Example: Setting up Inventory Requirements for a Project This script demonstrates how to configure inventory requirements for a typical FTTH (Fiber to the Home) installation project. """ # Example 1: FTTH Installation Project ftth_inventory_requirements = { # Equipment - Installed at customer sites "ONT-ZTE-F670L": { "code": "ONT-ZTE-F670L", "name": "ZTE F670L ONT Device", "description": "Fiber optic network terminal with 4 GE ports and WiFi", "usage_type": "installed", "unit": "pieces", "requires_serial_number": True, "category": "Equipment", "include_in_completion": True, "completion_field_label": "ONT Serial Number", "completion_required": True }, "ONT-HUAWEI-HG8546M": { "code": "ONT-HUAWEI-HG8546M", "name": "Huawei HG8546M ONT", "description": "GPON ONT with 4 GE ports, 2 POTS, WiFi", "usage_type": "installed", "unit": "pieces", "requires_serial_number": True, "category": "Equipment", "include_in_completion": True, "completion_field_label": "ONT Serial Number", "completion_required": True }, "ROUTER-TP-C6": { "code": "ROUTER-TP-C6", "name": "TP-Link Archer C6 Router", "description": "AC1200 Dual-band wireless router", "usage_type": "installed", "unit": "pieces", "requires_serial_number": True, "category": "Equipment", "include_in_completion": True, "completion_field_label": "Router Serial Number", "completion_required": False # Optional if ONT has WiFi }, # Cables - Consumed during installation "CABLE-FIBER-SM-DROP": { "code": "CABLE-FIBER-SM-DROP", "name": "Single Mode Fiber Drop Cable", "description": "Outdoor drop cable from pole to customer premises", "usage_type": "consumed", "unit": "meters", "requires_serial_number": False, "category": "Cable", "include_in_completion": False }, "CABLE-FIBER-SM-INDOOR": { "code": "CABLE-FIBER-SM-INDOOR", "name": "Single Mode Indoor Fiber Cable", "description": "Indoor fiber cable for in-home routing", "usage_type": "consumed", "unit": "meters", "requires_serial_number": False, "category": "Cable", "include_in_completion": False }, "CABLE-CAT6": { "code": "CABLE-CAT6", "name": "Cat6 Ethernet Cable", "description": "Category 6 UTP cable for LAN connections", "usage_type": "consumed", "unit": "meters", "requires_serial_number": False, "category": "Cable", "include_in_completion": False }, # Connectors & Consumables "CONNECTOR-SC-APC": { "code": "CONNECTOR-SC-APC", "name": "SC/APC Fiber Connector", "description": "Single mode SC/APC connector for termination", "usage_type": "consumed", "unit": "pieces", "requires_serial_number": False, "category": "Consumables", "include_in_completion": False }, "CONNECTOR-LC-UPC": { "code": "CONNECTOR-LC-UPC", "name": "LC/UPC Fiber Connector", "description": "Single mode LC/UPC connector", "usage_type": "consumed", "unit": "pieces", "requires_serial_number": False, "category": "Consumables", "include_in_completion": False }, "CONNECTOR-RJ45": { "code": "CONNECTOR-RJ45", "name": "RJ45 Ethernet Connector", "description": "Cat6 RJ45 connector for termination", "usage_type": "consumed", "unit": "pieces", "requires_serial_number": False, "category": "Consumables", "include_in_completion": False }, # Installation Materials "FASTENER-CABLE-CLIP": { "code": "FASTENER-CABLE-CLIP", "name": "Cable Clips", "description": "Plastic clips for securing drop cable", "usage_type": "consumed", "unit": "pieces", "requires_serial_number": False, "category": "Installation Materials", "include_in_completion": False }, "FASTENER-WALL-ANCHOR": { "code": "FASTENER-WALL-ANCHOR", "name": "Wall Anchors", "description": "Plastic wall anchors for mounting", "usage_type": "consumed", "unit": "pieces", "requires_serial_number": False, "category": "Installation Materials", "include_in_completion": False }, "TAPE-DUCT": { "code": "TAPE-DUCT", "name": "Duct Tape", "description": "Heavy-duty duct tape for cable management", "usage_type": "consumed", "unit": "rolls", "requires_serial_number": False, "category": "Installation Materials", "include_in_completion": False }, # Power & Protection "ADAPTER-POWER-12V": { "code": "ADAPTER-POWER-12V", "name": "12V Power Adapter", "description": "12V DC power adapter for ONT", "usage_type": "installed", "unit": "pieces", "requires_serial_number": False, "category": "Power", "include_in_completion": False }, "PROTECTOR-SURGE": { "code": "PROTECTOR-SURGE", "name": "Surge Protector", "description": "Electrical surge protector", "usage_type": "installed", "unit": "pieces", "requires_serial_number": False, "category": "Protection", "include_in_completion": False } } # Example 2: Fixed Wireless Project fixed_wireless_inventory_requirements = { "CPE-UBIQUITI-LITEBEAM": { "code": "CPE-UBIQUITI-LITEBEAM", "name": "Ubiquiti LiteBeam AC Gen2", "description": "5GHz airMAX CPE with integrated antenna", "usage_type": "installed", "unit": "pieces", "requires_serial_number": True, "category": "Equipment", "include_in_completion": True, "completion_field_label": "CPE Serial Number", "completion_required": True }, "ROUTER-MIKROTIK-RB750": { "code": "ROUTER-MIKROTIK-RB750", "name": "MikroTik hEX RB750Gr3", "description": "5-port Gigabit router", "usage_type": "installed", "unit": "pieces", "requires_serial_number": True, "category": "Equipment", "include_in_completion": True, "completion_field_label": "Router Serial Number", "completion_required": True }, "CABLE-CAT6-OUTDOOR": { "code": "CABLE-CAT6-OUTDOOR", "name": "Cat6 Outdoor Cable", "description": "Outdoor-rated Cat6 cable for CPE connection", "usage_type": "consumed", "unit": "meters", "requires_serial_number": False, "category": "Cable", "include_in_completion": False }, "POE-INJECTOR-24V": { "code": "POE-INJECTOR-24V", "name": "24V PoE Injector", "description": "Power over Ethernet injector for CPE", "usage_type": "installed", "unit": "pieces", "requires_serial_number": False, "category": "Power", "include_in_completion": False } } # Example 3: API Request to Create Project with Inventory Requirements import requests def create_project_with_inventory_requirements(): """ Example API call to create a project with inventory requirements """ api_url = "https://api.example.com/api/v1/projects" headers = { "Authorization": "Bearer YOUR_TOKEN_HERE", "Content-Type": "application/json" } project_data = { "title": "Nairobi FTTH Rollout Phase 1", "description": "Fiber to the home installations in Nairobi suburbs", "project_type": "customer_service", "service_type": "ftth", "client_id": "client-uuid-here", "contractor_id": "contractor-uuid-here", "planned_start_date": "2025-01-01", "planned_end_date": "2025-12-31", # Inventory requirements "inventory_requirements": ftth_inventory_requirements, # Photo requirements "photo_requirements": [ { "type": "before_installation", "required": True, "min_photos": 1, "max_photos": 3, "description": "Photo of installation site before work" }, { "type": "ont_installation", "required": True, "min_photos": 1, "max_photos": 2, "description": "Photo of installed ONT device" }, { "type": "speedtest", "required": True, "min_photos": 1, "max_photos": 1, "description": "Screenshot of speed test results" } ], # Activation requirements "activation_requirements": [ { "field": "customer_phone", "label": "Customer Phone Number", "type": "text", "required": True, "placeholder": "+254..." }, { "field": "speed_test_download_mbps", "label": "Download Speed (Mbps)", "type": "number", "required": True }, { "field": "speed_test_upload_mbps", "label": "Upload Speed (Mbps)", "type": "number", "required": True } ] } response = requests.post(api_url, json=project_data, headers=headers) return response.json() # Example 4: Receiving Inventory Batch def receive_inventory_batch(): """ Example API call to receive inventory batch The equipment_type must match a code from inventory_requirements """ api_url = "https://api.example.com/api/v1/inventory" headers = { "Authorization": "Bearer YOUR_TOKEN_HERE", "Content-Type": "application/json" } inventory_data = { "project_id": "project-uuid-here", "equipment_type": "ONT-ZTE-F670L", # Must match inventory requirement code "equipment_name": "ZTE F670L ONT Device", # Auto-populated from requirement "description": "Batch received from supplier", "quantity_received": 100, "unit": "pieces", "item_type": "equipment", "has_serial_numbers": True, "serial_numbers": [ {"serial": "HW12345001", "status": "available"}, {"serial": "HW12345002", "status": "available"}, # ... more serials ], "received_date": "2025-01-15", "unit_cost": 2500.00, "total_cost": 250000.00, "currency": "KES" } response = requests.post(api_url, json=inventory_data, headers=headers) return response.json() if __name__ == "__main__": print("FTTH Inventory Requirements:") print(f"Total items: {len(ftth_inventory_requirements)}") installed_items = [k for k, v in ftth_inventory_requirements.items() if v['usage_type'] == 'installed'] consumed_items = [k for k, v in ftth_inventory_requirements.items() if v['usage_type'] == 'consumed'] print(f"Installed items: {len(installed_items)}") print(f"Consumed items: {len(consumed_items)}") print("\nInstalled items (will appear in ticket completion):") for code in installed_items: item = ftth_inventory_requirements[code] if item.get('include_in_completion'): print(f" - {item['name']} ({code})")