o2o-negosium-original/negodata/backend/router/v1/item/protocol.py
Mina Choi 103c80046e [feat] negodata: 신규 견적유형 + 목표가·앵커링 산정 + 협력사유형 + 협상카드 용도
- 견적유형 4종: QuotationType 에 신규협상(3)·신규견적(4) 추가(1·2 재 고정)
- 목표가 산정: items(매입가·판매가·인터넷최저가) + quotations.md_price +
  quotation_settings.internet_average_fee 로 _calc_target_price(KTC 이식, 신규/재 분리),
  세션 target_price·target_anchoring_price 저장
- 협력사유형: quotations.supplier_type(SupplierType) + 직전유형 조회 API(/supplier/{id}/last-type)
- 협상카드 용도: nego_cards/wild_cards.usage_type(CardUsageType: 공통/신규견적전용/재견적전용)
- 스키마(01-schema.sql)·ORM·protocol·service·crud·프론트(생성타입/폼) 일괄, /backend enums·models 미러

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 17:09:14 +09:00

136 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import uuid
from datetime import datetime
from typing import Optional
from pydantic import ConfigDict
from common.enums import DeliveryType
from common.models.gmodel import Res_PageProtocol, Res_WebPacketProtocol, WebPacketProtocol
class ItemProtocol(WebPacketProtocol):
pass
class Req_CreateItem(ItemProtocol):
name: str = ""
code: Optional[str] = None
category: Optional[str] = None
category_type: int = 1
image_url: Optional[str] = None
model_name: Optional[str] = None
spec: Optional[str] = None
manufacturer: Optional[str] = None
made_in: Optional[str] = None
price: Optional[int] = None
internet_lowest_price_yn: bool = False
internet_lowest_price: Optional[int] = None # 인터넷 최저가 실값(원). 목표가 산정용
purchase_price: Optional[int] = None # 매입가(원). 재견적 목표가 후보(그대로)
selling_price: Optional[int] = None # 판매가(원). 유통형 목표가 후보(×(1−마진율))
moq: Optional[str] = None
lead_time: Optional[int] = None
quantity_unit: Optional[str] = None
delivery_type: Optional[int] = None
vat_yn: Optional[bool] = None
delivery_fee_yn: Optional[bool] = None
class Req_UpdateItem(ItemProtocol):
name: Optional[str] = None
code: Optional[str] = None
category: Optional[str] = None
category_type: Optional[int] = None
image_url: Optional[str] = None
model_name: Optional[str] = None
spec: Optional[str] = None
manufacturer: Optional[str] = None
made_in: Optional[str] = None
price: Optional[int] = None
internet_lowest_price_yn: Optional[bool] = None
internet_lowest_price: Optional[int] = None # 인터넷 최저가 실값(원). 목표가 산정용
purchase_price: Optional[int] = None # 매입가(원). 재견적 목표가 후보(그대로)
selling_price: Optional[int] = None # 판매가(원). 유통형 목표가 후보(×(1−마진율))
moq: Optional[str] = None
lead_time: Optional[int] = None
quantity_unit: Optional[str] = None
delivery_type: Optional[int] = None
vat_yn: Optional[bool] = None
delivery_fee_yn: Optional[bool] = None
class ItemData(WebPacketProtocol):
model_config = ConfigDict(from_attributes=True)
item_id: uuid.UUID
company_id: uuid.UUID
user_id: uuid.UUID
name: str
code: Optional[str] = None
category: Optional[str] = None
category_type: int = 1
image_url: Optional[str] = None
model_name: Optional[str] = None
spec: Optional[str] = None
manufacturer: Optional[str] = None
made_in: Optional[str] = None
price: Optional[int] = None
internet_lowest_price_yn: bool = False
internet_lowest_price: Optional[int] = None # 인터넷 최저가 실값(원). 목표가 산정용
purchase_price: Optional[int] = None # 매입가(원). 재견적 목표가 후보(그대로)
selling_price: Optional[int] = None # 판매가(원). 유통형 목표가 후보(×(1−마진율))
moq: Optional[str] = None
lead_time: Optional[int] = None
quantity_unit: Optional[str] = None
delivery_type: Optional[DeliveryType] = None
vat_yn: Optional[bool] = None
delivery_fee_yn: Optional[bool] = None
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
class Res_Item(Res_WebPacketProtocol):
item: Optional[ItemData] = None
class Res_ItemList(Res_PageProtocol):
items: list[ItemData] = []
class ItemCategory(WebPacketProtocol):
name: str
category_type: int = 1
class Res_ItemCategories(Res_WebPacketProtocol):
categories: list[ItemCategory] = []
class Req_CheckCodes(ItemProtocol):
codes: list[str] = []
class Res_CheckCodes(Res_WebPacketProtocol):
existing: list[str] = [] # codes 중 이미 DB(같은 회사)에 존재하는 코드들
class Res_DeleteItem(Res_WebPacketProtocol):
pass
class Res_ItemImage(Res_WebPacketProtocol):
image_url: Optional[str] = None
filename: Optional[str] = None
size: Optional[int] = None
class Res_LowestPriceTrigger(Res_WebPacketProtocol):
item_id: str = ""
status: str = ""
message: str = ""
class Res_LowestPriceResult(Res_WebPacketProtocol):
item_id: str = ""
results: list = []
message: str = ""