保留各家工作表报价原文、公式、独立执行日期及签署原件;审核后按执行日期管理版本。33项测试、336项断言通过。生产业务迁移已获明确授权,服务器私有备份已完成并逐条校验。
112 lines
4.9 KiB
PHP
112 lines
4.9 KiB
PHP
<?php
|
||
|
||
namespace App\Support;
|
||
|
||
use App\Models\Business\CourierQuoteVersion;
|
||
|
||
final class CourierQuoteConfirmation
|
||
{
|
||
public function data(CourierQuoteVersion $version): array
|
||
{
|
||
$version->loadMissing(['change.items']);
|
||
$values = $this->decodeMatrix($version->values_json);
|
||
$nextVersion = CourierQuoteVersion::query()
|
||
->where('carrier_name', $version->carrier_name)
|
||
->where('quote_type', $version->quote_type)
|
||
->where('courier_expcode', $version->courier_expcode)
|
||
->where('status', 'approved')
|
||
->where('effective_date', '>', $version->effective_date)
|
||
->whereNull('end_date')
|
||
->orderBy('effective_date')
|
||
->first();
|
||
// 短期变价到期后恢复的长期报价(打印在确认单上,让快递知道到期后按哪份执行)。
|
||
$restore = $version->isTemporary()
|
||
? \App\Support\CourierRequoteService::resolveAt(
|
||
CourierQuoteVersion::query()->with('signature')->where('company_name', $version->company_name)
|
||
->where('courier_expcode', $version->courier_expcode)
|
||
->when(filled($version->courier_expcode), fn ($query) => $query->where('quote_type', $version->quote_type))
|
||
->where('status', 'approved')->where('id', '!=', $version->id)->get(),
|
||
$version->end_date->copy()->addDay(),
|
||
false,
|
||
)
|
||
: null;
|
||
|
||
return [
|
||
'version_id' => $version->id,
|
||
'version_code' => $version->version_code,
|
||
'party_a' => company((int) $version->company_id)?->name ?: '当前公司',
|
||
'party_b' => $version->carrier_name,
|
||
'carrier_name' => $version->carrier_name,
|
||
'quote_type' => $version->quote_type,
|
||
'effective_date' => $version->effective_date?->toDateString(),
|
||
'expiry_date' => $version->isTemporary()
|
||
? $version->end_date->toDateString()
|
||
: ($nextVersion?->effective_date?->copy()->subDay()->toDateString() ?: '长期'),
|
||
'temporary_note' => $version->isTemporary()
|
||
? '本报价为短期(临时)报价,仅在 ' . $version->effective_date->toDateString() . ' 至 ' . $version->end_date->toDateString() . ' 期间执行;'
|
||
. $version->end_date->copy()->addDay()->toDateString() . ' 起自动恢复' . ($restore ? '原报价 ' . $restore->version_code . '(' . $restore->effective_date->toDateString() . ' 起执行)' : '原长期报价') . ',无需另行签署。'
|
||
: null,
|
||
'face_fee' => $this->matrixMetric($values, ['面单费', '面单费用', '面单']),
|
||
'bubble_coefficient' => $this->matrixMetric($values, ['计泡系数', '泡系数', '计泡']),
|
||
'values' => $values,
|
||
'formulas' => $this->decodeMatrix($version->formulas_json),
|
||
];
|
||
}
|
||
|
||
private function decodeMatrix(?string $json): array
|
||
{
|
||
if (blank($json)) {
|
||
return [];
|
||
}
|
||
|
||
$decoded = json_decode($json, true);
|
||
|
||
return is_array($decoded) ? $decoded : [];
|
||
}
|
||
|
||
private function matrixMetric(array $values, array $labels): string
|
||
{
|
||
foreach ($values as $rowIndex => $row) {
|
||
if (! is_array($row)) {
|
||
continue;
|
||
}
|
||
|
||
foreach (array_values($row) as $columnIndex => $cell) {
|
||
$text = trim((string) $cell);
|
||
foreach ($labels as $label) {
|
||
if ($text !== $label && ! str_contains($text, $label)) {
|
||
continue;
|
||
}
|
||
|
||
$inline = trim((string) preg_replace('/^.*?' . preg_quote($label, '/') . '\\s*[::=]?\\s*/u', '', $text));
|
||
if ($inline !== '' && $inline !== $text && $inline !== $label) {
|
||
return $inline;
|
||
}
|
||
|
||
$columnValues = [];
|
||
foreach (array_slice($values, $rowIndex + 1) as $nextRow) {
|
||
$value = is_array($nextRow) ? ($nextRow[$columnIndex] ?? null) : null;
|
||
if ($value !== null && trim((string) $value) !== '') {
|
||
$columnValues[] = trim((string) $value);
|
||
}
|
||
}
|
||
$columnValues = array_values(array_unique($columnValues));
|
||
if (count($columnValues) === 1) {
|
||
return $columnValues[0];
|
||
}
|
||
if (count($columnValues) > 1) {
|
||
return '详见报价明细';
|
||
}
|
||
|
||
$adjacent = $row[$columnIndex + 1] ?? null;
|
||
if ($adjacent !== null && trim((string) $adjacent) !== '') {
|
||
return trim((string) $adjacent);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return '按报价明细';
|
||
}
|
||
}
|