103 lines
3.3 KiB
TypeScript
103 lines
3.3 KiB
TypeScript
import { Socket } from "socket.io";
|
|
import { attachSocketEventPermissions } from "../middleware/authorization";
|
|
import { opportunities } from "../../../managers/opportunities";
|
|
|
|
const LIVE_QUOTE_PREVIEW_PERMISSION = "sales.opportunity.fetch";
|
|
|
|
export const registerLiveQuotePreviewHandlers = (socket: Socket) => {
|
|
attachSocketEventPermissions(socket, {
|
|
"opp:live_quote_preview": [LIVE_QUOTE_PREVIEW_PERMISSION],
|
|
});
|
|
|
|
const registeredLivePreviewEvents = new Set<string>();
|
|
|
|
socket.on(
|
|
"opp:live_quote_preview",
|
|
async (
|
|
payload: { id?: string | number },
|
|
ack?: (response: { ok: boolean; event?: string; error?: string }) => void,
|
|
) => {
|
|
const oppId = payload?.id;
|
|
const normalizedId =
|
|
typeof oppId === "string" || typeof oppId === "number"
|
|
? `${oppId}`
|
|
: "";
|
|
|
|
if (!normalizedId) {
|
|
if (ack) return ack({ ok: false, error: "Missing opportunity id" });
|
|
socket.emit("opp:live_quote_preview:error", {
|
|
message: "Missing opportunity id",
|
|
});
|
|
return;
|
|
}
|
|
|
|
const dataEvent = `opp:live_quote_preview:${normalizedId}:data`;
|
|
const previewEvent = `opp:live_quote_preview:${normalizedId}:preview`;
|
|
const roomName = `opp:live_quote_preview:${normalizedId}`;
|
|
|
|
if (!registeredLivePreviewEvents.has(dataEvent)) {
|
|
registeredLivePreviewEvents.add(dataEvent);
|
|
socket.join(roomName);
|
|
|
|
socket.on(dataEvent, async (data: any) => {
|
|
socket.to(roomName).emit(dataEvent, data);
|
|
|
|
try {
|
|
const opportunity = await opportunities.fetchRecord(normalizedId);
|
|
const opts =
|
|
data?.options && typeof data.options === "object"
|
|
? data.options
|
|
: data;
|
|
|
|
const previewBuffer = await opportunity.generateQuote({
|
|
lineItemPricing: opts?.lineItemPricing,
|
|
includeQuoteNarrative: opts?.includeQuoteNarrative,
|
|
includeItemNarratives: opts?.includeItemNarratives,
|
|
logoPath: opts?.logoPath,
|
|
showPreview: true,
|
|
});
|
|
|
|
const previewBase64 = Buffer.from(previewBuffer).toString("base64");
|
|
|
|
socket.to(roomName).emit(previewEvent, {
|
|
id: normalizedId,
|
|
mimeType: "application/pdf",
|
|
contentBase64: previewBase64,
|
|
});
|
|
|
|
socket.to(roomName).emit(dataEvent, {
|
|
id: normalizedId,
|
|
mimeType: "application/pdf",
|
|
contentBase64: previewBase64,
|
|
});
|
|
|
|
socket.emit(previewEvent, {
|
|
id: normalizedId,
|
|
mimeType: "application/pdf",
|
|
contentBase64: previewBase64,
|
|
});
|
|
|
|
socket.emit(dataEvent, {
|
|
id: normalizedId,
|
|
mimeType: "application/pdf",
|
|
contentBase64: previewBase64,
|
|
});
|
|
} catch (err: any) {
|
|
socket.emit("opp:live_quote_preview:error", {
|
|
message: err?.message ?? "Failed to generate live quote preview",
|
|
id: normalizedId,
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
if (ack) return ack({ ok: true, event: dataEvent });
|
|
|
|
socket.emit("opp:live_quote_preview:ready", {
|
|
id: normalizedId,
|
|
event: dataEvent,
|
|
});
|
|
},
|
|
);
|
|
};
|