添加市场
This commit is contained in:
@@ -20,7 +20,7 @@ use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
class ProductExport implements FromCollection, WithStrictNullComparison, WithStyles
|
||||
{
|
||||
/** 列头(与 ProductImport 的解析顺序一一对应,改动需同步) */
|
||||
public const array HEADERS = ['品名', '分类', '供应商', '规格/包规', '单位', '成本价', '排序', '库存', '保质期', '状态', '备注'];
|
||||
public const array HEADERS = ['品名', '分类', '供应商', '市场', '规格/包规', '单位', '成本价', '排序', '库存', '保质期', '状态', '备注'];
|
||||
|
||||
private ?Collection $rows = null;
|
||||
|
||||
@@ -46,7 +46,7 @@ class ProductExport implements FromCollection, WithStrictNullComparison, WithSty
|
||||
$rows = [self::HEADERS];
|
||||
|
||||
if ($this->template) {
|
||||
$rows[] = ['西红柿', '蔬菜/茄果类', '示例供应商', '10斤/箱', '斤', 2.5, 0, 100, 3, '上架', '示例行,导入前请删除'];
|
||||
$rows[] = ['西红柿', '蔬菜/茄果类', '示例供应商', '新发地', '10斤/箱', '斤', 2.5, 0, 100, 3, '上架', '示例行,导入前请删除'];
|
||||
return $this->rows = collect($rows);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ class ProductExport implements FromCollection, WithStrictNullComparison, WithSty
|
||||
$product->name,
|
||||
$categoryPaths[(int) $product->category_id] ?? '',
|
||||
$supplierNames[(int) $product->supplier_id] ?? '',
|
||||
$product->market,
|
||||
$product->spec,
|
||||
$product->unit,
|
||||
(float) $product->cost_price,
|
||||
@@ -87,7 +88,7 @@ class ProductExport implements FromCollection, WithStrictNullComparison, WithSty
|
||||
$this->collection();
|
||||
|
||||
$sheet->freezePane('A2');
|
||||
$widths = [20, 16, 14, 14, 8, 10, 8, 8, 8, 8, 24];
|
||||
$widths = [20, 16, 14, 12, 14, 8, 10, 8, 8, 8, 8, 24];
|
||||
foreach ($widths as $index => $width) {
|
||||
$sheet->getColumnDimension(Coordinate::stringFromColumnIndex($index + 1))->setWidth($width);
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
|
||||
'category' => $categoryNames[(int) $productId] ?? '',
|
||||
'product_name' => (string) ($snapshot->product_name ?? $product->name),
|
||||
'supplier' => $supplierNames[$rowSupplierId] ?? '',
|
||||
'market' => (string) ($product->market ?? ''),
|
||||
'product_spec' => $spec,
|
||||
'unit' => (string) ($snapshot->unit ?? $product->unit),
|
||||
'cost_price' => (float) ($snapshot->cost_price ?? $product->cost_price),
|
||||
@@ -172,7 +173,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
|
||||
|
||||
// 列头
|
||||
$rows[] = array_merge(
|
||||
['序号', '分类', '品名', '供应商', '包规', '单位', '成本', '参考零售价', '数量', '实际称重', '金额'],
|
||||
['序号', '分类', '品名', '供应商', '市场', '包规', '单位', '成本', '参考零售价', '数量', '实际称重', '金额'],
|
||||
array_values($this->storeNames),
|
||||
);
|
||||
$this->specialRows[++$rowIndex] = 'header';
|
||||
@@ -189,6 +190,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
|
||||
$item['category'],
|
||||
$item['product_name'],
|
||||
$item['supplier'],
|
||||
$item['market'],
|
||||
$item['product_spec'],
|
||||
$item['unit'],
|
||||
$item['cost_price'],
|
||||
@@ -208,7 +210,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
|
||||
|
||||
// 合计行(行合计 + 门店列合计)
|
||||
$rows[] = array_merge(
|
||||
['', '', '合计', '', '', '', '', '', (float) $totalQuantity, (float) $totalWeight, (float) $totalAmount],
|
||||
['', '', '合计', '', '', '', '', '', '', (float) $totalQuantity, (float) $totalWeight, (float) $totalAmount],
|
||||
array_values($storeTotals),
|
||||
);
|
||||
$this->specialRows[++$rowIndex] = 'summary';
|
||||
@@ -225,7 +227,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
|
||||
$this->collection();
|
||||
|
||||
$sheet->freezePane('A' . ($this->headerRow + 1));
|
||||
$widths = [6, 10, 20, 12, 12, 8, 10, 12, 10, 12, 12];
|
||||
$widths = [6, 10, 20, 12, 12, 12, 8, 10, 12, 10, 12, 12];
|
||||
foreach ($widths as $index => $width) {
|
||||
$sheet->getColumnDimension(Coordinate::stringFromColumnIndex($index + 1))->setWidth($width);
|
||||
}
|
||||
@@ -233,7 +235,7 @@ class PurchaseOrderExport implements FromCollection, WithStrictNullComparison, W
|
||||
// 门店列整列(列头 → 合计行)填充突出颜色
|
||||
$storeCount = count($this->storeNames);
|
||||
for ($i = 0; $i < $storeCount; $i++) {
|
||||
$column = Coordinate::stringFromColumnIndex(12 + $i);
|
||||
$column = Coordinate::stringFromColumnIndex(13 + $i);
|
||||
$sheet->getColumnDimension($column)->setWidth(12);
|
||||
$sheet->getStyle($column . $this->headerRow . ':' . $column . $this->lastRow)
|
||||
->getFill()
|
||||
|
||||
@@ -55,7 +55,7 @@ class PurchaseStoreSheet implements FromCollection, WithStrictNullComparison, Wi
|
||||
$rowIndex++;
|
||||
|
||||
// 列头
|
||||
$rows[] = ['序号', '品名', '包规', '单位', '单价', '数量', '重量(斤)', '预计金额'];
|
||||
$rows[] = ['序号', '品名', '市场', '包规', '单位', '单价', '数量', '重量(斤)', '预计金额'];
|
||||
$this->specialRows[++$rowIndex] = 'header';
|
||||
$this->headerRow = $rowIndex;
|
||||
|
||||
@@ -67,6 +67,7 @@ class PurchaseStoreSheet implements FromCollection, WithStrictNullComparison, Wi
|
||||
$rows[] = [
|
||||
$sort + 1,
|
||||
$item['product_name'],
|
||||
$item['market'],
|
||||
$item['product_spec'],
|
||||
$item['unit'],
|
||||
(float) $item['price'],
|
||||
@@ -81,7 +82,7 @@ class PurchaseStoreSheet implements FromCollection, WithStrictNullComparison, Wi
|
||||
}
|
||||
|
||||
// 合计行
|
||||
$rows[] = ['', '合计', '', '', '', $totalQuantity, (float) $totalWeight, (float) $totalAmount];
|
||||
$rows[] = ['', '合计', '', '', '', '', $totalQuantity, (float) $totalWeight, (float) $totalAmount];
|
||||
$this->specialRows[++$rowIndex] = 'summary';
|
||||
|
||||
return $this->rows = collect($rows);
|
||||
@@ -100,7 +101,7 @@ class PurchaseStoreSheet implements FromCollection, WithStrictNullComparison, Wi
|
||||
$this->collection();
|
||||
|
||||
$sheet->freezePane('A' . ($this->headerRow + 1));
|
||||
$widths = [6, 24, 14, 8, 10, 10, 12, 12];
|
||||
$widths = [6, 24, 12, 14, 8, 10, 10, 12, 12];
|
||||
foreach ($widths as $index => $width) {
|
||||
$sheet->getColumnDimension(\PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($index + 1))
|
||||
->setWidth($width);
|
||||
|
||||
@@ -56,7 +56,7 @@ class PurchaseSupplierSheet implements FromCollection, WithStrictNullComparison,
|
||||
$rowIndex++;
|
||||
|
||||
// 列头
|
||||
$rows[] = ['序号', '品名', '包规', '单位', '成本价', '数量', '重量(斤)', '金额'];
|
||||
$rows[] = ['序号', '品名', '市场', '包规', '单位', '成本价', '数量', '重量(斤)', '金额'];
|
||||
$this->specialRows[++$rowIndex] = 'header';
|
||||
$this->headerRow = $rowIndex;
|
||||
|
||||
@@ -68,6 +68,7 @@ class PurchaseSupplierSheet implements FromCollection, WithStrictNullComparison,
|
||||
$rows[] = [
|
||||
$sort + 1,
|
||||
$item['product_name'],
|
||||
$item['market'],
|
||||
$item['product_spec'],
|
||||
$item['unit'],
|
||||
(float) $item['cost_price'],
|
||||
@@ -82,7 +83,7 @@ class PurchaseSupplierSheet implements FromCollection, WithStrictNullComparison,
|
||||
}
|
||||
|
||||
// 合计行
|
||||
$rows[] = ['', '合计', '', '', '', $totalQuantity, (float) $totalWeight, (float) $totalAmount];
|
||||
$rows[] = ['', '合计', '', '', '', '', $totalQuantity, (float) $totalWeight, (float) $totalAmount];
|
||||
$this->specialRows[++$rowIndex] = 'summary';
|
||||
|
||||
return $this->rows = collect($rows);
|
||||
@@ -101,7 +102,7 @@ class PurchaseSupplierSheet implements FromCollection, WithStrictNullComparison,
|
||||
$this->collection();
|
||||
|
||||
$sheet->freezePane('A' . ($this->headerRow + 1));
|
||||
$widths = [6, 24, 14, 8, 10, 10, 12, 12];
|
||||
$widths = [6, 24, 12, 14, 8, 10, 10, 12, 12];
|
||||
foreach ($widths as $index => $width) {
|
||||
$sheet->getColumnDimension(Coordinate::stringFromColumnIndex($index + 1))->setWidth($width);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ class ProductController extends BaseController
|
||||
'name' => 'like',
|
||||
'category_id' => '=',
|
||||
'supplier_id' => '=',
|
||||
'market' => 'like',
|
||||
'status' => '=',
|
||||
];
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ class PurchaseOrderController extends BaseController
|
||||
'unit' => $first->unit, // 单位
|
||||
'supplier_id' => (int) $first->supplier_id, // 供应商id
|
||||
'supplier' => $supplier, // 供应商
|
||||
'market' => (string) ($product?->market ?? ''), // 市场(取商品档案)
|
||||
'cost_price' => $first->cost_price, // 成本价
|
||||
'quantity' => $quantity,
|
||||
'weight' => (float) $weight,
|
||||
|
||||
@@ -22,6 +22,7 @@ class ProductFormRequest extends BaseFormRequest
|
||||
return [
|
||||
'category_id' => ['required','integer', new Exists(ProductCategoryModel::class,'id')],
|
||||
'supplier_id' => ['nullable','integer', 'exclude_if:supplier_id,0', new Exists(SupplierModel::class,'id')],
|
||||
'market' => 'nullable|string|max:50',
|
||||
'name' => 'required|string|max:100',
|
||||
'spec' => 'nullable|string|max:100',
|
||||
'unit' => 'nullable|string|max:20',
|
||||
|
||||
@@ -92,8 +92,8 @@ class ProductImport implements ToCollection
|
||||
*/
|
||||
private function parseRow(array $cells, Collection $categories, array $leafIds): array
|
||||
{
|
||||
[$name, $categoryName, $supplierName, $spec, $unit, $costPrice, $sort, $stock, $shelfLife, $statusText, $remark] =
|
||||
array_pad(array_slice($cells, 0, 11), 11, null);
|
||||
[$name, $categoryName, $supplierName, $market, $spec, $unit, $costPrice, $sort, $stock, $shelfLife, $statusText, $remark] =
|
||||
array_pad(array_slice($cells, 0, 12), 12, null);
|
||||
|
||||
$errors = [];
|
||||
|
||||
@@ -120,6 +120,11 @@ class ProductImport implements ToCollection
|
||||
$errors[] = '供应商名称最长 100 个字符';
|
||||
}
|
||||
|
||||
$market = (string) $market;
|
||||
if (mb_strlen($market) > 50) {
|
||||
$errors[] = '市场最长 50 个字符';
|
||||
}
|
||||
|
||||
$spec = (string) $spec;
|
||||
if (mb_strlen($spec) > 100) {
|
||||
$errors[] = '规格/包规最长 100 个字符';
|
||||
@@ -169,6 +174,7 @@ class ProductImport implements ToCollection
|
||||
'category_id' => $categoryId,
|
||||
'supplier_id' => 0, // 写入阶段按 supplier_name 解析(匹配或自动创建)
|
||||
'supplier_name' => $supplierName, // 写入阶段解析,不入 product 表
|
||||
'market' => $market,
|
||||
'name' => $name,
|
||||
'spec' => $spec,
|
||||
'unit' => $unit,
|
||||
|
||||
@@ -27,6 +27,7 @@ class ProductModel extends Model
|
||||
protected $fillable = [
|
||||
'category_id',
|
||||
'supplier_id',
|
||||
'market',
|
||||
'name',
|
||||
'spec',
|
||||
'unit',
|
||||
|
||||
@@ -80,6 +80,7 @@ class PurchaseItemService
|
||||
'product_name' => $first->product_name,
|
||||
'product_spec' => $first->product_spec,
|
||||
'unit' => $first->unit,
|
||||
'market' => (string) data_get($first, 'market', ''),
|
||||
// 加权平均单价(保证 单价×数量=预计金额)
|
||||
'price' => $quantity > 0
|
||||
? bcdiv($amount, (string) $quantity, 2)
|
||||
@@ -124,6 +125,7 @@ class PurchaseItemService
|
||||
'product_name' => $first->product_name,
|
||||
'product_spec' => $first->product_spec,
|
||||
'unit' => $first->unit,
|
||||
'market' => (string) data_get($first, 'market', ''),
|
||||
'cost_price' => (string) $first->cost_price,
|
||||
'quantity' => $quantity,
|
||||
'weight' => $weight,
|
||||
@@ -151,17 +153,18 @@ class PurchaseItemService
|
||||
->get()
|
||||
->makeVisible('cost_price');
|
||||
|
||||
// 排序键:商品分类 sort → 商品 sort(商品含软删除,保证历史单据可导出)
|
||||
// 排序键:商品分类 sort → 商品 sort;市场取商品档案(商品含软删除,保证历史单据可导出)
|
||||
$products = ProductModel::withTrashed()
|
||||
->with('category:id,sort')
|
||||
->whereIn('id', $items->pluck('product_id')->unique())
|
||||
->get(['id', 'category_id', 'sort'])
|
||||
->get(['id', 'category_id', 'sort', 'market'])
|
||||
->keyBy('id');
|
||||
|
||||
foreach ($items as $item) {
|
||||
$product = $products->get((int) $item->product_id);
|
||||
$item->setAttribute('category_sort', (int) ($product?->category?->sort ?? 9999));
|
||||
$item->setAttribute('product_sort', (int) ($product?->sort ?? 9999));
|
||||
$item->setAttribute('market', (string) ($product?->market ?? ''));
|
||||
}
|
||||
|
||||
return $items;
|
||||
|
||||
Reference in New Issue
Block a user