feat: support off-shelf location registration
This commit is contained in:
@@ -18,7 +18,7 @@ router = APIRouter()
|
||||
"model": ErrorResponse,
|
||||
},
|
||||
409: {
|
||||
"description": "该总排号已存在货位记录",
|
||||
"description": "重复上架或已下架",
|
||||
"model": ErrorResponse,
|
||||
},
|
||||
},
|
||||
@@ -29,4 +29,5 @@ def create_location(req: LocationRequest, db: Session = Depends(get_db)):
|
||||
zongpai_no=record.zongpai_no,
|
||||
location_code=record.location_code,
|
||||
created_at=record.created_at.isoformat(),
|
||||
previous_location=getattr(record, "previous_location", None),
|
||||
)
|
||||
|
||||
15
app/main.py
15
app/main.py
@@ -18,7 +18,7 @@ except Exception as e:
|
||||
|
||||
from app.api.v1.location import router as location_router
|
||||
from app.api.v1.box import router as box_router
|
||||
from app.services.location_service import DuplicateLocationError
|
||||
from app.services.location_service import AlreadyOffShelfError, DuplicateLocationError
|
||||
from app.services.box_service import (
|
||||
BoxItemNotFoundError,
|
||||
DuplicateBoxItemError,
|
||||
@@ -47,6 +47,19 @@ async def duplicate_location_handler(request: Request, exc: DuplicateLocationErr
|
||||
)
|
||||
|
||||
|
||||
@app.exception_handler(AlreadyOffShelfError)
|
||||
async def already_off_shelf_handler(request: Request, exc: AlreadyOffShelfError):
|
||||
return JSONResponse(
|
||||
status_code=409,
|
||||
content={
|
||||
"error_code": "ALREADY_OFF_SHELF",
|
||||
"message": "该总排号已下架至转运区域,不可重新上架",
|
||||
"location_code": exc.location_code,
|
||||
"registered_at": exc.registered_at,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@app.exception_handler(RequestValidationError)
|
||||
async def validation_error_handler(request: Request, exc: RequestValidationError):
|
||||
for err in exc.errors():
|
||||
|
||||
@@ -32,6 +32,7 @@ class LocationResponse(BaseModel):
|
||||
zongpai_no: str
|
||||
location_code: str
|
||||
created_at: str
|
||||
previous_location: str | None = None
|
||||
|
||||
|
||||
class DuplicateLocationDetail(BaseModel):
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.finished_goods import FinishedGoodsLocation
|
||||
@@ -12,6 +14,18 @@ class DuplicateLocationError(Exception):
|
||||
self.registered_at = registered_at
|
||||
|
||||
|
||||
class AlreadyOffShelfError(Exception):
|
||||
"""总排号已下架至转运区域。"""
|
||||
|
||||
def __init__(self, location_code: str, registered_at: str):
|
||||
self.location_code = location_code
|
||||
self.registered_at = registered_at
|
||||
|
||||
|
||||
def _is_transit_location(location_code: str) -> bool:
|
||||
return location_code.startswith("TRANS-")
|
||||
|
||||
|
||||
def register_location(db: Session, req: LocationRequest) -> FinishedGoodsLocation:
|
||||
existing = (
|
||||
db.query(FinishedGoodsLocation)
|
||||
@@ -19,6 +33,21 @@ def register_location(db: Session, req: LocationRequest) -> FinishedGoodsLocatio
|
||||
.first()
|
||||
)
|
||||
if existing:
|
||||
if _is_transit_location(existing.location_code):
|
||||
raise AlreadyOffShelfError(
|
||||
location_code=existing.location_code,
|
||||
registered_at=existing.created_at.isoformat(),
|
||||
)
|
||||
|
||||
if _is_transit_location(req.location_code):
|
||||
previous_location = existing.location_code
|
||||
existing.location_code = req.location_code
|
||||
existing.created_at = datetime.now()
|
||||
db.commit()
|
||||
db.refresh(existing)
|
||||
existing.previous_location = previous_location
|
||||
return existing
|
||||
|
||||
raise DuplicateLocationError(
|
||||
location_code=existing.location_code,
|
||||
registered_at=existing.created_at.isoformat(),
|
||||
|
||||
Reference in New Issue
Block a user