import Foundation /// `/api/export/{csv,excel,pdf}` — Pro-only (403 `pro_required` for a /// free-plan account, surfaced via `APIError.server`). Every route takes the /// same request body and returns the raw file with its name in /// `Content-Disposition`; present the returned `Data` via `UIActivityViewController` /// (share sheet) or write it into a temp file and use `.fileExporter` / /// `QLPreviewController` — either is fine, this layer just gets you the bytes. enum ExportAPI { enum Format: String { case csv, excel, pdf var path: String { "/api/export/\(rawValue)" } var fallbackExtension: String { switch self { case .csv: return "csv" case .excel: return "xlsx" case .pdf: return "pdf" } } } struct ExportRequestBody: Encodable { let receipts: [Receipt] let locale: String // Only meaningful for the PDF export (date range on the cover page); // harmless to omit for csv/excel, which ignore unknown fields. var dateFrom: String? var dateTo: String? } struct ExportResult { let data: Data let fileName: String } /// - Parameters: /// - receipts: exactly the receipts to include — the backend does not /// look anything up server-side, it only formats what you send. /// - locale: `"de"` or `"en"`; anything else falls back to German on /// the backend, so just always pass one of the two. static func export( _ format: Format, receipts: [Receipt], locale: String = "de", dateFrom: String? = nil, dateTo: String? = nil ) async throws -> ExportResult { let body = ExportRequestBody(receipts: receipts, locale: locale, dateFrom: dateFrom, dateTo: dateTo) let request = try APIRequest.json(path: format.path, method: .post, body: body) let (data, suggestedName) = try await APIClient.shared.sendForFile(request) let fileName = suggestedName ?? "Belege_Export.\(format.fallbackExtension)" return ExportResult(data: data, fileName: fileName) } }