*/ public function mergedItems(BillModel $bill): array { $items = StoreOrderItemModel::query() ->where('bill_id', $bill->id) ->orderBy('id') ->get(); return $this->aggregateItems($items); } /** * 合并后的商品明细(跨账单口径):按商品聚合多张账单的全部订单明细 * 用于账单合并导出,单价同为加权平均口径 * * @param array $billIds 账单ID列表 * @return array */ public function mergedItemsOfBills(array $billIds): array { $items = StoreOrderItemModel::query() ->whereIn('bill_id', $billIds) ->orderBy('id') ->get(); return $this->aggregateItems($items); } /** * 按商品聚合订单明细:数量累加、重量/金额 bc 累加、单价加权平均, * 首图取明细快照 image_ids 批量解析,按「分类sort → 商品sort」排序 * * @param Collection $items * @return array */ private function aggregateItems(Collection $items): array { // 排序键:分类 sort → 商品 sort(与采购单明细矩阵同序) $products = ProductModel::withTrashed() ->with('category:id,sort') ->whereIn('id', $items->pluck('product_id')->unique()) ->get() ->keyBy('id'); $rows = []; foreach ($items->groupBy('product_id') as $productId => $group) { $product = $products->get((int) $productId); $first = $group->first(); $quantity = 0; $weight = '0'; $amount = '0'; foreach ($group as $item) { $quantity += (int) $item->quantity; $weight = bcadd($weight, (string) $item->weight, 3); $amount = bcadd($amount, (string) $item->amount, 2); } $rows[] = [ 'product_id' => (int) $productId, 'product_name' => $first->product_name, 'product_spec' => $first->product_spec, 'unit' => $first->unit, 'price' => $quantity > 0 ? bcdiv($amount, (string) $quantity, 2) : (string) $first->price, 'quantity' => $quantity, 'weight' => $weight, 'amount' => $amount, 'spec' => $product->spec, 'price_unit' => $product->price_unit, 'image_ids' => (array) $first->image_ids, 'category_sort' => (int) ($product->category->sort ?? 9999), 'product_sort' => (int) ($product->sort ?? 9999), ]; } usort($rows, static fn (array $a, array $b): int => [$a['category_sort'], $a['product_sort'], $a['product_id']] <=> [$b['category_sort'], $b['product_sort'], $b['product_id']]); // 首图批量解析(写入 image、移除 image_ids) app(ItemImageResolver::class)->resolve($rows); return array_map(static function (array $row): array { unset($row['category_sort'], $row['product_sort']); return $row; }, $rows); } }