function createOpportunityCrmServiceRequests({ requestCrmServiceRequest, isCurrentPeriodRequest, bindPopover, closePopover, createSrButton, closeSrForm, allowsCrmActivities, reportProgress, activityCache, setBadgeContent, formatDate, environment }) { let status = "idle"; let byOpportunity = new Map(); let pending = null; let generation = 0; let loadedItems = []; function reset() { closeSrForm(); closePopover(); generation += 1; pending = null; status = "idle"; byOpportunity = new Map(); loadedItems = []; reportProgress("idle"); } function load(token, version, cacheOptions = null) { if (!allowsCrmActivities() || !isCurrentPeriodRequest(version)) return; if (status === "ready") { return Promise.resolve(cacheOptions ? activityCache.write("sr", "all", cacheOptions.cachedAt, loadedItems) : undefined).then(() => true); } if (!pending) { const request = run(token, version, generation, cacheOptions); pending = request; request.finally(() => { if (pending === request) pending = null; }); } return pending; } async function run(token, version, currentGeneration, cacheOptions) { const isActive = () => currentGeneration === generation; status = "loading"; try { const cached = cacheOptions ? await activityCache.read("sr", "all", cacheOptions.cachedAt) : null; if (!isActive()) return false; if (!cached && cacheOptions?.cacheOnly) { status = "idle"; return false; } let items = cached?.items; if (!items) { reportProgress("running", 0); items = await requestCrmServiceRequest(token, version, isActive, (count, total) => { if (isActive()) reportProgress("running", count, total); }); if (items && isActive() && cacheOptions) await activityCache.write("sr", "all", cacheOptions.cachedAt, items); } if (!items || !isActive()) return false; const grouped = new Map(); for (const item of items) { const number = item?.OpportunityName_Id_c?.OptyNumber; if (!number) continue; const key = String(number); if (!grouped.has(key)) grouped.set(key, []); grouped.get(key).push(item); } byOpportunity = grouped; loadedItems = items; status = "ready"; if (!cached) reportProgress("complete", items.length, items.length); return true; } catch { if (isActive()) { status = "error"; reportProgress("error"); } return false; } } function getSummary(optyNumber) { if (!allowsCrmActivities() || !optyNumber) return null; const items = byOpportunity.get(String(optyNumber)) || []; const hours = items.map(item => item.ReportedHours_c).filter(value => (typeof value === "number" || (typeof value === "string" && value.trim() !== "")) && Number.isFinite(Number(value)) ).map(Number); return { state: status === "ready" ? items.length ? "matched" : "missing" : status, reportedHours: hours.length === items.length ? hours.reduce((total, value) => total + value, 0) : null, hasUnderFourHours: status === "ready" && hours.some(value => value < 4) }; } function createBadge(optyNumber) { if (!allowsCrmActivities() || !optyNumber || status === "idle" || status === "loading") return null; const items = byOpportunity.get(String(optyNumber)) || []; const badge = environment.document.createElement(items.length && status === "ready" ? "button" : "span"); badge.className = "opportunities-extension-crm-sr-badge"; badge.setAttribute("data-state", status === "error" ? "error" : items.length ? "matched" : "missing"); const summary = getSummary(optyNumber); const reportedHours = summary.reportedHours !== null ? new Intl.NumberFormat("en-US", { useGrouping: false, maximumFractionDigits: 10 }).format(summary.reportedHours) : "N/A"; setBadgeContent(badge, "sr", status === "error" ? "?" : items.length ? `${reportedHours}${reportedHours === "N/A" ? "" : "h"}` : "0h"); const display = value => value === null || value === undefined || value === "" ? "N/A" : String(value); const descriptions = items.map(item => [ `Title: ${display(item.Title)}`, `Opportunity: ${display(item.OpportunityName_Id_c?.OptyNumber)}`, `Reported Hours: ${display(item.ReportedHours_c)}`, `Customer Deadline: ${display(formatDate(item.CustomerDeadline_c))}`, `Owner: ${[item.Owner?.PersonFirstName, item.Owner?.PersonLastName].filter(Boolean).join(" ") || "N/A"}`, `Email: ${display(item.Owner?.PrimaryEmail?.EmailAddress)}`, `Do Not Call: ${display(item.DoNotCallFlag)}`, `Do Not Email: ${display(item.DoNotEmailFlag)}` ].join("\n")); const description = status === "error" ? "Unable to check CRM service requests. See Debug Requests." : !items.length ? "No matching CRM service request with status SVC_PENDING_DELIVERY in your SR team." : items.map((item, index) => `SR Number: ${display(item.SrNumber)}\n${descriptions[index]}`).join("\n\n"); badge.setAttribute("aria-label", description); badge.title = "Whether a Service Request has been created for the opportunities."; if (items.length && status === "ready") bindPopover(badge, items, descriptions); if (!items.length && status === "ready") badge.append(createSrButton(String(optyNumber))); badge.tabIndex = 0; return badge; } return { reset, load, createBadge, getSummary }; }