fix: Replace all remaining hardcoded English reasoning with structured codes

This commit removes the last hardcoded English text from reasoning fields
across all backend services, completing the i18n implementation.

Changes by service:

Safety Stock Calculator (safety_stock_calculator.py):
- CALC:STATISTICAL_Z_SCORE - Statistical calculation with Z-score
- CALC:ADVANCED_VARIABILITY - Advanced formula with demand and lead time variability
- CALC:FIXED_PERCENTAGE - Fixed percentage of lead time demand
- All calculation methods now use structured codes with pipe-separated parameters

Price Forecaster (price_forecaster.py):
- PRICE_FORECAST:DECREASE_EXPECTED - Price expected to decrease
- PRICE_FORECAST:INCREASE_EXPECTED - Price expected to increase
- PRICE_FORECAST:HIGH_VOLATILITY - High price volatility detected
- PRICE_FORECAST:BELOW_AVERAGE - Current price below average (buy opportunity)
- PRICE_FORECAST:STABLE - Price stable, normal schedule
- All forecasts include relevant parameters (change_pct, days, etc.)

Optimization Utils (shared/utils/optimization.py):
- EOQ:BASE - Economic Order Quantity base calculation
- EOQ:MOQ_APPLIED - Minimum order quantity constraint applied
- EOQ:MAX_APPLIED - Maximum order quantity constraint applied
- TIER_PRICING:CURRENT_TIER - Current tier pricing
- TIER_PRICING:UPGRADED - Upgraded to higher tier for savings
- All optimizations include calculation parameters

Format: All codes use pattern "CATEGORY:TYPE|param1=value|param2=value"
This allows frontend to parse and translate with parameters while maintaining
technical accuracy for logging and debugging.

Frontend can now translate ALL reasoning codes across the entire system.
This commit is contained in:
Claude
2025-11-07 19:00:00 +00:00
parent ed7db4d4f2
commit be8cb20b18
3 changed files with 21 additions and 20 deletions

View File

@@ -498,35 +498,36 @@ class PriceForecaster:
# Calculate expected price change
expected_change_pct = ((forecast_mean - current_price) / current_price * 100) if current_price > 0 else 0
# Decision logic
# Decision logic with i18n-friendly reasoning codes
if expected_change_pct < -5:
# Price expected to drop >5%
action = 'wait'
reasoning = f'Price expected to decrease by {abs(expected_change_pct):.1f}% in next 30 days. Delay purchase.'
reasoning = f'PRICE_FORECAST:DECREASE_EXPECTED|change_pct={abs(expected_change_pct):.1f}|days=30'
urgency = 'low'
elif expected_change_pct > 5:
# Price expected to increase >5%
action = 'buy_now'
reasoning = f'Price expected to increase by {expected_change_pct:.1f}% in next 30 days. Purchase soon.'
reasoning = f'PRICE_FORECAST:INCREASE_EXPECTED|change_pct={expected_change_pct:.1f}|days=30'
urgency = 'high'
elif volatility['volatility_level'] == 'high':
# High volatility - wait for dip
action = 'wait_for_dip'
reasoning = f'High price volatility (CV={volatility["coefficient_of_variation"]:.2f}). Wait for favorable dip.'
reasoning = f'PRICE_FORECAST:HIGH_VOLATILITY|coefficient={volatility["coefficient_of_variation"]:.2f}'
urgency = 'medium'
elif current_price < price_stats['mean_price'] * 0.95:
# Currently below average
below_avg_pct = ((price_stats["mean_price"] - current_price) / price_stats["mean_price"] * 100)
action = 'buy_now'
reasoning = f'Current price{current_price:.2f} is {((price_stats["mean_price"] - current_price) / price_stats["mean_price"] * 100):.1f}% below average. Good buying opportunity.'
reasoning = f'PRICE_FORECAST:BELOW_AVERAGE|current_price={current_price:.2f}|below_avg_pct={below_avg_pct:.1f}'
urgency = 'medium'
else:
# Neutral
action = 'normal_purchase'
reasoning = 'Price stable. Follow normal procurement schedule.'
reasoning = 'PRICE_FORECAST:STABLE'
urgency = 'low'
# Optimal purchase timing

View File

@@ -117,10 +117,8 @@ class SafetyStockCalculator:
# Determine confidence
confidence = self._determine_confidence(demand_std_dev, lead_time_days)
reasoning = (
f"Service level {service_level*100:.1f}% (Z={z_score:.2f}) × "
f"Demand σ={demand_std_dev:.2f} ×{lead_time_days} days"
)
# Use calculation method as reasoning code with parameters
reasoning = f"CALC:STATISTICAL_Z_SCORE|service_level={service_level*100:.1f}|z_score={z_score:.2f}|demand_std={demand_std_dev:.2f}|lead_time={lead_time_days}"
return SafetyStockResult(
safety_stock_quantity=Decimal(str(round(safety_stock, 2))),
@@ -211,10 +209,8 @@ class SafetyStockCalculator:
confidence = 'high' if lead_time_std_dev > 0 else 'medium'
reasoning = (
f"Advanced formula considering both demand variability "
f"(σ={demand_std_dev:.2f}) and lead time variability (σ={lead_time_std_dev:.1f} days)"
)
# Use calculation method as reasoning code with parameters
reasoning = f"CALC:ADVANCED_VARIABILITY|demand_std={demand_std_dev:.2f}|lead_time_std={lead_time_std_dev:.1f}"
return SafetyStockResult(
safety_stock_quantity=Decimal(str(round(safety_stock, 2))),
@@ -249,7 +245,8 @@ class SafetyStockCalculator:
lead_time_demand = average_demand * lead_time_days
safety_stock = lead_time_demand * percentage
reasoning = f"{percentage*100:.0f}% of lead time demand ({lead_time_demand:.2f})"
# Use calculation method as reasoning code with parameters
reasoning = f"CALC:FIXED_PERCENTAGE|percentage={percentage*100:.0f}|lead_time_demand={lead_time_demand:.2f}"
return SafetyStockResult(
safety_stock_quantity=Decimal(str(round(safety_stock, 2))),