mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 00:52:50 +00:00
100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Get,
|
|
Param,
|
|
ParseUUIDPipe,
|
|
Post,
|
|
Query,
|
|
Res,
|
|
} from "@nestjs/common";
|
|
import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger";
|
|
import type { Response } from "express";
|
|
import { CurrentUser } from "@edr/api-common";
|
|
|
|
import {
|
|
type AuthUserPayload,
|
|
resolveAuthUserId,
|
|
} from "../../common/resolve-auth-user-id";
|
|
import { sendPdf } from "./billing.controller";
|
|
import { BillingService } from "./billing.service";
|
|
import { PayInvoiceDto } from "./dto/pay-invoice.dto";
|
|
|
|
/**
|
|
* Customer-facing billing endpoints. Unlike {@link BillingController} (admin,
|
|
* org-wide), every route here is force-scoped to the signed-in customer's
|
|
* company — they only ever see and pay their own invoices.
|
|
*/
|
|
@ApiTags("billing")
|
|
@ApiBearerAuth()
|
|
@Controller("billing")
|
|
export class PortalBillingController {
|
|
constructor(private readonly billingService: BillingService) {}
|
|
|
|
@Get("my-invoices")
|
|
@ApiOperation({ summary: "List the signed-in customer's invoices" })
|
|
findMine(
|
|
@CurrentUser() user: AuthUserPayload,
|
|
@Query("source") source?: string,
|
|
@Query("sourceId") sourceId?: string,
|
|
) {
|
|
return this.billingService.findForUser(resolveAuthUserId(user), {
|
|
source,
|
|
sourceId,
|
|
});
|
|
}
|
|
|
|
@Get("my-invoices/:id")
|
|
@ApiOperation({ summary: "Get one of the customer's invoices (+ line items)" })
|
|
findMineById(
|
|
@Param("id", ParseUUIDPipe) id: string,
|
|
@CurrentUser() user: AuthUserPayload,
|
|
) {
|
|
return this.billingService.findByIdForUser(id, resolveAuthUserId(user));
|
|
}
|
|
|
|
@Get("my-invoices/:id/document")
|
|
@ApiOperation({ summary: "Download one of the customer's invoice PDFs" })
|
|
async document(
|
|
@Param("id", ParseUUIDPipe) id: string,
|
|
@CurrentUser() user: AuthUserPayload,
|
|
@Res() res: Response,
|
|
) {
|
|
const { filename, buffer } = await this.billingService.documentForUser(
|
|
id,
|
|
resolveAuthUserId(user),
|
|
);
|
|
sendPdf(res, filename, buffer);
|
|
}
|
|
|
|
@Get("my-invoices/:id/receipt")
|
|
@ApiOperation({ summary: "Download one of the customer's payment receipt PDFs" })
|
|
async receipt(
|
|
@Param("id", ParseUUIDPipe) id: string,
|
|
@CurrentUser() user: AuthUserPayload,
|
|
@Res() res: Response,
|
|
) {
|
|
const { filename, buffer } = await this.billingService.receiptForUser(
|
|
id,
|
|
resolveAuthUserId(user),
|
|
);
|
|
sendPdf(res, filename, buffer);
|
|
}
|
|
|
|
@Post("my-invoices/:id/pay")
|
|
@ApiOperation({ summary: "Initiate payment for one of the customer's invoices" })
|
|
pay(
|
|
@Param("id", ParseUUIDPipe) id: string,
|
|
@CurrentUser() user: AuthUserPayload,
|
|
@Body() dto: PayInvoiceDto,
|
|
) {
|
|
return this.billingService.payInvoiceForUser(id, resolveAuthUserId(user), {
|
|
method: dto.method,
|
|
platform: dto.platform ?? "web",
|
|
payerAccount: dto.payerAccount,
|
|
returnUrl: dto.returnUrl,
|
|
failureUrl: dto.failureUrl,
|
|
});
|
|
}
|
|
}
|