|
|
import json |
|
|
import os |
|
|
from typing import List, Dict, Any |
|
|
|
|
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) |
|
|
DATA_DIR = os.path.join(BASE_DIR, 'data', 'extracted') |
|
|
MASTER_INDEX_PATH = os.path.join(BASE_DIR, 'data', 'master_index.json') |
|
|
|
|
|
|
|
|
_MASTER_INDEX_CACHE = [] |
|
|
|
|
|
def init_master_index(): |
|
|
"""Loads the index into the global cache variable.""" |
|
|
global _MASTER_INDEX_CACHE |
|
|
if os.path.exists(MASTER_INDEX_PATH): |
|
|
with open(MASTER_INDEX_PATH, 'r') as f: |
|
|
_MASTER_INDEX_CACHE = json.load(f) |
|
|
print(f"Loaded {len(_MASTER_INDEX_CACHE)} vendors into memory.") |
|
|
else: |
|
|
print("Warning: master_index.json not found.") |
|
|
_MASTER_INDEX_CACHE = [] |
|
|
|
|
|
def get_master_index(): |
|
|
"""Returns the cached index.""" |
|
|
return _MASTER_INDEX_CACHE |
|
|
|
|
|
PRESET_WEIGHTS = { |
|
|
'resource-saving': {'quantity': 0.1, 'cost': 0.5, 'delivery': 0.1, 'quality': 0.1, 'reliability': 0.2}, |
|
|
'time': {'quantity': 0.1, 'cost': 0.1, 'delivery': 0.5, 'quality': 0.1, 'reliability': 0.2}, |
|
|
'quality': {'quantity': 0.1, 'cost': 0.1, 'delivery': 0.1, 'quality': 0.5, 'reliability': 0.2}, |
|
|
'quantity': {'quantity': 0.5, 'cost': 0.1, 'delivery': 0.1, 'quality': 0.1, 'reliability': 0.2}, |
|
|
'default': {'quantity': 0.2, 'cost': 0.2, 'delivery': 0.2, 'quality': 0.2, 'reliability': 0.2} |
|
|
} |
|
|
|
|
|
def score_vendors(vendors: List[Dict], target_qty: int, preferences: List[str]): |
|
|
w = PRESET_WEIGHTS['default'].copy() |
|
|
|
|
|
|
|
|
if preferences: |
|
|
active_weights = [PRESET_WEIGHTS.get(p, PRESET_WEIGHTS['default']) for p in preferences] |
|
|
if active_weights: |
|
|
for key in w: |
|
|
w[key] = sum(aw[key] for aw in active_weights) / len(active_weights) |
|
|
|
|
|
scored = [] |
|
|
for v in vendors: |
|
|
|
|
|
s_qty = min(1.0, v.get('availableQty', 0) / target_qty) if target_qty > 0 else 0 |
|
|
s_cost = 1.0 / (1.0 + (v.get('landedCost', 0) / 100)) |
|
|
s_delivery = 1.0 / (1.0 + (v.get('deliveryDays', 0) / 7)) |
|
|
s_quality = v.get('qualityScore', 0) / 10.0 |
|
|
s_reliability = v.get('reliabilityScore', 0) / 10.0 |
|
|
|
|
|
final_score = ( |
|
|
w['quantity'] * s_qty + |
|
|
w['cost'] * s_cost + |
|
|
w['delivery'] * s_delivery + |
|
|
w['quality'] * s_quality + |
|
|
w['reliability'] * s_reliability |
|
|
) |
|
|
|
|
|
v_copy = v.copy() |
|
|
v_copy['score'] = round(final_score * 10, 2) |
|
|
scored.append(v_copy) |
|
|
|
|
|
return sorted(scored, key=lambda x: x['score'], reverse=True) |