CodeIgniter中基于FIFO的库存盘亏弃置表更新问题求助
CodeIgniter FIFO规则更新弃置表逻辑修正
核心逻辑梳理
要实现FIFO扣减,需按最早批次优先扣至0,剩余扣减额顺延至下一批次的规则执行,步骤如下:
- 计算需扣减的总量:
deduct_total = 系统库存数 - 实物盘点数(仅当deduct_total > 0时执行后续操作) - 按FIFO顺序(如批次创建时间升序/批次号升序)查询该商品的有效弃置批次(数量>0的记录)
- 遍历批次记录,逐次扣减:
- 若当前批次数量 ≤ 剩余扣减额:将该批次数量置为0,剩余扣减额减去当前批次数量
- 若当前批次数量 > 剩余扣减额:将该批次数量减去剩余扣减额,剩余扣减额置0,终止循环
- 批量更新弃置表,同时开启事务保证数据一致性
修正后的update_complete函数示例(CodeIgniter模型方法)
public function update_complete($item_id, $system_qty, $actual_qty) { // 计算需扣减的总量 $deduct_total = $system_qty - $actual_qty; if ($deduct_total <= 0) { return true; // 无需扣减,直接返回 } // 开启数据库事务 $this->db->trans_start(); // 1. 更新库存表(你已完成的逻辑,保留示意) $this->db->set('stock_qty', $actual_qty) ->where('item_id', $item_id) ->update('inventory_table'); // 2. 按FIFO顺序获取需扣减的弃置批次(按created_at升序确保最早批次优先) $batches = $this->db->select('id, qty') ->where('item_id', $item_id) ->where('qty >', 0) ->order_by('created_at', 'ASC') ->get('disposal_table') ->result_array(); $remaining_deduct = $deduct_total; $update_data = []; foreach ($batches as $batch) { if ($remaining_deduct <= 0) { break; // 扣减完成,终止循环 } $batch_id = $batch['id']; $current_qty = $batch['qty']; if ($current_qty <= $remaining_deduct) { // 该批次全部扣完,数量置0 $update_data[] = [ 'id' => $batch_id, 'qty' => 0 ]; $remaining_deduct -= $current_qty; } else { // 该批次扣减剩余额度,更新剩余数量 $update_data[] = [ 'id' => $batch_id, 'qty' => $current_qty - $remaining_deduct ]; $remaining_deduct = 0; } } // 批量更新弃置表 if (!empty($update_data)) { $this->db->update_batch('disposal_table', $update_data, 'id'); } // 提交事务 $this->db->trans_complete(); // 检查事务是否成功 if ($this->db->trans_status() === false) { return false; } return true; }
关键注意事项
- 事务控制:必须开启事务,避免库存表更新成功但弃置表更新失败导致数据不一致
- 排序规则:务必确保批次查询的排序是严格的FIFO顺序(比如用
created_at或batch_no升序,根据你的表结构调整) - 边界判断:要处理
deduct_total为0或负数的情况,避免无效操作 - 批量更新:使用
update_batch比逐个更新更高效,减少数据库请求次数
内容的提问来源于stack exchange,提问作者CodeLearner
相关产品推荐
相关产品推荐

