feat(server): add PATCH/DELETE /attachment/box mirroring product box ops
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -371,3 +371,119 @@ def save_attachment_box(db: Session, req) -> dict:
|
||||
"quantity": req.quantity,
|
||||
"created_at": record.created_at.isoformat(),
|
||||
}
|
||||
|
||||
|
||||
def update_attachment_box(db: Session, item_id: int, req) -> dict:
|
||||
record = (
|
||||
db.query(FinishedGoodsBoxAttachmentItem)
|
||||
.filter(FinishedGoodsBoxAttachmentItem.id == item_id)
|
||||
.first()
|
||||
)
|
||||
if record is None:
|
||||
raise AttachmentItemNotFoundError()
|
||||
|
||||
current_box = (
|
||||
db.query(FinishedGoodsBox)
|
||||
.filter(FinishedGoodsBox.id == record.box_id)
|
||||
.first()
|
||||
)
|
||||
if current_box is None:
|
||||
raise AttachmentItemNotFoundError()
|
||||
paichan_no = current_box.paichan_no
|
||||
|
||||
target_box = (
|
||||
db.query(FinishedGoodsBox)
|
||||
.filter(
|
||||
FinishedGoodsBox.paichan_no == paichan_no,
|
||||
FinishedGoodsBox.box_no == req.box_no,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
if target_box is None:
|
||||
target_box = FinishedGoodsBox(paichan_no=paichan_no, box_no=req.box_no)
|
||||
db.add(target_box)
|
||||
db.flush()
|
||||
else:
|
||||
dup = (
|
||||
db.query(FinishedGoodsBoxAttachmentItem)
|
||||
.filter(
|
||||
FinishedGoodsBoxAttachmentItem.box_id == target_box.id,
|
||||
FinishedGoodsBoxAttachmentItem.zongpai_no == record.zongpai_no,
|
||||
FinishedGoodsBoxAttachmentItem.category_id == record.category_id,
|
||||
FinishedGoodsBoxAttachmentItem.id != record.id,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
if dup is not None:
|
||||
raise DuplicateAttachmentBoxItemError(paichan_no, req.box_no)
|
||||
|
||||
item = (
|
||||
db.query(FinishedGoodsAttachmentItem)
|
||||
.filter(
|
||||
FinishedGoodsAttachmentItem.zongpai_no == record.zongpai_no,
|
||||
FinishedGoodsAttachmentItem.category_id == record.category_id,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
expected_qty = item.expected_qty if item is not None else 0
|
||||
already_boxed = _boxed_for_category(
|
||||
db, record.zongpai_no, record.category_id, exclude_item_id=record.id
|
||||
)
|
||||
if already_boxed + req.quantity > expected_qty:
|
||||
raise InvalidQuantityError()
|
||||
|
||||
old_box_id = record.box_id
|
||||
record.box_id = target_box.id
|
||||
record.quantity = req.quantity
|
||||
|
||||
if old_box_id != target_box.id:
|
||||
_cleanup_empty_box(db, old_box_id, exclude_item_id=record.id)
|
||||
|
||||
db.commit()
|
||||
db.refresh(record)
|
||||
return {
|
||||
"box_item_id": record.id,
|
||||
"paichan_no": paichan_no,
|
||||
"box_no": req.box_no,
|
||||
"zongpai_no": record.zongpai_no,
|
||||
"category_id": record.category_id,
|
||||
"quantity": int(record.quantity or 0),
|
||||
"updated_at": record.created_at.isoformat(),
|
||||
}
|
||||
|
||||
|
||||
def delete_attachment_box(db: Session, item_id: int) -> dict:
|
||||
record = (
|
||||
db.query(FinishedGoodsBoxAttachmentItem)
|
||||
.filter(FinishedGoodsBoxAttachmentItem.id == item_id)
|
||||
.first()
|
||||
)
|
||||
if record is None:
|
||||
raise AttachmentItemNotFoundError()
|
||||
box_id = record.box_id
|
||||
db.delete(record)
|
||||
db.flush()
|
||||
_cleanup_empty_box(db, box_id)
|
||||
db.commit()
|
||||
return {"box_item_id": item_id, "deleted": True}
|
||||
|
||||
|
||||
def _cleanup_empty_box(db: Session, box_id: int, exclude_item_id: int | None = None) -> None:
|
||||
"""If a box has no product items and no attachment items, delete it."""
|
||||
from app.models.finished_goods import FinishedGoodsBoxItem
|
||||
|
||||
product_q = db.query(FinishedGoodsBoxItem.id).filter(
|
||||
FinishedGoodsBoxItem.box_id == box_id
|
||||
)
|
||||
if product_q.first() is not None:
|
||||
return
|
||||
att_q = db.query(FinishedGoodsBoxAttachmentItem.id).filter(
|
||||
FinishedGoodsBoxAttachmentItem.box_id == box_id
|
||||
)
|
||||
if exclude_item_id is not None:
|
||||
att_q = att_q.filter(FinishedGoodsBoxAttachmentItem.id != exclude_item_id)
|
||||
if att_q.first() is not None:
|
||||
return
|
||||
box = db.query(FinishedGoodsBox).filter(FinishedGoodsBox.id == box_id).first()
|
||||
if box is not None:
|
||||
db.delete(box)
|
||||
|
||||
Reference in New Issue
Block a user