feat: 세금계산서/거래명세서 일괄 발행 API 추가

- POST /api/v1/tax-invoices/bulk-issue: 세금계산서 일괄 발행
- POST /api/v1/sales/bulk-issue-statement: 거래명세서 일괄 발행
- FormRequest 검증 (최대 100건)
- Service 일괄 처리 로직 (개별 오류 처리)
- Swagger 문서 추가
- i18n 메시지 키 추가 (ko/en)
This commit is contained in:
2026-01-19 20:53:36 +09:00
parent 7dd683ace8
commit 0b94da0741
12 changed files with 444 additions and 0 deletions

View File

@@ -195,6 +195,54 @@ public function issue(int $id): TaxInvoice
return $this->barobillService->issueTaxInvoice($taxInvoice);
}
/**
* 세금계산서 일괄 발행
*
* @param array<int> $ids 발행할 세금계산서 ID 배열
* @return array{issued: int, failed: int, errors: array<int, string>}
*/
public function bulkIssue(array $ids): array
{
$tenantId = $this->tenantId();
$results = [
'issued' => 0,
'failed' => 0,
'errors' => [],
];
$taxInvoices = TaxInvoice::query()
->where('tenant_id', $tenantId)
->whereIn('id', $ids)
->get();
foreach ($taxInvoices as $taxInvoice) {
try {
if (! $taxInvoice->canEdit()) {
$results['errors'][$taxInvoice->id] = __('error.tax_invoice.already_issued');
$results['failed']++;
continue;
}
$this->barobillService->issueTaxInvoice($taxInvoice);
$results['issued']++;
} catch (\Throwable $e) {
$results['errors'][$taxInvoice->id] = $e->getMessage();
$results['failed']++;
}
}
// 요청된 ID 중 찾지 못한 것들도 실패 처리
$foundIds = $taxInvoices->pluck('id')->toArray();
$notFoundIds = array_diff($ids, $foundIds);
foreach ($notFoundIds as $notFoundId) {
$results['errors'][$notFoundId] = __('error.tax_invoice.not_found');
$results['failed']++;
}
return $results;
}
/**
* 세금계산서 취소
*/