Spaces:
Sleeping
Sleeping
| """ | |
| 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})") | |