어느 가격이 "공급사에 지불하는 단가"인지는 회사마다 달라, 컬럼을 합치는 대신 회사가 고르게 했다.
판정은 settings.features.nego_baseline_field 1순위, 미설정 회사는 price 만 숨겼으면 purchase_price 폴백.
판정식 정본은 negodata/backend/common/nego_baseline.py (agent·negosium backend 가 같은 규칙 미러).
- negodata front: 회사 설정에 협상 기준가 라디오(선택지마다 실제 나갈 문장 미리보기 + 학습 경고),
'공급사 포털 안내' 탭 신설(협상 유의사항·헬프데스크 연락처), 용어 카탈로그에 target_price·supplier 추가.
인터넷 최저가는 숨김 대상에서 제외(신규 견적의 유일한 목표가 후보).
상품 등록 기본값에서 개발용 더미 제거(price 1,000,000·PROD-BAT-###·800,000·대한민국·10 EA·14).
- agent: get_item_price → get_item_baseline (기준가·호칭·회사 용어사전을 한 쿼리로),
"기존 공급가 대비" 하드코딩을 회사 용어로 치환 + 받침 기준 조사 자동 보정,
협상 스크립트 4종의 협력사·목표가·배송형태 용어를 {label_*} 토큰화, input_options 도 변수 치환 적용.
- negosium: 협상 화면 기준 단가·배송형태 라벨을 회사 설정 기준으로, 유의사항 본문과 헬프데스크 연락처를
하드코딩에서 회사 설정으로(미등록 시 영역 숨김). 유의사항의 VAT·배송비 문구 삭제(IMK 0803 ⑥).
- negodata backend: LPS 검색 가격 힌트를 items.price 고정에서 기준가 규칙으로.
검증: 기준가 설정 3 × 숨김 4 = 12조합에서 협상 멘트·포털 표시·LPS 힌트가 전부 일치.
agent 테스트 176건 통과. 보고서 negodata/docs/nego-baseline-verification.md
39 lines
1.9 KiB
Python
39 lines
1.9 KiB
Python
"""협상 기준가 판정 — 회사 설정에서 '이 회사가 관리하는 지불 단가' 컬럼을 고른다.
|
|
|
|
이 값은 협상 인하율 멘트의 분모이자 RL 가격 수용률의 기준가이고, 인터넷 최저가 검색의
|
|
가격 힌트로도 나간다. 회사마다 다르다 — 매입해서 되파는 곳은 공급가(items.price)가,
|
|
매입만 하는 곳은 매입가(items.purchase_price)가 실제 지불 단가다.
|
|
|
|
같은 규칙을 agent(negotiation/chat/infra/repository/nego_context_crud.py `_resolve_baseline`)와
|
|
루트 backend(services/chat_service.py)도 쓴다. 세 곳이 어긋나면 화면값과 협상 멘트가 갈리므로
|
|
판정식을 바꿀 때는 반드시 같이 고친다.
|
|
"""
|
|
|
|
from typing import Optional
|
|
|
|
NEGO_BASELINE_FIELDS = ("price", "purchase_price")
|
|
DEFAULT_NEGO_BASELINE_FIELD = "price"
|
|
|
|
|
|
def resolve_baseline_field(settings: Optional[dict]) -> str:
|
|
"""회사 설정 → 협상 기준가로 쓸 items 컬럼명.
|
|
|
|
1순위는 관리자가 설정 화면에서 고른 값(features.nego_baseline_field).
|
|
미설정 회사는 공급가가 기본이되, 공급가를 화면에서 감췄다면(hidden_fields) 그 회사는
|
|
공급가를 관리하지 않는다는 뜻이므로 매입가로 폴백한다 — 설정 화면이 생기기 전에
|
|
만들어진 회사를 위한 안전망.
|
|
"""
|
|
settings = settings or {}
|
|
chosen = (settings.get("features") or {}).get("nego_baseline_field")
|
|
if chosen in NEGO_BASELINE_FIELDS:
|
|
return chosen
|
|
hidden = set(settings.get("hidden_fields") or [])
|
|
if "price" in hidden and "purchase_price" not in hidden:
|
|
return "purchase_price"
|
|
return DEFAULT_NEGO_BASELINE_FIELD
|
|
|
|
|
|
def resolve_baseline_price(item, settings: Optional[dict]) -> int:
|
|
"""상품의 협상 기준가(원). 값이 없으면 0."""
|
|
return int(getattr(item, resolve_baseline_field(settings), None) or 0)
|