autoParams($params); $keyword = $this->pg('keyword'); $repo_id = $this->pg('repo_id'); $good_id = $this->pg('good_id'); $filter_zero_transit = $this->pgd(false, 'filter_zero_transit'); if ($repo_id && !Repo::find($repo_id)) { throw $this->exception('仓库不存在'); } if ($good_id && !Good::find($good_id)) { throw $this->exception('物品不存在'); } $where = WhereBuilder::builder() ->like('g.no|g.name|r.name', $keyword) ->in('s.repo_id', $repo_id) ->build(); $transit_filter_symbol = '>='; if ($filter_zero_transit) { $transit_filter_symbol = '>'; } $page = (new Stock) ->alias('s') ->field('s.*, g.name as good_name, g.no as good_no, r.name as repo_name, IFNULL(sum(abs(d.num) - d.transit_received), 0) as sum_transit') ->join('good g', 'g.id = s.good_id', 'LEFT') ->join('repo r', 'r.id = s.repo_id', 'LEFT') ->join('io_detail d', 'd.good_id = s.good_id AND d.repo_id = s.repo_id AND d.transit_status = "TRANSIT"', 'LEFT') ->where($where) ->whereRaw("IFNULL(abs(d.num) - d.transit_received, 0) $transit_filter_symbol 0") ->group('s.id') ->paginate($this->tp6Page(PHP_INT_MAX)); return $page; } public function allByRepo($params = []) { $this->autoParams($params); $repo = $this->one(Repo::class); return (new Stock)->where('repo_id', '=', $repo->id)->select(); } public function info($params = []) { $this->autoParams($params); $stock = $this->one(Stock::class); $stock->append(['good']); return $stock; } public function getByGoodAndRepo($params = []) { $this->autoParams($params); $good = $this->one(Good::class, 'good_id'); $repo = $this->one(Repo::class, 'repo_id'); return (new Stock) ->with(['good']) ->where('good_id', '=', $good->id) ->where('repo_id', '=', $repo->id) ->find() ?? Result::rest(['repo_id' => $repo->id, 'good_id' => $good->id, 'num' => 0]); } /** * tp6是支持事务嵌套的,为了保证修改库存时数据不出现问题,请无脑使用该事务方法 */ public function chengeStockTrans(Repo $repo, Good $good, $change) { // tp6是支持事务嵌套的,所有修改可以直接用事务 return Db::transaction(fn() => $this->changeStock($repo, $good, $change)); } protected function changeStock(Repo $repo, Good $good, $change) { if (!$repo) { throw $this->exception('致命错误,$repo为空'); } if (!$good) { throw $this->exception('致命错误,$good为空'); } /** * @var Stock */ $stock = (new Stock) ->lock(true) ->where('good_id', '=', $good->id) ->where('repo_id', '=', $repo->id) ->find(); if (!$stock) { $stock = Stock::create([ 'repo_id' => $repo->id, 'good_id' => $good->id, 'num' => 0 ]); } if ($change < 0 && $stock->num < abs($change)) { $info = <<name}库存不足,当前库存为{$stock->num},出库数量为{$change} 出现这种情况可能有以下原因: - 在该操作前,该物品已由另一名操作员出库,导致库存不足 - 多个相同商品出库相加库存不足 - 库存不足 - 库存低于0.01,此时系统会认为没有库存,请避免此类情况的发生 - 出库数量/库存数量过高导致溢出,如出现此类情况请联系开发人员解决 EOF; throw $this->exception($info); } $stock->num += $change; $stock->save(); } public function export($params = []) { $params = $this->autoParams($params); $params['pageParams']['size'] = PHP_INT_MAX; $stocks = $this->page($params)->getCollection(); $stocks = $stocks->map(fn(Stock $stock) => $stock->getData()); $header = [ [ 'id', '仓库id', '商品id', '创建时间', '更新时间', '删除时间', '数量', '商品名', '编号', '仓库名', '在途数量' ] ]; $res = PhpSpreadsheetExportV2::outputFile( $stocks, $header, '仓储管理系统' . date('Ymdis'), [] ); return $res; } }