import { createRoute } from "../../../../../modules/api-utils/createRoute"; import { opportunities } from "../../../../../managers/opportunities"; import { apiResponse } from "../../../../../modules/api-utils/apiResponse"; import { ContentfulStatusCode } from "hono/utils/http-status"; import { authMiddleware } from "../../../../middleware/authorization"; import { z } from "zod"; import { cwMembers } from "../../../../../managers/cwMembers"; import { createWorkflowActivity, OptimaType, } from "../../../../../workflows/wf.opportunity"; const commitQuoteSchema = z .object({ lineItemPricing: z.boolean().optional(), includeQuoteNarrative: z.boolean().optional(), includeItemNarratives: z.boolean().optional(), }) .strict() .optional(); /* POST /v1/sales/opportunities/:identifier/quote/commit */ export default createRoute( "post", ["/opportunities/:identifier/quote/commit"], async (c) => { const identifier = c.req.param("identifier"); const body = await c.req.json().catch(() => undefined); const opts = commitQuoteSchema.parse(body); const item = await opportunities.fetchRecord(identifier); const user = c.get("user"); const quote = await item.commitQuote(opts ?? {}, user); // Create a workflow activity for the generated quote try { let cwMemberId: number | null = null; if (user.cwIdentifier) { const cwMember = await cwMembers.fetch(user.cwIdentifier); cwMemberId = cwMember.cwMemberId; } if (cwMemberId) { await createWorkflowActivity({ name: `[Workflow] Quote generated — ${item.name}`, opportunityCwId: item.cwOpportunityId, companyCwId: item.companyCwId, assignToCwMemberId: cwMemberId, notes: `Quote "${quote.quoteFileName}" generated.`, optimaType: OptimaType.QuoteGenerated, quoteId: quote.id, }); } } catch (activityErr) { console.error( "[Quote Commit] Failed to create workflow activity:", activityErr, ); // Don't fail the quote commit if the activity fails } const response = apiResponse.created( "Quote committed successfully!", quote.toJson({ includeRegenData: true, includeRegenParams: true }), ); return c.json(response, response.status as ContentfulStatusCode); }, authMiddleware({ permissions: ["sales.opportunity.quote.commit"] }), );