112 lines
4.5 KiB
PHP
112 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Business\ServiceCompanyReconciliation\CustomerServiceMappingWorkbookImporter;
|
|
use App\Business\ServiceCompanyReconciliation\ServiceCompanyReconciliationRepository;
|
|
use Illuminate\Console\Command;
|
|
|
|
class ImportServiceCompanyCustomerMapping extends Command
|
|
{
|
|
protected $signature = 'service-company:import-customer-mapping
|
|
{file : 客服公司映射 Excel 路径}
|
|
{--company-id=1 : 租户公司 ID}
|
|
{--effective-from=2026-10-01 : 结算关系生效日期}
|
|
{--auto-assign-period= : 未分配店铺按该月收入自动平衡,默认上一个完整月}
|
|
{--deactivate-empty-auto : 校正错误自动分配,停用报表当前月份无收入的自动来源关系}
|
|
{--actor=客服公司映射导入 : 导入操作人}
|
|
{--dry-run : 只解析和校验,不写入数据库}';
|
|
|
|
protected $description = '导入客服公司与店铺公司的配置映射';
|
|
|
|
public function handle(
|
|
CustomerServiceMappingWorkbookImporter $importer,
|
|
ServiceCompanyReconciliationRepository $repository,
|
|
): int {
|
|
$companyId = (int) $this->option('company-id');
|
|
$effectiveFrom = trim((string) $this->option('effective-from'));
|
|
$autoAssignPeriod = trim((string) $this->option('auto-assign-period'));
|
|
if ($autoAssignPeriod === '') {
|
|
$autoAssignPeriod = now()->startOfMonth()->subMonthNoOverflow()->format('Y-m');
|
|
}
|
|
try {
|
|
$parsed = $importer->rows((string) $this->argument('file'));
|
|
} catch (\Throwable $exception) {
|
|
$this->error($exception->getMessage());
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$this->table(['指标', '数量'], [
|
|
['店铺公司行数', $parsed['total_rows']],
|
|
['已分配客服公司', $parsed['assigned_rows']],
|
|
['暂不分配', $parsed['unassigned_rows']],
|
|
['无效行', count($parsed['invalid_rows'])],
|
|
]);
|
|
if ($parsed['invalid_rows'] !== []) {
|
|
$this->error(implode(PHP_EOL, $parsed['invalid_rows']));
|
|
|
|
return self::FAILURE;
|
|
}
|
|
if ((bool) $this->option('dry-run')) {
|
|
$this->info('校验通过,未写入数据库。');
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
$result = $repository->syncCustomerServiceMappings(
|
|
$companyId,
|
|
$parsed['rows'],
|
|
$effectiveFrom,
|
|
trim((string) $this->option('actor')) ?: '客服公司映射导入',
|
|
$parsed['unassigned'],
|
|
$autoAssignPeriod,
|
|
);
|
|
if ($result['errors'] !== []) {
|
|
$this->error(implode(PHP_EOL, $result['errors']));
|
|
|
|
return self::FAILURE;
|
|
}
|
|
|
|
$this->table(['结果', '数量'], [
|
|
['新增', $result['created']],
|
|
['更新', $result['updated']],
|
|
['无变化', $result['unchanged']],
|
|
['停用', $result['inactive']],
|
|
['自动补分配', $result['auto_assigned']],
|
|
['有收入但无法分配', count($result['auto_errors'])],
|
|
]);
|
|
if ($result['auto_totals'] !== []) {
|
|
$this->table(
|
|
['客服公司', '自动补分配后收入'],
|
|
collect($result['auto_totals'])
|
|
->map(static fn (float $amount, string $name): array => [$name, number_format($amount, 2, '.', '')])
|
|
->values()
|
|
->all(),
|
|
);
|
|
}
|
|
if ($result['auto_errors'] !== []) {
|
|
$this->warn(implode(PHP_EOL, $result['auto_errors']));
|
|
}
|
|
if ((bool) $this->option('deactivate-empty-auto')) {
|
|
$cleanup = $repository->deactivateAutoMappingsWithoutReportIncome(
|
|
$companyId,
|
|
$autoAssignPeriod,
|
|
trim((string) $this->option('actor')) ?: '客服公司映射导入',
|
|
);
|
|
if ($cleanup['errors'] !== []) {
|
|
$this->error(implode(PHP_EOL, $cleanup['errors']));
|
|
|
|
return self::FAILURE;
|
|
}
|
|
$this->table(['自动分配校正', '数量'], [
|
|
['停用无收入关系', $cleanup['deactivated']],
|
|
['保留有收入关系', $cleanup['kept']],
|
|
]);
|
|
}
|
|
$this->info("客服公司映射已同步,生效日期:{$effectiveFrom}");
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
}
|