151 lines
3.3 KiB
TypeScript
151 lines
3.3 KiB
TypeScript
import { IDWithPrefix } from "#components/Ausweis/types.js";
|
|
import { transport } from "#lib/mail.js";
|
|
import { adminMiddleware } from "#lib/middleware/authorization.js";
|
|
import { mollieClient } from "#lib/mollie.js";
|
|
import { getPrismaAusweisAdapter } from "#lib/server/ausweis.js";
|
|
import { Benutzer, Prisma, prisma } from "#lib/server/prisma.js";
|
|
import { RefundStatus } from "@mollie/api-client";
|
|
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
|
import { z } from "zod";
|
|
|
|
export const PUT = defineApiRoute({
|
|
input: z.object({
|
|
ausweis_id: IDWithPrefix
|
|
}),
|
|
middleware: adminMiddleware,
|
|
async fetch(input, context, transfer) {
|
|
const adapter = getPrismaAusweisAdapter(input.ausweis_id) as Prisma.VerbrauchsausweisWohnenDelegate;
|
|
|
|
if (!adapter) {
|
|
throw new APIError({
|
|
code: "BAD_REQUEST",
|
|
message: "Ungültige 'uid_ausweis'"
|
|
})
|
|
}
|
|
|
|
const ausweis = await adapter.findUnique({
|
|
where: {
|
|
id: input.ausweis_id
|
|
}
|
|
})
|
|
|
|
if (!ausweis) {
|
|
throw new APIError({
|
|
code: "NOT_FOUND",
|
|
message: "Ausweis konnte nicht gefunden werden."
|
|
})
|
|
}
|
|
|
|
const user = await prisma.benutzer.findUnique({
|
|
where: {
|
|
id: ausweis.benutzer_id as string
|
|
}
|
|
}) as Benutzer;
|
|
|
|
const response = await adapter.findUnique({
|
|
where: {
|
|
id: input.ausweis_id
|
|
},
|
|
select: {
|
|
rechnung: true
|
|
}
|
|
})
|
|
|
|
if (!response || !response.rechnung) {
|
|
await adapter.update({
|
|
where: {
|
|
id: input.ausweis_id
|
|
},
|
|
data: {
|
|
storniert: true
|
|
}
|
|
})
|
|
|
|
throw new APIError({
|
|
code: "NOT_FOUND",
|
|
message: "Rechnung konnte nicht gefunden werden aber Ausweis wurde storniert."
|
|
})
|
|
}
|
|
|
|
const rechnung = response.rechnung;
|
|
|
|
await adapter.update({
|
|
where: {
|
|
id: input.ausweis_id
|
|
},
|
|
data: {
|
|
storniert: true,
|
|
rechnung: {
|
|
update: {
|
|
status: "canceled",
|
|
storniert_am: new Date()
|
|
}
|
|
}
|
|
},
|
|
select: {
|
|
rechnung: {
|
|
select: {
|
|
betrag: true,
|
|
bezahlmethode: true,
|
|
status: true
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
if (rechnung.betrag > 0 && rechnung.bezahlmethode !== "rechnung" && rechnung.status === "paid" && rechnung.transaktions_referenz) {
|
|
const refund = await mollieClient.paymentRefunds.create({
|
|
description: "Rückerstattung IBCornelsen",
|
|
paymentId: rechnung.transaktions_referenz,
|
|
amount: {
|
|
currency: "EUR",
|
|
value: rechnung.betrag.toFixed(2)
|
|
},
|
|
metadata: {
|
|
rechnung_id: rechnung.id
|
|
},
|
|
testmode: true
|
|
})
|
|
|
|
if (refund.status === RefundStatus.failed) {
|
|
throw new APIError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: "Rückerstattung konnte nicht durchgeführt werden, Mollie hat die Rückerstattung abgelehnt."
|
|
})
|
|
}
|
|
}
|
|
|
|
await transport.sendMail({
|
|
from: `"IBCornelsen" <info@online-energieausweis.org>`,
|
|
to: rechnung.email || user.email,
|
|
bcc: "info@online-energieausweis.org",
|
|
subject: `Stornierung des Energieausweises vom Ingenieurbüro Cornelsen (ID: ${ausweis.id})`,
|
|
html: `<p>Sehr geehrte*r ${user.vorname} ${user.name},</p>
|
|
|
|
<p>Ihr Energieausweis wurde soeben storniert.
|
|
<br>
|
|
<p>
|
|
<p>
|
|
Mit freundlichen Grüßen,
|
|
<br>
|
|
Dipl.-Ing. Jens Cornelsen
|
|
<br>
|
|
<br>
|
|
|
|
<strong>IB Cornelsen</strong>
|
|
<br>
|
|
Katendeich 5A
|
|
<br>
|
|
21035 Hamburg
|
|
<br>
|
|
www.online-energieausweis.org
|
|
<br>
|
|
<br>
|
|
|
|
fon 040 · 209339850
|
|
<br>
|
|
fax 040 · 209339859
|
|
</p>`
|
|
});
|
|
},
|
|
}) |