first version
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use App\Models\ProductCategoryModel;
|
||||
use App\Models\ProductModel;
|
||||
use App\Models\PurchaseOrderModel;
|
||||
use App\Models\SupplierModel;
|
||||
use Illuminate\Support\Collection;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
/**
|
||||
* 采购单导出(C2 全品类按分类 sort 排序 / C3 仅蔬果分类)
|
||||
*/
|
||||
class PurchaseOrderExport implements FromCollection, WithHeadings, WithMapping, WithStyles
|
||||
{
|
||||
/** @var array<int, string> 商品ID => 顶级分类名 */
|
||||
private array $categoryNames = [];
|
||||
|
||||
/** @var array<int, string> 供应商ID => 名称 */
|
||||
private array $supplierNames = [];
|
||||
|
||||
private ?Collection $items = null;
|
||||
|
||||
/**
|
||||
* @param PurchaseOrderModel $purchase 采购单
|
||||
* @param string $type all 全品类 / category 仅蔬果分类
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly PurchaseOrderModel $purchase,
|
||||
private readonly string $type = 'all',
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出行(按 sort 排序;蔬果分类时按顶级分类名过滤)
|
||||
*/
|
||||
public function collection(): Collection
|
||||
{
|
||||
if ($this->items !== null) {
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
$items = $this->purchase->items()->orderBy('sort')->get();
|
||||
$this->loadLookups($items);
|
||||
|
||||
if ($this->type === 'category') {
|
||||
$items = $items->filter(function ($item): bool {
|
||||
$rootName = $this->categoryNames[(int) $item->product_id] ?? '';
|
||||
return str_contains($rootName, '蔬菜') || str_contains($rootName, '水果');
|
||||
})->values();
|
||||
}
|
||||
|
||||
return $this->items = $items;
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return ['序号', '分类', '品名', '规格/包规', '单价', '数量', '实际称重', '金额', '供应商', '备注'];
|
||||
}
|
||||
|
||||
public function map($item): array
|
||||
{
|
||||
return [
|
||||
$item->sort,
|
||||
$this->categoryNames[(int) $item->product_id] ?? '',
|
||||
$item->product_name,
|
||||
$item->product_spec,
|
||||
(float) $item->price,
|
||||
(float) $item->quantity,
|
||||
(float) $item->weight,
|
||||
(float) $item->amount,
|
||||
$this->supplierNames[(int) $item->supplier_id] ?? '',
|
||||
$item->remark,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 表头加粗 + 冻结首行
|
||||
*/
|
||||
public function styles(Worksheet $sheet): array
|
||||
{
|
||||
$sheet->freezePane('A2');
|
||||
|
||||
return [
|
||||
1 => ['font' => ['bold' => true]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* PDF 模板视图数据
|
||||
*
|
||||
* @return array{purchase: PurchaseOrderModel, items: Collection, categoryNames: array<int, string>, supplierNames: array<int, string>}
|
||||
*/
|
||||
public function viewData(): array
|
||||
{
|
||||
return [
|
||||
'purchase' => $this->purchase,
|
||||
'items' => $this->collection(),
|
||||
'categoryNames' => $this->categoryNames,
|
||||
'supplierNames' => $this->supplierNames,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 预加载供应商名与商品顶级分类名(商品/供应商均含软删除,保证历史单据可导出)
|
||||
*/
|
||||
private function loadLookups(Collection $items): void
|
||||
{
|
||||
$this->supplierNames = SupplierModel::withTrashed()
|
||||
->whereIn('id', $items->pluck('supplier_id')->unique())
|
||||
->pluck('name', 'id')
|
||||
->toArray();
|
||||
|
||||
$productCategoryIds = ProductModel::withTrashed()
|
||||
->whereIn('id', $items->pluck('product_id')->unique())
|
||||
->pluck('category_id', 'id');
|
||||
|
||||
$categories = ProductCategoryModel::all()->keyBy('id');
|
||||
$this->categoryNames = [];
|
||||
foreach ($productCategoryIds as $productId => $categoryId) {
|
||||
$rootName = '';
|
||||
$cursor = (int) $categoryId;
|
||||
$guard = 0;
|
||||
while ($cursor > 0 && $guard++ < 20) {
|
||||
$category = $categories->get($cursor);
|
||||
if ($category === null) {
|
||||
break;
|
||||
}
|
||||
$rootName = $category->name;
|
||||
$cursor = (int) $category->parent_id;
|
||||
}
|
||||
$this->categoryNames[(int) $productId] = $rootName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use App\Models\ReconciliationItemModel;
|
||||
use App\Models\SettlementModel;
|
||||
use Illuminate\Support\Collection;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
/**
|
||||
* D10 结算表导出(结算头 + 来源对账单中该门店的明细)
|
||||
*/
|
||||
class SettlementExport implements FromCollection, WithHeadings, WithMapping, WithStyles
|
||||
{
|
||||
public function __construct(private readonly SettlementModel $settlement)
|
||||
{
|
||||
}
|
||||
|
||||
public function collection(): Collection
|
||||
{
|
||||
return ReconciliationItemModel::query()
|
||||
->where('recon_id', $this->settlement->recon_id)
|
||||
->where('store_id', $this->settlement->store_id)
|
||||
->orderBy('sort')
|
||||
->get();
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return ['品名', '数量', '称重', '公布金额', '实际金额', '差额', '对账状态', '门店备注'];
|
||||
}
|
||||
|
||||
public function map($item): array
|
||||
{
|
||||
return [
|
||||
$item->product_name,
|
||||
(float) $item->quantity,
|
||||
(float) $item->weight,
|
||||
(float) $item->publish_amount,
|
||||
(float) $item->actual_amount,
|
||||
(float) $item->diff_amount,
|
||||
$item->is_reconciled ? '已对账' : '未对账',
|
||||
$item->store_remark,
|
||||
];
|
||||
}
|
||||
|
||||
public function styles(Worksheet $sheet): array
|
||||
{
|
||||
$sheet->freezePane('A2');
|
||||
|
||||
return [
|
||||
1 => ['font' => ['bold' => true]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* PDF 模板视图数据
|
||||
*
|
||||
* @return array{settlement: SettlementModel, storeName: string, reconNo: string, items: Collection}
|
||||
*/
|
||||
public function viewData(): array
|
||||
{
|
||||
return [
|
||||
'settlement' => $this->settlement,
|
||||
'storeName' => $this->settlement->store?->name ?? '',
|
||||
'reconNo' => $this->settlement->recon?->recon_no ?? '',
|
||||
'items' => $this->collection(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use App\Models\StatementModel;
|
||||
use Illuminate\Support\Collection;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
/**
|
||||
* 门店对账单导出
|
||||
*/
|
||||
class StatementExport implements FromCollection, WithHeadings, WithMapping, WithStyles
|
||||
{
|
||||
public function __construct(private readonly StatementModel $statement)
|
||||
{
|
||||
}
|
||||
|
||||
public function collection(): Collection
|
||||
{
|
||||
return $this->statement->items()->orderBy('id')->get();
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return ['品名', '单价', '数量', '重量', '金额', '对账状态', '备注'];
|
||||
}
|
||||
|
||||
public function map($item): array
|
||||
{
|
||||
return [
|
||||
$item->product_name,
|
||||
(float) $item->price,
|
||||
(float) $item->quantity,
|
||||
(float) $item->weight,
|
||||
(float) $item->amount,
|
||||
$item->is_reconciled ? '已对账' : '未对账',
|
||||
$item->store_remark,
|
||||
];
|
||||
}
|
||||
|
||||
public function styles(Worksheet $sheet): array
|
||||
{
|
||||
$sheet->freezePane('A2');
|
||||
|
||||
return [
|
||||
1 => ['font' => ['bold' => true]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* PDF 模板视图数据
|
||||
*
|
||||
* @return array{statement: StatementModel, storeName: string, items: Collection}
|
||||
*/
|
||||
public function viewData(): array
|
||||
{
|
||||
return [
|
||||
'statement' => $this->statement,
|
||||
'storeName' => $this->statement->store?->name ?? '',
|
||||
'items' => $this->collection(),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user