fix: pick best targeted momo offer per pchome item
All checks were successful
CD Pipeline / deploy (push) Successful in 1m4s

This commit is contained in:
OoO
2026-06-19 00:55:35 +08:00
parent 9d84cbfd43
commit bed4488a72
3 changed files with 103 additions and 3 deletions

View File

@@ -712,6 +712,31 @@ def _targeted_candidate_needs_review(candidate: dict[str, Any]) -> bool:
return bool(reasons & review_reason_markers)
def _targeted_candidate_sync_rank(candidate: dict[str, Any]) -> tuple[float, float, float, float]:
"""同一個 PChome 商品有多個候選時,挑最適合營運判斷的一筆。"""
auto_type = _targeted_candidate_auto_type(candidate)
type_rank = 3.0 if auto_type == "total_price" else 2.0 if auto_type == "unit_price" else 0.0
try:
match_score = float(candidate.get("target_match_score") or 0.0)
except (TypeError, ValueError):
match_score = 0.0
unit_price_comparison = (
candidate.get("target_unit_price_comparison")
if isinstance(candidate.get("target_unit_price_comparison"), dict)
else {}
)
momo_total = _to_float(unit_price_comparison.get("momo_total_quantity"))
pchome_total = _to_float(unit_price_comparison.get("competitor_total_quantity"))
quantity_delta = 999999.0
same_quantity = 0.0
if momo_total > 0 and pchome_total > 0:
quantity_delta = abs(momo_total - pchome_total)
same_quantity = 1.0 if quantity_delta <= 0.0001 else 0.0
return (type_rank, same_quantity, -quantity_delta, match_score)
def _targeted_candidate_to_external_offer(
candidate: dict[str, Any],
*,
@@ -839,7 +864,7 @@ def sync_targeted_momo_candidates_to_external_offers(
_ensure_external_market_source_seeds(conn)
base_observed_at = datetime.now()
offers: list[dict[str, Any]] = []
ranked_offers: list[tuple[dict[str, Any], tuple[float, float, float, float]]] = []
skipped_reasons: dict[str, int] = {}
for index, candidate in enumerate(candidates):
offer, reason = _targeted_candidate_to_external_offer(
@@ -847,9 +872,16 @@ def sync_targeted_momo_candidates_to_external_offers(
observed_at=base_observed_at + timedelta(microseconds=index),
)
if offer:
offers.append(offer)
ranked_offers.append((offer, _targeted_candidate_sync_rank(candidate)))
else:
skipped_reasons[reason] = skipped_reasons.get(reason, 0) + 1
selected_by_pchome: dict[str, tuple[dict[str, Any], tuple[float, float, float, float]]] = {}
for offer, rank in ranked_offers:
key = str(offer.get("pchome_product_id") or offer.get("source_offer_key") or "").strip()
existing = selected_by_pchome.get(key)
if existing is None or rank > existing[1]:
selected_by_pchome[key] = (offer, rank)
offers = [offer for offer, _ in selected_by_pchome.values()]
if not dry_run:
for offer in offers: