fix(borrow): 统一归还/报废时间口径为北京时间,并修正过期注释

时间口径(与归还流水同时引入,故随本轮一并修)
----
process_return 与 scrap_sources.deduct 原用 datetime.now() 写 return_time,
而 datetime.now() 取的是**容器本地时间**(Docker 下为 UTC);同一行的
borrow_time 却由 beijing_time() 写入 —— 两个字段差 8 小时,台账时间线
自相矛盾,并会让新做的流转时间线出现「先借出、后归还,却显示归还更早」
的倒序假象。

统一改用 beijing_time(),并与新增的归还流水共用同一个时间戳,保证主表快照
与流水逐笔完全对齐。

(与 db_migrations/unify_approval_timezone.sql 处理的是同一类问题:aware/naive
与本地/北京时间的口径混用。)

注释修正
----
borrow_service.submit_approval 的 docstring 写着「仅存储意向,不扣库存」,
但 Phase 1 起该函数已调用 reserve_for_items() 预占库存(扣 available_quantity)。
过期注释会误导后续开发者(尤其是做转交的人以为库存没动过),已改写为实际的
预占语义与三种释放路径(驳回 / 撤回 / 扫码执行)。
This commit is contained in:
yueli
2026-09-17 09:18:02 +08:00
parent cccd6f6081
commit f7c49f41a8
2 changed files with 15 additions and 4 deletions

View File

@ -64,7 +64,16 @@ class BorrowApprovalService:
def submit_approval(applicant_id, items, allowed_approvers, remark=None, approver_id=None,
borrower_name=None, force_approval=False):
"""
提交借库申请(仅存储意向,不扣库存)
提交借库申请
★ 库存语义:**提交即预占**Phase 1 起)。
本函数会调用 reserve_for_items() 锁定具体批次并扣减 available_quantity
不动 stock_quantity —— 借出期间该批货不可再被他人领用。
预占的释放时机:
· 驳回 / 撤回 → release_reserved() 全额归还;
· 扫码执行 → restore_then_deduct() 先全量释放、再按实扫批次扣减。
(原注释写「仅存储意向,不扣库存」,是 Phase 1 改造前的旧描述,
与下方实现不符,已修正。)
Args:
applicant_id: 申请人ID

View File

@ -29,7 +29,7 @@
"""
import logging
from app.extensions import db
from app.extensions import db, beijing_time
logger = logging.getLogger(__name__)
@ -368,7 +368,6 @@ class BorrowScrapAdapter(ScrapSourceAdapter):
(base.spec_model if base else '') or '')
def deduct(self, row_id, qty, req, operator_name):
from datetime import datetime
from app.models.transaction import TransScrap, TransBorrow
record = TransBorrow.query.with_for_update().get(row_id)
@ -390,7 +389,10 @@ class BorrowScrapAdapter(ScrapSourceAdapter):
# 1) 标记借用记录:不再追讨归还
record.is_returned = True
record.status = 'scrapped'
record.return_time = datetime.now()
# ★ 时间口径:与 borrow_time / 归还流水统一取北京时间。
# 原用 datetime.now()(容器 UTC会让报废时间在台账上比实际早 8 小时,
# 与同一行的 borrow_time 自相矛盾,也让流转时间线出现倒序假象。
record.return_time = beijing_time()
record.return_operator = operator_name
# 2) 扣总库存(该物品确认损失);可用量已在借出时冻结,不重复扣