printedparts stage 14: retire/restore in the UI, dashless item codes
Retire button with confirmation on the detail page (item leaves the storefront and the kiosk rejects its code; ledger history and label survive), Restore on retired items, and an Include-retired list toggle with a badge. Restore is its own permission-gated POST - the generic update still cannot flip isactive. New codes mint as WJRP0042 style without the dash; existing codes are immutable bin labels and keep their form.
This commit is contained in:
@@ -91,7 +91,7 @@ def _imagedir():
|
||||
def _mint_itemcode(item):
|
||||
"""Set itemcode from the configured prefix + the flushed row id."""
|
||||
prefix = Setting.get('printedparts_code_prefix') or '3DP'
|
||||
item.itemcode = f'{prefix}-{item.printeditemid:04d}'
|
||||
item.itemcode = f'{prefix}{item.printeditemid:04d}'
|
||||
|
||||
|
||||
@printedparts_bp.route('/items', methods=['POST'])
|
||||
@@ -159,6 +159,20 @@ def delete_item(item_id: int):
|
||||
return success_response(message='Printed item retired')
|
||||
|
||||
|
||||
@printedparts_bp.route('/items/<int:item_id>/restore', methods=['POST'])
|
||||
@jwt_required()
|
||||
@require_permission('printedparts.delete')
|
||||
def restore_item(item_id: int):
|
||||
"""Bring a retired item back; code, photo, and history are intact."""
|
||||
item = db.session.get(PrintedItem, item_id)
|
||||
if not item:
|
||||
return error_response(ErrorCodes.NOT_FOUND,
|
||||
f'Printed item {item_id} not found', http_code=404)
|
||||
item.isactive = True
|
||||
db.session.commit()
|
||||
return success_response(item.to_dict(), message='Printed item restored')
|
||||
|
||||
|
||||
# --- item image: the models.py upload/serve/delete trio ---------------------
|
||||
|
||||
@printedparts_bp.route('/items/<int:item_id>/image', methods=['POST'])
|
||||
|
||||
Reference in New Issue
Block a user