Files
FEDEO/backend/src/routes/exports.ts

190 lines
5.6 KiB
TypeScript

import { FastifyInstance } from "fastify";
import {buildExportZip} from "../utils/export/datev";
import {s3} from "../utils/s3";
import {GetObjectCommand, PutObjectCommand} from "@aws-sdk/client-s3"
import {getSignedUrl} from "@aws-sdk/s3-request-presigner";
import dayjs from "dayjs";
import {randomUUID} from "node:crypto";
import {secrets} from "../utils/secrets";
import {createSEPAExport} from "../utils/export/sepa";
import {generatedexports} from "../../db/schema";
import {eq} from "drizzle-orm";
const createDatevExport = async (server:FastifyInstance,req:any,startDate,endDate,beraternr,mandantennr) => {
try {
console.log(startDate,endDate,beraternr,mandantennr)
// 1) ZIP erzeugen
const buffer = await buildExportZip(server,req.user.tenant_id, startDate, endDate, beraternr, mandantennr)
console.log("ZIP created")
console.log(buffer)
// 2) Dateiname & Key festlegen
const fileKey = `${req.user.tenant_id}/exports/Export_${dayjs(startDate).format("YYYY-MM-DD")}_${dayjs(endDate).format("YYYY-MM-DD")}_${randomUUID()}.zip`
console.log(fileKey)
// 3) In S3 hochladen
await s3.send(
new PutObjectCommand({
Bucket: secrets.S3_BUCKET,
Key: fileKey,
Body: buffer,
ContentType: "application/zip",
})
)
// 4) Presigned URL erzeugen (24h gültig)
const url = await getSignedUrl(
s3,
new GetObjectCommand({
Bucket: secrets.S3_BUCKET,
Key: fileKey,
}),
{ expiresIn: 60 * 60 * 24 }
)
console.log(url)
// 5) In Haupt-DB speichern
const inserted = await server.db
.insert(generatedexports)
.values({
tenantId: req.user.tenant_id,
startDate: new Date(startDate),
endDate: new Date(endDate),
validUntil: dayjs().add(24, "hours").toDate(),
filePath: fileKey,
url,
type: "datev",
})
.returning()
console.log(inserted[0])
} catch (error) {
console.log(error)
}
}
const createSepaExport = async (server: FastifyInstance, req: any, idsToExport: number[], creditorBankaccountId: number) => {
const exportData = await createSEPAExport(server, idsToExport, req.user.tenant_id, creditorBankaccountId)
const fileKey = `${req.user.tenant_id}/exports/SEPA_${dayjs().format("YYYY-MM-DD")}_${randomUUID()}.xml`
await s3.send(
new PutObjectCommand({
Bucket: secrets.S3_BUCKET,
Key: fileKey,
Body: exportData.buffer,
ContentType: "application/xml",
})
)
const url = await getSignedUrl(
s3,
new GetObjectCommand({
Bucket: secrets.S3_BUCKET,
Key: fileKey,
}),
{ expiresIn: 60 * 60 * 24 }
)
const inserted = await server.db
.insert(generatedexports)
.values({
tenantId: req.user.tenant_id,
startDate: exportData.startDate,
endDate: exportData.endDate,
validUntil: dayjs().add(24, "hours").toDate(),
filePath: fileKey,
url,
type: "sepa",
})
.returning()
console.log(inserted[0])
}
export default async function exportRoutes(server: FastifyInstance) {
//Export DATEV
server.post("/exports/datev", async (req, reply) => {
const { start_date, end_date, beraternr, mandantennr } = req.body as {
start_date: string
end_date: string
beraternr: string
mandantennr: string
}
reply.send({success:true})
setImmediate(async () => {
try {
await createDatevExport(server,req,start_date,end_date,beraternr,mandantennr)
console.log("Job done ✅")
} catch (err) {
console.error("Job failed ❌", err)
}
})
})
server.post("/exports/sepa", async (req, reply) => {
const { idsToExport, creditorBankaccountId } = req.body as {
idsToExport: Array<number>
creditorBankaccountId: number
}
if (!idsToExport?.length || !creditorBankaccountId) {
return reply.send({
success: false,
message: "Belege und Gläubigerkonto sind Pflichtfelder."
})
}
reply.send({success:true})
setImmediate(async () => {
try {
await createSepaExport(server, req, idsToExport, creditorBankaccountId)
console.log("Job done ✅")
} catch (err) {
console.error("Job failed ❌", err)
}
})
})
//List Exports Available for Download
server.get("/exports", async (req,reply) => {
const data = await server.db
.select({
id: generatedexports.id,
created_at: generatedexports.createdAt,
tenant_id: generatedexports.tenantId,
start_date: generatedexports.startDate,
end_date: generatedexports.endDate,
valid_until: generatedexports.validUntil,
type: generatedexports.type,
url: generatedexports.url,
file_path: generatedexports.filePath,
})
.from(generatedexports)
.where(eq(generatedexports.tenantId, req.user.tenant_id))
console.log(data)
reply.send(data)
})
}