49 lines
3.3 KiB
PHP
49 lines
3.3 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Business;
|
||
|
||
use Illuminate\Routing\Controller;
|
||
use Modules\EcommerceFinance\View\AccessoryReshipPageData;
|
||
|
||
class AccessoryReshipDeductions extends Controller
|
||
{
|
||
public function selectCourier(\Illuminate\Http\Request $request, AccessoryReshipPageData $data, \Modules\EcommerceFinance\Services\AccessoryReshipSelectionStore $store)
|
||
{
|
||
$input = $request->validate([
|
||
'month' => ['required', 'date_format:Y-m', 'after_or_equal:2000-01'],
|
||
'row_key' => ['required', 'regex:/^[a-f0-9]{64}$/'],
|
||
'courier' => ['required', 'string', 'max:191'],
|
||
]);
|
||
// 重新读取候选,禁止提交任意快递名称或其他公司的包裹。
|
||
$found = false;
|
||
foreach ($data->rows(['month' => $input['month']]) as $row) {
|
||
if ($row['selection_key'] !== $input['row_key']) continue;
|
||
$found = in_array($input['courier'], array_column($row['courier_candidates'], 'courier'), true);
|
||
break;
|
||
}
|
||
abort_unless($found, 422, '该快递已不在当前首发候选中,请刷新后重新选择。');
|
||
$store->save((int) company_id(), $input['month'], $input['row_key'], $input['courier'], mb_substr((string) user()->name, 0, 191));
|
||
return response()->json(['message' => '扣款快递已保存。']);
|
||
}
|
||
|
||
public function export(AccessoryReshipPageData $data)
|
||
{
|
||
$filters = $data->filters();
|
||
// 先完成读取,失败时返回正常错误,避免下载半份扣款清单。
|
||
$file = tmpfile();
|
||
if ($file === false) abort(500, '无法创建导出文件。');
|
||
fwrite($file, "\xEF\xBB\xBF");
|
||
fputcsv($file, ['交易单号','补发快递单号','补发快递','补发时间','原始条形码','处理后条形码','补发运费','匹配状态','首发快递公司(候选)','首发快递单号(候选)','首发所属月份(候选)','扣款比例(%)','扣款金额','说明']);
|
||
foreach ($data->rows($filters) as $row) {
|
||
if (!AccessoryReshipPageData::inCategory($row, $filters['match_status'])) continue;
|
||
$values = [$row['trade_no'], $row['express_no'], ($row['express_name1'] ?: ($row['express_name2'] ?? '')), $row['ship_time'], $row['barcode'], $row['normalized_barcode'], $row['freight'], $row['deduction_state'] === 'ready' ? '可扣款' : ($row['status'] === 'matched' ? '已匹配待核对' : '未匹配不扣款'), implode(' / ', array_column($row['matches'], 'courier')), implode(' / ', array_column($row['matches'], 'express_no')), implode(' / ', array_column($row['matches'], 'month')), $row['deduction_rate_basis_points'] === null ? '' : number_format($row['deduction_rate_basis_points'] / 100, 2, '.', '') . '%', $row['deduction_cents'] === null ? '' : number_format($row['deduction_cents'] / 100, 2, '.', ''), $row['deduction_note']];
|
||
fputcsv($file, array_map(static function ($value) {
|
||
$value = (string) $value;
|
||
return preg_match('/^[=+\-@\t\r\n]/u', $value) ? "'" . $value : $value;
|
||
}, $values));
|
||
}
|
||
rewind($file);
|
||
return response()->streamDownload(function () use ($file) { fpassthru($file); fclose($file); }, '配件补发扣款-' . $filters['month'] . '.csv', ['Content-Type' => 'text/csv; charset=UTF-8']);
|
||
}
|
||
}
|