84 lines
2.5 KiB
PHP
84 lines
2.5 KiB
PHP
<?php
|
||
|
||
namespace App\Business\ServiceCompanyReconciliation;
|
||
|
||
use App\Business\XlsxSheetReader;
|
||
use RuntimeException;
|
||
|
||
class CustomerServiceMappingWorkbookImporter
|
||
{
|
||
public function __construct(private readonly XlsxSheetReader $reader) {}
|
||
|
||
/**
|
||
* @return array{
|
||
* rows:list<array{service_company_name:string,store_company_name:string,fee_rate:float,source_row:int}>,
|
||
* total_rows:int,
|
||
* assigned_rows:int,
|
||
* unassigned_rows:int,
|
||
* invalid_rows:list<string>
|
||
* }
|
||
*/
|
||
public function rows(string $path): array
|
||
{
|
||
if (! is_file($path)) {
|
||
throw new RuntimeException('客服公司映射文件不存在:' . $path);
|
||
}
|
||
|
||
$result = [
|
||
'rows' => [],
|
||
'total_rows' => 0,
|
||
'assigned_rows' => 0,
|
||
'unassigned_rows' => 0,
|
||
'invalid_rows' => [],
|
||
];
|
||
foreach ($this->reader->rows(
|
||
$path,
|
||
['公司名称', '结算比例', '对应客服公司'],
|
||
sheetName: '公司盘点',
|
||
) as $row) {
|
||
$result['total_rows']++;
|
||
$sourceRow = $result['total_rows'] + 1;
|
||
$storeName = trim((string) ($row['公司名称'] ?? ''));
|
||
$serviceName = trim((string) ($row['对应客服公司'] ?? ''));
|
||
if ($storeName === '') {
|
||
continue;
|
||
}
|
||
if ($serviceName === '') {
|
||
$result['unassigned_rows']++;
|
||
continue;
|
||
}
|
||
|
||
$feeRate = $this->feeRate((string) ($row['结算比例'] ?? ''));
|
||
if ($feeRate === null) {
|
||
$result['invalid_rows'][] = "第 {$sourceRow} 行结算比例无效。";
|
||
continue;
|
||
}
|
||
|
||
$result['rows'][] = [
|
||
'service_company_name' => $serviceName,
|
||
'store_company_name' => $storeName,
|
||
'fee_rate' => $feeRate,
|
||
'source_row' => $sourceRow,
|
||
];
|
||
$result['assigned_rows']++;
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
private function feeRate(string $value): ?float
|
||
{
|
||
$normalized = trim(str_replace(['%', ',', ','], ['', '', ''], $value));
|
||
if ($normalized === '' || ! is_numeric($normalized)) {
|
||
return null;
|
||
}
|
||
|
||
$rate = (float) $normalized;
|
||
if ($rate > 1) {
|
||
$rate /= 100;
|
||
}
|
||
|
||
return $rate > 0 && $rate <= 1 ? round($rate, 6) : null;
|
||
}
|
||
}
|