feat: add boxing module API — GET /box/info and POST /box
- Add box schemas (BoxInfoResponse, BoxSaveRequest, BoxSaveResponse) - Add box service with ERP view query and save logic (supports many2one append) - Add box router with GET /box/info and POST /box endpoints - Register exception handlers for InvalidZongpaiError, ZongpaiNotFoundError, DuplicateBoxItemError - Update RequestValidationError handler to cover INVALID_BOX_NO and INVALID_QUANTITY - Add 7 integration tests for box API Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
65
app/schemas/box.py
Normal file
65
app/schemas/box.py
Normal file
@@ -0,0 +1,65 @@
|
||||
import re
|
||||
|
||||
from pydantic import BaseModel, field_validator
|
||||
|
||||
ZONGPAI_PATTERN = re.compile(r"^(\d{2}(B|C|T)\d+|\d{2}(BW|CW)\d{4})$")
|
||||
|
||||
|
||||
class BoxItemDetail(BaseModel):
|
||||
"""箱号下某个总排号的明细"""
|
||||
zongpai_no: str
|
||||
quantity: int
|
||||
|
||||
|
||||
class BoxDetail(BaseModel):
|
||||
"""一个箱号的完整信息"""
|
||||
box_no: int
|
||||
items: list[BoxItemDetail]
|
||||
|
||||
|
||||
class BoxInfoResponse(BaseModel):
|
||||
"""GET /box/info 响应"""
|
||||
zongpai_no: str
|
||||
paichan_no: str
|
||||
quantity: int
|
||||
existing_boxes: list[BoxDetail]
|
||||
max_box_no: int
|
||||
suggested_box_no: int
|
||||
|
||||
|
||||
class BoxSaveRequest(BaseModel):
|
||||
"""POST /box 请求"""
|
||||
zongpai_no: str
|
||||
box_no: int
|
||||
quantity: int
|
||||
|
||||
@field_validator("zongpai_no")
|
||||
@classmethod
|
||||
def validate_zongpai_no(cls, v: str) -> str:
|
||||
v = v.strip().upper()
|
||||
if not ZONGPAI_PATTERN.match(v):
|
||||
raise ValueError("INVALID_ZONGPAI")
|
||||
return v
|
||||
|
||||
@field_validator("box_no")
|
||||
@classmethod
|
||||
def validate_box_no(cls, v: int) -> int:
|
||||
if v <= 0:
|
||||
raise ValueError("INVALID_BOX_NO")
|
||||
return v
|
||||
|
||||
@field_validator("quantity")
|
||||
@classmethod
|
||||
def validate_quantity(cls, v: int) -> int:
|
||||
if v <= 0:
|
||||
raise ValueError("INVALID_QUANTITY")
|
||||
return v
|
||||
|
||||
|
||||
class BoxSaveResponse(BaseModel):
|
||||
"""POST /box 响应"""
|
||||
paichan_no: str
|
||||
box_no: int
|
||||
zongpai_no: str
|
||||
quantity: int
|
||||
created_at: str
|
||||
Reference in New Issue
Block a user