170 lines
3.8 KiB
Python
170 lines
3.8 KiB
Python
from pydantic import BaseModel, Field, field_validator
|
|
|
|
|
|
class CategoryResponse(BaseModel):
|
|
id: int
|
|
name: str
|
|
sort_order: int
|
|
|
|
|
|
class AttachmentStatusItem(BaseModel):
|
|
category_id: int
|
|
name: str
|
|
expected_qty: int
|
|
boxed_qty: int
|
|
location_code: str | None = None
|
|
complete: bool
|
|
|
|
|
|
class AttachmentStatusResponse(BaseModel):
|
|
zongpai_no: str
|
|
determination: str
|
|
all_complete: bool
|
|
items: list[AttachmentStatusItem] = Field(default_factory=list)
|
|
|
|
|
|
class AttachmentConfigItem(BaseModel):
|
|
category_id: int
|
|
expected_qty: int
|
|
|
|
@field_validator("expected_qty")
|
|
@classmethod
|
|
def _positive(cls, v: int) -> int:
|
|
if v <= 0:
|
|
raise ValueError("INVALID_QUANTITY")
|
|
return v
|
|
|
|
|
|
class AttachmentConfigRequest(BaseModel):
|
|
zongpai_no: str
|
|
determination: str
|
|
items: list[AttachmentConfigItem] = Field(default_factory=list)
|
|
|
|
@field_validator("zongpai_no")
|
|
@classmethod
|
|
def _zongpai(cls, v: str) -> str:
|
|
import re
|
|
|
|
v = v.strip().upper()
|
|
if not re.match(r"^(\d{2}(B|C|T)\d+|\d{2}(BW|CW)\d{4})$", v):
|
|
raise ValueError("INVALID_ZONGPAI")
|
|
return v
|
|
|
|
@field_validator("determination")
|
|
@classmethod
|
|
def _det(cls, v: str) -> str:
|
|
if v not in ("none", "has"):
|
|
raise ValueError("INVALID_DETERMINATION")
|
|
return v
|
|
|
|
|
|
class AttachmentLocationRequest(BaseModel):
|
|
zongpai_no: str
|
|
category_id: int
|
|
location_code: str
|
|
|
|
@field_validator("zongpai_no")
|
|
@classmethod
|
|
def _zongpai(cls, v: str) -> str:
|
|
import re
|
|
|
|
v = v.strip().upper()
|
|
if not re.match(r"^(\d{2}(B|C|T)\d+|\d{2}(BW|CW)\d{4})$", v):
|
|
raise ValueError("INVALID_ZONGPAI")
|
|
return v
|
|
|
|
@field_validator("location_code")
|
|
@classmethod
|
|
def _location(cls, v: str) -> str:
|
|
import re
|
|
|
|
v = v.strip().upper()
|
|
normal = re.match(r"^[A-Z]+\d+-\d+-\d+$", v)
|
|
transit = re.match(r"^TRANS-\d+", v)
|
|
if not normal and not transit:
|
|
raise ValueError("INVALID_LOCATION")
|
|
return v
|
|
|
|
|
|
class AttachmentLocationResponse(BaseModel):
|
|
zongpai_no: str
|
|
category_id: int
|
|
location_code: str
|
|
created_at: str
|
|
previous_location: str | None = None
|
|
|
|
|
|
class AttachmentBoxSaveRequest(BaseModel):
|
|
zongpai_no: str
|
|
category_id: int
|
|
box_no: int
|
|
quantity: int
|
|
|
|
@field_validator("zongpai_no")
|
|
@classmethod
|
|
def _zongpai(cls, v: str) -> str:
|
|
import re
|
|
|
|
v = v.strip().upper()
|
|
if not re.match(r"^(\d{2}(B|C|T)\d+|\d{2}(BW|CW)\d{4})$", v):
|
|
raise ValueError("INVALID_ZONGPAI")
|
|
return v
|
|
|
|
@field_validator("box_no")
|
|
@classmethod
|
|
def _box_no(cls, v: int) -> int:
|
|
if v <= 0:
|
|
raise ValueError("INVALID_BOX_NO")
|
|
return v
|
|
|
|
@field_validator("quantity")
|
|
@classmethod
|
|
def _qty(cls, v: int) -> int:
|
|
if v <= 0:
|
|
raise ValueError("INVALID_QUANTITY")
|
|
return v
|
|
|
|
|
|
class AttachmentBoxSaveResponse(BaseModel):
|
|
box_item_id: int
|
|
paichan_no: str
|
|
box_no: int
|
|
zongpai_no: str
|
|
category_id: int
|
|
quantity: int
|
|
created_at: str
|
|
|
|
|
|
class AttachmentBoxUpdateRequest(BaseModel):
|
|
box_no: int
|
|
quantity: int
|
|
|
|
@field_validator("box_no")
|
|
@classmethod
|
|
def _box_no(cls, v: int) -> int:
|
|
if v <= 0:
|
|
raise ValueError("INVALID_BOX_NO")
|
|
return v
|
|
|
|
@field_validator("quantity")
|
|
@classmethod
|
|
def _qty(cls, v: int) -> int:
|
|
if v <= 0:
|
|
raise ValueError("INVALID_QUANTITY")
|
|
return v
|
|
|
|
|
|
class AttachmentBoxUpdateResponse(BaseModel):
|
|
box_item_id: int
|
|
paichan_no: str
|
|
box_no: int
|
|
zongpai_no: str
|
|
category_id: int
|
|
quantity: int
|
|
updated_at: str
|
|
|
|
|
|
class AttachmentBoxDeleteResponse(BaseModel):
|
|
box_item_id: int
|
|
deleted: bool
|