56 lines
2.1 KiB
TypeScript
56 lines
2.1 KiB
TypeScript
import { createRoute } from "../../../../../modules/api-utils/createRoute";
|
|
import { generatedQuotes } from "../../../../../managers/generatedQuotes";
|
|
import { apiResponse } from "../../../../../modules/api-utils/apiResponse";
|
|
import { injectPdfMetadata } from "../../../../../modules/pdf-utils";
|
|
import { ContentfulStatusCode } from "hono/utils/http-status";
|
|
import { authMiddleware } from "../../../../middleware/authorization";
|
|
import GenericError from "../../../../../Errors/GenericError";
|
|
|
|
const VALID_FETCH_ACTIONS = ["download", "print"] as const;
|
|
type FetchAction = (typeof VALID_FETCH_ACTIONS)[number];
|
|
|
|
/* GET /v1/sales/opportunities/:identifier/quote/:quoteId/download?fetchAction=download|print */
|
|
export default createRoute(
|
|
"get",
|
|
["/opportunities/:identifier/quote/:quoteId/download"],
|
|
async (c) => {
|
|
const quoteId = c.req.param("quoteId");
|
|
const user = c.get("user");
|
|
const fetchAction = c.req.query("fetchAction") as FetchAction | undefined;
|
|
|
|
if (!fetchAction || !VALID_FETCH_ACTIONS.includes(fetchAction)) {
|
|
throw new GenericError({
|
|
status: 400,
|
|
name: "InvalidFetchAction",
|
|
message: `Query parameter 'fetchAction' is required and must be one of: ${VALID_FETCH_ACTIONS.join(", ")}`,
|
|
});
|
|
}
|
|
|
|
const downloadedAt = new Date().toISOString();
|
|
|
|
const quote = await generatedQuotes.recordDownload(quoteId, {
|
|
id: user.id,
|
|
name: user.name,
|
|
email: user.email,
|
|
fetchAction,
|
|
});
|
|
|
|
// Inject download-time metadata into the PDF's document properties
|
|
const pdfWithMetadata = await injectPdfMetadata(quote.quoteFile, {
|
|
downloadedAt,
|
|
downloadedById: user.id,
|
|
downloadedByName: user.name ?? undefined,
|
|
downloadedByEmail: user.email ?? undefined,
|
|
});
|
|
|
|
const response = apiResponse.successful("Quote downloaded successfully!", {
|
|
id: quote.id,
|
|
quoteFileName: quote.quoteFileName,
|
|
mimeType: "application/pdf",
|
|
contentBase64: Buffer.from(pdfWithMetadata).toString("base64"),
|
|
});
|
|
return c.json(response, response.status as ContentfulStatusCode);
|
|
},
|
|
authMiddleware({ permissions: ["sales.opportunity.quote.download"] }),
|
|
);
|