supplierContext(); $data = $this->pageData->portalData($supplier, $companyId); return view('portal.supplier-reconciliation.index', array_merge($data, [ 'contact' => $contact, 'supplier' => $supplier, 'statementTemplateUrl' => route('portal.supplier-reconciliation.template'), 'uploadUrl' => route('portal.supplier-reconciliation.statement.upload'), 'returnConfirmUrl' => route('portal.supplier-reconciliation.return.confirm'), 'returnDisputeUrl' => route('portal.supplier-reconciliation.return.dispute'), 'returnConfirmAllUrl' => route('portal.supplier-reconciliation.return.confirm-all'), ])); } public function template(): BinaryFileResponse { $this->supplierContext(); $path = $this->template->path(); abort_unless(is_file($path), 404, '对账单模板不存在。'); return response()->download($path, $this->template->filename()); } public function upload(Request $request): JsonResponse|RedirectResponse { $request->validate([ 'import' => ['required', 'file', 'mimes:xlsx,xls,csv', 'max:51200'], ]); [, $supplier, $companyId] = $this->supplierContext(); $records = $this->template->parse($request->file('import'), $supplier); $rows = $this->statements->save( $supplier, $records, (string) $request->file('import')->getClientOriginalName(), $companyId, user_id() ? (int) user_id() : null, ); $message = "对账单已保存:{$supplier} 共 {$rows} 行。"; return $request->expectsJson() ? response()->json(['message' => $message, 'rows' => $rows]) : redirect() ->route('portal.supplier-reconciliation.index', ['company_id' => $companyId]) ->with('success', $message); } public function confirmReturn(Request $request): RedirectResponse { return $this->markReturn($request, SupplierReturnConfirmation::STATUS_CONFIRMED, '已确认该行退货扣减。'); } public function disputeReturn(Request $request): RedirectResponse { return $this->markReturn($request, SupplierReturnConfirmation::STATUS_DISPUTED, '已提交异议,复核通过前该行暂不扣减。'); } public function confirmAllReturns(Request $request): RedirectResponse { [, $supplier, $companyId] = $this->supplierContext(); $keys = array_values(array_map( static fn (array $row): string => (string) ($row['_action_key'] ?? ''), $this->pageData->returnRowsForFilters($supplier, $companyId, $request->all()), )); $confirmed = $this->returnConfirmations->confirmAll( $supplier, $keys, $companyId, user_id() ? (int) user_id() : null, ); return back()->with('success', "已全部确认:{$confirmed} 行退货扣减生效(异议行保持暂不扣减)。"); } public function exportReturns(Request $request): StreamedResponse { [, $supplier, $companyId] = $this->supplierContext(); $rows = $this->pageData->returnRowsForFilters($supplier, $companyId, $request->query()); return $this->returnCsvExporter->download($rows, $supplier); } private function markReturn(Request $request, string $status, string $message): RedirectResponse { $request->validate(['key' => ['required', 'string', 'max:191']]); [, $supplier, $companyId] = $this->supplierContext(); $key = (string) $request->input('key'); $owned = collect($this->pageData->returnRows($supplier, $companyId)) ->contains(static fn (array $row): bool => (string) ($row['_action_key'] ?? '') === $key); abort_unless($owned, 403, '该退货明细不属于当前厂家账号。'); $this->returnConfirmations->mark( $supplier, $key, $status, $companyId, user_id() ? (int) user_id() : null, ); return back()->with('success', $message); } /** @return array{0:Contact,1:string,2:int} */ private function supplierContext(): array { $contact = user()->contact; abort_unless( $contact instanceof Contact && $contact->type === Contact::VENDOR_TYPE && $contact->enabled, 403, '当前账号未绑定有效的厂家资料,请联系财务人员。', ); $supplier = trim((string) $contact->name); abort_if($supplier === '', 403, '当前厂家账号未设置供应商名称,请联系财务人员。'); return [$contact, $supplier, (int) (company_id() ?: 1)]; } }