feat(borrow): 转交粒度下沉到明细行,支持部分转交
背景(业务方推翻上一轮约束)
----
上一轮按「一张单同时只能有一个持有人」实现了**整单转交**,并把「单内出现多个
持有人」当作 bug 去修。业务方验收后明确纠正:
物理现场经常只转交部分工具(借了 2 件、只把 1 件转给别人),
单内多持有人才是符合现实的正常状态。
故转交粒度从 borrow_no 下沉回 trans_borrow.id(明细行)。
改动
----
· transfer_borrow:只操作传入的那**一行**明细,不再按单号整批覆盖。
转出方 = 该行当前持有人;数量 = 该行待还量。
· accept_transfer:只转移 transfer.borrow_id 指向的那一行 ——
整批改写会把别人手上的东西一并抢过来(部分转交下同单明细分属不同人)。
· 唯一性约束从「单号至多一条 PENDING」下沉为「明细行至多一条」:
同单的其他明细可以同时各自挂着待接收,互不阻塞 —— 这正是部分转交的语义。
· get_records 的 pending_transfer 改按 borrow_id 关联(原按 borrow_no),
否则同单多项待接收会互相覆盖。
· 删除已无用的 _load_slip_for_update。
★ 数量粒度:一行只支持**整行转交**。一行只能有一个 current_holder_id,
「同一行只转一部分」需要把这行拆成两行 —— 经业务确认,现场场景中
「借 2 件转 1 件」的两件本就是两条明细行,故该限制不影响实际使用;
接口对传入的非整行数量会明确提示「应另立一条明细行」。
数据层
----
无需改表结构:borrow_id 本就是流水的关联列,borrow_no 退化为单据归属与
分组展示用。仅补 (borrow_id, status) 复合索引支撑新的查询路径。
存量撕裂数据(BOR-20260917-0001 的「测试 / 杜邢宸」)按业务方选择**保留不动**
—— 它现在不再是 bug,而是部分转交的正常形态。
验证(合成 2 明细单,21 项断言全通过)
----
· 只转工具A:工具B 完全不受影响
· 同一张单可同时挂两条待接收,互不阻塞;同一明细重复发起被拒
· accept 工具A 后:A→测试,B 仍是杜邢宸(单内两个持有人)
· 两个持有人、以及待接收人,三方各自都能在列表中看到该单
· pending_transfer 挂在正确的明细行上,is_mine 判定正确
· reject 后主表持有人不变;非整行数量被拒并提示拆行
· 全程 available_quantity 无变化,库存精确还原、零残留数据
This commit is contained in:
@ -636,8 +636,9 @@ def transfer_borrow(borrow_id):
|
||||
东西还没到接收人手上,责任仍归原持有人 —— 接收人在自己的列表里确认
|
||||
(POST /borrow/transfer/<id>/accept)后才真正转移。
|
||||
|
||||
★ 覆盖范围是**整张单**(borrow_no)的全部未还明细,不是传入的这一行,
|
||||
避免同一张单出现两个持有人。
|
||||
★ 转交粒度 = **明细行**(传入的 borrow_id 就是目标)。同一张单的其他明细
|
||||
不受影响,故「借 2 件只转 1 件」得到天然支持;同单不同明细归属不同持有人
|
||||
是正常业务形态。
|
||||
|
||||
★ 严禁触碰库存:转交是纯持有权变更,实物不出入库,
|
||||
stock_buy / stock_semi / stock_product 的任何字段都不会被修改。
|
||||
@ -677,17 +678,17 @@ def accept_borrow_transfer(transfer_id):
|
||||
★ 权限:**不加 permission_required**。这不是库管职权,而是员工对自己名下
|
||||
资产的确认动作;service 层强校验当前登录人 == to_user_id 本人。
|
||||
|
||||
★ 副作用:该单号下全部未还明细的 current_holder 一并改为接收人。
|
||||
转交是整单行为,不允许单内出现两个持有人。
|
||||
★ 副作用:**仅**该转交指向的那一条明细的 current_holder 改为接收人。
|
||||
同单的其他明细可能挂在别人名下(部分转交),一律不动。
|
||||
"""
|
||||
try:
|
||||
transfer, affected = TransService.accept_transfer(
|
||||
transfer, record = TransService.accept_transfer(
|
||||
transfer_id=transfer_id,
|
||||
user_id=get_jwt_identity(),
|
||||
)
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'msg': f'已接收,{affected} 项资产的持有权已转移到您名下',
|
||||
'msg': f'已接收,物品【{record.sku}】的持有权已转移到您名下',
|
||||
'data': transfer.to_dict(),
|
||||
}), 200
|
||||
except ValueError as e:
|
||||
|
||||
Reference in New Issue
Block a user