| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 | <?phpnamespace app\common\service;use Carbon\Carbon;use think\Validate;use think\facade\Db;use app\common\model\Io;use app\common\model\Good;use app\common\model\Admin;use app\common\model\IoDetail;use app\common\model\Allocation;use app\common\util\WhereBuilder;use app\common\model\AllocationDetail;class AllocationService extends Service{    public function page($params = [])    {        // 自动处理传入的参数        $this->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'    ];}
 |