CaiWuXiTong/app/Exports/ThirdPartyWarehouseStorageSettlementExport.php

189 lines
6.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Exports;
use Carbon\Carbon;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Maatwebsite\Excel\Concerns\WithTitle;
/**
* 三方仓仓储费核算明细导出:汇总 / 进销存数据汇总(每日) / 进销存(逐商品) /
* 每日商品仓储费四张表。
* 数据来自 ThirdPartyWarehouseStorageFeeCalculator 的核算结果(或存档快照)。
*/
class ThirdPartyWarehouseStorageSettlementExport implements WithMultipleSheets
{
/**
* @param array{summary:array<string,mixed>,daily:list<array<string,mixed>>,per_sku:list<array<string,mixed>>,daily_sku?:list<array<string,mixed>>} $result
*/
public function __construct(private readonly array $result)
{
}
/** @return array<int,object> */
public function sheets(): array
{
return [
new StorageSettlementSummarySheet($this->result['summary']),
new StorageSettlementDailySheet($this->result['summary'], $this->result['daily']),
new StorageSettlementSkuSheet($this->result['per_sku']),
new ThirdPartyWarehouseStorageDetailExport($this->result['daily_sku'] ?? []),
];
}
}
class StorageSettlementSummarySheet implements FromArray, WithHeadings, WithTitle
{
/** @param array<string,mixed> $summary */
public function __construct(private readonly array $summary)
{
}
public function title(): string
{
return '汇总';
}
/** @return array<int,string> */
public function headings(): array
{
$period = (string) ($this->summary['period'] ?? '');
$label = $period !== '' ? Carbon::createFromFormat('Y-m-d', $period . '-01')->format('Y年n月') : '汇总';
return [$label, '仓库提供', '简尚核算', '差异'];
}
/** @return array<int,array<int,mixed>> */
public function array(): array
{
$s = $this->summary;
$rate = static fn (string $key): string => rtrim(rtrim(number_format((float) ($s[$key] ?? 0), 4, '.', ''), '0'), '.');
$rows = [
['入库管理费(' . $rate('inbound_rate_per_ton') . '元/吨)', null, (float) $s['inbound_fee']],
['出库费用(' . $rate('outbound_rate_per_order') . '元/单)', null, (float) $s['outbound_fee']],
['当天仓储费用(每日库存结余÷' . $rate('pieces_per_pallet') . '件×托盘' . $rate('pallet_area_sqm') . '㎡×' . $rate('storage_rate_per_sqm_month') . '÷当月天数,逐日累加)', null, (float) $s['storage_fee']],
['记账', null, (float) $s['memo_fee']],
['盘亏扣款', null, (float) $s['loss_fee']],
['赔偿', null, (float) $s['compensation_fee']],
['合计', 0, (float) $s['total_fee']],
];
return array_map(static function (array $row): array {
$provided = $row[1];
$checked = $row[2];
$diff = $checked === null ? null : round((float) ($provided ?? 0) - (float) $checked, 2);
return [$row[0], $provided, $checked, $diff];
}, $rows);
}
}
class StorageSettlementDailySheet implements FromArray, WithHeadings, WithTitle
{
/**
* @param array<string,mixed> $summary
* @param list<array<string,mixed>> $daily
*/
public function __construct(private readonly array $summary, private readonly array $daily)
{
}
public function title(): string
{
return '进销存数据汇总';
}
/** @return array<int,string> */
public function headings(): array
{
return ['日期', '当日入库计费件数', '入库管理(吨重)', '当日出库计费件数', '当日库存结余', '坪效仓储费', '入库管理费', '出库费用', '增值服务(元/件)', '合计'];
}
/** @return array<int,array<int,mixed>> */
public function array(): array
{
$rows = [];
$sumInbound = 0.0;
$sumOut = 0.0;
$sumStorage = 0.0;
$sumOutFee = 0.0;
foreach ($this->daily as $d) {
$rows[] = [
$d['date'],
(float) $d['inbound_qty'],
null,
(float) $d['outbound_qty'],
(float) $d['closing'],
(float) $d['storage_fee'],
null,
(float) $d['outbound_fee'],
null,
(float) $d['total'],
];
$sumInbound += (float) $d['inbound_qty'];
$sumOut += (float) $d['outbound_qty'];
$sumStorage += (float) $d['storage_fee'];
$sumOutFee += (float) $d['outbound_fee'];
}
$s = $this->summary;
$rows[] = [
'合计',
round($sumInbound, 2),
(float) $s['inbound_tons'],
round($sumOut, 2),
null,
round($sumStorage, 2),
(float) $s['inbound_fee'],
round($sumOutFee, 2),
null,
round($sumStorage + (float) $s['inbound_fee'] + round($sumOutFee, 2), 2),
];
return $rows;
}
}
class StorageSettlementSkuSheet implements FromArray, WithHeadings, WithTitle
{
/** @param list<array<string,mixed>> $perSku */
public function __construct(private readonly array $perSku)
{
}
public function title(): string
{
return '进销存';
}
/** @return array<int,string> */
public function headings(): array
{
return ['货主', '商品编码', '商品名称', '供应商', '分类', '单位', '重量(kg)', '单件吨', '入库计费件数', '总吨(单件吨×入库计费件数)', '出库计费件数', '期初数量', '期末数量'];
}
/** @return array<int,array<int,mixed>> */
public function array(): array
{
return array_map(static fn (array $r): array => [
$r['owner'],
$r['sku_code'],
$r['product_name'],
$r['supplier'],
$r['category'],
$r['unit'],
(float) $r['weight'],
(float) $r['per_ton'],
(float) $r['inbound_qty'],
(float) $r['total_ton'],
(float) $r['outbound_qty'],
(float) $r['opening'],
(float) $r['closing'],
], $this->perSku);
}
}