autoParams($params); // 获取关键词 $keyword = $this->pg('keyword'); // 获取来源仓库ID $from_repo_id = $this->pg('from_repo_id'); // 获取目标仓库ID $to_repo_id = $this->pg('to_repo_id'); // 获取开始日期 $begin_date = $this->pg('begin_date'); // 获取结束日期 $end_date = $this->pg('end_date'); // 如果结束日期存在,则将其解析为 Carbon 对象并增加一天,并转换为日期字符串 if ($end_date) { $end_date = Carbon::parse($end_date)->addDay()->toDateString(); } // 构建查询条件 $where = WhereBuilder::builder() ->like('a.id|from.name|to.name|a.remark', $keyword) ->in('a.from_repo_id', $from_repo_id) ->in('a.to_repo_id', $to_repo_id) ->between('a.date', $begin_date, $end_date) ->build(); // 执行查询,并返回分页结果 return (new Allocation)->alias('a') ->field('a.*, from.name as from_repo_name, to.name as to_repo_name') ->join('repo from', 'from.id = a.from_repo_id', 'LEFT') ->join('repo to', 'to.id = a.to_repo_id', 'LEFT') ->where($where) ->order('a.create_time desc') ->paginate($this->tp6Page()); } public function info($params = []) { $this->autoParams($params); $alloc = $this->one(Allocation::class); $alloc->append(['from', 'to', 'details', 'details.good', 'details.good.goodClass']); return $alloc; } /** * 创建调拨单(事务处理) * * @param Admin $admin 管理员对象 * @param array $params 参数数组 * @return Allocation 创建的调拨单对象 */ public function createTrans(Admin $admin, $params = []) { // 使用事务处理创建调拨单 return Db::transaction(fn() => $this->create($admin, $params)); } /** * 创建调拨单 * * @param Admin $admin 管理员对象 * @param array $params 参数数组 * @return Allocation 创建的调拨单对象 */ public function create(Admin $admin, $params = []) { // 自动处理参数 $params = $this->autoParams($params); // 验证参数 $this->validate($params, new AllocateValidate); // 获取调拨明细 $details = $this->pg('details'); // 设置管理员ID $params['admin_id'] = $admin->id; // 创建调拨单 $allocation = Allocation::create($params); // 遍历调拨明细进行赋值和检查 foreach ($details as &$detail) { // 设置调拨单ID和日期 $detail['allocation_id'] = $allocation->id; $detail['date'] = isset($detail['date']) && $detail['date'] ? $detail['date'] : $allocation->date; // 检查出入库数量 if ($detail['num'] == 0) { $good = Good::find($detail['good_id']); throw $this->exception("物品--{$good?->name}的出入库数量不能为0"); } if ($detail['num'] > 0 && $allocation->type == Io::TYPE_OUT) { $good = Good::find($detail['good_id']); throw $this->exception("物品--{$good?->name}的出入库数量大于0但是类型为出库"); } if ($detail['num'] < 0 && $allocation->type == Io::TYPE_IN) { $good = Good::find($detail['good_id']); throw $this->exception("物品--{$good?->name}的出入库数量小于0但是类型为入库"); } } // 保存调拨明细 $allocationDetails = (new AllocationDetail)->saveAll($details); // 出库 $outIoData = [ 'repo_id' => $allocation->from_repo_id, 'type' => Io::TYPE_OUT, 'change_type' => Io::CHANGE_TYPE_ALLOCATION, 'date' => $allocation->date, 'remark' => "自动生成自调拨单{$allocation->id}", 'sn' => "SYS_ALC_OUT_T" . hrtime(true) . '_SN' . rand(100000, 999999), 'admin_id' => $admin->id, 'source' => "调拨单{$allocation->id}" ]; $outIo = Io::create($outIoData); // 出库详情 foreach ($details as &$detail) { $detail['type'] = Io::TYPE_OUT; $detail['io_id'] = $outIo->id; $detail['repo_id'] = $allocation->from_repo_id; $detail['num'] = -$detail['num']; } $outDetails = (new IoDetail)->saveAll($details); // 入库 $inIoData = [ 'repo_id' => $allocation->to_repo_id, 'type' => Io::TYPE_IN, 'change_type' => Io::CHANGE_TYPE_ALLOCATION, 'date' => $allocation->date, 'remark' => "自动生成自调拨单{$allocation->id}", 'sn' => "SYS_ALC_IN_T" . hrtime(true) . '_SN' . rand(100000, 999999), 'admin_id' => $admin->id, 'source' => "调拨单{$allocation->id}" ]; $inIo = Io::create($inIoData); // 入库详情 foreach ($details as &$detail) { $detail['type'] = Io::TYPE_IN; $detail['io_id'] = $inIo->id; $detail['repo_id'] = $allocation->to_repo_id; $detail['num'] = -$detail['num']; } $inDetails = (new IoDetail)->saveAll($details); $allocation->out_io_id = $outIo->id; $allocation->in_io_id = $inIo->id; $allocation->save(); // 返回创建的调拨单对象 return $allocation; } public function revertTrans(Admin $admin, $params = []) { return Db::transaction(fn() => $this->revert($admin, $params)); } public function revert(Admin $admin, $params = []) { $this->autoParams($params); $allc = $this->one(Allocation::class); if ($allc->revert_id) { return true; } $service = (new IoService($this->app))->exceptionClass($this->exceptionClass); $out_revert_to_in_io = $service->revertTrans($admin, ['id' => $allc->out_io_id]); $in_revert_to_out_io = $service->revertTrans($admin, ['id' => $allc->in_io_id]); // 创建调拨单 $revertData = [ 'from_repo_id' => $allc->to_repo_id, 'to_repo_id' => $allc->from_repo_id, 'date' => date('Ymd'), 'remark' => "回滚自$allc->id", 'admin_id' => $admin->id, 'out_io_id' => $in_revert_to_out_io->id, 'in_io_id' => $out_revert_to_in_io->id ]; $revert = Allocation::create($revertData); $revertDetails = []; // 遍历调拨明细进行赋值和检查 foreach ($allc->details as $detail) { // 设置调拨单ID和日期 $revertDetail = [ 'good_id' => $detail->good_id, 'num' => $detail->num, 'date' => date('Ymd'), 'remark' => '回滚', 'allocation_id' => $revert->id ]; $revertDetails[] = $revertDetail; } // 保存调拨明细 $allocationDetails = (new AllocationDetail)->saveAll($revertDetails); $allc->revert_id = $revert->id; $allc->save(); return $revert; } } class AllocateValidate extends Validate { protected $rule = [ 'from_repo_id' => 'require', 'to_repo_id' => 'require', 'date' => 'require', 'remark' => 'max:255', 'details' => 'require|array' ]; }