servchan/src/services/workOrderNteService.js
jmcqueen 6ecdf6ee69 Add NTE floor on WO open and refine close-out digest rules.
Raise NTE to $400 when a new WO space opens, align /createWO defaults with SC_WO_OPEN_MIN_NTE, limit the daily digest to all non-invoiced COMPLETED WOs, and add unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-27 10:57:42 -04:00

43 lines
1.4 KiB
JavaScript

/**
* Minimum NTE floor when a new Webex WO space is opened (first webhook).
* Pure logic — no ServiceChannel client import (safe for unit tests).
*/
function parseNumberEnv(name, fallback) {
const raw = process.env[name];
if (raw == null || raw === '') return fallback;
const n = Number(raw);
return Number.isFinite(n) ? n : fallback;
}
/** Minimum NTE applied on new space open; 0 disables the feature. */
export function getWoOpenMinNte() {
return parseNumberEnv('SC_WO_OPEN_MIN_NTE', 400);
}
export function createWorkOrderNteService({
getWorkOrderForNte: getWo,
updateWorkOrderNte: updateNte,
} = {}) {
if (typeof getWo !== 'function' || typeof updateNte !== 'function') {
throw new Error('createWorkOrderNteService requires getWorkOrderForNte and updateWorkOrderNte');
}
async function ensureWorkOrderMinimumNte(woId, { minNte = 400, hintNte = null } = {}) {
if (!woId || minNte <= 0) return { updated: false, skipped: true };
let current = hintNte != null ? Number(hintNte) : NaN;
if (!Number.isFinite(current)) {
const wo = await getWo(woId);
current = Number(wo?.Nte);
}
if (!Number.isFinite(current) || current >= minNte) {
return { updated: false, nte: current };
}
await updateNte(woId, minNte);
return { updated: true, previousNte: current, nte: minNte };
}
return { ensureWorkOrderMinimumNte };
}