- 种菜数据汇总新增「种菜报销工作台」:按聚工单锁单口径取单(待处理 WAIT_CONFIRM、付款 D-7~D-1、ERP订单状态非取消/删除/空、售后单号为空;可切换处理中 CONFIRMING 和付款起始日),逐单校验重复报销、金额公式、佣金资格、收款人在职、以旧换新买家实付(取买家实付/看板订单实付中最低,查不到标签的待复查)、看板超额(同日按付款先后报到日限额)与看板未匹配 - 导出前须勾选「已在聚工单核对条数和金额一致」;页面给出应核对的条数/金额、各口径合计自检,聚工单镜像停更超过 20 分钟时提示先别报销 - 页面给出可报销合计(三大天猫/其他)、钉钉「种菜报销流程」明细行、按发起人的发群通知与取消清单 - 导出种菜对账、种菜报销明细(打款卡号明细表)、聚工单种菜任务工单导入模版,格式对齐手工文件 - 财务可上传种菜监控看板、报销佣金人员、花名册在职、店铺信息;名单存 storage 持久卷 JSON,花名册只存姓名 - 聚工单镜像读取补充 ERP订单标签、待报销工单和已报销订单查询 涉及:只读聚工单镜像;不涉及迁移、上游写入、钉钉和聚工单写操作。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VANWYsNUbu2piMtCKymoyd
71 lines
3.3 KiB
PHP
71 lines
3.3 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Business;
|
||
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Routing\Controller;
|
||
use InvalidArgumentException;
|
||
use Modules\EcommerceFinance\Services\PlantingReimbursementReferences as References;
|
||
use Modules\EcommerceFinance\Services\PlantingReimbursementWorkbookExporter as Exporter;
|
||
use Modules\EcommerceFinance\View\PlantingReimbursementWorkbenchPageData as PageData;
|
||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||
|
||
/** 种菜报销工作台:上传参考名单、导出对账 / 打款明细 / 种菜任务工单导入模板。 */
|
||
class PlantingReimbursementWorkbench extends Controller
|
||
{
|
||
public function upload(Request $request, string $kind, References $references)
|
||
{
|
||
abort_unless(isset(References::KINDS[$kind]), 404);
|
||
$request->validate(['file' => ['required', 'file', 'max:51200']]);
|
||
$file = $request->file('file');
|
||
$name = (string) $file->getClientOriginalName();
|
||
$redirect = redirect()->route('business.pages.show', [
|
||
'company_id' => company_id(),
|
||
'section' => 'planting-data',
|
||
'page' => 'planting-reimbursement-workbench',
|
||
'date' => (string) $request->input('date', ''),
|
||
'paid_from' => (string) $request->input('paid_from', ''),
|
||
'scope' => (string) $request->input('scope', ''),
|
||
]);
|
||
|
||
try {
|
||
$rows = $references->parse($kind, (string) $file->getRealPath(), $name);
|
||
$references->replace((int) company_id(), $kind, $rows, $name, optional(user())->id);
|
||
} catch (InvalidArgumentException $exception) {
|
||
return $redirect->with('error', References::KINDS[$kind] . '上传失败:' . $exception->getMessage());
|
||
} catch (\Throwable $exception) {
|
||
report($exception);
|
||
|
||
return $redirect->with('error', References::KINDS[$kind] . '上传失败,请检查文件格式后重新上传。');
|
||
}
|
||
|
||
return $redirect->with('success', sprintf('%s已更新:%s 条。', References::KINDS[$kind], number_format(count($rows))));
|
||
}
|
||
|
||
public function export(string $type, PageData $page, Exporter $exporter)
|
||
{
|
||
abort_unless(isset(Exporter::TYPES[$type]), 404);
|
||
$filters = $page->filters();
|
||
// 导出前必须先在聚工单核对条数、金额一致。
|
||
if (request('verified') !== '1') {
|
||
return redirect()->route('business.pages.show', [
|
||
'company_id' => company_id(), 'section' => 'planting-data', 'page' => 'planting-reimbursement-workbench',
|
||
] + array_diff_key($filters, ['decision' => true]))->with('error', '请先在聚工单按同样条件查询,核对条数和最终报销金额一致后,勾选「已核对」再导出。');
|
||
}
|
||
|
||
try {
|
||
$result = $page->build($filters);
|
||
$spreadsheet = $exporter->build($type, $result);
|
||
} catch (\Throwable $exception) {
|
||
report($exception);
|
||
abort(503, '聚工单镜像未就绪,未生成不完整的导出文件,请稍后重试。');
|
||
}
|
||
|
||
return response()->streamDownload(static function () use ($spreadsheet): void {
|
||
(new Xlsx($spreadsheet))->save('php://output');
|
||
}, $exporter->fileName($type, $result['summary']), [
|
||
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||
]);
|
||
}
|
||
}
|