优化全仓进销存分页查询 #217
@ -260,28 +260,88 @@ class ThirdPartyWarehouseStorageMirrorRepository
|
||||
$anchorAt = $this->stateAnchor($state);
|
||||
$rangeStart = min($period['start'], $anchorAt);
|
||||
$rangeEnd = max($period['end'], $anchorAt);
|
||||
$movementPairs = $this->confirmedMovements($headerGeneration, $itemGeneration, null)
|
||||
->where('h.occurred_at', '>=', $rangeStart)
|
||||
->where('h.occurred_at', '<', $rangeEnd)
|
||||
->select(['h.wms_co_id', 'i.sku_code']);
|
||||
$latestProducts = $this->connection->table(self::PRODUCT_TABLE)
|
||||
->where('sku_type', 'normal')->whereNotNull('sku_id')->where('sku_id', '!=', '')
|
||||
->groupBy('sku_id')->select('sku_id')->selectRaw('MAX(autoid) AS autoid');
|
||||
$latestWarehouses = $this->connection->table(self::WAREHOUSE_TABLE)
|
||||
->whereNotNull('wms_co_id')->groupBy('wms_co_id')
|
||||
->select('wms_co_id')->selectRaw('MAX(Id) AS Id');
|
||||
$inventoryPairs = $this->connection->table(self::INVENTORY_TABLE)
|
||||
->where('generation', $inventoryGeneration)
|
||||
->whereNotNull('sku_code')->where('sku_code', '!=', '')
|
||||
->select(['wms_co_id', 'sku_code'])
|
||||
->union($movementPairs);
|
||||
$anchors = $this->connection->query()->fromSub($inventoryPairs, 'pairs')
|
||||
->select(['wms_co_id', 'sku_code']);
|
||||
$candidates = $this->connection->query()->fromSub($inventoryPairs, 'pairs')
|
||||
->select(['pairs.wms_co_id', 'pairs.sku_code']);
|
||||
$this->containsFilter($candidates, 'pairs.sku_code', $filters['product_code'] ?? '');
|
||||
$warehouseFilter = trim((string) ($filters['warehouse_provider'] ?? ''));
|
||||
if ($warehouseFilter !== '') {
|
||||
$warehouseIds = $this->connection->query()->fromSub(
|
||||
clone $latestWarehouses,
|
||||
'filter_latest_warehouse',
|
||||
)->join(self::WAREHOUSE_TABLE . ' as filter_warehouse', function ($join): void {
|
||||
$join->on('filter_warehouse.wms_co_id', '=', 'filter_latest_warehouse.wms_co_id')
|
||||
->on('filter_warehouse.Id', '=', 'filter_latest_warehouse.Id');
|
||||
});
|
||||
$this->containsFilter($warehouseIds, 'filter_warehouse.name', $warehouseFilter);
|
||||
$candidates->whereIn('pairs.wms_co_id', $warehouseIds->select('filter_warehouse.wms_co_id'));
|
||||
}
|
||||
$categoryFilter = trim((string) ($filters['category'] ?? ''));
|
||||
if ($categoryFilter !== '') {
|
||||
$categorySkus = $this->connection->table(self::PRODUCT_TABLE)
|
||||
->where('sku_type', 'normal')
|
||||
->whereNotNull('sku_id')->where('sku_id', '!=', '')
|
||||
->select('sku_id')->distinct();
|
||||
$this->containsFilter($categorySkus, 'category', $categoryFilter);
|
||||
$candidates->whereIn('pairs.sku_code', $categorySkus);
|
||||
}
|
||||
|
||||
$total = (clone $candidates)->count();
|
||||
$pagePairs = (clone $candidates)
|
||||
->orderBy('pairs.wms_co_id')->orderBy('pairs.sku_code')
|
||||
->forPage($page, $perPage);
|
||||
$pairRows = (clone $pagePairs)->get();
|
||||
if ($pairRows->isEmpty()) {
|
||||
return [
|
||||
'data' => [],
|
||||
'total' => $total,
|
||||
'state' => $state,
|
||||
'sync' => $this->syncStatus($state),
|
||||
];
|
||||
}
|
||||
|
||||
$dimensionedPagePairs = $this->connection->query()->fromSub($pagePairs, 'pairs')
|
||||
->leftJoinSub($latestProducts, 'latest_product', 'latest_product.sku_id', '=', 'pairs.sku_code')
|
||||
->leftJoin(self::PRODUCT_TABLE . ' as s', function ($join): void {
|
||||
$join->on('s.sku_id', '=', 'latest_product.sku_id')
|
||||
->on('s.autoid', '=', 'latest_product.autoid');
|
||||
})
|
||||
->leftJoinSub($latestWarehouses, 'latest_warehouse', 'latest_warehouse.wms_co_id', '=', 'pairs.wms_co_id')
|
||||
->leftJoin(self::WAREHOUSE_TABLE . ' as w', function ($join): void {
|
||||
$join->on('w.wms_co_id', '=', 'latest_warehouse.wms_co_id')
|
||||
->on('w.Id', '=', 'latest_warehouse.Id');
|
||||
})
|
||||
->select(['pairs.wms_co_id', 'pairs.sku_code', 's.category', 'w.name as warehouse_name']);
|
||||
$anchors = $this->connection->query()->fromSub($dimensionedPagePairs, 'pairs')
|
||||
->leftJoin(self::INVENTORY_TABLE . ' as inventory', function ($join) use ($inventoryGeneration): void {
|
||||
$join->on('inventory.wms_co_id', '=', 'pairs.wms_co_id')
|
||||
->on('inventory.sku_code', '=', 'pairs.sku_code')
|
||||
->where('inventory.generation', '=', $inventoryGeneration);
|
||||
})
|
||||
->select(['pairs.wms_co_id', 'pairs.sku_code'])
|
||||
->select(['pairs.wms_co_id', 'pairs.sku_code', 'pairs.category', 'pairs.warehouse_name'])
|
||||
->selectRaw('COALESCE(inventory.qty, 0) AS snapshot_qty')
|
||||
->selectRaw('COALESCE(inventory.captured_at, ?) AS snapshot_at', [$anchorAt]);
|
||||
|
||||
$movements = $this->confirmedMovements($headerGeneration, $itemGeneration, null)
|
||||
->where('h.occurred_at', '>=', $rangeStart)
|
||||
->where('h.occurred_at', '<', $rangeEnd)
|
||||
->where(function (Builder $pairs) use ($pairRows): void {
|
||||
foreach ($pairRows as $pair) {
|
||||
$pairs->orWhere(function (Builder $candidate) use ($pair): void {
|
||||
$candidate->where('h.wms_co_id', (int) $pair->wms_co_id)
|
||||
->where('i.sku_code', (string) $pair->sku_code);
|
||||
});
|
||||
}
|
||||
})
|
||||
->select([
|
||||
'h.wms_co_id', 'h.io_type', 'h.occurred_at', 'i.sku_code',
|
||||
'i.qty as movement_qty', 'i.qty_type as movement_qty_type',
|
||||
@ -301,8 +361,11 @@ class ThirdPartyWarehouseStorageMirrorRepository
|
||||
$join->on('mv.wms_co_id', '=', 'a.wms_co_id')
|
||||
->on('mv.sku_code', '=', 'a.sku_code');
|
||||
})
|
||||
->groupBy(['a.wms_co_id', 'a.sku_code', 'a.snapshot_qty', 'a.snapshot_at'])
|
||||
->select(['a.wms_co_id', 'a.sku_code'])
|
||||
->groupBy([
|
||||
'a.wms_co_id', 'a.sku_code', 'a.category', 'a.warehouse_name',
|
||||
'a.snapshot_qty', 'a.snapshot_at',
|
||||
])
|
||||
->select(['a.wms_co_id', 'a.sku_code', 'a.category', 'a.warehouse_name'])
|
||||
->selectRaw($openingSql . ' AS opening_qty', $openingBindings)
|
||||
->selectRaw($closingSql . ' AS closing_qty', $closingBindings);
|
||||
foreach (self::MOVEMENT_COLUMNS as $column => $type) {
|
||||
@ -314,37 +377,8 @@ class ThirdPartyWarehouseStorageMirrorRepository
|
||||
}
|
||||
$monthly->selectRaw('0 AS opening_aux');
|
||||
|
||||
$latestProducts = $this->connection->table(self::PRODUCT_TABLE)
|
||||
->where('sku_type', 'normal')->whereNotNull('sku_id')->where('sku_id', '!=', '')
|
||||
->groupBy('sku_id')->select('sku_id')->selectRaw('MAX(autoid) AS autoid');
|
||||
$latestWarehouses = $this->connection->table(self::WAREHOUSE_TABLE)
|
||||
->whereNotNull('wms_co_id')->groupBy('wms_co_id')
|
||||
->select('wms_co_id')->selectRaw('MAX(Id) AS Id');
|
||||
$query = $this->connection->query()->fromSub($monthly, 'm')
|
||||
->leftJoinSub($latestProducts, 'latest_product', 'latest_product.sku_id', '=', 'm.sku_code')
|
||||
->leftJoin(self::PRODUCT_TABLE . ' as s', function ($join): void {
|
||||
$join->on('s.sku_id', '=', 'latest_product.sku_id')
|
||||
->on('s.autoid', '=', 'latest_product.autoid');
|
||||
})
|
||||
->leftJoinSub($latestWarehouses, 'latest_warehouse', 'latest_warehouse.wms_co_id', '=', 'm.wms_co_id')
|
||||
->leftJoin(self::WAREHOUSE_TABLE . ' as w', function ($join): void {
|
||||
$join->on('w.wms_co_id', '=', 'latest_warehouse.wms_co_id')
|
||||
->on('w.Id', '=', 'latest_warehouse.Id');
|
||||
})
|
||||
->select(['m.*', 's.category', 'w.name as warehouse_name']);
|
||||
$this->containsFilter($query, 'm.sku_code', $filters['product_code'] ?? '');
|
||||
$this->containsFilter($query, 's.category', $filters['category'] ?? '');
|
||||
$this->containsFilter($query, 'w.name', $filters['warehouse_provider'] ?? '');
|
||||
$nonZero = ['opening_qty', 'closing_qty', ...array_keys(self::MOVEMENT_COLUMNS)];
|
||||
$query->where(function (Builder $values) use ($nonZero): void {
|
||||
foreach ($nonZero as $index => $column) {
|
||||
$method = $index === 0 ? 'where' : 'orWhere';
|
||||
$values->{$method}('m.' . $column, '<>', 0);
|
||||
}
|
||||
});
|
||||
|
||||
$total = (clone $query)->count();
|
||||
$rows = $query->orderBy('w.name')->orderBy('m.sku_code')->forPage($page, $perPage)->get()
|
||||
$rows = $this->connection->query()->fromSub($monthly, 'm')
|
||||
->select('m.*')->orderBy('m.warehouse_name')->orderBy('m.sku_code')->get()
|
||||
->map(static function (object $row) use ($period): object {
|
||||
$warehouse = trim((string) ($row->warehouse_name ?? ''));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user