taxInvoiceService->list($request->validated()); }, __('message.fetched')); } /** * 세금계산서 상세 조회 */ public function show(int $id) { return ApiResponse::handle(function () use ($id) { return $this->taxInvoiceService->show($id); }, __('message.fetched')); } /** * 세금계산서 생성 */ public function store(CreateTaxInvoiceRequest $request) { return ApiResponse::handle(function () use ($request) { return $this->taxInvoiceService->create($request->validated()); }, __('message.created')); } /** * 세금계산서 수정 */ public function update(UpdateTaxInvoiceRequest $request, int $id) { return ApiResponse::handle(function () use ($request, $id) { return $this->taxInvoiceService->update($id, $request->validated()); }, __('message.updated')); } /** * 세금계산서 삭제 */ public function destroy(int $id) { return ApiResponse::handle(function () use ($id) { $this->taxInvoiceService->delete($id); return null; }, __('message.deleted')); } /** * 세금계산서 발행 */ public function issue(int $id) { return ApiResponse::handle(function () use ($id) { return $this->taxInvoiceService->issue($id); }, __('message.tax_invoice.issued')); } /** * 세금계산서 일괄 발행 */ public function bulkIssue(BulkIssueRequest $request) { return ApiResponse::handle(function () use ($request) { return $this->taxInvoiceService->bulkIssue($request->getIds()); }, __('message.tax_invoice.bulk_issued')); } /** * 세금계산서 취소 */ public function cancel(CancelTaxInvoiceRequest $request, int $id) { return ApiResponse::handle(function () use ($request, $id) { return $this->taxInvoiceService->cancel($id, $request->validated()['reason']); }, __('message.tax_invoice.cancelled')); } /** * 국세청 전송 상태 조회 */ public function checkStatus(int $id) { return ApiResponse::handle(function () use ($id) { return $this->taxInvoiceService->checkStatus($id); }, __('message.fetched')); } /** * 세금계산서 요약 통계 */ public function summary(TaxInvoiceSummaryRequest $request) { return ApiResponse::handle(function () use ($request) { return $this->taxInvoiceService->summary($request->validated()); }, __('message.fetched')); } // ========================================================================= // 분개 (Journal Entries) // ========================================================================= /** * 세금계산서 분개 조회 */ public function getJournalEntries(int $id): JsonResponse { return ApiResponse::handle(function () use ($id) { $sourceKey = "tax_invoice_{$id}"; $data = $this->journalSyncService->getForSource( JournalEntry::SOURCE_TAX_INVOICE, $sourceKey ); return $data ?? ['rows' => []]; }, __('message.fetched')); } /** * 세금계산서 분개 저장/수정 */ public function storeJournalEntries(Request $request, int $id): JsonResponse { return ApiResponse::handle(function () use ($request, $id) { $validated = $request->validate([ 'rows' => 'required|array|min:1', 'rows.*.side' => 'required|in:debit,credit', 'rows.*.account_subject' => 'required|string|max:20', 'rows.*.debit_amount' => 'required|integer|min:0', 'rows.*.credit_amount' => 'required|integer|min:0', ]); // 세금계산서 정보 조회 (entry_date용) $taxInvoice = $this->taxInvoiceService->show($id); $rows = array_map(fn ($row) => [ 'side' => $row['side'], 'account_code' => $row['account_subject'], 'debit_amount' => $row['debit_amount'], 'credit_amount' => $row['credit_amount'], ], $validated['rows']); $sourceKey = "tax_invoice_{$id}"; return $this->journalSyncService->saveForSource( JournalEntry::SOURCE_TAX_INVOICE, $sourceKey, $taxInvoice->issue_date?->format('Y-m-d') ?? now()->format('Y-m-d'), "세금계산서 분개 (#{$id})", $rows, ); }, __('message.created')); } /** * 세금계산서 분개 삭제 */ public function deleteJournalEntries(int $id): JsonResponse { return ApiResponse::handle(function () use ($id) { $sourceKey = "tax_invoice_{$id}"; return $this->journalSyncService->deleteForSource( JournalEntry::SOURCE_TAX_INVOICE, $sourceKey ); }, __('message.deleted')); } }