Files
bakery-ia/shared/demo/fixtures/professional/enhance_procurement_data.py
Urtzi Alfaro 9f3b39bd28 Add comprehensive documentation and final improvements
Documentation Added:
- AI_INSIGHTS_DEMO_SETUP_GUIDE.md: Complete setup guide for demo sessions
- AI_INSIGHTS_DATA_FLOW.md: Architecture and data flow diagrams
- AI_INSIGHTS_QUICK_START.md: Quick reference guide
- DEMO_SESSION_ANALYSIS_REPORT.md: Detailed analysis of demo session d67eaae4
- ROOT_CAUSE_ANALYSIS_AND_FIXES.md: Complete analysis of 8 issues (6 fixed, 2 analyzed)
- COMPLETE_FIX_SUMMARY.md: Executive summary of all fixes
- FIX_MISSING_INSIGHTS.md: Forecasting and procurement fix guide
- FINAL_STATUS_SUMMARY.md: Status overview
- verify_fixes.sh: Automated verification script
- enhance_procurement_data.py: Procurement data enhancement script

Service Improvements:
- Demo session cleanup worker: Use proper settings for Redis configuration with TLS/auth
- Procurement service: Add Redis initialization with proper error handling and cleanup
- Production fixture: Remove duplicate worker assignments (cleaned 56 duplicates)
- Orchestrator fixture: Add purchase order metadata for better tracking

Impact:
- Complete documentation for troubleshooting and setup
- Improved Redis connection handling across services
- Clean production data without duplicates
- Better error handling and logging

🤖 Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 11:32:45 +01:00

210 lines
6.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Enhance Procurement Data for AI Insights
Adds purchase order items with price trends to enable procurement insights
"""
import json
import random
from pathlib import Path
# Set seed for reproducibility
random.seed(42)
# Price trend data (realistic price movements over 90 days)
INGREDIENTS_WITH_TRENDS = [
{
"id": "10000000-0000-0000-0000-000000000001",
"name": "Harina de Trigo T55",
"base_price": 0.85,
"trend": 0.08, # 8% increase over 90 days
"variability": 0.02,
"unit": "kg"
},
{
"id": "10000000-0000-0000-0000-000000000002",
"name": "Harina de Trigo T65",
"base_price": 0.95,
"trend": 0.06, # 6% increase
"variability": 0.02,
"unit": "kg"
},
{
"id": "10000000-0000-0000-0000-000000000011",
"name": "Mantequilla sin Sal",
"base_price": 6.50,
"trend": 0.12, # 12% increase (highest)
"variability": 0.05,
"unit": "kg"
},
{
"id": "10000000-0000-0000-0000-000000000012",
"name": "Leche Entera Fresca",
"base_price": 0.95,
"trend": -0.03, # 3% decrease (seasonal surplus)
"variability": 0.02,
"unit": "L"
},
{
"id": "10000000-0000-0000-0000-000000000021",
"name": "Levadura Fresca",
"base_price": 4.20,
"trend": 0.04, # 4% increase
"variability": 0.03,
"unit": "kg"
},
{
"id": "10000000-0000-0000-0000-000000000032",
"name": "Azúcar Blanco",
"base_price": 1.10,
"trend": 0.02, # 2% increase (stable)
"variability": 0.01,
"unit": "kg"
},
]
def calculate_price(ingredient, days_ago):
"""
Calculate price based on linear trend + random variability
Args:
ingredient: Dict with base_price, trend, variability
days_ago: Number of days in the past
Returns:
Price at that point in time
"""
# Apply trend proportionally based on how far back in time
# If trend is 8% over 90 days, price 45 days ago had 4% increase from base
trend_factor = 1 + (ingredient["trend"] * (90 - days_ago) / 90)
# Add random variability
variability = random.uniform(-ingredient["variability"], ingredient["variability"])
price = ingredient["base_price"] * trend_factor * (1 + variability)
return round(price, 2)
def parse_days_ago(order_date_str):
"""Parse order_date to extract days ago"""
if 'BASE_TS' in order_date_str:
if '- ' in order_date_str:
# Extract number from "BASE_TS - 1d" or "BASE_TS - 1h"
parts = order_date_str.split('- ')[1]
if 'd' in parts:
try:
return int(parts.split('d')[0])
except:
pass
elif 'h' in parts:
# Hours - treat as 0 days
return 0
elif '+ ' in order_date_str:
# Future date - treat as 0 days ago (current price)
return 0
return 30 # Default fallback
def add_items_to_pos():
"""Add items arrays to purchase orders with realistic price trends"""
fixture_path = Path(__file__).parent / "07-procurement.json"
print("🔧 Enhancing Procurement Data for AI Insights...")
print()
# Load existing data
with open(fixture_path, 'r', encoding='utf-8') as f:
data = json.load(f)
pos = data.get('purchase_orders', [])
print(f"📦 Found {len(pos)} purchase orders")
print()
items_added = 0
for i, po in enumerate(pos):
# Parse order date to get days ago
order_date_str = po.get('order_date', 'BASE_TS - 1d')
days_ago = parse_days_ago(order_date_str)
# Select 2-4 random ingredients for this PO
num_items = random.randint(2, 4)
selected_ingredients = random.sample(INGREDIENTS_WITH_TRENDS, k=num_items)
items = []
po_subtotal = 0.0
for ingredient in selected_ingredients:
# Calculate price at this point in time
unit_price = calculate_price(ingredient, days_ago)
# Order quantity (realistic for ingredient type)
if ingredient["unit"] == "kg":
quantity = random.randint(100, 500)
else: # Liters
quantity = random.randint(50, 200)
total_price = round(quantity * unit_price, 2)
po_subtotal += total_price
items.append({
"ingredient_id": ingredient["id"],
"ingredient_name": ingredient["name"],
"ordered_quantity": float(quantity),
"unit": ingredient["unit"],
"unit_price": unit_price,
"total_price": total_price,
"received_quantity": None,
"status": "pending" if po.get('status') != 'delivered' else "received"
})
# Add items to PO
po['items'] = items
# Update PO totals to match items
po['subtotal'] = round(po_subtotal, 2)
tax_rate = 0.21 # 21% IVA in Spain
po['tax_amount'] = round(po_subtotal * tax_rate, 2)
po['shipping_cost'] = 15.0 if po_subtotal < 500 else 20.0
po['total_amount'] = round(po['subtotal'] + po['tax_amount'] + po['shipping_cost'], 2)
items_added += len(items)
print(f" ✓ PO-{i+1} ({order_date_str}): {len(items)} items, €{po['total_amount']:.2f} total")
# Save back
with open(fixture_path, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print()
print("=" * 60)
print("✅ PROCUREMENT DATA ENHANCEMENT COMPLETE")
print("=" * 60)
print()
print(f"📊 SUMMARY:")
print(f" • Purchase orders enhanced: {len(pos)}")
print(f" • Total items added: {items_added}")
print(f" • Average items per PO: {items_added / len(pos):.1f}")
print()
print("🎯 PRICE TRENDS ADDED:")
for ing in INGREDIENTS_WITH_TRENDS:
direction = "" if ing["trend"] > 0 else ""
print(f" {direction} {ing['name']}: {ing['trend']*100:+.1f}% over 90 days")
print()
print("🚀 PROCUREMENT INSIGHTS READY:")
print(" ✓ Price Forecaster: Can detect trends & recommend actions")
print(" ✓ Supplier Performance: Can analyze delivery reliability")
print(" ✓ Cost Optimizer: Can identify bulk buying opportunities")
print()
print("Next steps:")
print(" 1. Create new demo session")
print(" 2. Wait 60 seconds for AI models")
print(" 3. Check for procurement insights (expect 1-2)")
print()
if __name__ == "__main__":
add_items_to_pos()