node-autotask 0.11.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MCP_TOOL_CATALOG.json +26 -8
- package/MCP_TOOL_MANIFEST.md +12 -11
- package/N8N_MCP_MANIFEST.json +3 -3
- package/N8N_MCP_MANIFEST.md +4 -4
- package/README.md +1 -1
- package/capabilities.json +1352 -1233
- package/dist/capabilities.cjs +2 -2
- package/dist/capabilities.js +1 -1
- package/dist/{chunk-QAX222R6.cjs → chunk-36PG2IU2.cjs} +1647 -394
- package/dist/{chunk-T5FLSJOD.cjs → chunk-CSRCMBZ2.cjs} +1351 -1232
- package/dist/{chunk-YKEX4SK7.cjs → chunk-IHRXVIUU.cjs} +519 -39
- package/dist/{chunk-7L23FDQW.js → chunk-NACI2NDF.js} +1351 -1232
- package/dist/{chunk-CJONZQ7E.js → chunk-P35GFG2H.js} +1259 -6
- package/dist/{chunk-25ZUKHS4.cjs → chunk-PGQIGE63.cjs} +135 -135
- package/dist/{chunk-SXHPUQMB.js → chunk-PPTAMCFA.js} +2 -2
- package/dist/{chunk-LNRN45XS.js → chunk-ZOA5HUFX.js} +498 -18
- package/dist/{index-B_xToSpq.d.ts → index-DZfd9Gt7.d.cts} +251 -2
- package/dist/{index-Dv_GSZaN.d.cts → index-UilX3PFL.d.ts} +251 -2
- package/dist/index.cjs +20 -20
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/operations/index.cjs +123 -588
- package/dist/operations/index.d.cts +4 -4
- package/dist/operations/index.d.ts +4 -4
- package/dist/operations/index.js +10 -475
- package/dist/pool.cjs +8 -8
- package/dist/pool.d.cts +2 -2
- package/dist/pool.d.ts +2 -2
- package/dist/pool.js +4 -4
- package/dist/resources/index.cjs +4 -4
- package/dist/resources/index.d.cts +2 -2
- package/dist/resources/index.d.ts +2 -2
- package/dist/resources/index.js +3 -3
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/docs/API.md +301 -2
- package/docs/N8N-ADAPTER.md +1 -1
- package/package.json +1 -1
- package/dist/{index-cQ6CRexR.d.cts → index-BXtKN1M5.d.cts} +201 -201
- package/dist/{index-cQ6CRexR.d.ts → index-BXtKN1M5.d.ts} +201 -201
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } async function _asyncOptionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = await fn(value); } else if (op === 'call' || op === 'optionalCall') { value = await fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
@@ -30,13 +30,16 @@
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
var _chunkYKEX4SK7cjs = require('./chunk-YKEX4SK7.cjs');
|
|
34
33
|
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
|
|
36
|
+
var _chunkIHRXVIUUcjs = require('./chunk-IHRXVIUU.cjs');
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
var _chunkCSRCMBZ2cjs = require('./chunk-CSRCMBZ2.cjs');
|
|
37
40
|
|
|
38
41
|
// src/resources/appointments.ts
|
|
39
|
-
var AppointmentsResource = class extends
|
|
42
|
+
var AppointmentsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
40
43
|
constructor(http, pageSize) {
|
|
41
44
|
super(http, {
|
|
42
45
|
key: "appointments",
|
|
@@ -121,7 +124,7 @@ var AuthenticateResource = class {
|
|
|
121
124
|
};
|
|
122
125
|
|
|
123
126
|
// src/resources/billing_codes.ts
|
|
124
|
-
var BillingCodesResource = class extends
|
|
127
|
+
var BillingCodesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
125
128
|
constructor(http, pageSize) {
|
|
126
129
|
super(http, {
|
|
127
130
|
key: "billing_codes",
|
|
@@ -171,7 +174,7 @@ var MAX_LIMIT = 500;
|
|
|
171
174
|
function clampWindowLimit(limit) {
|
|
172
175
|
const n = limit === void 0 ? DEFAULT_LIMIT : Math.trunc(limit);
|
|
173
176
|
if (!Number.isInteger(n) || n < 1) {
|
|
174
|
-
throw new (0,
|
|
177
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`limit must be an integer >= 1 (got ${String(limit)})`);
|
|
175
178
|
}
|
|
176
179
|
return Math.min(n, MAX_LIMIT);
|
|
177
180
|
}
|
|
@@ -217,7 +220,7 @@ function wallParts(tz, ms) {
|
|
|
217
220
|
}
|
|
218
221
|
}
|
|
219
222
|
if (weekday < 0 || [w.y, w.m, w.d, w.h, w.mi, w.s].some((v) => v === void 0 || Number.isNaN(v))) {
|
|
220
|
-
throw new (0,
|
|
223
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`dateWindow: could not read the wall-clock parts for timezone "${tz}" (the Intl format returned an incomplete or unmapped part)`);
|
|
221
224
|
}
|
|
222
225
|
return { y: w.y, m: w.m, d: w.d, h: w.h, mi: w.mi, s: w.s, weekday };
|
|
223
226
|
}
|
|
@@ -244,7 +247,7 @@ function localDayEndMs(y, m, d, tz) {
|
|
|
244
247
|
}
|
|
245
248
|
function validateZone(tz, opName = "dateWindow") {
|
|
246
249
|
if (typeof tz !== "string" || tz.length === 0) {
|
|
247
|
-
throw new (0,
|
|
250
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
248
251
|
`${opName}: tz must be a non-empty IANA timezone string (got ${JSON.stringify(tz)}; e.g. 'Australia/Sydney' \u2014 omitted tz = UTC)`,
|
|
249
252
|
{ operation: opName }
|
|
250
253
|
);
|
|
@@ -252,7 +255,7 @@ function validateZone(tz, opName = "dateWindow") {
|
|
|
252
255
|
try {
|
|
253
256
|
new Intl.DateTimeFormat("en-US", { timeZone: tz });
|
|
254
257
|
} catch (e2) {
|
|
255
|
-
throw new (0,
|
|
258
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
256
259
|
`${opName}: tz is not a valid IANA timezone (${JSON.stringify(tz)}; e.g. 'Australia/Sydney' \u2014 omitted tz = UTC)`,
|
|
257
260
|
{ operation: opName }
|
|
258
261
|
);
|
|
@@ -404,13 +407,13 @@ async function dateWindowQuery(http, path, field, kind, limit, operation, now, t
|
|
|
404
407
|
body: { MaxRecords: limit, filter },
|
|
405
408
|
operation
|
|
406
409
|
});
|
|
407
|
-
return
|
|
410
|
+
return _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res).items;
|
|
408
411
|
}
|
|
409
412
|
var isoUtc = (ms) => new Date(ms).toISOString().slice(0, 19) + "Z";
|
|
410
413
|
function customRangeDay(value, label, zone, opName) {
|
|
411
414
|
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
|
|
412
415
|
if (!m) {
|
|
413
|
-
throw new (0,
|
|
416
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
414
417
|
zone === void 0 ? `${opName}: ${label} must be a UTC 'YYYY-MM-DD' date (got ${JSON.stringify(value)})` : `${opName}: ${label} must be a 'YYYY-MM-DD' local calendar day in ${zone} (got ${JSON.stringify(value)})`,
|
|
415
418
|
{ operation: opName }
|
|
416
419
|
);
|
|
@@ -422,7 +425,7 @@ function customRangeDay(value, label, zone, opName) {
|
|
|
422
425
|
const real = probe.getUTCFullYear() === y && probe.getUTCMonth() === mo - 1 && probe.getUTCDate() === d;
|
|
423
426
|
const ms = !real ? NaN : zone === void 0 ? Date.UTC(y, mo - 1, d) : localDayStartMs(y, mo, d, zone);
|
|
424
427
|
if (!Number.isFinite(ms)) {
|
|
425
|
-
throw new (0,
|
|
428
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
426
429
|
zone === void 0 ? `${opName}: ${label} is not a valid UTC date (${JSON.stringify(value)})` : `${opName}: ${label} is not a valid calendar day in ${zone} (${JSON.stringify(value)})`,
|
|
427
430
|
{ operation: opName }
|
|
428
431
|
);
|
|
@@ -433,7 +436,7 @@ async function customRangeQuery(http, path, field, from, to, limit, operation, z
|
|
|
433
436
|
const fromB = customRangeDay(from, "from", zone, operation);
|
|
434
437
|
const toB = customRangeDay(to, "to", zone, operation);
|
|
435
438
|
if (fromB.ms > toB.ms) {
|
|
436
|
-
throw new (0,
|
|
439
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
437
440
|
`${operation}: from (${isoUtc(fromB.ms)}) must not be after to (${isoUtc(toB.ms)})`,
|
|
438
441
|
{ operation }
|
|
439
442
|
);
|
|
@@ -450,7 +453,7 @@ async function customRangeQuery(http, path, field, from, to, limit, operation, z
|
|
|
450
453
|
body: { MaxRecords: limit, filter },
|
|
451
454
|
operation
|
|
452
455
|
});
|
|
453
|
-
return
|
|
456
|
+
return _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res).items;
|
|
454
457
|
}
|
|
455
458
|
|
|
456
459
|
// src/resources/special/billing_items.ts
|
|
@@ -483,7 +486,7 @@ async function customRange(_resource, from, to, http, opts) {
|
|
|
483
486
|
}
|
|
484
487
|
|
|
485
488
|
// src/resources/billing_items.ts
|
|
486
|
-
var BillingItemsResource = class extends
|
|
489
|
+
var BillingItemsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
487
490
|
constructor(http, pageSize) {
|
|
488
491
|
super(http, {
|
|
489
492
|
key: "billing_items",
|
|
@@ -585,7 +588,7 @@ var BillingItemsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
585
588
|
};
|
|
586
589
|
|
|
587
590
|
// src/resources/change_request_links.ts
|
|
588
|
-
var ChangeRequestLinksResource = class extends
|
|
591
|
+
var ChangeRequestLinksResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
589
592
|
constructor(http, pageSize) {
|
|
590
593
|
super(http, {
|
|
591
594
|
key: "change_request_links",
|
|
@@ -639,7 +642,7 @@ var ChangeRequestLinksResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
639
642
|
};
|
|
640
643
|
|
|
641
644
|
// src/resources/checklist_libraries.ts
|
|
642
|
-
var ChecklistLibrariesResource = class extends
|
|
645
|
+
var ChecklistLibrariesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
643
646
|
constructor(http, pageSize) {
|
|
644
647
|
super(http, {
|
|
645
648
|
key: "checklist_libraries",
|
|
@@ -713,7 +716,7 @@ var ChecklistLibrariesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
713
716
|
};
|
|
714
717
|
|
|
715
718
|
// src/resources/checklist_library_checklist_items.ts
|
|
716
|
-
var ChecklistLibraryChecklistItemsResource = class extends
|
|
719
|
+
var ChecklistLibraryChecklistItemsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
717
720
|
constructor(http, pageSize) {
|
|
718
721
|
super(http, {
|
|
719
722
|
key: "checklist_library_checklist_items",
|
|
@@ -779,7 +782,7 @@ var ChecklistLibraryChecklistItemsResource = class extends _chunkYKEX4SK7cjs.Bas
|
|
|
779
782
|
};
|
|
780
783
|
|
|
781
784
|
// src/resources/classification_icons.ts
|
|
782
|
-
var ClassificationIconsResource = class extends
|
|
785
|
+
var ClassificationIconsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
783
786
|
constructor(http, pageSize) {
|
|
784
787
|
super(http, {
|
|
785
788
|
key: "classification_icons",
|
|
@@ -827,7 +830,7 @@ var DEFAULT_LIMIT2 = 25;
|
|
|
827
830
|
var MAX_LIMIT2 = 500;
|
|
828
831
|
function clampLimit(limit) {
|
|
829
832
|
const n = limit === void 0 ? DEFAULT_LIMIT2 : Math.trunc(limit);
|
|
830
|
-
if (!Number.isInteger(n) || n < 1) throw new (0,
|
|
833
|
+
if (!Number.isInteger(n) || n < 1) throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`limit must be an integer >= 1 (got ${String(limit)})`);
|
|
831
834
|
return Math.min(n, MAX_LIMIT2);
|
|
832
835
|
}
|
|
833
836
|
async function queryCompanies(http, filter, limit) {
|
|
@@ -838,7 +841,7 @@ async function queryCompanies(http, filter, limit) {
|
|
|
838
841
|
body: { MaxRecords: limit, filter },
|
|
839
842
|
operation: "companies.searchByDomain"
|
|
840
843
|
});
|
|
841
|
-
return
|
|
844
|
+
return _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res).items;
|
|
842
845
|
}
|
|
843
846
|
async function queryContacts(http, filter, limit) {
|
|
844
847
|
const res = await http.request({
|
|
@@ -848,7 +851,7 @@ async function queryContacts(http, filter, limit) {
|
|
|
848
851
|
body: { MaxRecords: limit, filter },
|
|
849
852
|
operation: "companies.searchByDomain"
|
|
850
853
|
});
|
|
851
|
-
return
|
|
854
|
+
return _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res).items;
|
|
852
855
|
}
|
|
853
856
|
async function fetchCompanies(http, ids, limit) {
|
|
854
857
|
const out = [];
|
|
@@ -863,7 +866,7 @@ async function fetchCompanies(http, ids, limit) {
|
|
|
863
866
|
const item = body && "item" in body ? body.item : null;
|
|
864
867
|
if (item) out.push(item);
|
|
865
868
|
} catch (err) {
|
|
866
|
-
if (err instanceof
|
|
869
|
+
if (err instanceof _chunkIHRXVIUUcjs.NotFoundError) continue;
|
|
867
870
|
throw err;
|
|
868
871
|
}
|
|
869
872
|
}
|
|
@@ -871,7 +874,7 @@ async function fetchCompanies(http, ids, limit) {
|
|
|
871
874
|
}
|
|
872
875
|
async function searchByDomain(_resource, domain, opts = {}, http) {
|
|
873
876
|
const text = domain.trim();
|
|
874
|
-
if (text === "") throw new (0,
|
|
877
|
+
if (text === "") throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("searchByDomain: empty domain");
|
|
875
878
|
const limit = clampLimit(opts.limit);
|
|
876
879
|
const filter = [{ field: "webAddress", op: "contains", value: text }];
|
|
877
880
|
const direct = await queryCompanies(http, filter, limit);
|
|
@@ -885,7 +888,7 @@ async function searchByIdentity(_resource, identity, opts = {}, http) {
|
|
|
885
888
|
const email = _nullishCoalesce(_optionalChain([identity, 'access', _9 => _9.email, 'optionalAccess', _10 => _10.trim, 'call', _11 => _11()]), () => ( ""));
|
|
886
889
|
const website = _nullishCoalesce(_optionalChain([identity, 'access', _12 => _12.website, 'optionalAccess', _13 => _13.trim, 'call', _14 => _14()]), () => ( ""));
|
|
887
890
|
if (name === "" && email === "" && website === "") {
|
|
888
|
-
throw new (0,
|
|
891
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("searchByIdentity: at least one of companyName / email / website is required");
|
|
889
892
|
}
|
|
890
893
|
const limit = clampLimit(opts.limit);
|
|
891
894
|
const found = /* @__PURE__ */ new Map();
|
|
@@ -912,23 +915,23 @@ async function familyChildPage(http, parentID) {
|
|
|
912
915
|
path: "/V1.0/Companies/query",
|
|
913
916
|
body: {
|
|
914
917
|
MaxRecords: COMPANIES_FAMILY_CHILD_CAP,
|
|
915
|
-
filter:
|
|
918
|
+
filter: _chunkIHRXVIUUcjs.buildFilter.call(void 0, [{ field: "parentCompanyID", op: "eq", value: parentID }]).filter
|
|
916
919
|
},
|
|
917
920
|
operation: "companies.search"
|
|
918
921
|
});
|
|
919
|
-
const { items, pageDetails } =
|
|
922
|
+
const { items, pageDetails } = _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res, "companies.search");
|
|
920
923
|
return { rows: items, hasNext: pageDetails.nextPageUrl !== null };
|
|
921
924
|
}
|
|
922
925
|
function assertSearchWithDetailOpts(opts) {
|
|
923
926
|
if (opts === void 0) return;
|
|
924
927
|
if (typeof opts !== "object" || opts === null || Array.isArray(opts)) {
|
|
925
|
-
throw new (0,
|
|
928
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("companies.searchWithDetail: opts must be an object { limit?: number }", {
|
|
926
929
|
operation: "companies.searchWithDetail"
|
|
927
930
|
});
|
|
928
931
|
}
|
|
929
932
|
for (const key of Object.keys(opts)) {
|
|
930
933
|
if (key !== "limit") {
|
|
931
|
-
throw new (0,
|
|
934
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
932
935
|
`companies.searchWithDetail: unknown opts key "${key}" \u2014 the bag is closed: limit (includeFamily is a companies.search option)`,
|
|
933
936
|
{ operation: "companies.searchWithDetail" }
|
|
934
937
|
);
|
|
@@ -937,32 +940,32 @@ function assertSearchWithDetailOpts(opts) {
|
|
|
937
940
|
}
|
|
938
941
|
async function searchWithFamily(_resource, query, opts = {}, http) {
|
|
939
942
|
if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
940
|
-
throw new (0,
|
|
943
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("companies.search: opts must be an object { limit?: number, includeFamily?: boolean }");
|
|
941
944
|
}
|
|
942
945
|
for (const key of Object.keys(_nullishCoalesce(opts, () => ( {})))) {
|
|
943
946
|
if (!COMPANY_SEARCH_OPT_KEYS.includes(key)) {
|
|
944
|
-
throw new (0,
|
|
947
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
945
948
|
`companies.search: unknown opts key "${key}" \u2014 the bag is closed: ${COMPANY_SEARCH_OPT_KEYS.join(", ")}`,
|
|
946
949
|
{ operation: "companies.search" }
|
|
947
950
|
);
|
|
948
951
|
}
|
|
949
952
|
}
|
|
950
953
|
if (opts.includeFamily !== void 0 && typeof opts.includeFamily !== "boolean") {
|
|
951
|
-
throw new (0,
|
|
954
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`companies.search: opts.includeFamily must be a boolean (got ${String(opts.includeFamily)})`, {
|
|
952
955
|
operation: "companies.search"
|
|
953
956
|
});
|
|
954
957
|
}
|
|
955
958
|
const text = query.trim();
|
|
956
|
-
if (text === "") throw new (0,
|
|
957
|
-
const limit = opts.limit === void 0 ? 25 :
|
|
959
|
+
if (text === "") throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("search: empty query", { operation: "companies.search" });
|
|
960
|
+
const limit = opts.limit === void 0 ? 25 : _chunkIHRXVIUUcjs.clampPageSize.call(void 0, opts.limit);
|
|
958
961
|
const res = await http.request({
|
|
959
962
|
method: "POST",
|
|
960
963
|
idempotent: true,
|
|
961
964
|
path: "/V1.0/Companies/query",
|
|
962
|
-
body: { MaxRecords: limit, filter:
|
|
965
|
+
body: { MaxRecords: limit, filter: _chunkIHRXVIUUcjs.buildFilter.call(void 0, [{ field: "companyName", op: "contains", value: text }]).filter },
|
|
963
966
|
operation: "companies.search"
|
|
964
967
|
});
|
|
965
|
-
const hits =
|
|
968
|
+
const hits = _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res, "companies.search").items;
|
|
966
969
|
if (opts.includeFamily !== true) return hits;
|
|
967
970
|
const rows = [];
|
|
968
971
|
for (const hit of hits) {
|
|
@@ -986,7 +989,7 @@ var DEFAULT_COMPANY_TYPE = 1;
|
|
|
986
989
|
var DEDUP_NAME_LIMIT = 10;
|
|
987
990
|
var BLIND_SURFACE_CAVEAT = "dedup only covers companies this API user can enumerate (the unowned surface is blind); a same-name company outside that scope is not detected";
|
|
988
991
|
var SAFE_COMPANY_CREATE_DEFAULTS = {};
|
|
989
|
-
var OwnerResourceRequiredError = class extends
|
|
992
|
+
var OwnerResourceRequiredError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
990
993
|
constructor(message, options = {}) {
|
|
991
994
|
super(message, {
|
|
992
995
|
code: "OWNER_RESOURCE_REQUIRED",
|
|
@@ -997,13 +1000,13 @@ var OwnerResourceRequiredError = class extends _chunkYKEX4SK7cjs.AutotaskError {
|
|
|
997
1000
|
this.name = "OwnerResourceRequiredError";
|
|
998
1001
|
}
|
|
999
1002
|
};
|
|
1000
|
-
var CompanyResourceInvalidError = class extends
|
|
1003
|
+
var CompanyResourceInvalidError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
1001
1004
|
constructor(message, options = {}) {
|
|
1002
1005
|
super(message, { code: "RESOURCE_INVALID", category: "validation", ...options });
|
|
1003
1006
|
this.name = "CompanyResourceInvalidError";
|
|
1004
1007
|
}
|
|
1005
1008
|
};
|
|
1006
|
-
var CompanyCreateFailedError = class extends
|
|
1009
|
+
var CompanyCreateFailedError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
1007
1010
|
/** The vendor-named fields (empty when the 500 body named nothing parseable). */
|
|
1008
1011
|
|
|
1009
1012
|
constructor(message, vendorFields, options = {}) {
|
|
@@ -1014,18 +1017,18 @@ var CompanyCreateFailedError = class extends _chunkYKEX4SK7cjs.AutotaskError {
|
|
|
1014
1017
|
};
|
|
1015
1018
|
async function upsertByName(resource, companyName, params, opts, http) {
|
|
1016
1019
|
if (typeof companyName !== "string" || companyName.trim() === "") {
|
|
1017
|
-
throw new (0,
|
|
1020
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("upsertByName: companyName is required (a non-empty string)", { operation: OP_UPSERT_NAME });
|
|
1018
1021
|
}
|
|
1019
1022
|
if (typeof _optionalChain([params, 'optionalAccess', _15 => _15.phone]) !== "string" || params.phone.trim() === "") {
|
|
1020
|
-
throw new (0,
|
|
1023
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("upsertByName: params.phone is required (a non-empty string \u2014 the ww29 live-required set is { companyName, companyType, phone, ownerResourceID })", { operation: OP_UPSERT_NAME });
|
|
1021
1024
|
}
|
|
1022
1025
|
const companyType = _nullishCoalesce(params.companyType, () => ( DEFAULT_COMPANY_TYPE));
|
|
1023
1026
|
if (typeof companyType !== "number" || !Number.isSafeInteger(companyType) || companyType < 1) {
|
|
1024
|
-
throw new (0,
|
|
1027
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`upsertByName: params.companyType must be a positive integer picklist value (got ${String(params.companyType)}; default 1 \u2014 the ww29-proven value)`, { operation: OP_UPSERT_NAME });
|
|
1025
1028
|
}
|
|
1026
1029
|
const owner = params.ownerResourceID;
|
|
1027
1030
|
if (owner !== void 0 && (typeof owner !== "number" || !Number.isSafeInteger(owner) || owner < 1)) {
|
|
1028
|
-
throw new (0,
|
|
1031
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`upsertByName: params.ownerResourceID must be a positive integer (got ${String(owner)})`, { operation: OP_UPSERT_NAME });
|
|
1029
1032
|
}
|
|
1030
1033
|
const q = await resource.queryBounded({ filter: [{ field: "companyName", op: "eq", value: companyName }], limit: DEDUP_NAME_LIMIT });
|
|
1031
1034
|
const caveat = {
|
|
@@ -1036,7 +1039,7 @@ async function upsertByName(resource, companyName, params, opts, http) {
|
|
|
1036
1039
|
const match = q.items[0];
|
|
1037
1040
|
if (match !== void 0) {
|
|
1038
1041
|
if (opts.dryRun === true) {
|
|
1039
|
-
return
|
|
1042
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0,
|
|
1040
1043
|
{
|
|
1041
1044
|
operation: OP_UPSERT_NAME,
|
|
1042
1045
|
method: "POST",
|
|
@@ -1071,7 +1074,7 @@ async function upsertByName(resource, companyName, params, opts, http) {
|
|
|
1071
1074
|
"ownerResourceID is REQUIRED on the apply path (the vendor requires it; the node cannot enumerate candidates \u2014 the resources table is blind to this API user (count/query return 0)): the apply throws the typed OWNER_RESOURCE_REQUIRED if it is still absent"
|
|
1072
1075
|
);
|
|
1073
1076
|
}
|
|
1074
|
-
return
|
|
1077
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0,
|
|
1075
1078
|
{
|
|
1076
1079
|
operation: OP_UPSERT_NAME,
|
|
1077
1080
|
method: "POST",
|
|
@@ -1119,8 +1122,8 @@ async function upsertByName(resource, companyName, params, opts, http) {
|
|
|
1119
1122
|
sideEffects: ['vendor auto-creates a "Primary Address" location under the new company (UI-only cleanup \u2014 the delete 405 gap, \xA711.5)']
|
|
1120
1123
|
};
|
|
1121
1124
|
} catch (err) {
|
|
1122
|
-
if (!
|
|
1123
|
-
const named = (_nullishCoalesce(
|
|
1125
|
+
if (!_chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) || err.vendorError === void 0) throw err;
|
|
1126
|
+
const named = (_nullishCoalesce(_chunkIHRXVIUUcjs.parseVendorErrors.call(void 0, err.vendorError), () => ( []))).map((e) => e.field).filter((f) => f !== void 0);
|
|
1124
1127
|
const seen = /* @__PURE__ */ new Set();
|
|
1125
1128
|
const unique = [...named].filter((f) => seen.has(f) ? false : (seen.add(f), true));
|
|
1126
1129
|
const hasDefault = unique.some((f) => SAFE_COMPANY_CREATE_DEFAULTS[f] !== void 0);
|
|
@@ -1134,7 +1137,7 @@ async function upsertByName(resource, companyName, params, opts, http) {
|
|
|
1134
1137
|
}
|
|
1135
1138
|
continue;
|
|
1136
1139
|
}
|
|
1137
|
-
const detail =
|
|
1140
|
+
const detail = _chunkIHRXVIUUcjs.formatVendorDetail.call(void 0, err.vendorError);
|
|
1138
1141
|
throw new CompanyCreateFailedError(
|
|
1139
1142
|
`upsertByName: the vendor rejected the company create${unique.length > 0 ? ` naming field(s) ${unique.join(", ")}` : ""} (no proven-safe default \u2014 the ww29 required set is fully filled by the node)${detail ? ` \u2014 ${detail}` : ""}`,
|
|
1140
1143
|
unique,
|
|
@@ -1153,7 +1156,7 @@ var PROFILE_PART_LIMIT = 50;
|
|
|
1153
1156
|
function profilePartLimit(value, name) {
|
|
1154
1157
|
const n = value === void 0 ? PROFILE_PART_LIMIT : Math.trunc(value);
|
|
1155
1158
|
if (!Number.isInteger(n) || n < 1) {
|
|
1156
|
-
throw new (0,
|
|
1159
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`fullProfile: ${name} must be an integer >= 1 (got ${String(value)})`);
|
|
1157
1160
|
}
|
|
1158
1161
|
return n;
|
|
1159
1162
|
}
|
|
@@ -1165,14 +1168,14 @@ async function scopedCompanyQuery(http, path, companyID, limit) {
|
|
|
1165
1168
|
body: { MaxRecords: limit, filter: [{ field: "companyID", op: "eq", value: companyID }] },
|
|
1166
1169
|
operation: "companies.fullProfile"
|
|
1167
1170
|
});
|
|
1168
|
-
return
|
|
1171
|
+
return _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res).items;
|
|
1169
1172
|
}
|
|
1170
1173
|
async function fullProfile(resource, id, opts = {}, http) {
|
|
1171
1174
|
const contactLimit = profilePartLimit(opts.contactLimit, "contactLimit");
|
|
1172
1175
|
const noteLimit = profilePartLimit(opts.noteLimit, "noteLimit");
|
|
1173
1176
|
const ticketLimit = profilePartLimit(opts.ticketLimit, "ticketLimit");
|
|
1174
1177
|
const projectLimit = profilePartLimit(opts.projectLimit, "projectLimit");
|
|
1175
|
-
const companyID =
|
|
1178
|
+
const companyID = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, id, "id");
|
|
1176
1179
|
const company = await resource.get(companyID);
|
|
1177
1180
|
const locations = await scopedCompanyQuery(http, "/V1.0/CompanyLocations/query", companyID, PROFILE_PART_LIMIT);
|
|
1178
1181
|
const contacts = await scopedCompanyQuery(http, "/V1.0/Contacts/query", companyID, contactLimit);
|
|
@@ -1189,7 +1192,7 @@ async function fullProfile(resource, id, opts = {}, http) {
|
|
|
1189
1192
|
},
|
|
1190
1193
|
operation: "companies.fullProfile"
|
|
1191
1194
|
});
|
|
1192
|
-
return
|
|
1195
|
+
return _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res).items;
|
|
1193
1196
|
})();
|
|
1194
1197
|
let openTickets = {
|
|
1195
1198
|
items: openRows,
|
|
@@ -1198,7 +1201,7 @@ async function fullProfile(resource, id, opts = {}, http) {
|
|
|
1198
1201
|
note: OPEN_TICKETS_NOTE
|
|
1199
1202
|
};
|
|
1200
1203
|
if (openRows.length === 0) {
|
|
1201
|
-
const stamp =
|
|
1204
|
+
const stamp = _chunkIHRXVIUUcjs.blindStampFor.call(void 0, _optionalChain([_chunkIHRXVIUUcjs.BLIND_SURFACE_STAMPS, 'access', _16 => _16["tickets"], 'optionalAccess', _17 => _17.query]), [
|
|
1202
1205
|
{ field: "companyID", op: "eq", value: companyID },
|
|
1203
1206
|
{ field: "status", op: "noteq", value: 5 }
|
|
1204
1207
|
]);
|
|
@@ -1229,7 +1232,7 @@ async function fullProfile(resource, id, opts = {}, http) {
|
|
|
1229
1232
|
}
|
|
1230
1233
|
};
|
|
1231
1234
|
if (opts.names === true) {
|
|
1232
|
-
const builder =
|
|
1235
|
+
const builder = _chunkIHRXVIUUcjs.createNamePlan.call(void 0, _chunkIHRXVIUUcjs.TICKET_LABEL_FIELDS);
|
|
1233
1236
|
const c = company;
|
|
1234
1237
|
builder.addResource(c["ownerResourceID"]);
|
|
1235
1238
|
builder.addResource(c["createdByResourceID"]);
|
|
@@ -1246,20 +1249,20 @@ async function fullProfile(resource, id, opts = {}, http) {
|
|
|
1246
1249
|
builder.addResource(r["creatorResourceID"]);
|
|
1247
1250
|
builder.addFk("contract", r["contractID"]);
|
|
1248
1251
|
}
|
|
1249
|
-
const names = await
|
|
1252
|
+
const names = await _chunkIHRXVIUUcjs.resolveCompositeNames.call(void 0, http, builder.plan(), { maxNameReads: opts.maxNameReads });
|
|
1250
1253
|
const companyRow = { ...company };
|
|
1251
|
-
|
|
1252
|
-
|
|
1254
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, companyRow, "ownerResourceID", (v) => names.resourceName(v));
|
|
1255
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, companyRow, "createdByResourceID", (v) => names.resourceName(v));
|
|
1253
1256
|
result.company = companyRow;
|
|
1254
1257
|
result.openTickets = {
|
|
1255
1258
|
...openTickets,
|
|
1256
1259
|
items: openTickets.items.map((row) => {
|
|
1257
1260
|
const r = { ...row };
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
for (const f of
|
|
1261
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, r, "creatorResourceID", (v) => names.resourceName(v));
|
|
1262
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, r, "contractID", (v) => names.recordName("contract", v));
|
|
1263
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, r, "billingCodeID", (v) => names.recordName("billingCode", v));
|
|
1264
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, r, "assignedResourceRoleID", (v) => names.recordName("role", v));
|
|
1265
|
+
for (const f of _chunkIHRXVIUUcjs.TICKET_LABEL_FIELDS) _chunkIHRXVIUUcjs.addLabelSibling.call(void 0, r, f, names);
|
|
1263
1266
|
return r;
|
|
1264
1267
|
})
|
|
1265
1268
|
};
|
|
@@ -1267,9 +1270,9 @@ async function fullProfile(resource, id, opts = {}, http) {
|
|
|
1267
1270
|
...result.projects,
|
|
1268
1271
|
items: result.projects.items.map((row) => {
|
|
1269
1272
|
const r = { ...row };
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, r, "projectLeadResourceID", (v) => names.resourceName(v));
|
|
1274
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, r, "creatorResourceID", (v) => names.resourceName(v));
|
|
1275
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, r, "contractID", (v) => names.recordName("contract", v));
|
|
1273
1276
|
return r;
|
|
1274
1277
|
})
|
|
1275
1278
|
};
|
|
@@ -1301,7 +1304,7 @@ function isDateYMD(v) {
|
|
|
1301
1304
|
}
|
|
1302
1305
|
function validateUnbilledWorkOptions(companyId, opts) {
|
|
1303
1306
|
if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
1304
|
-
throw new (0,
|
|
1307
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
1305
1308
|
`unbilledWork: opts must be the options object (got ${Array.isArray(opts) ? "an array" : typeof opts})`,
|
|
1306
1309
|
{ operation: "companies.unbilledWork" }
|
|
1307
1310
|
);
|
|
@@ -1330,7 +1333,7 @@ function validateUnbilledWorkOptions(companyId, opts) {
|
|
|
1330
1333
|
try {
|
|
1331
1334
|
limit = clampLimit(opts.limit);
|
|
1332
1335
|
} catch (err) {
|
|
1333
|
-
problems.push(err instanceof
|
|
1336
|
+
problems.push(err instanceof _chunkIHRXVIUUcjs.AutotaskError ? err.message : `limit must be an integer >= 1 (got ${String(opts.limit)})`);
|
|
1334
1337
|
limit = 50;
|
|
1335
1338
|
}
|
|
1336
1339
|
if (source === "date_range") {
|
|
@@ -1345,9 +1348,9 @@ function validateUnbilledWorkOptions(companyId, opts) {
|
|
|
1345
1348
|
problems.push('invoiceId is required (the vendor invoice id) when source is "invoice"');
|
|
1346
1349
|
} else {
|
|
1347
1350
|
try {
|
|
1348
|
-
|
|
1351
|
+
_chunkIHRXVIUUcjs.parseIdentifier.call(void 0, opts.invoiceId, "opts.invoiceId");
|
|
1349
1352
|
} catch (err) {
|
|
1350
|
-
problems.push(err instanceof
|
|
1353
|
+
problems.push(err instanceof _chunkIHRXVIUUcjs.AutotaskError ? err.message : "invoiceId must be a vendor numeric id");
|
|
1351
1354
|
}
|
|
1352
1355
|
}
|
|
1353
1356
|
}
|
|
@@ -1357,20 +1360,20 @@ function validateUnbilledWorkOptions(companyId, opts) {
|
|
|
1357
1360
|
} else {
|
|
1358
1361
|
opts.ticketIds.forEach((tid, i) => {
|
|
1359
1362
|
try {
|
|
1360
|
-
|
|
1363
|
+
_chunkIHRXVIUUcjs.parseIdentifier.call(void 0, tid, `opts.ticketIds[${i}]`);
|
|
1361
1364
|
} catch (err) {
|
|
1362
|
-
problems.push(err instanceof
|
|
1365
|
+
problems.push(err instanceof _chunkIHRXVIUUcjs.AutotaskError ? err.message : `ticketIds[${i}] must be a vendor numeric id`);
|
|
1363
1366
|
}
|
|
1364
1367
|
});
|
|
1365
1368
|
}
|
|
1366
1369
|
}
|
|
1367
1370
|
try {
|
|
1368
|
-
|
|
1371
|
+
_chunkIHRXVIUUcjs.parseIdentifier.call(void 0, companyId, "companyId");
|
|
1369
1372
|
} catch (err) {
|
|
1370
|
-
problems.push(err instanceof
|
|
1373
|
+
problems.push(err instanceof _chunkIHRXVIUUcjs.AutotaskError ? err.message : "companyId must be a vendor numeric id");
|
|
1371
1374
|
}
|
|
1372
1375
|
if (problems.length > 0) {
|
|
1373
|
-
throw new (0,
|
|
1376
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
1374
1377
|
`unbilledWork: ${problems.length} problem(s) found pre-request (zero wire was issued)
|
|
1375
1378
|
- ` + problems.join("\n- "),
|
|
1376
1379
|
{ operation: "companies.unbilledWork" }
|
|
@@ -1399,7 +1402,7 @@ async function boundedPart(http, path, conditions, limit, includeFields) {
|
|
|
1399
1402
|
body,
|
|
1400
1403
|
operation: "companies.unbilledWork"
|
|
1401
1404
|
});
|
|
1402
|
-
const { items, pageDetails } =
|
|
1405
|
+
const { items, pageDetails } = _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res, "companies.unbilledWork");
|
|
1403
1406
|
const capped = items.length >= limit;
|
|
1404
1407
|
return { items, capped, hasMore: capped && pageDetails.nextPageUrl != null };
|
|
1405
1408
|
}
|
|
@@ -1410,7 +1413,7 @@ function capJoinSet(ids, cap) {
|
|
|
1410
1413
|
}
|
|
1411
1414
|
function unbilledWorkPartStatus(key, conditions, items) {
|
|
1412
1415
|
if (items.length !== 0) return { status: "ok" };
|
|
1413
|
-
const stamp =
|
|
1416
|
+
const stamp = _chunkIHRXVIUUcjs.blindStampFor.call(void 0, _optionalChain([_chunkIHRXVIUUcjs.BLIND_SURFACE_STAMPS, 'access', _18 => _18[key], 'optionalAccess', _19 => _19.query]), conditions);
|
|
1414
1417
|
if (stamp !== void 0) return { status: "blind", blindSurface: stamp, note: stamp.note };
|
|
1415
1418
|
return {
|
|
1416
1419
|
status: "ok",
|
|
@@ -1419,7 +1422,7 @@ function unbilledWorkPartStatus(key, conditions, items) {
|
|
|
1419
1422
|
}
|
|
1420
1423
|
async function unbilledWork(resource, companyId, opts = {}, http) {
|
|
1421
1424
|
const v = validateUnbilledWorkOptions(companyId, opts);
|
|
1422
|
-
const id =
|
|
1425
|
+
const id = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, companyId, "companyId");
|
|
1423
1426
|
const company = await resource.get(id);
|
|
1424
1427
|
const companyIds = [num(company.id)];
|
|
1425
1428
|
let parent = null;
|
|
@@ -1432,7 +1435,7 @@ async function unbilledWork(resource, companyId, opts = {}, http) {
|
|
|
1432
1435
|
parentStatus = "ok";
|
|
1433
1436
|
companyIds.push(num(parent.id));
|
|
1434
1437
|
} catch (err) {
|
|
1435
|
-
if (err instanceof
|
|
1438
|
+
if (err instanceof _chunkIHRXVIUUcjs.NotFoundError) parent = null;
|
|
1436
1439
|
else throw err;
|
|
1437
1440
|
}
|
|
1438
1441
|
}
|
|
@@ -1464,7 +1467,7 @@ async function unbilledWork(resource, companyId, opts = {}, http) {
|
|
|
1464
1467
|
if (v.dateFrom !== void 0) billingConditions.push({ field: "itemDate", op: "gte", value: v.dateFrom });
|
|
1465
1468
|
if (v.dateTo !== void 0) billingConditions.push({ field: "itemDate", op: "lte", value: v.dateTo });
|
|
1466
1469
|
}
|
|
1467
|
-
const billingFields =
|
|
1470
|
+
const billingFields = _chunkIHRXVIUUcjs.resolveFieldsPreset.call(void 0, "billing_join", "billing_items");
|
|
1468
1471
|
const billingIncludeFields = [...billingFields, "id", ...v.includeNotes ? ["description"] : []];
|
|
1469
1472
|
const billingRaw = await boundedPart(http, "/V1.0/BillingItems/query", billingConditions, v.limit, billingIncludeFields);
|
|
1470
1473
|
const taskCap = capJoinSet(taskIds, UNBILLED_WORK_JOIN_SET_CAP);
|
|
@@ -1496,7 +1499,7 @@ async function unbilledWork(resource, companyId, opts = {}, http) {
|
|
|
1496
1499
|
let cappedItems = entries;
|
|
1497
1500
|
let noteCharsTruncated = 0;
|
|
1498
1501
|
if (v.includeNotes) {
|
|
1499
|
-
[cappedItems, noteCharsTruncated] =
|
|
1502
|
+
[cappedItems, noteCharsTruncated] = _chunkIHRXVIUUcjs.truncateNoteChars.call(void 0, entries, v.noteChars, ["summaryNotes"]);
|
|
1500
1503
|
}
|
|
1501
1504
|
const st = unbilledWorkPartStatus("time_entries", timeConditions, entries);
|
|
1502
1505
|
timePart = {
|
|
@@ -1511,8 +1514,8 @@ async function unbilledWork(resource, companyId, opts = {}, http) {
|
|
|
1511
1514
|
let billingItems = billingRaw.items;
|
|
1512
1515
|
let billingNoteCharsTruncated = 0;
|
|
1513
1516
|
if (v.includeNotes) {
|
|
1514
|
-
const noteFields = (_nullishCoalesce(
|
|
1515
|
-
[billingItems, billingNoteCharsTruncated] =
|
|
1517
|
+
const noteFields = (_nullishCoalesce(_chunkIHRXVIUUcjs.UNTRUSTED_FIELDS_BY_RESOURCE["billing_items"], () => ( []))).filter((f) => billingIncludeFields.includes(f));
|
|
1518
|
+
[billingItems, billingNoteCharsTruncated] = _chunkIHRXVIUUcjs.truncateNoteChars.call(void 0, billingRaw.items, v.noteChars, noteFields);
|
|
1516
1519
|
}
|
|
1517
1520
|
const billingSt = unbilledWorkPartStatus("billing_items", billingConditions, billingRaw.items);
|
|
1518
1521
|
const billingItemsPart = {
|
|
@@ -1609,7 +1612,7 @@ async function unbilledWork(resource, companyId, opts = {}, http) {
|
|
|
1609
1612
|
}
|
|
1610
1613
|
|
|
1611
1614
|
// src/resources/companies.ts
|
|
1612
|
-
var CompaniesResource = class extends
|
|
1615
|
+
var CompaniesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
1613
1616
|
constructor(http, pageSize) {
|
|
1614
1617
|
super(http, {
|
|
1615
1618
|
key: "companies",
|
|
@@ -1716,7 +1719,7 @@ var CompaniesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
1716
1719
|
};
|
|
1717
1720
|
|
|
1718
1721
|
// src/resources/company_alerts.ts
|
|
1719
|
-
var CompanyAlertsResource = class extends
|
|
1722
|
+
var CompanyAlertsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
1720
1723
|
constructor(http, pageSize) {
|
|
1721
1724
|
super(http, {
|
|
1722
1725
|
key: "company_alerts",
|
|
@@ -1782,7 +1785,7 @@ var CompanyAlertsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
1782
1785
|
};
|
|
1783
1786
|
|
|
1784
1787
|
// src/resources/company_locations.ts
|
|
1785
|
-
var CompanyLocationsResource = class extends
|
|
1788
|
+
var CompanyLocationsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
1786
1789
|
constructor(http, pageSize) {
|
|
1787
1790
|
super(http, {
|
|
1788
1791
|
key: "company_locations",
|
|
@@ -1853,7 +1856,7 @@ var CompanyLocationsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
1853
1856
|
};
|
|
1854
1857
|
|
|
1855
1858
|
// src/resources/company_notes.ts
|
|
1856
|
-
var CompanyNotesResource = class extends
|
|
1859
|
+
var CompanyNotesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
1857
1860
|
constructor(http, pageSize) {
|
|
1858
1861
|
super(http, {
|
|
1859
1862
|
key: "company_notes",
|
|
@@ -1918,7 +1921,7 @@ var CompanyNotesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
1918
1921
|
};
|
|
1919
1922
|
|
|
1920
1923
|
// src/resources/company_site_configurations.ts
|
|
1921
|
-
var CompanySiteConfigurationsResource = class extends
|
|
1924
|
+
var CompanySiteConfigurationsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
1922
1925
|
constructor(http, pageSize) {
|
|
1923
1926
|
super(http, {
|
|
1924
1927
|
key: "company_site_configurations",
|
|
@@ -1969,7 +1972,7 @@ var CompanySiteConfigurationsResource = class extends _chunkYKEX4SK7cjs.BaseReso
|
|
|
1969
1972
|
};
|
|
1970
1973
|
|
|
1971
1974
|
// src/resources/company_webhooks.ts
|
|
1972
|
-
var CompanyWebhooksResource = class extends
|
|
1975
|
+
var CompanyWebhooksResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
1973
1976
|
constructor(http, pageSize) {
|
|
1974
1977
|
super(http, {
|
|
1975
1978
|
key: "company_webhooks",
|
|
@@ -2045,7 +2048,7 @@ var CompanyWebhooksResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
2045
2048
|
};
|
|
2046
2049
|
|
|
2047
2050
|
// src/resources/configuration_item_billing_product_associations.ts
|
|
2048
|
-
var ConfigurationItemBillingProductAssociationsResource = class extends
|
|
2051
|
+
var ConfigurationItemBillingProductAssociationsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2049
2052
|
constructor(http, pageSize) {
|
|
2050
2053
|
super(http, {
|
|
2051
2054
|
key: "configuration_item_billing_product_associations",
|
|
@@ -2111,7 +2114,7 @@ var ConfigurationItemBillingProductAssociationsResource = class extends _chunkYK
|
|
|
2111
2114
|
};
|
|
2112
2115
|
|
|
2113
2116
|
// src/resources/configuration_item_categories.ts
|
|
2114
|
-
var ConfigurationItemCategoriesResource = class extends
|
|
2117
|
+
var ConfigurationItemCategoriesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2115
2118
|
constructor(http, pageSize) {
|
|
2116
2119
|
super(http, {
|
|
2117
2120
|
key: "configuration_item_categories",
|
|
@@ -2178,7 +2181,7 @@ var ConfigurationItemCategoriesResource = class extends _chunkYKEX4SK7cjs.BaseRe
|
|
|
2178
2181
|
};
|
|
2179
2182
|
|
|
2180
2183
|
// src/resources/configuration_item_category_udf_associations.ts
|
|
2181
|
-
var ConfigurationItemCategoryUdfAssociationsResource = class extends
|
|
2184
|
+
var ConfigurationItemCategoryUdfAssociationsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2182
2185
|
constructor(http, pageSize) {
|
|
2183
2186
|
super(http, {
|
|
2184
2187
|
key: "configuration_item_category_udf_associations",
|
|
@@ -2244,7 +2247,7 @@ var ConfigurationItemCategoryUdfAssociationsResource = class extends _chunkYKEX4
|
|
|
2244
2247
|
};
|
|
2245
2248
|
|
|
2246
2249
|
// src/resources/configuration_item_dns_records.ts
|
|
2247
|
-
var ConfigurationItemDnsRecordsResource = class extends
|
|
2250
|
+
var ConfigurationItemDnsRecordsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2248
2251
|
constructor(http, pageSize) {
|
|
2249
2252
|
super(http, {
|
|
2250
2253
|
key: "configuration_item_dns_records",
|
|
@@ -2293,7 +2296,7 @@ var ConfigurationItemDnsRecordsResource = class extends _chunkYKEX4SK7cjs.BaseRe
|
|
|
2293
2296
|
};
|
|
2294
2297
|
|
|
2295
2298
|
// src/resources/configuration_item_notes.ts
|
|
2296
|
-
var ConfigurationItemNotesResource = class extends
|
|
2299
|
+
var ConfigurationItemNotesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2297
2300
|
constructor(http, pageSize) {
|
|
2298
2301
|
super(http, {
|
|
2299
2302
|
key: "configuration_item_notes",
|
|
@@ -2352,7 +2355,7 @@ var ConfigurationItemNotesResource = class extends _chunkYKEX4SK7cjs.BaseResourc
|
|
|
2352
2355
|
};
|
|
2353
2356
|
|
|
2354
2357
|
// src/resources/configuration_item_related_items.ts
|
|
2355
|
-
var ConfigurationItemRelatedItemsResource = class extends
|
|
2358
|
+
var ConfigurationItemRelatedItemsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2356
2359
|
constructor(http, pageSize) {
|
|
2357
2360
|
super(http, {
|
|
2358
2361
|
key: "configuration_item_related_items",
|
|
@@ -2413,16 +2416,16 @@ async function fetchRecord(http, path, label) {
|
|
|
2413
2416
|
const res = await http.request({ method: "GET", path, operation: "configuration_items.moveConfigurationItem" });
|
|
2414
2417
|
const body = res;
|
|
2415
2418
|
if (body === null || !("item" in body) || body.item === null || body.item === void 0) {
|
|
2416
|
-
throw new (0,
|
|
2419
|
+
throw new (0, _chunkIHRXVIUUcjs.NotFoundError)(`${label} not found`, { code: "NOT_FOUND", category: "not_found" });
|
|
2417
2420
|
}
|
|
2418
2421
|
return body.item;
|
|
2419
2422
|
}
|
|
2420
2423
|
async function moveConfigurationItem(_resource, sourceId, opts, http) {
|
|
2421
|
-
const numericSource =
|
|
2424
|
+
const numericSource = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, sourceId, "sourceId");
|
|
2422
2425
|
if (_optionalChain([opts, 'optionalAccess', _20 => _20.destinationCompanyId]) === void 0) {
|
|
2423
|
-
throw new (0,
|
|
2426
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("moveConfigurationItem: destinationCompanyId is required");
|
|
2424
2427
|
}
|
|
2425
|
-
const destId =
|
|
2428
|
+
const destId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, opts.destinationCompanyId, "destinationCompanyId");
|
|
2426
2429
|
const source = await fetchRecord(http, `/V1.0/ConfigurationItems/${numericSource}`, `Configuration item ${numericSource}`);
|
|
2427
2430
|
await fetchRecord(http, `/V1.0/Companies/${destId}`, `Company ${destId}`);
|
|
2428
2431
|
const body = { ...source };
|
|
@@ -2432,20 +2435,20 @@ async function moveConfigurationItem(_resource, sourceId, opts, http) {
|
|
|
2432
2435
|
body.companyID = destId;
|
|
2433
2436
|
body.isActive = true;
|
|
2434
2437
|
if (opts.newReferenceTitle !== void 0) {
|
|
2435
|
-
if (opts.newReferenceTitle.trim() === "") throw new (0,
|
|
2438
|
+
if (opts.newReferenceTitle.trim() === "") throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("moveConfigurationItem: newReferenceTitle must be non-empty");
|
|
2436
2439
|
body.referenceTitle = opts.newReferenceTitle.trim();
|
|
2437
2440
|
}
|
|
2438
2441
|
if (opts.lastModifiedDate !== void 0) {
|
|
2439
2442
|
const current = source.lastModifiedDate;
|
|
2440
2443
|
if (current !== opts.lastModifiedDate) {
|
|
2441
|
-
throw new (0,
|
|
2444
|
+
throw new (0, _chunkIHRXVIUUcjs.StaleObjectError)(
|
|
2442
2445
|
`moveConfigurationItem: source item ${numericSource} was modified since the snapshot (expected lastModifiedDate ${opts.lastModifiedDate}, current ${_nullishCoalesce(current, () => ( "unknown"))})`,
|
|
2443
2446
|
{ operation: "configuration_items.moveConfigurationItem", resourceIds: [numericSource] }
|
|
2444
2447
|
);
|
|
2445
2448
|
}
|
|
2446
2449
|
}
|
|
2447
2450
|
if (opts.dryRun === true) {
|
|
2448
|
-
return
|
|
2451
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0, {
|
|
2449
2452
|
operation: "configuration_items.moveConfigurationItem",
|
|
2450
2453
|
method: "POST",
|
|
2451
2454
|
path: "/V1.0/ConfigurationItems",
|
|
@@ -2469,7 +2472,7 @@ async function moveConfigurationItem(_resource, sourceId, opts, http) {
|
|
|
2469
2472
|
const createdBody = created;
|
|
2470
2473
|
const newId = createdBody !== null ? _nullishCoalesce(createdBody.itemId, () => ( createdBody.id)) : void 0;
|
|
2471
2474
|
if (typeof newId !== "number") {
|
|
2472
|
-
throw new (0,
|
|
2475
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("moveConfigurationItem: vendor create response has no itemId");
|
|
2473
2476
|
}
|
|
2474
2477
|
let sourceDeactivated = false;
|
|
2475
2478
|
if (opts.deactivateSource !== false) {
|
|
@@ -2487,7 +2490,7 @@ var PROFILE_PART_LIMIT2 = 50;
|
|
|
2487
2490
|
function profilePartLimit2(value, name) {
|
|
2488
2491
|
const n = value === void 0 ? PROFILE_PART_LIMIT2 : Math.trunc(value);
|
|
2489
2492
|
if (!Number.isInteger(n) || n < 1) {
|
|
2490
|
-
throw new (0,
|
|
2493
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`profile: ${name} must be an integer >= 1 (got ${String(value)})`);
|
|
2491
2494
|
}
|
|
2492
2495
|
return n;
|
|
2493
2496
|
}
|
|
@@ -2503,14 +2506,14 @@ async function contextFetchPart(http, entityPath, referenceId) {
|
|
|
2503
2506
|
});
|
|
2504
2507
|
const body = res;
|
|
2505
2508
|
if (body === null || !("item" in body)) {
|
|
2506
|
-
throw new (0,
|
|
2509
|
+
throw new (0, _chunkIHRXVIUUcjs.NotFoundError)(`context part not found (unexpected envelope shape)`, { resourceIds: [referenceId] });
|
|
2507
2510
|
}
|
|
2508
2511
|
if (body.item === null || body.item === void 0) {
|
|
2509
|
-
throw new (0,
|
|
2512
|
+
throw new (0, _chunkIHRXVIUUcjs.NotFoundError)("context part not found", { resourceIds: [referenceId] });
|
|
2510
2513
|
}
|
|
2511
2514
|
return body.item;
|
|
2512
2515
|
} catch (err) {
|
|
2513
|
-
if (err instanceof
|
|
2516
|
+
if (err instanceof _chunkIHRXVIUUcjs.NotFoundError) return null;
|
|
2514
2517
|
throw err;
|
|
2515
2518
|
}
|
|
2516
2519
|
}
|
|
@@ -2522,7 +2525,7 @@ async function ciScopedQuery(http, path, itemID, limit) {
|
|
|
2522
2525
|
body: { MaxRecords: limit, filter: [{ field: "configurationItemID", op: "eq", value: itemID }] },
|
|
2523
2526
|
operation: "configuration_items.profile"
|
|
2524
2527
|
});
|
|
2525
|
-
return
|
|
2528
|
+
return _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res).items;
|
|
2526
2529
|
}
|
|
2527
2530
|
async function profile(resource, id, opts = {}, http) {
|
|
2528
2531
|
const noteLimit = profilePartLimit2(opts.noteLimit, "noteLimit");
|
|
@@ -2534,7 +2537,7 @@ async function profile(resource, id, opts = {}, http) {
|
|
|
2534
2537
|
const notes = await ciScopedQuery(http, "/V1.0/ConfigurationItemNotes/query", id, noteLimit);
|
|
2535
2538
|
const relatedItems = await ciScopedQuery(http, "/V1.0/ConfigurationItemRelatedItems/query", id, relatedLimit);
|
|
2536
2539
|
const associations = await ciScopedQuery(http, "/V1.0/ConfigurationItemBillingProductAssociations/query", id, PROFILE_PART_LIMIT2);
|
|
2537
|
-
const wallQuirk = _optionalChain([
|
|
2540
|
+
const wallQuirk = _optionalChain([_chunkIHRXVIUUcjs.RELATIONSHIP_MAP, 'access', _21 => _21["configuration_items"], 'optionalAccess', _22 => _22.zoneFacts, 'optionalAccess', _23 => _23.quirks, 'optionalAccess', _24 => _24.find, 'call', _25 => _25((q) => q.startsWith("product wall"))]);
|
|
2538
2541
|
const productAssociations = {
|
|
2539
2542
|
items: associations,
|
|
2540
2543
|
capped: associations.length >= PROFILE_PART_LIMIT2,
|
|
@@ -2558,11 +2561,11 @@ async function profile(resource, id, opts = {}, http) {
|
|
|
2558
2561
|
}
|
|
2559
2562
|
};
|
|
2560
2563
|
if (opts.names === true) {
|
|
2561
|
-
const builder =
|
|
2564
|
+
const builder = _chunkIHRXVIUUcjs.createNamePlan.call(void 0, );
|
|
2562
2565
|
builder.addFk("contract", root["contractID"]);
|
|
2563
|
-
const names = await
|
|
2566
|
+
const names = await _chunkIHRXVIUUcjs.resolveCompositeNames.call(void 0, http, builder.plan(), { maxNameReads: opts.maxNameReads });
|
|
2564
2567
|
const ciRow = { ...ci };
|
|
2565
|
-
|
|
2568
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, ciRow, "contractID", (v) => names.recordName("contract", v));
|
|
2566
2569
|
result.ci = ciRow;
|
|
2567
2570
|
result.names = names.section;
|
|
2568
2571
|
}
|
|
@@ -2570,7 +2573,7 @@ async function profile(resource, id, opts = {}, http) {
|
|
|
2570
2573
|
}
|
|
2571
2574
|
|
|
2572
2575
|
// src/resources/configuration_items.ts
|
|
2573
|
-
var ConfigurationItemsResource = class extends
|
|
2576
|
+
var ConfigurationItemsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2574
2577
|
constructor(http, pageSize) {
|
|
2575
2578
|
super(http, {
|
|
2576
2579
|
key: "configuration_items",
|
|
@@ -2659,7 +2662,7 @@ var ConfigurationItemsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
2659
2662
|
};
|
|
2660
2663
|
|
|
2661
2664
|
// src/resources/configuration_item_ssl_subject_alternative_names.ts
|
|
2662
|
-
var ConfigurationItemSslSubjectAlternativeNamesResource = class extends
|
|
2665
|
+
var ConfigurationItemSslSubjectAlternativeNamesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2663
2666
|
constructor(http, pageSize) {
|
|
2664
2667
|
super(http, {
|
|
2665
2668
|
key: "configuration_item_ssl_subject_alternative_names",
|
|
@@ -2722,7 +2725,7 @@ var ConfigurationItemSslSubjectAlternativeNamesResource = class extends _chunkYK
|
|
|
2722
2725
|
};
|
|
2723
2726
|
|
|
2724
2727
|
// src/resources/configuration_item_types.ts
|
|
2725
|
-
var ConfigurationItemTypesResource = class extends
|
|
2728
|
+
var ConfigurationItemTypesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2726
2729
|
constructor(http, pageSize) {
|
|
2727
2730
|
super(http, {
|
|
2728
2731
|
key: "configuration_item_types",
|
|
@@ -2796,7 +2799,7 @@ var ConfigurationItemTypesResource = class extends _chunkYKEX4SK7cjs.BaseResourc
|
|
|
2796
2799
|
};
|
|
2797
2800
|
|
|
2798
2801
|
// src/resources/configuration_item_webhooks.ts
|
|
2799
|
-
var ConfigurationItemWebhooksResource = class extends
|
|
2802
|
+
var ConfigurationItemWebhooksResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2800
2803
|
constructor(http, pageSize) {
|
|
2801
2804
|
super(http, {
|
|
2802
2805
|
key: "configuration_item_webhooks",
|
|
@@ -2872,7 +2875,7 @@ var ConfigurationItemWebhooksResource = class extends _chunkYKEX4SK7cjs.BaseReso
|
|
|
2872
2875
|
};
|
|
2873
2876
|
|
|
2874
2877
|
// src/resources/contact_group_contacts.ts
|
|
2875
|
-
var ContactGroupContactsResource = class extends
|
|
2878
|
+
var ContactGroupContactsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2876
2879
|
constructor(http, pageSize) {
|
|
2877
2880
|
super(http, {
|
|
2878
2881
|
key: "contact_group_contacts",
|
|
@@ -2926,7 +2929,7 @@ var ContactGroupContactsResource = class extends _chunkYKEX4SK7cjs.BaseResource
|
|
|
2926
2929
|
};
|
|
2927
2930
|
|
|
2928
2931
|
// src/resources/contact_groups.ts
|
|
2929
|
-
var ContactGroupsResource = class extends
|
|
2932
|
+
var ContactGroupsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
2930
2933
|
constructor(http, pageSize) {
|
|
2931
2934
|
super(http, {
|
|
2932
2935
|
key: "contact_groups",
|
|
@@ -3004,22 +3007,22 @@ async function fetchRecord2(http, path, label) {
|
|
|
3004
3007
|
const res = await http.request({ method: "GET", path, operation: "contacts.moveToCompany" });
|
|
3005
3008
|
const body = res;
|
|
3006
3009
|
if (body === null || !("item" in body) || body.item === null || body.item === void 0) {
|
|
3007
|
-
throw new (0,
|
|
3010
|
+
throw new (0, _chunkIHRXVIUUcjs.NotFoundError)(`${label} not found`, { code: "NOT_FOUND", category: "not_found" });
|
|
3008
3011
|
}
|
|
3009
3012
|
return body.item;
|
|
3010
3013
|
}
|
|
3011
3014
|
async function moveToCompany(_resource, sourceContactId, destinationCompanyId, opts = {}, http) {
|
|
3012
|
-
const sourceId =
|
|
3013
|
-
const destId =
|
|
3015
|
+
const sourceId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, sourceContactId, "sourceContactId");
|
|
3016
|
+
const destId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, destinationCompanyId, "destinationCompanyId");
|
|
3014
3017
|
const source = await fetchRecord2(http, `/V1.0/Contacts/${sourceId}`, `Contact ${sourceId}`);
|
|
3015
3018
|
const companyID = source.companyID;
|
|
3016
3019
|
if (typeof companyID !== "number" || companyID < 0) {
|
|
3017
|
-
throw new (0,
|
|
3020
|
+
throw new (0, _chunkIHRXVIUUcjs.NotFoundError)(`Contact ${sourceId} has no companyID (cannot scope the source delete)`);
|
|
3018
3021
|
}
|
|
3019
3022
|
if (opts.lastModifiedDate !== void 0) {
|
|
3020
3023
|
const current = source.lastModifiedDate;
|
|
3021
3024
|
if (current !== opts.lastModifiedDate) {
|
|
3022
|
-
throw new (0,
|
|
3025
|
+
throw new (0, _chunkIHRXVIUUcjs.StaleObjectError)(
|
|
3023
3026
|
`moveToCompany: source contact ${sourceId} was modified since the snapshot (expected lastModifiedDate ${opts.lastModifiedDate}, current ${typeof current === "string" ? current : "unknown"})`,
|
|
3024
3027
|
{ operation: "contacts.moveToCompany", resourceIds: [sourceId, destId] }
|
|
3025
3028
|
);
|
|
@@ -3041,10 +3044,10 @@ async function moveToCompany(_resource, sourceContactId, destinationCompanyId, o
|
|
|
3041
3044
|
},
|
|
3042
3045
|
operation: "contacts.moveToCompany"
|
|
3043
3046
|
});
|
|
3044
|
-
const items =
|
|
3047
|
+
const items = _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res).items;
|
|
3045
3048
|
const clash = items.find((c) => String(c.id) !== String(sourceId));
|
|
3046
3049
|
if (clash !== void 0) {
|
|
3047
|
-
throw new (0,
|
|
3050
|
+
throw new (0, _chunkIHRXVIUUcjs.ConflictError)(
|
|
3048
3051
|
`Contact email "${email}" already exists under company ${destId} (contact ${String(clash.id)}); aborting the move`,
|
|
3049
3052
|
{ resourceIds: [sourceId, destId] }
|
|
3050
3053
|
);
|
|
@@ -3058,7 +3061,7 @@ async function moveToCompany(_resource, sourceContactId, destinationCompanyId, o
|
|
|
3058
3061
|
if (opts.dryRun === true) {
|
|
3059
3062
|
const warnings = [];
|
|
3060
3063
|
if (opts.deleteSource === true) warnings.push("the source contact will be deleted after the move");
|
|
3061
|
-
return
|
|
3064
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0, {
|
|
3062
3065
|
operation: "contacts.moveToCompany",
|
|
3063
3066
|
method: "POST",
|
|
3064
3067
|
path: `/V1.0/Companies/${destId}/Contacts`,
|
|
@@ -3083,7 +3086,7 @@ async function moveToCompany(_resource, sourceContactId, destinationCompanyId, o
|
|
|
3083
3086
|
const createdBody = created;
|
|
3084
3087
|
const newId = createdBody !== null ? _nullishCoalesce(createdBody.itemId, () => ( createdBody.id)) : void 0;
|
|
3085
3088
|
if (typeof newId !== "number") {
|
|
3086
|
-
throw new (0,
|
|
3089
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("contacts.moveToCompany: vendor create response has no itemId");
|
|
3087
3090
|
}
|
|
3088
3091
|
let sourceDeleted = false;
|
|
3089
3092
|
if (opts.deleteSource === true) {
|
|
@@ -3101,7 +3104,7 @@ var UPSERT_MAX_DISCOVERY_MERGES = 3;
|
|
|
3101
3104
|
var EMAIL_SHAPE = /^.+@.+/;
|
|
3102
3105
|
var SAFE_CONTACT_CREATE_DEFAULTS = {};
|
|
3103
3106
|
var DEDUP_LIMIT = 10;
|
|
3104
|
-
var CompanyNotFoundError = class extends
|
|
3107
|
+
var CompanyNotFoundError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
3105
3108
|
constructor(message, options = {}) {
|
|
3106
3109
|
super(message, {
|
|
3107
3110
|
code: "COMPANY_NOT_FOUND",
|
|
@@ -3112,7 +3115,7 @@ var CompanyNotFoundError = class extends _chunkYKEX4SK7cjs.AutotaskError {
|
|
|
3112
3115
|
this.name = "CompanyNotFoundError";
|
|
3113
3116
|
}
|
|
3114
3117
|
};
|
|
3115
|
-
var ContactCreateFailedError = class extends
|
|
3118
|
+
var ContactCreateFailedError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
3116
3119
|
/** The vendor-named fields (empty when the 500 body named nothing parseable). */
|
|
3117
3120
|
|
|
3118
3121
|
constructor(message, vendorFields, options = {}) {
|
|
@@ -3122,25 +3125,25 @@ var ContactCreateFailedError = class extends _chunkYKEX4SK7cjs.AutotaskError {
|
|
|
3122
3125
|
}
|
|
3123
3126
|
};
|
|
3124
3127
|
async function upsertByEmail(resource, companyID, email, extra, opts, http) {
|
|
3125
|
-
const cid =
|
|
3128
|
+
const cid = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, companyID, "companyID");
|
|
3126
3129
|
if (typeof email !== "string" || !EMAIL_SHAPE.test(email)) {
|
|
3127
|
-
throw new (0,
|
|
3130
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
3128
3131
|
`upsertByEmail: email must be a non-empty string with the @ shape (a non-empty local part + a non-empty domain; got ${JSON.stringify(email)})`,
|
|
3129
3132
|
{ operation: OP_UPSERT_EMAIL }
|
|
3130
3133
|
);
|
|
3131
3134
|
}
|
|
3132
3135
|
if (extra !== void 0) {
|
|
3133
3136
|
if (extra.isActive !== void 0 && typeof extra.isActive !== "boolean" && extra.isActive !== 0 && extra.isActive !== 1) {
|
|
3134
|
-
throw new (0,
|
|
3137
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
3135
3138
|
`upsertByEmail: extra.isActive must be a boolean (mapped to the zone-correct number 1/0) or a raw 0/1 number (got ${String(extra.isActive)})`,
|
|
3136
3139
|
{ operation: OP_UPSERT_EMAIL }
|
|
3137
3140
|
);
|
|
3138
3141
|
}
|
|
3139
3142
|
if (extra.firstName !== void 0 && (typeof extra.firstName !== "string" || extra.firstName === "")) {
|
|
3140
|
-
throw new (0,
|
|
3143
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("upsertByEmail: extra.firstName must be a non-empty string (or omitted \u2014 the node defaults it to the email local-part)", { operation: OP_UPSERT_EMAIL });
|
|
3141
3144
|
}
|
|
3142
3145
|
if (extra.lastName !== void 0 && typeof extra.lastName !== "string") {
|
|
3143
|
-
throw new (0,
|
|
3146
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("upsertByEmail: extra.lastName must be a string (or omitted \u2014 the node defaults it to the non-empty neutral value Unknown)", { operation: OP_UPSERT_EMAIL });
|
|
3144
3147
|
}
|
|
3145
3148
|
}
|
|
3146
3149
|
const parentRes = await http.request({ method: "GET", path: `/V1.0/Companies/${cid}`, operation: OP_UPSERT_EMAIL });
|
|
@@ -3161,7 +3164,7 @@ async function upsertByEmail(resource, companyID, email, extra, opts, http) {
|
|
|
3161
3164
|
const match = q.items[0];
|
|
3162
3165
|
if (match !== void 0) {
|
|
3163
3166
|
if (opts.dryRun === true) {
|
|
3164
|
-
return
|
|
3167
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0,
|
|
3165
3168
|
{
|
|
3166
3169
|
operation: OP_UPSERT_EMAIL,
|
|
3167
3170
|
method: "POST",
|
|
@@ -3191,7 +3194,7 @@ async function upsertByEmail(resource, companyID, email, extra, opts, http) {
|
|
|
3191
3194
|
isActive: typeof isActive === "boolean" ? isActive ? 1 : 0 : isActive
|
|
3192
3195
|
};
|
|
3193
3196
|
if (opts.dryRun === true) {
|
|
3194
|
-
return
|
|
3197
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0,
|
|
3195
3198
|
{
|
|
3196
3199
|
operation: OP_UPSERT_EMAIL,
|
|
3197
3200
|
method: "POST",
|
|
@@ -3214,8 +3217,8 @@ async function upsertByEmail(resource, companyID, email, extra, opts, http) {
|
|
|
3214
3217
|
const created = await resource.create(cid, body, {});
|
|
3215
3218
|
return { id: created.id, created: true };
|
|
3216
3219
|
} catch (err) {
|
|
3217
|
-
if (!
|
|
3218
|
-
const named = (_nullishCoalesce(
|
|
3220
|
+
if (!_chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) || err.vendorError === void 0) throw err;
|
|
3221
|
+
const named = (_nullishCoalesce(_chunkIHRXVIUUcjs.parseVendorErrors.call(void 0, err.vendorError), () => ( []))).map((e) => e.field).filter((f) => f !== void 0);
|
|
3219
3222
|
const seen = /* @__PURE__ */ new Set();
|
|
3220
3223
|
const unique = [...named].filter((f) => seen.has(f) ? false : (seen.add(f), true));
|
|
3221
3224
|
const hasDefault = unique.some((f) => SAFE_CONTACT_CREATE_DEFAULTS[f] !== void 0);
|
|
@@ -3229,7 +3232,7 @@ async function upsertByEmail(resource, companyID, email, extra, opts, http) {
|
|
|
3229
3232
|
}
|
|
3230
3233
|
continue;
|
|
3231
3234
|
}
|
|
3232
|
-
const detail =
|
|
3235
|
+
const detail = _chunkIHRXVIUUcjs.formatVendorDetail.call(void 0, err.vendorError);
|
|
3233
3236
|
throw new ContactCreateFailedError(
|
|
3234
3237
|
`upsertByEmail: the vendor rejected the contact create${unique.length > 0 ? ` naming field(s) ${unique.join(", ")}` : ""} (no proven-safe default \u2014 the required set is fully filled by the node)${detail ? ` \u2014 ${detail}` : ""}`,
|
|
3235
3238
|
unique,
|
|
@@ -3245,7 +3248,7 @@ async function upsertByEmail(resource, companyID, email, extra, opts, http) {
|
|
|
3245
3248
|
}
|
|
3246
3249
|
|
|
3247
3250
|
// src/resources/contacts.ts
|
|
3248
|
-
var ContactsResource = class extends
|
|
3251
|
+
var ContactsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3249
3252
|
constructor(http, pageSize) {
|
|
3250
3253
|
super(http, {
|
|
3251
3254
|
key: "contacts",
|
|
@@ -3337,7 +3340,7 @@ var ContactsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
3337
3340
|
};
|
|
3338
3341
|
|
|
3339
3342
|
// src/resources/contact_webhooks.ts
|
|
3340
|
-
var ContactWebhooksResource = class extends
|
|
3343
|
+
var ContactWebhooksResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3341
3344
|
constructor(http, pageSize) {
|
|
3342
3345
|
super(http, {
|
|
3343
3346
|
key: "contact_webhooks",
|
|
@@ -3413,7 +3416,7 @@ var ContactWebhooksResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
3413
3416
|
};
|
|
3414
3417
|
|
|
3415
3418
|
// src/resources/contract_billing_rules.ts
|
|
3416
|
-
var ContractBillingRulesResource = class extends
|
|
3419
|
+
var ContractBillingRulesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3417
3420
|
constructor(http, pageSize) {
|
|
3418
3421
|
super(http, {
|
|
3419
3422
|
key: "contract_billing_rules",
|
|
@@ -3479,7 +3482,7 @@ var ContractBillingRulesResource = class extends _chunkYKEX4SK7cjs.BaseResource
|
|
|
3479
3482
|
};
|
|
3480
3483
|
|
|
3481
3484
|
// src/resources/contract_block_hour_factors.ts
|
|
3482
|
-
var ContractBlockHourFactorsResource = class extends
|
|
3485
|
+
var ContractBlockHourFactorsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3483
3486
|
constructor(http, pageSize) {
|
|
3484
3487
|
super(http, {
|
|
3485
3488
|
key: "contract_block_hour_factors",
|
|
@@ -3538,7 +3541,7 @@ var ContractBlockHourFactorsResource = class extends _chunkYKEX4SK7cjs.BaseResou
|
|
|
3538
3541
|
};
|
|
3539
3542
|
|
|
3540
3543
|
// src/resources/contract_blocks.ts
|
|
3541
|
-
var ContractBlocksResource = class extends
|
|
3544
|
+
var ContractBlocksResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3542
3545
|
constructor(http, pageSize) {
|
|
3543
3546
|
super(http, {
|
|
3544
3547
|
key: "contract_blocks",
|
|
@@ -3597,7 +3600,7 @@ var ContractBlocksResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
3597
3600
|
};
|
|
3598
3601
|
|
|
3599
3602
|
// src/resources/contract_charges.ts
|
|
3600
|
-
var ContractChargesResource = class extends
|
|
3603
|
+
var ContractChargesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3601
3604
|
constructor(http, pageSize) {
|
|
3602
3605
|
super(http, {
|
|
3603
3606
|
key: "contract_charges",
|
|
@@ -3668,7 +3671,7 @@ var ContractChargesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
3668
3671
|
};
|
|
3669
3672
|
|
|
3670
3673
|
// src/resources/contract_exclusion_billing_codes.ts
|
|
3671
|
-
var ContractExclusionBillingCodesResource = class extends
|
|
3674
|
+
var ContractExclusionBillingCodesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3672
3675
|
constructor(http, pageSize) {
|
|
3673
3676
|
super(http, {
|
|
3674
3677
|
key: "contract_exclusion_billing_codes",
|
|
@@ -3725,7 +3728,7 @@ var ContractExclusionBillingCodesResource = class extends _chunkYKEX4SK7cjs.Base
|
|
|
3725
3728
|
};
|
|
3726
3729
|
|
|
3727
3730
|
// src/resources/contract_exclusion_roles.ts
|
|
3728
|
-
var ContractExclusionRolesResource = class extends
|
|
3731
|
+
var ContractExclusionRolesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3729
3732
|
constructor(http, pageSize) {
|
|
3730
3733
|
super(http, {
|
|
3731
3734
|
key: "contract_exclusion_roles",
|
|
@@ -3782,7 +3785,7 @@ var ContractExclusionRolesResource = class extends _chunkYKEX4SK7cjs.BaseResourc
|
|
|
3782
3785
|
};
|
|
3783
3786
|
|
|
3784
3787
|
// src/resources/contract_exclusion_set_excluded_roles.ts
|
|
3785
|
-
var ContractExclusionSetExcludedRolesResource = class extends
|
|
3788
|
+
var ContractExclusionSetExcludedRolesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3786
3789
|
constructor(http, pageSize) {
|
|
3787
3790
|
super(http, {
|
|
3788
3791
|
key: "contract_exclusion_set_excluded_roles",
|
|
@@ -3839,7 +3842,7 @@ var ContractExclusionSetExcludedRolesResource = class extends _chunkYKEX4SK7cjs.
|
|
|
3839
3842
|
};
|
|
3840
3843
|
|
|
3841
3844
|
// src/resources/contract_exclusion_set_excluded_work_types.ts
|
|
3842
|
-
var ContractExclusionSetExcludedWorkTypesResource = class extends
|
|
3845
|
+
var ContractExclusionSetExcludedWorkTypesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3843
3846
|
constructor(http, pageSize) {
|
|
3844
3847
|
super(http, {
|
|
3845
3848
|
key: "contract_exclusion_set_excluded_work_types",
|
|
@@ -3896,7 +3899,7 @@ var ContractExclusionSetExcludedWorkTypesResource = class extends _chunkYKEX4SK7
|
|
|
3896
3899
|
};
|
|
3897
3900
|
|
|
3898
3901
|
// src/resources/contract_exclusion_sets.ts
|
|
3899
|
-
var ContractExclusionSetsResource = class extends
|
|
3902
|
+
var ContractExclusionSetsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3900
3903
|
constructor(http, pageSize) {
|
|
3901
3904
|
super(http, {
|
|
3902
3905
|
key: "contract_exclusion_sets",
|
|
@@ -3970,7 +3973,7 @@ var ContractExclusionSetsResource = class extends _chunkYKEX4SK7cjs.BaseResource
|
|
|
3970
3973
|
};
|
|
3971
3974
|
|
|
3972
3975
|
// src/resources/contract_milestones.ts
|
|
3973
|
-
var ContractMilestonesResource = class extends
|
|
3976
|
+
var ContractMilestonesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
3974
3977
|
constructor(http, pageSize) {
|
|
3975
3978
|
super(http, {
|
|
3976
3979
|
key: "contract_milestones",
|
|
@@ -4029,7 +4032,7 @@ var ContractMilestonesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
4029
4032
|
};
|
|
4030
4033
|
|
|
4031
4034
|
// src/resources/contract_notes.ts
|
|
4032
|
-
var ContractNotesResource = class extends
|
|
4035
|
+
var ContractNotesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4033
4036
|
constructor(http, pageSize) {
|
|
4034
4037
|
super(http, {
|
|
4035
4038
|
key: "contract_notes",
|
|
@@ -4088,7 +4091,7 @@ var ContractNotesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
4088
4091
|
};
|
|
4089
4092
|
|
|
4090
4093
|
// src/resources/contract_rates.ts
|
|
4091
|
-
var ContractRatesResource = class extends
|
|
4094
|
+
var ContractRatesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4092
4095
|
constructor(http, pageSize) {
|
|
4093
4096
|
super(http, {
|
|
4094
4097
|
key: "contract_rates",
|
|
@@ -4147,7 +4150,7 @@ var ContractRatesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
4147
4150
|
};
|
|
4148
4151
|
|
|
4149
4152
|
// src/resources/contract_retainers.ts
|
|
4150
|
-
var ContractRetainersResource = class extends
|
|
4153
|
+
var ContractRetainersResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4151
4154
|
constructor(http, pageSize) {
|
|
4152
4155
|
super(http, {
|
|
4153
4156
|
key: "contract_retainers",
|
|
@@ -4206,7 +4209,7 @@ var ContractRetainersResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
4206
4209
|
};
|
|
4207
4210
|
|
|
4208
4211
|
// src/resources/contract_role_costs.ts
|
|
4209
|
-
var ContractRoleCostsResource = class extends
|
|
4212
|
+
var ContractRoleCostsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4210
4213
|
constructor(http, pageSize) {
|
|
4211
4214
|
super(http, {
|
|
4212
4215
|
key: "contract_role_costs",
|
|
@@ -4265,7 +4268,7 @@ var ContractRoleCostsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
4265
4268
|
};
|
|
4266
4269
|
|
|
4267
4270
|
// src/resources/contract_service_adjustments.ts
|
|
4268
|
-
var ContractServiceAdjustmentsResource = class extends
|
|
4271
|
+
var ContractServiceAdjustmentsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4269
4272
|
constructor(http, pageSize) {
|
|
4270
4273
|
super(http, {
|
|
4271
4274
|
key: "contract_service_adjustments",
|
|
@@ -4299,7 +4302,7 @@ var ContractServiceAdjustmentsResource = class extends _chunkYKEX4SK7cjs.BaseRes
|
|
|
4299
4302
|
};
|
|
4300
4303
|
|
|
4301
4304
|
// src/resources/contract_service_bundle_adjustments.ts
|
|
4302
|
-
var ContractServiceBundleAdjustmentsResource = class extends
|
|
4305
|
+
var ContractServiceBundleAdjustmentsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4303
4306
|
constructor(http, pageSize) {
|
|
4304
4307
|
super(http, {
|
|
4305
4308
|
key: "contract_service_bundle_adjustments",
|
|
@@ -4333,7 +4336,7 @@ var ContractServiceBundleAdjustmentsResource = class extends _chunkYKEX4SK7cjs.B
|
|
|
4333
4336
|
};
|
|
4334
4337
|
|
|
4335
4338
|
// src/resources/contract_service_bundles.ts
|
|
4336
|
-
var ContractServiceBundlesResource = class extends
|
|
4339
|
+
var ContractServiceBundlesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4337
4340
|
constructor(http, pageSize) {
|
|
4338
4341
|
super(http, {
|
|
4339
4342
|
key: "contract_service_bundles",
|
|
@@ -4392,7 +4395,7 @@ var ContractServiceBundlesResource = class extends _chunkYKEX4SK7cjs.BaseResourc
|
|
|
4392
4395
|
};
|
|
4393
4396
|
|
|
4394
4397
|
// src/resources/contract_service_bundle_units.ts
|
|
4395
|
-
var ContractServiceBundleUnitsResource = class extends
|
|
4398
|
+
var ContractServiceBundleUnitsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4396
4399
|
constructor(http, pageSize) {
|
|
4397
4400
|
super(http, {
|
|
4398
4401
|
key: "contract_service_bundle_units",
|
|
@@ -4434,7 +4437,7 @@ var ContractServiceBundleUnitsResource = class extends _chunkYKEX4SK7cjs.BaseRes
|
|
|
4434
4437
|
};
|
|
4435
4438
|
|
|
4436
4439
|
// src/resources/contract_services.ts
|
|
4437
|
-
var ContractServicesResource = class extends
|
|
4440
|
+
var ContractServicesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4438
4441
|
constructor(http, pageSize) {
|
|
4439
4442
|
super(http, {
|
|
4440
4443
|
key: "contract_services",
|
|
@@ -4493,7 +4496,7 @@ var ContractServicesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
4493
4496
|
};
|
|
4494
4497
|
|
|
4495
4498
|
// src/resources/contract_service_units.ts
|
|
4496
|
-
var ContractServiceUnitsResource = class extends
|
|
4499
|
+
var ContractServiceUnitsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4497
4500
|
constructor(http, pageSize) {
|
|
4498
4501
|
super(http, {
|
|
4499
4502
|
key: "contract_service_units",
|
|
@@ -4534,8 +4537,1254 @@ var ContractServiceUnitsResource = class extends _chunkYKEX4SK7cjs.BaseResource
|
|
|
4534
4537
|
}
|
|
4535
4538
|
};
|
|
4536
4539
|
|
|
4540
|
+
// src/resources/special/contracts.ts
|
|
4541
|
+
var PROFITABILITY_OPT_KEYS = [
|
|
4542
|
+
"dateFrom",
|
|
4543
|
+
"dateTo",
|
|
4544
|
+
"labourCostMethod",
|
|
4545
|
+
"labourRatePerHour",
|
|
4546
|
+
"includeRecurringCosts",
|
|
4547
|
+
"includeUnbilledRevenue",
|
|
4548
|
+
"externalMonthlyCosts",
|
|
4549
|
+
"groupByActivity",
|
|
4550
|
+
"staleAfterDays",
|
|
4551
|
+
"maxTicketsForJoin",
|
|
4552
|
+
"limit"
|
|
4553
|
+
];
|
|
4554
|
+
var LABOUR_METHOD_SET = [
|
|
4555
|
+
"billing_item_our_cost",
|
|
4556
|
+
"contract_role_cost",
|
|
4557
|
+
"resource_internal_cost",
|
|
4558
|
+
"provided"
|
|
4559
|
+
];
|
|
4560
|
+
var PROFITABILITY_MAX_WINDOW_MONTHS = 36;
|
|
4561
|
+
var RECURRING_DRIFT_EPSILON = 5e-3;
|
|
4562
|
+
var ESTIMATE_DEVIATION_THRESHOLD_PCT = 10;
|
|
4563
|
+
var CLOSED_STATUS_LABEL_RE = /resolved|completed|cancelled|canceled|closed|deleted/i;
|
|
4564
|
+
var PROFITABILITY_WIRE_BUDGET = 21;
|
|
4565
|
+
var BLOCK_HOURS_LABEL_RE = /block\s*hours?/i;
|
|
4566
|
+
var TIME_AND_MATERIALS_LABEL_RE = /time.*materials?/i;
|
|
4567
|
+
var NOT_ACTIVE_LABEL_RE = /cancel|inactive/i;
|
|
4568
|
+
var SUBSCRIPTION_NOT_ACTIVE_STATUS_IDS = /* @__PURE__ */ new Set([2, 3]);
|
|
4569
|
+
var PERIOD_TYPE_MONTHLY_FACTOR = { 2: 1, 3: 1 / 3, 4: 1 / 6, 5: 1 / 12 };
|
|
4570
|
+
var PERIOD_TYPE_ONE_TIME = 1;
|
|
4571
|
+
var SERVICE_LINE_FKS = ["contractServiceID", "contractServiceBundleID", "contractServicePeriodID", "contractServiceBundlePeriodID", "contractServiceAdjustmentID", "contractServiceBundleAdjustmentID"];
|
|
4572
|
+
var CHARGE_LINE_FKS = ["contractChargeID", "ticketChargeID", "projectChargeID"];
|
|
4573
|
+
var DATE_RE2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
4574
|
+
function num2(v) {
|
|
4575
|
+
return typeof v === "number" && Number.isFinite(v) ? v : 0;
|
|
4576
|
+
}
|
|
4577
|
+
function isDateYMD2(v) {
|
|
4578
|
+
return typeof v === "string" && DATE_RE2.test(v) && !Number.isNaN(Date.parse(v));
|
|
4579
|
+
}
|
|
4580
|
+
function monthsInWindow(dateFrom, dateTo) {
|
|
4581
|
+
const a = `${dateFrom.slice(0, 7)}`;
|
|
4582
|
+
const b = `${dateTo.slice(0, 7)}`;
|
|
4583
|
+
if (a > b) return 0;
|
|
4584
|
+
const ay = Number(a.slice(0, 4));
|
|
4585
|
+
const am = Number(a.slice(5, 7));
|
|
4586
|
+
const by = Number(b.slice(0, 4));
|
|
4587
|
+
const bm = Number(b.slice(5, 7));
|
|
4588
|
+
return (by - ay) * 12 + (bm - am) + 1;
|
|
4589
|
+
}
|
|
4590
|
+
function monthsBetween(dateFrom, dateTo) {
|
|
4591
|
+
const out = [];
|
|
4592
|
+
let y = Number(dateFrom.slice(0, 4));
|
|
4593
|
+
let m = Number(dateFrom.slice(5, 7));
|
|
4594
|
+
const end = dateTo.slice(0, 7);
|
|
4595
|
+
for (; ; ) {
|
|
4596
|
+
const tag = `${y}-${String(m).padStart(2, "0")}`;
|
|
4597
|
+
out.push(tag);
|
|
4598
|
+
if (tag === end) break;
|
|
4599
|
+
m += 1;
|
|
4600
|
+
if (m === 13) {
|
|
4601
|
+
m = 1;
|
|
4602
|
+
y += 1;
|
|
4603
|
+
}
|
|
4604
|
+
if (out.length > 500) break;
|
|
4605
|
+
}
|
|
4606
|
+
return out;
|
|
4607
|
+
}
|
|
4608
|
+
function dayAfter(date) {
|
|
4609
|
+
return new Date(Date.parse(date) + 864e5).toISOString().slice(0, 10);
|
|
4610
|
+
}
|
|
4611
|
+
function monthBounds(month, dateFrom, dateTo) {
|
|
4612
|
+
const y = Number(month.slice(0, 4));
|
|
4613
|
+
const m = Number(month.slice(5, 7));
|
|
4614
|
+
const first = `${month}-01`;
|
|
4615
|
+
const nextFirst = new Date(Date.UTC(y, m, 1)).toISOString().slice(0, 10);
|
|
4616
|
+
const toExcl = dayAfter(dateTo);
|
|
4617
|
+
return {
|
|
4618
|
+
start: first > dateFrom ? first : dateFrom,
|
|
4619
|
+
endExclusive: nextFirst < toExcl ? nextFirst : toExcl
|
|
4620
|
+
};
|
|
4621
|
+
}
|
|
4622
|
+
function chargeCost(charge) {
|
|
4623
|
+
const ext = charge["extendedCost"];
|
|
4624
|
+
const fromUnits = num2(charge["unitCost"]) * num2(charge["unitQuantity"]);
|
|
4625
|
+
if (typeof ext === "number" && Number.isFinite(ext) && !(ext === 0 && fromUnits !== 0)) return ext;
|
|
4626
|
+
return fromUnits;
|
|
4627
|
+
}
|
|
4628
|
+
function isOneTimePeriod(periodType, label) {
|
|
4629
|
+
return label !== void 0 ? /one[\s-]*time/i.test(label) : periodType === PERIOD_TYPE_ONE_TIME;
|
|
4630
|
+
}
|
|
4631
|
+
function periodMonthlyFactor(periodType, label) {
|
|
4632
|
+
if (label !== void 0) {
|
|
4633
|
+
if (/semi/i.test(label)) return 1 / 6;
|
|
4634
|
+
if (/quarter/i.test(label)) return 1 / 3;
|
|
4635
|
+
if (/annual|year/i.test(label)) return 1 / 12;
|
|
4636
|
+
if (/month/i.test(label)) return 1;
|
|
4637
|
+
return null;
|
|
4638
|
+
}
|
|
4639
|
+
return typeof periodType === "number" ? _nullishCoalesce(PERIOD_TYPE_MONTHLY_FACTOR[periodType], () => ( null)) : null;
|
|
4640
|
+
}
|
|
4641
|
+
var BILLING_ITEM_TYPE_KIND = {
|
|
4642
|
+
1: "labour",
|
|
4643
|
+
2: "labour",
|
|
4644
|
+
3: "charges",
|
|
4645
|
+
4: "expenses",
|
|
4646
|
+
5: "other",
|
|
4647
|
+
6: "recurring",
|
|
4648
|
+
7: "charges",
|
|
4649
|
+
8: "other"
|
|
4650
|
+
};
|
|
4651
|
+
function billingLineType(item) {
|
|
4652
|
+
const byType = BILLING_ITEM_TYPE_KIND[num2(item["billingItemType"])];
|
|
4653
|
+
if (byType !== void 0) return byType;
|
|
4654
|
+
if (num2(item["timeEntryID"]) > 0) return "labour";
|
|
4655
|
+
if (num2(item["expenseItemID"]) > 0) return "expenses";
|
|
4656
|
+
if (CHARGE_LINE_FKS.some((k) => num2(item[k]) > 0)) return "charges";
|
|
4657
|
+
if (SERVICE_LINE_FKS.some((k) => num2(item[k]) > 0)) return "recurring";
|
|
4658
|
+
return "other";
|
|
4659
|
+
}
|
|
4660
|
+
function internalAmount(row, internalKey, localKey) {
|
|
4661
|
+
const v = row[internalKey];
|
|
4662
|
+
return typeof v === "number" && Number.isFinite(v) ? v : num2(row[localKey]);
|
|
4663
|
+
}
|
|
4664
|
+
function cents(v) {
|
|
4665
|
+
return v === null ? null : Math.round(v * 100) / 100;
|
|
4666
|
+
}
|
|
4667
|
+
async function readPicklists(http, entityPath, operation) {
|
|
4668
|
+
const res = await http.request({ method: "GET", path: `${entityPath}/entityInformation/fields`, operation });
|
|
4669
|
+
const body = typeof res === "object" && res !== null ? res : {};
|
|
4670
|
+
const fields = Array.isArray(body["fields"]) ? body["fields"] : [];
|
|
4671
|
+
const out = /* @__PURE__ */ new Map();
|
|
4672
|
+
for (const f of fields) {
|
|
4673
|
+
if (f["isPickList"] !== true || typeof f["name"] !== "string" || !Array.isArray(f["picklistValues"])) continue;
|
|
4674
|
+
const values = /* @__PURE__ */ new Map();
|
|
4675
|
+
for (const p of f["picklistValues"]) {
|
|
4676
|
+
const id = typeof p["value"] === "string" ? Number.parseInt(p["value"], 10) : Number.NaN;
|
|
4677
|
+
if (Number.isFinite(id)) values.set(id, String(_nullishCoalesce(p["label"], () => ( ""))));
|
|
4678
|
+
}
|
|
4679
|
+
out.set(f["name"], values);
|
|
4680
|
+
}
|
|
4681
|
+
return out;
|
|
4682
|
+
}
|
|
4683
|
+
function dateToDay(v) {
|
|
4684
|
+
if (typeof v !== "string" || v.length < 10) return null;
|
|
4685
|
+
const d = Date.parse(v.slice(0, 10));
|
|
4686
|
+
return Number.isNaN(d) ? null : Math.floor(d / 864e5);
|
|
4687
|
+
}
|
|
4688
|
+
function validateProfitabilityOptions(contractId, opts) {
|
|
4689
|
+
if (opts === void 0 || (typeof opts !== "object" || opts === null || Array.isArray(opts))) {
|
|
4690
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
4691
|
+
`profitability: opts must be the options object (got ${opts === void 0 ? "undefined" : Array.isArray(opts) ? "an array" : typeof opts})`,
|
|
4692
|
+
{ operation: "contracts.profitability" }
|
|
4693
|
+
);
|
|
4694
|
+
}
|
|
4695
|
+
const problems = [];
|
|
4696
|
+
for (const key of Object.keys(opts)) {
|
|
4697
|
+
if (!PROFITABILITY_OPT_KEYS.includes(key)) {
|
|
4698
|
+
problems.push(
|
|
4699
|
+
`unknown opts key "${key}" \u2014 the bag is closed: ${PROFITABILITY_OPT_KEYS.join(", ")}`
|
|
4700
|
+
);
|
|
4701
|
+
}
|
|
4702
|
+
}
|
|
4703
|
+
if (!isDateYMD2(opts.dateFrom)) problems.push(`dateFrom is required (YYYY-MM-DD) (got ${String(opts.dateFrom)})`);
|
|
4704
|
+
if (!isDateYMD2(opts.dateTo)) problems.push(`dateTo is required (YYYY-MM-DD) (got ${String(opts.dateTo)})`);
|
|
4705
|
+
if (isDateYMD2(opts.dateFrom) && isDateYMD2(opts.dateTo) && opts.dateTo < opts.dateFrom) {
|
|
4706
|
+
problems.push(`dateTo must be >= dateFrom (got ${opts.dateTo})`);
|
|
4707
|
+
}
|
|
4708
|
+
if (isDateYMD2(opts.dateFrom) && isDateYMD2(opts.dateTo) && opts.dateTo >= opts.dateFrom) {
|
|
4709
|
+
const months = monthsInWindow(opts.dateFrom, opts.dateTo);
|
|
4710
|
+
if (months > PROFITABILITY_MAX_WINDOW_MONTHS) {
|
|
4711
|
+
problems.push(
|
|
4712
|
+
`window must span at most ${PROFITABILITY_MAX_WINDOW_MONTHS} months (the per-month windowing budget stays bounded; got ${months} months)`
|
|
4713
|
+
);
|
|
4714
|
+
}
|
|
4715
|
+
}
|
|
4716
|
+
const method = _nullishCoalesce(opts.labourCostMethod, () => ( "billing_item_our_cost"));
|
|
4717
|
+
if (!LABOUR_METHOD_SET.includes(method)) {
|
|
4718
|
+
problems.push(`labourCostMethod must be one of: ${LABOUR_METHOD_SET.join(", ")} (got ${String(opts.labourCostMethod)})`);
|
|
4719
|
+
}
|
|
4720
|
+
let rate = null;
|
|
4721
|
+
if (opts.labourRatePerHour !== void 0) {
|
|
4722
|
+
if (typeof opts.labourRatePerHour !== "number" || !Number.isFinite(opts.labourRatePerHour) || opts.labourRatePerHour < 0) {
|
|
4723
|
+
problems.push(`labourRatePerHour must be a finite number >= 0 (got ${String(opts.labourRatePerHour)})`);
|
|
4724
|
+
} else {
|
|
4725
|
+
rate = opts.labourRatePerHour;
|
|
4726
|
+
}
|
|
4727
|
+
}
|
|
4728
|
+
if (method === "provided" && rate === null) {
|
|
4729
|
+
problems.push(`labourRatePerHour is required (finite number >= 0) when labourCostMethod is "provided" (got ${String(opts.labourRatePerHour)})`);
|
|
4730
|
+
}
|
|
4731
|
+
for (const key of ["includeRecurringCosts", "includeUnbilledRevenue", "groupByActivity"]) {
|
|
4732
|
+
const v = opts[key];
|
|
4733
|
+
if (v !== void 0 && typeof v !== "boolean") problems.push(`${key} must be a boolean (got ${String(v)})`);
|
|
4734
|
+
}
|
|
4735
|
+
if (opts.externalMonthlyCosts !== void 0) {
|
|
4736
|
+
const emc = opts.externalMonthlyCosts;
|
|
4737
|
+
if (!Array.isArray(emc)) {
|
|
4738
|
+
problems.push("externalMonthlyCosts must be an array of finite numbers >= 0, indexed by month from dateFrom (got a non-array)");
|
|
4739
|
+
} else {
|
|
4740
|
+
const max = isDateYMD2(opts.dateFrom) && isDateYMD2(opts.dateTo) && opts.dateTo >= opts.dateFrom ? monthsInWindow(opts.dateFrom, opts.dateTo) : Infinity;
|
|
4741
|
+
for (let i = 0; i < emc.length; i++) {
|
|
4742
|
+
const v = emc[i];
|
|
4743
|
+
if (typeof v !== "number" || !Number.isFinite(v) || v < 0) {
|
|
4744
|
+
problems.push(`externalMonthlyCosts[${i}] must be a finite number >= 0 (got ${String(v)})`);
|
|
4745
|
+
}
|
|
4746
|
+
}
|
|
4747
|
+
if (emc.length > max) {
|
|
4748
|
+
problems.push(`externalMonthlyCosts must be an array of finite numbers >= 0, indexed by month from dateFrom, with at most ${max} entries (got ${emc.length})`);
|
|
4749
|
+
}
|
|
4750
|
+
}
|
|
4751
|
+
}
|
|
4752
|
+
const stale = _nullishCoalesce(opts.staleAfterDays, () => ( 30));
|
|
4753
|
+
if (!Number.isInteger(stale) || stale < 1) problems.push(`staleAfterDays must be an integer >= 1 (got ${String(opts.staleAfterDays)})`);
|
|
4754
|
+
const mtj = _nullishCoalesce(opts.maxTicketsForJoin, () => ( 500));
|
|
4755
|
+
if (!Number.isInteger(mtj) || mtj < 1 || mtj > 500) {
|
|
4756
|
+
problems.push(`maxTicketsForJoin must be an integer 1..500 (the in-filter cap; got ${String(opts.maxTicketsForJoin)})`);
|
|
4757
|
+
}
|
|
4758
|
+
let limit = 50;
|
|
4759
|
+
if (opts.limit !== void 0) {
|
|
4760
|
+
if (!Number.isInteger(opts.limit) || opts.limit < 1) {
|
|
4761
|
+
problems.push(`limit must be an integer >= 1 (got ${String(opts.limit)})`);
|
|
4762
|
+
} else {
|
|
4763
|
+
limit = Math.min(opts.limit, 500);
|
|
4764
|
+
}
|
|
4765
|
+
}
|
|
4766
|
+
try {
|
|
4767
|
+
_chunkIHRXVIUUcjs.parseIdentifier.call(void 0, contractId, "contractId");
|
|
4768
|
+
} catch (err) {
|
|
4769
|
+
problems.push(err instanceof _chunkIHRXVIUUcjs.AutotaskError ? err.message : "contractId must be a vendor numeric id");
|
|
4770
|
+
}
|
|
4771
|
+
if (problems.length > 0) {
|
|
4772
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
4773
|
+
`profitability: ${problems.length} problem(s) found pre-request (zero wire was issued)
|
|
4774
|
+
- ` + problems.join("\n- "),
|
|
4775
|
+
{ operation: "contracts.profitability" }
|
|
4776
|
+
);
|
|
4777
|
+
}
|
|
4778
|
+
return {
|
|
4779
|
+
dateFrom: opts.dateFrom,
|
|
4780
|
+
dateTo: opts.dateTo,
|
|
4781
|
+
method,
|
|
4782
|
+
labourRatePerHour: rate,
|
|
4783
|
+
includeRecurringCosts: _nullishCoalesce(opts.includeRecurringCosts, () => ( true)),
|
|
4784
|
+
includeUnbilledRevenue: _nullishCoalesce(opts.includeUnbilledRevenue, () => ( true)),
|
|
4785
|
+
externalMonthlyCosts: Array.isArray(opts.externalMonthlyCosts) ? [...opts.externalMonthlyCosts] : [],
|
|
4786
|
+
groupByActivity: _nullishCoalesce(opts.groupByActivity, () => ( true)),
|
|
4787
|
+
staleAfterDays: stale,
|
|
4788
|
+
maxTicketsForJoin: mtj,
|
|
4789
|
+
limit
|
|
4790
|
+
};
|
|
4791
|
+
}
|
|
4792
|
+
async function boundedPart2(http, path, conditions, limit, operation, includeFields) {
|
|
4793
|
+
const body = { MaxRecords: limit, filter: conditions };
|
|
4794
|
+
if (includeFields !== void 0) body.IncludeFields = includeFields;
|
|
4795
|
+
const res = await http.request({
|
|
4796
|
+
method: "POST",
|
|
4797
|
+
idempotent: true,
|
|
4798
|
+
path,
|
|
4799
|
+
body,
|
|
4800
|
+
operation
|
|
4801
|
+
});
|
|
4802
|
+
const { items, pageDetails } = _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res, operation);
|
|
4803
|
+
const capped = items.length >= limit;
|
|
4804
|
+
return { items, capped, hasMore: capped && pageDetails.nextPageUrl != null };
|
|
4805
|
+
}
|
|
4806
|
+
function capJoinSet2(ids, cap) {
|
|
4807
|
+
const sorted = [...new Set(ids)].sort((a, b) => a - b);
|
|
4808
|
+
if (sorted.length <= cap) return { ids: sorted, truncated: false, total: sorted.length };
|
|
4809
|
+
return { ids: sorted.slice(0, cap), truncated: true, total: sorted.length };
|
|
4810
|
+
}
|
|
4811
|
+
async function fetchByIdsPart(http, entityPath, ids, fields, operation) {
|
|
4812
|
+
const unique = [...new Set(ids)].sort((a, b) => a - b);
|
|
4813
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
4814
|
+
const misses = [];
|
|
4815
|
+
const notes = [];
|
|
4816
|
+
for (let c = 0; c < unique.length; c += _chunkIHRXVIUUcjs.FETCH_BY_IDS_CHUNK_SIZE) {
|
|
4817
|
+
const chunk = unique.slice(c, c + _chunkIHRXVIUUcjs.FETCH_BY_IDS_CHUNK_SIZE);
|
|
4818
|
+
const chunkKeys = new Set(chunk);
|
|
4819
|
+
try {
|
|
4820
|
+
const body = {
|
|
4821
|
+
MaxRecords: _chunkIHRXVIUUcjs.FETCH_BY_IDS_CHUNK_SIZE,
|
|
4822
|
+
filter: [{ field: "id", op: "in", value: chunk }],
|
|
4823
|
+
IncludeFields: fields
|
|
4824
|
+
};
|
|
4825
|
+
const res = await http.request({ method: "POST", idempotent: true, path: `${entityPath}/query`, body, operation });
|
|
4826
|
+
const { items: rows } = _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res, operation);
|
|
4827
|
+
for (const row of rows) {
|
|
4828
|
+
const k = num2(row.id);
|
|
4829
|
+
if (k > 0 && chunkKeys.has(k)) byKey.set(k, row);
|
|
4830
|
+
}
|
|
4831
|
+
} catch (err) {
|
|
4832
|
+
const code = err instanceof _chunkIHRXVIUUcjs.AutotaskError ? err.code : "SERVER_ERROR";
|
|
4833
|
+
for (const k of chunk) {
|
|
4834
|
+
if (!byKey.has(k) && !misses.some((m) => m.id === k)) misses.push({ id: k, code, message: err instanceof Error ? err.message : String(err) });
|
|
4835
|
+
}
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
const queryMissed = unique.filter((k) => !byKey.has(k) && !misses.some((m) => m.id === k));
|
|
4839
|
+
for (const k of queryMissed) {
|
|
4840
|
+
try {
|
|
4841
|
+
const res = await http.request({ method: "GET", path: `${entityPath}/${k}`, operation });
|
|
4842
|
+
byKey.set(k, _chunkIHRXVIUUcjs.unwrapItem.call(void 0, res, k, operation));
|
|
4843
|
+
} catch (err) {
|
|
4844
|
+
if (err instanceof _chunkIHRXVIUUcjs.NotFoundError) {
|
|
4845
|
+
misses.push({ id: k, code: "NOT_FOUND", message: err.message });
|
|
4846
|
+
} else if (err instanceof _chunkIHRXVIUUcjs.AutotaskError) {
|
|
4847
|
+
misses.push({ id: k, code: err.code, message: err.message });
|
|
4848
|
+
} else {
|
|
4849
|
+
misses.push({ id: k, code: "SERVER_ERROR", message: err instanceof Error ? err.message : String(err) });
|
|
4850
|
+
}
|
|
4851
|
+
}
|
|
4852
|
+
}
|
|
4853
|
+
const items = unique.map((k) => byKey.get(k)).filter((r) => r !== void 0);
|
|
4854
|
+
const gotByQuery = unique.length - queryMissed.length;
|
|
4855
|
+
if (queryMissed.length > 0 && gotByQuery === 0 && byKey.size > 0) {
|
|
4856
|
+
notes.push(
|
|
4857
|
+
`the chunk \`id in\` query returned 0 rows for ${byKey.size} id(s) \u2014 the per-id get fallback resolved them (the list-scoping quirk: get-by-id is the authority)`
|
|
4858
|
+
);
|
|
4859
|
+
}
|
|
4860
|
+
const foundIds = new Set(byKey.keys());
|
|
4861
|
+
if (misses.length > 0) {
|
|
4862
|
+
const byCode = /* @__PURE__ */ new Map();
|
|
4863
|
+
for (const m of misses) byCode.set(m.code, (_nullishCoalesce(byCode.get(m.code), () => ( 0))) + 1);
|
|
4864
|
+
notes.push(`${misses.length} id(s) unreadable: ${[...byCode.entries()].map(([code, n]) => `${n} \xD7 ${code}`).join(", ")} (per-item typed misses \u2014 the rest resolved)`);
|
|
4865
|
+
}
|
|
4866
|
+
return { items, foundIds, misses, notes };
|
|
4867
|
+
}
|
|
4868
|
+
function ladderFrom(ctx) {
|
|
4869
|
+
const rungs = [];
|
|
4870
|
+
const push = (s) => rungs.push(s);
|
|
4871
|
+
switch (ctx.method) {
|
|
4872
|
+
case "billing_item_our_cost":
|
|
4873
|
+
push("billing_item.ourCost");
|
|
4874
|
+
push("contract_role_costs.rate");
|
|
4875
|
+
push("resource.internalCost");
|
|
4876
|
+
break;
|
|
4877
|
+
case "contract_role_cost":
|
|
4878
|
+
push("contract_role_costs.rate");
|
|
4879
|
+
push("resource.internalCost");
|
|
4880
|
+
break;
|
|
4881
|
+
case "resource_internal_cost":
|
|
4882
|
+
push("resource.internalCost");
|
|
4883
|
+
break;
|
|
4884
|
+
case "provided":
|
|
4885
|
+
break;
|
|
4886
|
+
}
|
|
4887
|
+
if (ctx.rate !== null) push("provided");
|
|
4888
|
+
return rungs;
|
|
4889
|
+
}
|
|
4890
|
+
function hoursOf(entry) {
|
|
4891
|
+
const h = entry["hoursWorked"];
|
|
4892
|
+
return typeof h === "number" && Number.isFinite(h) && h > 0 ? h : 0;
|
|
4893
|
+
}
|
|
4894
|
+
function resolveLabour(entry, ctx) {
|
|
4895
|
+
const id = num2(entry["id"]);
|
|
4896
|
+
const hours = hoursOf(entry);
|
|
4897
|
+
for (const rung of ladderFrom(ctx)) {
|
|
4898
|
+
if (rung === "billing_item.ourCost") {
|
|
4899
|
+
const items = _nullishCoalesce(ctx.billedByEntryId.get(id), () => ( []));
|
|
4900
|
+
const costs = items.map((i) => i["ourCost"]).filter((v) => typeof v === "number" && Number.isFinite(v) && v >= 0);
|
|
4901
|
+
if (costs.length > 0) {
|
|
4902
|
+
return {
|
|
4903
|
+
source: "billing_item.ourCost",
|
|
4904
|
+
cost: costs.reduce((a, b) => a + b, 0),
|
|
4905
|
+
rate: null,
|
|
4906
|
+
evidence: { billingItemIds: items.map((i) => num2(i["id"])) }
|
|
4907
|
+
};
|
|
4908
|
+
}
|
|
4909
|
+
continue;
|
|
4910
|
+
}
|
|
4911
|
+
if (rung === "contract_role_costs.rate") {
|
|
4912
|
+
const resId = num2(entry["resourceID"]);
|
|
4913
|
+
const roleId = num2(entry["roleID"]);
|
|
4914
|
+
const row = resId > 0 && roleId > 0 ? _nullishCoalesce(ctx.roleCostByResourceRole.get(`${resId}:${roleId}`), () => ( ctx.roleCostByRole.get(roleId))) : roleId > 0 ? ctx.roleCostByRole.get(roleId) : void 0;
|
|
4915
|
+
const rate = row ? row["rate"] : void 0;
|
|
4916
|
+
if (row !== void 0 && typeof rate === "number" && Number.isFinite(rate) && rate >= 0) {
|
|
4917
|
+
const matched = row !== void 0 && resId > 0 && roleId > 0 && ctx.roleCostByResourceRole.get(`${resId}:${roleId}`) !== void 0 ? "resource+role" : "role";
|
|
4918
|
+
return { source: "contract_role_costs.rate", cost: rate * hours, rate, evidence: { contractRoleCostId: num2(row["id"]), matched } };
|
|
4919
|
+
}
|
|
4920
|
+
continue;
|
|
4921
|
+
}
|
|
4922
|
+
if (rung === "resource.internalCost") {
|
|
4923
|
+
const resId = num2(entry["resourceID"]);
|
|
4924
|
+
const r = resId > 0 ? ctx.resourcesById.get(resId) : void 0;
|
|
4925
|
+
const ic = r ? r["internalCost"] : void 0;
|
|
4926
|
+
if (r !== void 0 && typeof ic === "number" && Number.isFinite(ic) && ic >= 0) {
|
|
4927
|
+
return { source: "resource.internalCost", cost: ic * hours, rate: ic, evidence: { resourceId: resId } };
|
|
4928
|
+
}
|
|
4929
|
+
continue;
|
|
4930
|
+
}
|
|
4931
|
+
if (rung === "provided" && ctx.rate !== null) {
|
|
4932
|
+
return { source: "provided", cost: ctx.rate * hours, rate: ctx.rate, evidence: {} };
|
|
4933
|
+
}
|
|
4934
|
+
}
|
|
4935
|
+
return { source: "missing", cost: null, rate: null, evidence: {} };
|
|
4936
|
+
}
|
|
4937
|
+
async function expandByMonth(http, path, fullWindowCond, limit, operation, fields, dateField, dateFrom, dateTo, wires) {
|
|
4938
|
+
const months = monthsBetween(dateFrom, dateTo);
|
|
4939
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4940
|
+
const all = [];
|
|
4941
|
+
const cappedMonths = [];
|
|
4942
|
+
const fullMonths = [];
|
|
4943
|
+
for (const m of months) {
|
|
4944
|
+
const b = monthBounds(m, dateFrom, dateTo);
|
|
4945
|
+
const cond = [
|
|
4946
|
+
...fullWindowCond.filter((c) => c.field !== dateField),
|
|
4947
|
+
{ field: dateField, op: "gte", value: b.start },
|
|
4948
|
+
{ field: dateField, op: "lt", value: b.endExclusive }
|
|
4949
|
+
];
|
|
4950
|
+
const page = await boundedPart2(http, path, cond, limit, operation, fields);
|
|
4951
|
+
wires.issued += 1;
|
|
4952
|
+
for (const row of page.items) {
|
|
4953
|
+
const k = num2(row["id"]);
|
|
4954
|
+
if (seen.has(k)) continue;
|
|
4955
|
+
seen.add(k);
|
|
4956
|
+
all.push(row);
|
|
4957
|
+
}
|
|
4958
|
+
if (page.capped) cappedMonths.push(m);
|
|
4959
|
+
if (page.capped && page.hasMore) fullMonths.push(m);
|
|
4960
|
+
}
|
|
4961
|
+
const partNote = `per-month windowing fired: ${months.length} month read(s) added after the full-window page carried a live cursor (no cursor walk \u2014 the single-page house rule)` + (fullMonths.length > 0 ? ` | month ${fullMonths.join(", ")} hit the limit of ${limit} \u2014 figures cover the returned rows only; widen with a narrower window or higher limit` : "");
|
|
4962
|
+
wires.note = (wires.note ? wires.note + " | " : "") + partNote;
|
|
4963
|
+
return { items: all, capped: cappedMonths.length > 0, hasMore: fullMonths.length > 0, note: partNote, status: "ok", truncatedMonths: fullMonths };
|
|
4964
|
+
}
|
|
4965
|
+
async function degradable(read) {
|
|
4966
|
+
try {
|
|
4967
|
+
return await read();
|
|
4968
|
+
} catch (err) {
|
|
4969
|
+
if (!(err instanceof _chunkIHRXVIUUcjs.AutotaskError)) throw err;
|
|
4970
|
+
return { items: [], capped: false, hasMore: false, absent: err.code, absentMessage: err.message };
|
|
4971
|
+
}
|
|
4972
|
+
}
|
|
4973
|
+
function fmtHours(h) {
|
|
4974
|
+
const r = Math.round(h * 100) / 100;
|
|
4975
|
+
return String(r);
|
|
4976
|
+
}
|
|
4977
|
+
function fmtNum(v) {
|
|
4978
|
+
const r = Math.round(v * 100) / 100;
|
|
4979
|
+
return String(r);
|
|
4980
|
+
}
|
|
4981
|
+
function pctOrNa(r) {
|
|
4982
|
+
return r === null ? "n/a" : `${Math.round(r * 1e3) / 10}%`;
|
|
4983
|
+
}
|
|
4984
|
+
function dedupeSortCap(ids, limit) {
|
|
4985
|
+
return [...new Set(ids)].sort((a, b) => Number(a) - Number(b)).slice(0, limit);
|
|
4986
|
+
}
|
|
4987
|
+
async function profitability(resource, contractId, opts, rawHttp) {
|
|
4988
|
+
const v = validateProfitabilityOptions(contractId, _nullishCoalesce(opts, () => ( {})));
|
|
4989
|
+
const OP2 = "contracts.profitability";
|
|
4990
|
+
const id = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, contractId, "contractId");
|
|
4991
|
+
const idNum = typeof id === "number" ? id : Number(id);
|
|
4992
|
+
const wires = { issued: 0, requests: 0, budget: PROFITABILITY_WIRE_BUDGET };
|
|
4993
|
+
const asOf = (/* @__PURE__ */ new Date()).toISOString();
|
|
4994
|
+
const asOfMs = Date.parse(asOf);
|
|
4995
|
+
const toExcl = dayAfter(v.dateTo);
|
|
4996
|
+
const windowOn = (field) => [{ field, op: "gte", value: v.dateFrom }, { field, op: "lt", value: toExcl }];
|
|
4997
|
+
const http = { request: (o) => {
|
|
4998
|
+
wires.requests += 1;
|
|
4999
|
+
return rawHttp.request(o);
|
|
5000
|
+
} };
|
|
5001
|
+
const readPart = (path, conditions, fields) => {
|
|
5002
|
+
wires.issued += 1;
|
|
5003
|
+
return degradable(() => boundedPart2(http, path, conditions, v.limit, OP2, fields));
|
|
5004
|
+
};
|
|
5005
|
+
const skipPart = (note) => ({ items: [], capped: false, hasMore: false, status: "skipped", note });
|
|
5006
|
+
const stampPart = (key, raw, conditions, extraNotes) => {
|
|
5007
|
+
if (raw.absent !== void 0) {
|
|
5008
|
+
return { items: [], capped: false, hasMore: false, status: "absent", absent: raw.absent, note: `absent: the read failed (${raw.absent}: ${_nullishCoalesce(raw.absentMessage, () => ( ""))}) \u2014 the monthly figures it feeds carry it in coverage_gaps` };
|
|
5009
|
+
}
|
|
5010
|
+
const st = unbilledWorkPartStatus(key, conditions, raw.items);
|
|
5011
|
+
return {
|
|
5012
|
+
items: raw.items,
|
|
5013
|
+
capped: raw.capped,
|
|
5014
|
+
hasMore: raw.hasMore,
|
|
5015
|
+
status: st.status,
|
|
5016
|
+
blindSurface: st.blindSurface,
|
|
5017
|
+
note: [st.note, ..._nullishCoalesce(extraNotes, () => ( []))].filter(Boolean).join(" | ") || void 0,
|
|
5018
|
+
emptyReason: raw.items.length === 0 && st.status === "ok" ? _optionalChain([_chunkIHRXVIUUcjs.EMPTY_REASON_STAMPS, 'access', _29 => _29[key], 'optionalAccess', _30 => _30.query]) : void 0
|
|
5019
|
+
};
|
|
5020
|
+
};
|
|
5021
|
+
const truncatedMonths = {};
|
|
5022
|
+
const windowedPart = async (name, key, path, cond, fields, dateField) => {
|
|
5023
|
+
const first = await readPart(path, cond, fields);
|
|
5024
|
+
if (first.absent !== void 0 || !first.hasMore) return { part: stampPart(key, first, cond), rows: first.items };
|
|
5025
|
+
const wp = await degradable(() => expandByMonth(http, path, cond, v.limit, OP2, fields, dateField, v.dateFrom, v.dateTo, wires));
|
|
5026
|
+
if (!("truncatedMonths" in wp)) return { part: stampPart(key, wp, cond), rows: [] };
|
|
5027
|
+
const { truncatedMonths: tm, ...part } = wp;
|
|
5028
|
+
truncatedMonths[name] = tm;
|
|
5029
|
+
return { part, rows: wp.items };
|
|
5030
|
+
};
|
|
5031
|
+
const contractCached = _optionalChain([rawHttp, 'access', _31 => _31.readCache, 'optionalAccess', _32 => _32.get, 'call', _33 => _33(`/V1.0/Contracts/${id}`)]) !== void 0;
|
|
5032
|
+
const contract = await resource.get(id);
|
|
5033
|
+
wires.issued += 1;
|
|
5034
|
+
if (!contractCached) wires.requests += 1;
|
|
5035
|
+
const contractRow = contract;
|
|
5036
|
+
const companyID = num2(contractRow["companyID"]);
|
|
5037
|
+
const contractType = num2(contractRow["contractType"]);
|
|
5038
|
+
let customer = null;
|
|
5039
|
+
let customerStatus = "skipped";
|
|
5040
|
+
let customerAbsent;
|
|
5041
|
+
if (companyID > 0) {
|
|
5042
|
+
try {
|
|
5043
|
+
const res = await http.request({
|
|
5044
|
+
method: "GET",
|
|
5045
|
+
path: `/V1.0/Companies/${companyID}`,
|
|
5046
|
+
operation: OP2
|
|
5047
|
+
});
|
|
5048
|
+
const item = _chunkIHRXVIUUcjs.unwrapItem.call(void 0, res, companyID, OP2);
|
|
5049
|
+
customer = _nullishCoalesce(item, () => ( null));
|
|
5050
|
+
customerStatus = "ok";
|
|
5051
|
+
} catch (err) {
|
|
5052
|
+
if (!(err instanceof _chunkIHRXVIUUcjs.AutotaskError)) throw err;
|
|
5053
|
+
if (!(err instanceof _chunkIHRXVIUUcjs.NotFoundError)) {
|
|
5054
|
+
customerStatus = "absent";
|
|
5055
|
+
customerAbsent = err.code;
|
|
5056
|
+
}
|
|
5057
|
+
}
|
|
5058
|
+
wires.issued += 1;
|
|
5059
|
+
}
|
|
5060
|
+
let contractTypeLabel = null;
|
|
5061
|
+
if (contractType > 0) {
|
|
5062
|
+
wires.issued += 1;
|
|
5063
|
+
try {
|
|
5064
|
+
contractTypeLabel = await _asyncNullishCoalesce(await _asyncOptionalChain([(await readPicklists(http, "/V1.0/Contracts", OP2)), 'access', async _34 => _34.get, 'call', async _35 => _35("contractType"), 'optionalAccess', async _36 => _36.get, 'call', async _37 => _37(contractType)]), async () => ( null));
|
|
5065
|
+
} catch (err) {
|
|
5066
|
+
if (!(err instanceof _chunkIHRXVIUUcjs.AutotaskError)) throw err;
|
|
5067
|
+
}
|
|
5068
|
+
}
|
|
5069
|
+
const contractTypeKnown = contractTypeLabel !== null;
|
|
5070
|
+
const isBlockHours = contractTypeKnown && BLOCK_HOURS_LABEL_RE.test(contractTypeLabel);
|
|
5071
|
+
const isTimeAndMaterials = contractTypeKnown && TIME_AND_MATERIALS_LABEL_RE.test(contractTypeLabel);
|
|
5072
|
+
const servicesCond = [{ field: "contractID", op: "eq", value: id }];
|
|
5073
|
+
const servicesRaw = await readPart("/V1.0/ContractServices/query", servicesCond, ["id", "serviceID", "unitPrice", "unitCost", "internalCurrencyUnitPrice", "internalDescription"]);
|
|
5074
|
+
const unitsCond = [{ field: "contractID", op: "eq", value: id }, ...windowOn("startDate")];
|
|
5075
|
+
const units = await windowedPart("contractServiceUnits", "contract_service_units", "/V1.0/ContractServiceUnits/query", unitsCond, ["id", "contractServiceID", "serviceID", "units", "price", "cost", "internalCurrencyPrice", "startDate", "endDate", "approveAndPostDate"], "startDate");
|
|
5076
|
+
const unitRows = units.rows;
|
|
5077
|
+
let chargesPart;
|
|
5078
|
+
let charges = [];
|
|
5079
|
+
let chargesCond = [];
|
|
5080
|
+
if (v.includeRecurringCosts) {
|
|
5081
|
+
chargesCond = [{ field: "contractID", op: "eq", value: id }, ...windowOn("datePurchased")];
|
|
5082
|
+
const raw = await readPart("/V1.0/ContractCharges/query", chargesCond, ["id", "chargeType", "billableAmount", "extendedCost", "unitCost", "unitPrice", "unitQuantity", "datePurchased", "isBilled", "status", "contractServiceID"]);
|
|
5083
|
+
charges = raw.items;
|
|
5084
|
+
chargesPart = stampPart("contract_charges", raw, chargesCond);
|
|
5085
|
+
} else {
|
|
5086
|
+
chargesPart = skipPart("skipped: includeRecurringCosts is false (zero wire)");
|
|
5087
|
+
}
|
|
5088
|
+
const roleCostsCond = [{ field: "contractID", op: "eq", value: id }];
|
|
5089
|
+
const roleCostsRaw = await readPart("/V1.0/ContractRoleCosts/query", roleCostsCond, ["id", "rate", "resourceID", "roleID"]);
|
|
5090
|
+
const ratesCond = [{ field: "contractID", op: "eq", value: id }];
|
|
5091
|
+
const ratesRaw = await readPart("/V1.0/ContractRates/query", ratesCond, ["id", "roleID", "contractHourlyRate", "internalCurrencyContractHourlyRate"]);
|
|
5092
|
+
let blocksPart;
|
|
5093
|
+
if (!isBlockHours) {
|
|
5094
|
+
blocksPart = skipPart(
|
|
5095
|
+
contractTypeKnown ? `skipped: not a Block Hours contract (contractType ${contractType} "${contractTypeLabel}") \u2014 included hours apply to hour blocks only (zero wire)` : `skipped: the contract type is unknown (contractType ${contractType || "absent"}; label unresolved) \u2014 included hours are not evaluable (zero wire)`
|
|
5096
|
+
);
|
|
5097
|
+
} else {
|
|
5098
|
+
const blocksCond = [{ field: "contractID", op: "eq", value: id }];
|
|
5099
|
+
const raw = await readPart("/V1.0/ContractBlocks/query", blocksCond, ["id", "datePurchased", "startDate", "endDate", "hours", "hoursApproved", "status", "isPaid"]);
|
|
5100
|
+
blocksPart = stampPart("contract_blocks", raw, blocksCond);
|
|
5101
|
+
}
|
|
5102
|
+
const billingCond = [{ field: "contractID", op: "eq", value: id }, ...windowOn("itemDate")];
|
|
5103
|
+
const billingFields = ["id", "invoiceID", "timeEntryID", "ticketID", "ourCost", "quantity", "rate", "extendedPrice", "internalCurrencyExtendedPrice", "itemDate", "postedDate", "nonBillable", "billingCodeID", "billingItemType", "expenseItemID", ...SERVICE_LINE_FKS, ...CHARGE_LINE_FKS];
|
|
5104
|
+
const billing = await windowedPart("billingItems", "billing_items", "/V1.0/BillingItems/query", billingCond, billingFields, "itemDate");
|
|
5105
|
+
const billingItems = billing.part;
|
|
5106
|
+
const billingRows = billing.rows;
|
|
5107
|
+
const invoiceIds = [...new Set(billingRows.map((b) => num2(b["invoiceID"])).filter((n) => n > 0))];
|
|
5108
|
+
let invoicesPart;
|
|
5109
|
+
let invoices = [];
|
|
5110
|
+
if (invoiceIds.length === 0) {
|
|
5111
|
+
invoicesPart = skipPart("skipped: the billing part has no invoiceIDs (zero wire)");
|
|
5112
|
+
} else {
|
|
5113
|
+
const capped = capJoinSet2(invoiceIds, _chunkIHRXVIUUcjs.FETCH_BY_IDS_MAX_ITEMS);
|
|
5114
|
+
if (capped.truncated) wires.note = (wires.note ? wires.note + " | " : "") + `invoiceJoinTruncated: the join set is capped at ${_chunkIHRXVIUUcjs.FETCH_BY_IDS_MAX_ITEMS} of ${capped.total} invoice ids (the fetch-by-ids cap) \u2014 the figures cover the returned set only`;
|
|
5115
|
+
const fb = await fetchByIdsPart(http, "/V1.0/Invoices", capped.ids, ["id", "invoiceNumber", "invoiceTotal", "paidDate", "isVoided", "dueDate"], OP2);
|
|
5116
|
+
wires.issued += 1;
|
|
5117
|
+
invoices = fb.items;
|
|
5118
|
+
invoicesPart = { items: fb.items, capped: capped.truncated, hasMore: capped.truncated, status: "ok", note: fb.notes.join(" | ") || void 0 };
|
|
5119
|
+
}
|
|
5120
|
+
const timeCond = [{ field: "contractID", op: "eq", value: id }, ...windowOn("dateWorked")];
|
|
5121
|
+
const timeFields = ["id", "ticketID", "taskID", "resourceID", "roleID", "hoursWorked", "hoursToBill", "dateWorked", "startDateTime", "endDateTime", "isNonBillable", "timeEntryType", "billingCodeID", "createDateTime"];
|
|
5122
|
+
const time = await windowedPart("timeEntries", "time_entries", "/V1.0/TimeEntries/query", timeCond, timeFields, "dateWorked");
|
|
5123
|
+
const timeEntries = time.part;
|
|
5124
|
+
const entries = time.rows;
|
|
5125
|
+
const ticketFields = ["id", "ticketNumber", "title", "status", "ticketCategory", "contractID", "createDate", "resolvedDateTime", "completedDate", "lastActivityDate", "dueDateTime"];
|
|
5126
|
+
const createdInWindow = [{ field: "contractID", op: "eq", value: id }, ...windowOn("createDate")];
|
|
5127
|
+
const refTicketIds = capJoinSet2(entries.map((e) => num2(e["ticketID"])).filter((n) => n > 0), v.maxTicketsForJoin);
|
|
5128
|
+
const ticketsActCond = refTicketIds.ids.length === 0 ? createdInWindow : [{ op: "or", items: [{ op: "and", items: createdInWindow }, { field: "id", op: "in", value: refTicketIds.ids }] }];
|
|
5129
|
+
const ticketsActRaw = await readPart("/V1.0/Tickets/query", ticketsActCond, ticketFields);
|
|
5130
|
+
let openStatusSet = null;
|
|
5131
|
+
let statusNote;
|
|
5132
|
+
wires.issued += 1;
|
|
5133
|
+
try {
|
|
5134
|
+
const values = (await readPicklists(http, "/V1.0/Tickets", OP2)).get("status");
|
|
5135
|
+
if (values === void 0 || values.size === 0) {
|
|
5136
|
+
statusNote = "the tickets.status picklist is not exposed to this API user \u2014 the open-status labels are unavailable";
|
|
5137
|
+
} else {
|
|
5138
|
+
const open = [...values].filter(([, label]) => !CLOSED_STATUS_LABEL_RE.test(label)).map(([v2]) => v2);
|
|
5139
|
+
if (open.length === 0) {
|
|
5140
|
+
statusNote = "every tickets.status picklist label is closed-class \u2014 no open statuses exist in this tenant";
|
|
5141
|
+
} else {
|
|
5142
|
+
openStatusSet = new Set(open);
|
|
5143
|
+
}
|
|
5144
|
+
}
|
|
5145
|
+
} catch (err) {
|
|
5146
|
+
statusNote = `the tickets.status field catalog read failed (${err instanceof _chunkIHRXVIUUcjs.AutotaskError ? err.code : "SERVER_ERROR"}: ${err instanceof Error ? err.message : String(err)}) \u2014 the open-status labels are unavailable`;
|
|
5147
|
+
}
|
|
5148
|
+
let ticketsOpenPart;
|
|
5149
|
+
let openTickets = [];
|
|
5150
|
+
if (openStatusSet === null) {
|
|
5151
|
+
ticketsOpenPart = skipPart(`skipped: ${statusNote} (zero wire)`);
|
|
5152
|
+
} else {
|
|
5153
|
+
const openCond = [{ field: "contractID", op: "eq", value: id }, { field: "status", op: "in", value: [...openStatusSet] }];
|
|
5154
|
+
const raw = await readPart("/V1.0/Tickets/query", openCond, ticketFields);
|
|
5155
|
+
openTickets = raw.items;
|
|
5156
|
+
ticketsOpenPart = stampPart("tickets", raw, openCond, ["openStatusHeuristic: true (the open set is the tenant picklist minus the closed-class labels)"]);
|
|
5157
|
+
}
|
|
5158
|
+
const resourceIds = [...new Set(entries.map((t) => num2(t["resourceID"])).filter((n) => n > 0))];
|
|
5159
|
+
let resourcesPart;
|
|
5160
|
+
let resources = [];
|
|
5161
|
+
const resourceMissIds = /* @__PURE__ */ new Set();
|
|
5162
|
+
if (resourceIds.length === 0) {
|
|
5163
|
+
resourcesPart = skipPart("skipped: the time part has no resourceIDs (zero wire)");
|
|
5164
|
+
} else {
|
|
5165
|
+
const capped = capJoinSet2(resourceIds, _chunkIHRXVIUUcjs.FETCH_BY_IDS_MAX_ITEMS);
|
|
5166
|
+
if (capped.truncated) wires.note = (wires.note ? wires.note + " | " : "") + `resourceJoinTruncated: the join set is capped at ${_chunkIHRXVIUUcjs.FETCH_BY_IDS_MAX_ITEMS} of ${capped.total} resource ids (the fetch-by-ids cap) \u2014 the figures cover the returned set only`;
|
|
5167
|
+
const fb = await fetchByIdsPart(http, "/V1.0/Resources", capped.ids, ["id", "internalCost", "firstName", "lastName", "isActive", "userType"], OP2);
|
|
5168
|
+
wires.issued += 1;
|
|
5169
|
+
resources = fb.items;
|
|
5170
|
+
for (const m of fb.misses) if (m.code === "NOT_FOUND") resourceMissIds.add(m.id);
|
|
5171
|
+
resourcesPart = { items: fb.items, capped: capped.truncated, hasMore: capped.truncated, status: "ok", note: fb.notes.join(" | ") || void 0 };
|
|
5172
|
+
}
|
|
5173
|
+
const fetchedTickets = /* @__PURE__ */ new Map();
|
|
5174
|
+
for (const t of [...ticketsActRaw.items, ...openTickets]) {
|
|
5175
|
+
const k = num2(t["id"]);
|
|
5176
|
+
if (k > 0 && !fetchedTickets.has(k)) fetchedTickets.set(k, t);
|
|
5177
|
+
}
|
|
5178
|
+
const contractTickets = [...fetchedTickets.values()].filter((t) => num2(t["contractID"]) === idNum);
|
|
5179
|
+
const ticketJoin = capJoinSet2(contractTickets.map((t) => num2(t["id"])), v.maxTicketsForJoin);
|
|
5180
|
+
const joinNote = ticketJoin.truncated ? `the ticket join set is capped at ${v.maxTicketsForJoin} of ${ticketJoin.total} ids \u2014 the expenses + the miscoding probe cover the returned join set only` : void 0;
|
|
5181
|
+
let expensesPart;
|
|
5182
|
+
let expenses = [];
|
|
5183
|
+
if (ticketJoin.ids.length === 0) {
|
|
5184
|
+
expensesPart = skipPart("skipped: the contract has no fetched tickets to join against (an empty join set is NOT evidence of no expenses \u2014 zero wire)");
|
|
5185
|
+
} else {
|
|
5186
|
+
const expCond = [{ field: "ticketID", op: "in", value: ticketJoin.ids }, ...windowOn("expenseDate")];
|
|
5187
|
+
const raw = await readPart("/V1.0/ExpenseItems/query", expCond, ["id", "expenseDate", "expenseCategory", "paymentType", "expenseCurrencyExpenseAmount", "internalCurrencyExpenseAmount", "ticketID"]);
|
|
5188
|
+
expenses = raw.items;
|
|
5189
|
+
expensesPart = stampPart("expense_items", raw, expCond, joinNote === void 0 ? void 0 : [joinNote]);
|
|
5190
|
+
}
|
|
5191
|
+
let probePart;
|
|
5192
|
+
let probeRows = [];
|
|
5193
|
+
if (ticketJoin.ids.length === 0) {
|
|
5194
|
+
probePart = skipPart("skipped: the contract has no fetched tickets to probe against (zero wire) \u2014 check 1 (miscoded_time_out) is not evaluable");
|
|
5195
|
+
} else {
|
|
5196
|
+
const probeCond = [
|
|
5197
|
+
{ field: "ticketID", op: "in", value: ticketJoin.ids },
|
|
5198
|
+
{ op: "or", items: [{ field: "contractID", op: "noteq", value: id }, { field: "contractID", op: "notExist" }] },
|
|
5199
|
+
...windowOn("dateWorked")
|
|
5200
|
+
];
|
|
5201
|
+
const raw = await readPart("/V1.0/TimeEntries/query", probeCond, ["id", "ticketID", "contractID", "resourceID", "hoursWorked", "dateWorked"]);
|
|
5202
|
+
probeRows = raw.items;
|
|
5203
|
+
probePart = stampPart("time_entries", raw, probeCond, joinNote === void 0 ? void 0 : [joinNote]);
|
|
5204
|
+
}
|
|
5205
|
+
let configurationItemsPart;
|
|
5206
|
+
let cis = [];
|
|
5207
|
+
if (!v.includeRecurringCosts) {
|
|
5208
|
+
configurationItemsPart = skipPart("skipped: includeRecurringCosts is false (zero wire)");
|
|
5209
|
+
} else {
|
|
5210
|
+
const ciCond = [{ field: "contractID", op: "eq", value: id }];
|
|
5211
|
+
const raw = await readPart("/V1.0/ConfigurationItems/query", ciCond, ["id", "configurationItemName", "status", "contractID"]);
|
|
5212
|
+
cis = raw.items;
|
|
5213
|
+
configurationItemsPart = stampPart("configuration_items", raw, ciCond);
|
|
5214
|
+
}
|
|
5215
|
+
let subscriptionsPart;
|
|
5216
|
+
let subscriptions = [];
|
|
5217
|
+
const subFactor = /* @__PURE__ */ new Map();
|
|
5218
|
+
const oneTimeSubs = /* @__PURE__ */ new Set();
|
|
5219
|
+
const cancelledSubs = /* @__PURE__ */ new Set();
|
|
5220
|
+
if (cis.length === 0) {
|
|
5221
|
+
subscriptionsPart = skipPart("skipped: the CI join found no configuration items \u2014 the subscriptions part is not evaluable (zero wire)");
|
|
5222
|
+
} else {
|
|
5223
|
+
const ciIds = capJoinSet2(cis.map((c) => num2(c["id"])).filter((n) => n > 0), _chunkIHRXVIUUcjs.FETCH_BY_IDS_MAX_ITEMS);
|
|
5224
|
+
const subCond = [{ field: "configurationItemID", op: "in", value: ciIds.ids }];
|
|
5225
|
+
const raw = await readPart("/V1.0/Subscriptions/query", subCond, ["id", "subscriptionName", "configurationItemID", "periodCost", "periodPrice", "periodType", "effectiveDate", "expirationDate", "status", "totalCost"]);
|
|
5226
|
+
subscriptions = raw.items;
|
|
5227
|
+
let labels = null;
|
|
5228
|
+
if (subscriptions.length > 0) {
|
|
5229
|
+
wires.issued += 1;
|
|
5230
|
+
try {
|
|
5231
|
+
labels = await readPicklists(http, "/V1.0/Subscriptions", OP2);
|
|
5232
|
+
} catch (err) {
|
|
5233
|
+
if (!(err instanceof _chunkIHRXVIUUcjs.AutotaskError)) throw err;
|
|
5234
|
+
}
|
|
5235
|
+
}
|
|
5236
|
+
for (const x of subscriptions) {
|
|
5237
|
+
const sid = num2(x["id"]);
|
|
5238
|
+
const periodLabel = _optionalChain([labels, 'optionalAccess', _38 => _38.get, 'call', _39 => _39("periodType"), 'optionalAccess', _40 => _40.get, 'call', _41 => _41(num2(x["periodType"]))]);
|
|
5239
|
+
subFactor.set(sid, periodMonthlyFactor(x["periodType"], periodLabel));
|
|
5240
|
+
if (isOneTimePeriod(x["periodType"], periodLabel)) oneTimeSubs.add(sid);
|
|
5241
|
+
const statusLabel = _optionalChain([labels, 'optionalAccess', _42 => _42.get, 'call', _43 => _43("status"), 'optionalAccess', _44 => _44.get, 'call', _45 => _45(num2(x["status"]))]);
|
|
5242
|
+
const notActive = statusLabel !== void 0 ? NOT_ACTIVE_LABEL_RE.test(statusLabel) : labels === null && SUBSCRIPTION_NOT_ACTIVE_STATUS_IDS.has(num2(x["status"]));
|
|
5243
|
+
if (notActive) cancelledSubs.add(sid);
|
|
5244
|
+
}
|
|
5245
|
+
const unknownPeriods = [...new Set(subscriptions.filter((x) => subFactor.get(num2(x["id"])) === null && !oneTimeSubs.has(num2(x["id"]))).map((x) => String(_nullishCoalesce(x["periodType"], () => ( "absent")))))];
|
|
5246
|
+
subscriptionsPart = stampPart("subscriptions", raw, subCond, [
|
|
5247
|
+
"scope: the subscriptions on the CIs this contract covers \u2014 periodCost prorated to a month by periodType into tooling_cost.vendor, REPORTED but NOT folded into total_cost/profit/margin (subscriptions bill outside the contract)",
|
|
5248
|
+
...subscriptions.length > 0 && labels === null ? ["the Subscriptions field catalog read failed \u2014 the verified id maps apply (periodType 1 One-Time, 2 Monthly, 3 Quarterly, 4 Semi-Annual, 5 Yearly; status 2 Cancelled / 3 Inactive excluded)"] : [],
|
|
5249
|
+
...cancelledSubs.size > 0 ? [`${cancelledSubs.size} not-active (cancelled/inactive) subscription(s) excluded from tooling_cost.vendor`] : [],
|
|
5250
|
+
...oneTimeSubs.size > 0 ? [`${oneTimeSubs.size} one-time subscription(s): periodCost booked whole in the effectiveDate month, never prorated`] : [],
|
|
5251
|
+
...unknownPeriods.length > 0 ? [`unrecognised periodType ${unknownPeriods.join(", ")} \u2014 those subscriptions are excluded from tooling_cost.vendor (not prorated)`] : []
|
|
5252
|
+
]);
|
|
5253
|
+
}
|
|
5254
|
+
const servicesPart = stampPart("contract_services", servicesRaw, servicesCond);
|
|
5255
|
+
const unitsPart = units.part;
|
|
5256
|
+
const roleCostsPart = stampPart("contract_role_costs", roleCostsRaw, roleCostsCond);
|
|
5257
|
+
const ratesPart = stampPart("contract_rates", ratesRaw, ratesCond);
|
|
5258
|
+
const ticketsActivityPart = stampPart("tickets", ticketsActRaw, ticketsActCond, [
|
|
5259
|
+
...ticketsActRaw.hasMore ? [`${fetchedTickets.size} ticket(s) returned of possibly more \u2014 the checks cover the returned set only`] : [],
|
|
5260
|
+
...refTicketIds.truncated ? [`the time-referenced ticket ids are capped at ${v.maxTicketsForJoin} of ${refTicketIds.total} \u2014 the rest read as ticket_not_in_fetched_set`] : []
|
|
5261
|
+
]);
|
|
5262
|
+
const billedByEntryId = /* @__PURE__ */ new Map();
|
|
5263
|
+
for (const b of billingRows) {
|
|
5264
|
+
const te = num2(b["timeEntryID"]);
|
|
5265
|
+
if (te <= 0) continue;
|
|
5266
|
+
const arr = _nullishCoalesce(billedByEntryId.get(te), () => ( []));
|
|
5267
|
+
arr.push(b);
|
|
5268
|
+
billedByEntryId.set(te, arr);
|
|
5269
|
+
}
|
|
5270
|
+
const roleCostByResourceRole = /* @__PURE__ */ new Map();
|
|
5271
|
+
const roleCostByRole = /* @__PURE__ */ new Map();
|
|
5272
|
+
for (const rc of roleCostsRaw.items) {
|
|
5273
|
+
const resId = num2(rc["resourceID"]);
|
|
5274
|
+
const roleId = num2(rc["roleID"]);
|
|
5275
|
+
if (resId > 0 && roleId > 0) roleCostByResourceRole.set(`${resId}:${roleId}`, rc);
|
|
5276
|
+
else if (roleId > 0) roleCostByRole.set(roleId, rc);
|
|
5277
|
+
}
|
|
5278
|
+
const resourcesById = new Map(resources.map((r) => [num2(r["id"]), r]));
|
|
5279
|
+
const ladderCtx = { method: v.method, rate: v.labourRatePerHour, billedByEntryId, roleCostByResourceRole, roleCostByRole, resourcesById, resourceMissIds };
|
|
5280
|
+
const entryResolution = /* @__PURE__ */ new Map();
|
|
5281
|
+
for (const e of entries) entryResolution.set(num2(e["id"]), resolveLabour(e, ladderCtx));
|
|
5282
|
+
const activeRungs = ladderFrom(ladderCtx);
|
|
5283
|
+
const sources = {};
|
|
5284
|
+
for (const rung of activeRungs) sources[rung] = { entries: 0, hours: 0, cost: 0 };
|
|
5285
|
+
sources.missing = { entries: 0, hours: 0, cost: 0 };
|
|
5286
|
+
const resolutionNotes = [];
|
|
5287
|
+
if (v.method === "billing_item_our_cost") {
|
|
5288
|
+
const noItems = entries.filter((e) => !billedByEntryId.has(num2(e["id"]))).length;
|
|
5289
|
+
if (noItems > 0) resolutionNotes.push(`${noItems} ${noItems === 1 ? "entry" : "entries"} had no billing item (non-billable or unposted) \u2014 rung 1 not usable`);
|
|
5290
|
+
}
|
|
5291
|
+
for (const resId of [...resourceMissIds].sort((a, b) => a - b)) {
|
|
5292
|
+
const n = entries.filter((e) => num2(e["resourceID"]) === resId).length;
|
|
5293
|
+
resolutionNotes.push(`resource ${resId} unreadable (fetchByIds NOT_FOUND) \u2014 rung 3 unavailable for ${n} ${n === 1 ? "entry" : "entries"}`);
|
|
5294
|
+
}
|
|
5295
|
+
for (const e of entries) {
|
|
5296
|
+
const r = entryResolution.get(num2(e["id"]));
|
|
5297
|
+
const bucket = _nullishCoalesce(sources[r.source], () => ( sources.missing));
|
|
5298
|
+
bucket.entries += 1;
|
|
5299
|
+
bucket.hours += hoursOf(e);
|
|
5300
|
+
bucket.cost += _nullishCoalesce(r.cost, () => ( 0));
|
|
5301
|
+
}
|
|
5302
|
+
for (const b of Object.values(sources)) b.cost = cents(b.cost);
|
|
5303
|
+
const unresolvedHours = sources.missing.hours;
|
|
5304
|
+
if (unresolvedHours > 0) resolutionNotes.push(`${fmtHours(unresolvedHours)} hours unresolved (missing rate) \u2014 total_cost is a lower bound`);
|
|
5305
|
+
const costRateResolution = { method: v.method, sources, unresolvedHours, notes: resolutionNotes };
|
|
5306
|
+
const months = monthsBetween(v.dateFrom, v.dateTo);
|
|
5307
|
+
const monthOf = (date) => typeof date === "string" && DATE_RE2.test(`${date}`.slice(0, 10)) ? date.slice(0, 7) : null;
|
|
5308
|
+
const inMonth = (date, m) => monthOf(date) === m;
|
|
5309
|
+
const unitIn = (unit, m) => inMonth(unit["startDate"], m);
|
|
5310
|
+
const lineRevenue = (b) => internalAmount(b, "internalCurrencyExtendedPrice", "extendedPrice");
|
|
5311
|
+
const expectedBasis = unitsPart.status !== "absent" && (servicesRaw.items.length > 0 || unitRows.length > 0);
|
|
5312
|
+
const expectedIn = (m) => unitRows.filter((u) => unitIn(u, m)).reduce((a, u) => a + internalAmount(u, "internalCurrencyPrice", "price"), 0);
|
|
5313
|
+
const recurringIn = (m) => {
|
|
5314
|
+
if (!v.includeRecurringCosts) return 0;
|
|
5315
|
+
let total = 0;
|
|
5316
|
+
for (const c of charges) if (inMonth(c["datePurchased"], m)) total += chargeCost(c);
|
|
5317
|
+
for (const u of unitRows) if (unitIn(u, m)) total += num2(u["cost"]);
|
|
5318
|
+
return total;
|
|
5319
|
+
};
|
|
5320
|
+
const invoicesById = new Map(invoices.map((i) => [num2(i["id"]), i]));
|
|
5321
|
+
const billedServiceIn = (m) => {
|
|
5322
|
+
let billed = 0;
|
|
5323
|
+
const ids = [];
|
|
5324
|
+
for (const b of billingRows) {
|
|
5325
|
+
if (!inMonth(b["itemDate"], m) || billingLineType(b) !== "recurring") continue;
|
|
5326
|
+
const invId = num2(b["invoiceID"]);
|
|
5327
|
+
const inv = invId > 0 ? invoicesById.get(invId) : void 0;
|
|
5328
|
+
if (inv === void 0 || inv["isVoided"] === true) continue;
|
|
5329
|
+
billed += lineRevenue(b);
|
|
5330
|
+
ids.push(num2(b["id"]));
|
|
5331
|
+
}
|
|
5332
|
+
return { billed, ids };
|
|
5333
|
+
};
|
|
5334
|
+
const contractRateByRole = /* @__PURE__ */ new Map();
|
|
5335
|
+
for (const r of ratesRaw.items) {
|
|
5336
|
+
const rate = typeof r["internalCurrencyContractHourlyRate"] === "number" ? r["internalCurrencyContractHourlyRate"] : r["contractHourlyRate"];
|
|
5337
|
+
if (num2(r["roleID"]) > 0 && typeof rate === "number" && Number.isFinite(rate)) contractRateByRole.set(num2(r["roleID"]), rate);
|
|
5338
|
+
}
|
|
5339
|
+
const monthlyParts = [
|
|
5340
|
+
["contractServiceUnits", unitsPart],
|
|
5341
|
+
["contractCharges", chargesPart],
|
|
5342
|
+
["contractRoleCosts", roleCostsPart],
|
|
5343
|
+
["billingItems", billingItems],
|
|
5344
|
+
["timeEntries", timeEntries],
|
|
5345
|
+
["expenses", expensesPart],
|
|
5346
|
+
["subscriptions", subscriptionsPart]
|
|
5347
|
+
];
|
|
5348
|
+
const coverageGaps = (m) => {
|
|
5349
|
+
const gaps = [];
|
|
5350
|
+
for (const [name, p] of monthlyParts) {
|
|
5351
|
+
if (p.status === "absent") gaps.push(`${name}: absent (${p.absent})`);
|
|
5352
|
+
else if (truncatedMonths[name] !== void 0) {
|
|
5353
|
+
if (truncatedMonths[name].includes(m)) gaps.push(`${name}: truncated at limit ${v.limit}`);
|
|
5354
|
+
} else if (p.hasMore) gaps.push(`${name}: capped at limit ${v.limit}`);
|
|
5355
|
+
}
|
|
5356
|
+
return gaps;
|
|
5357
|
+
};
|
|
5358
|
+
const monthly = [];
|
|
5359
|
+
for (let mi = 0; mi < months.length; mi++) {
|
|
5360
|
+
const m = months[mi];
|
|
5361
|
+
const mBilling = billingRows.filter((b) => inMonth(b["itemDate"], m));
|
|
5362
|
+
let revenueInvoiced = 0;
|
|
5363
|
+
let revenueVoided = 0;
|
|
5364
|
+
let postedUninvoiced = 0;
|
|
5365
|
+
const byType = { recurring: 0, labour: 0, charges: 0, expenses: 0, other: 0 };
|
|
5366
|
+
let unresolvedInvoice = 0;
|
|
5367
|
+
let unresolvedLines = 0;
|
|
5368
|
+
for (const b of mBilling) {
|
|
5369
|
+
const invId = num2(b["invoiceID"]);
|
|
5370
|
+
if (invId <= 0) {
|
|
5371
|
+
postedUninvoiced += lineRevenue(b);
|
|
5372
|
+
continue;
|
|
5373
|
+
}
|
|
5374
|
+
const inv = invoicesById.get(invId);
|
|
5375
|
+
if (inv === void 0) {
|
|
5376
|
+
unresolvedInvoice += lineRevenue(b);
|
|
5377
|
+
unresolvedLines += 1;
|
|
5378
|
+
continue;
|
|
5379
|
+
}
|
|
5380
|
+
if (inv["isVoided"] === true) revenueVoided += lineRevenue(b);
|
|
5381
|
+
else {
|
|
5382
|
+
revenueInvoiced += lineRevenue(b);
|
|
5383
|
+
byType[billingLineType(b)] += lineRevenue(b);
|
|
5384
|
+
}
|
|
5385
|
+
}
|
|
5386
|
+
const expected = v.includeUnbilledRevenue && expectedBasis ? expectedIn(m) : null;
|
|
5387
|
+
const expectedUnbilled = expected === null ? 0 : Math.max(0, expected - billedServiceIn(m).billed);
|
|
5388
|
+
const mEntries = entries.filter((e) => inMonth(e["dateWorked"], m));
|
|
5389
|
+
let labourHours = 0;
|
|
5390
|
+
let labourTotal = 0;
|
|
5391
|
+
let unresolved = 0;
|
|
5392
|
+
const rateSources = {};
|
|
5393
|
+
for (const rung of activeRungs) rateSources[rung] = { entries: 0, hours: 0, cost: 0 };
|
|
5394
|
+
rateSources.missing = { entries: 0, hours: 0, cost: 0 };
|
|
5395
|
+
for (const e of mEntries) {
|
|
5396
|
+
const r = entryResolution.get(num2(e["id"]));
|
|
5397
|
+
labourHours += hoursOf(e);
|
|
5398
|
+
const bucket = rateSources[r.source];
|
|
5399
|
+
bucket.entries += 1;
|
|
5400
|
+
bucket.hours += hoursOf(e);
|
|
5401
|
+
bucket.cost += _nullishCoalesce(r.cost, () => ( 0));
|
|
5402
|
+
if (r.source === "missing") unresolved += hoursOf(e);
|
|
5403
|
+
else labourTotal += _nullishCoalesce(r.cost, () => ( 0));
|
|
5404
|
+
}
|
|
5405
|
+
const unposted = mEntries.filter((e) => e["isNonBillable"] !== true && !billedByEntryId.has(num2(e["id"])));
|
|
5406
|
+
const unpostedHours = unposted.reduce((a, e) => a + Math.max(0, num2(e["hoursToBill"])), 0);
|
|
5407
|
+
let unpostedTime;
|
|
5408
|
+
if (!contractTypeKnown) {
|
|
5409
|
+
unpostedTime = { entries: unposted.length, hours: unpostedHours, value: null, absent: "CONTRACT_TYPE_UNKNOWN" };
|
|
5410
|
+
} else if (!isTimeAndMaterials) {
|
|
5411
|
+
unpostedTime = { entries: unposted.length, hours: unpostedHours, value: null, absent: "NOT_TIME_AND_MATERIALS_CONTRACT" };
|
|
5412
|
+
} else if (unposted.some((e) => !contractRateByRole.has(num2(e["roleID"])))) {
|
|
5413
|
+
unpostedTime = { entries: unposted.length, hours: unpostedHours, value: null, absent: "NO_CONTRACT_RATE" };
|
|
5414
|
+
} else {
|
|
5415
|
+
const value = unposted.reduce((a, e) => a + Math.max(0, num2(e["hoursToBill"])) * contractRateByRole.get(num2(e["roleID"])), 0);
|
|
5416
|
+
unpostedTime = { entries: unposted.length, hours: unpostedHours, value };
|
|
5417
|
+
}
|
|
5418
|
+
let toolingVendor = subscriptionsPart.status === "skipped" || subscriptionsPart.status === "absent" ? null : 0;
|
|
5419
|
+
if (toolingVendor !== null) {
|
|
5420
|
+
for (const s of subscriptions) {
|
|
5421
|
+
const eff = _nullishCoalesce(monthOf(s["effectiveDate"]), () => ( "0000-00"));
|
|
5422
|
+
const exp = _nullishCoalesce(monthOf(s["expirationDate"]), () => ( "9999-99"));
|
|
5423
|
+
const sid = num2(s["id"]);
|
|
5424
|
+
if (cancelledSubs.has(sid)) continue;
|
|
5425
|
+
if (oneTimeSubs.has(sid)) {
|
|
5426
|
+
if (eff === m) toolingVendor += num2(s["periodCost"]);
|
|
5427
|
+
continue;
|
|
5428
|
+
}
|
|
5429
|
+
const factor = _nullishCoalesce(subFactor.get(sid), () => ( null));
|
|
5430
|
+
if (factor !== null && eff <= m && m <= exp) toolingVendor += num2(s["periodCost"]) * factor;
|
|
5431
|
+
}
|
|
5432
|
+
}
|
|
5433
|
+
const callerSupplied = _nullishCoalesce(v.externalMonthlyCosts[mi], () => ( 0));
|
|
5434
|
+
const recurring = recurringIn(m);
|
|
5435
|
+
let expenseCost = 0;
|
|
5436
|
+
for (const x of expenses) if (inMonth(x["expenseDate"], m)) expenseCost += num2(x["internalCurrencyExpenseAmount"]);
|
|
5437
|
+
const totalCost = labourTotal + callerSupplied + recurring + expenseCost;
|
|
5438
|
+
const profit = revenueInvoiced - totalCost;
|
|
5439
|
+
const margin = revenueInvoiced > 0 ? profit / revenueInvoiced : null;
|
|
5440
|
+
const nonLabour = totalCost - labourTotal;
|
|
5441
|
+
const resolvedHours = mEntries.filter((e) => entryResolution.get(num2(e["id"])).source !== "missing").reduce((a, e) => a + hoursOf(e), 0);
|
|
5442
|
+
const avgRate = resolvedHours > 0 ? labourTotal / resolvedHours : 0;
|
|
5443
|
+
const breakEven = avgRate > 0 ? Math.max(0, (revenueInvoiced - nonLabour) / avgRate) : null;
|
|
5444
|
+
for (const b of Object.values(rateSources)) b.cost = cents(b.cost);
|
|
5445
|
+
const gaps = coverageGaps(m);
|
|
5446
|
+
if (unresolvedLines > 0) gaps.push(`invoices: ${unresolvedLines} line(s) on unresolved invoices`);
|
|
5447
|
+
monthly.push({
|
|
5448
|
+
month: m,
|
|
5449
|
+
revenue_invoiced: cents(revenueInvoiced),
|
|
5450
|
+
revenue_by_type: { recurring: cents(byType.recurring), labour: cents(byType.labour), charges: cents(byType.charges), expenses: cents(byType.expenses), other: cents(byType.other) },
|
|
5451
|
+
revenue_voided_excluded: cents(revenueVoided),
|
|
5452
|
+
revenue_posted_uninvoiced: cents(postedUninvoiced),
|
|
5453
|
+
revenue_unresolved_invoice: cents(unresolvedInvoice),
|
|
5454
|
+
revenue_expected: cents(expected),
|
|
5455
|
+
revenue_expected_unbilled: cents(expectedUnbilled),
|
|
5456
|
+
unposted_time: { ...unpostedTime, value: cents(unpostedTime.value) },
|
|
5457
|
+
labour_hours: labourHours,
|
|
5458
|
+
labour_cost: { total: cents(labourTotal), unresolvedHours: unresolved, rateSources },
|
|
5459
|
+
tooling_cost: { vendor: cents(toolingVendor), caller_supplied: cents(callerSupplied) },
|
|
5460
|
+
recurring_cost: cents(recurring),
|
|
5461
|
+
expense_cost: cents(expenseCost),
|
|
5462
|
+
total_cost: cents(totalCost),
|
|
5463
|
+
profit: cents(profit),
|
|
5464
|
+
margin,
|
|
5465
|
+
break_even_hours: breakEven,
|
|
5466
|
+
coverage_gaps: gaps
|
|
5467
|
+
});
|
|
5468
|
+
}
|
|
5469
|
+
const warnings = [];
|
|
5470
|
+
warnings.push({
|
|
5471
|
+
code: "miscoded_time_out",
|
|
5472
|
+
count: probeRows.length,
|
|
5473
|
+
sample_ids: dedupeSortCap(probeRows.map((p) => num2(p["id"])), v.limit)
|
|
5474
|
+
});
|
|
5475
|
+
const crossTimeEntries = entries.filter((e) => {
|
|
5476
|
+
const t = num2(e["ticketID"]);
|
|
5477
|
+
if (t <= 0) return false;
|
|
5478
|
+
const ticket = fetchedTickets.get(t);
|
|
5479
|
+
return ticket !== void 0 && num2(ticket["contractID"]) !== idNum;
|
|
5480
|
+
});
|
|
5481
|
+
warnings.push({ code: "cross_contract_ticket_time", count: crossTimeEntries.length, sample_ids: dedupeSortCap(crossTimeEntries.map((e) => num2(e["id"])), v.limit) });
|
|
5482
|
+
const tupleGroups = /* @__PURE__ */ new Map();
|
|
5483
|
+
for (const e of entries) {
|
|
5484
|
+
const key = [String(num2(e["resourceID"])), String(_nullishCoalesce(e["dateWorked"], () => ( ""))), String(num2(e["ticketID"])), String(_nullishCoalesce(e["hoursWorked"], () => ( "")))].join("|");
|
|
5485
|
+
const arr = _nullishCoalesce(tupleGroups.get(key), () => ( []));
|
|
5486
|
+
arr.push(e);
|
|
5487
|
+
tupleGroups.set(key, arr);
|
|
5488
|
+
}
|
|
5489
|
+
const dupAll = [];
|
|
5490
|
+
const dupSample = [];
|
|
5491
|
+
for (const group of tupleGroups.values()) {
|
|
5492
|
+
if (group.length < 2) continue;
|
|
5493
|
+
const sorted = [...group].sort((a, b) => num2(a["id"]) - num2(b["id"]));
|
|
5494
|
+
for (const e of sorted) dupAll.push(num2(e["id"]));
|
|
5495
|
+
for (const e of sorted.slice(1)) dupSample.push(num2(e["id"]));
|
|
5496
|
+
}
|
|
5497
|
+
warnings.push({ code: "duplicate_entries", count: dupAll.length, sample_ids: dedupeSortCap(dupSample, v.limit) });
|
|
5498
|
+
const zeroHours = entries.filter((e) => {
|
|
5499
|
+
const h = e["hoursWorked"];
|
|
5500
|
+
return !(typeof h === "number" && Number.isFinite(h) && h > 0);
|
|
5501
|
+
});
|
|
5502
|
+
warnings.push({ code: "zero_negative_hours", count: zeroHours.length, sample_ids: dedupeSortCap(zeroHours.map((e) => num2(e["id"])), v.limit) });
|
|
5503
|
+
const outPeriod = entries.filter((e) => {
|
|
5504
|
+
const t = num2(e["ticketID"]);
|
|
5505
|
+
if (t <= 0) return false;
|
|
5506
|
+
const ticket = fetchedTickets.get(t);
|
|
5507
|
+
if (ticket === void 0) return false;
|
|
5508
|
+
const dW = dateToDay(e["dateWorked"]);
|
|
5509
|
+
if (dW === null) return false;
|
|
5510
|
+
const created = dateToDay(ticket["createDate"]);
|
|
5511
|
+
if (created !== null && dW < created) return true;
|
|
5512
|
+
const ends = [dateToDay(ticket["resolvedDateTime"]), dateToDay(ticket["completedDate"])].filter((d) => d !== null);
|
|
5513
|
+
if (ends.length > 0 && dW > Math.min(...ends)) return true;
|
|
5514
|
+
return false;
|
|
5515
|
+
});
|
|
5516
|
+
warnings.push({ code: "time_outside_ticket_period", count: outPeriod.length, sample_ids: dedupeSortCap(outPeriod.map((e) => num2(e["id"])), v.limit) });
|
|
5517
|
+
const missingRate = entries.filter((e) => entryResolution.get(num2(e["id"])).source === "missing");
|
|
5518
|
+
warnings.push({ code: "missing_cost_rate", count: missingRate.length, sample_ids: dedupeSortCap(missingRate.map((e) => num2(e["id"])), v.limit) });
|
|
5519
|
+
let driftCount = 0;
|
|
5520
|
+
const driftIds = /* @__PURE__ */ new Set();
|
|
5521
|
+
if (v.includeRecurringCosts) {
|
|
5522
|
+
for (let i = 1; i < months.length; i++) {
|
|
5523
|
+
const r1 = recurringIn(months[i]);
|
|
5524
|
+
const r0 = recurringIn(months[i - 1]);
|
|
5525
|
+
if (r1 <= 0 || r0 <= 0 || Math.abs(r1 - r0) <= RECURRING_DRIFT_EPSILON) continue;
|
|
5526
|
+
driftCount += 1;
|
|
5527
|
+
const mA = months[i - 1];
|
|
5528
|
+
const mB = months[i];
|
|
5529
|
+
for (const c of charges) {
|
|
5530
|
+
const cA = inMonth(c["datePurchased"], mA) ? chargeCost(c) : 0;
|
|
5531
|
+
const cB = inMonth(c["datePurchased"], mB) ? chargeCost(c) : 0;
|
|
5532
|
+
if (Math.abs(cB - cA) > 0) driftIds.add(num2(c["id"]));
|
|
5533
|
+
}
|
|
5534
|
+
for (const u of unitRows) {
|
|
5535
|
+
const cA = unitIn(u, mA) ? num2(u["cost"]) : 0;
|
|
5536
|
+
const cB = unitIn(u, mB) ? num2(u["cost"]) : 0;
|
|
5537
|
+
if (Math.abs(cB - cA) > 0) driftIds.add(num2(u["id"]));
|
|
5538
|
+
}
|
|
5539
|
+
}
|
|
5540
|
+
}
|
|
5541
|
+
warnings.push({ code: "recurring_cost_drift", count: driftCount, sample_ids: dedupeSortCap([...driftIds], v.limit) });
|
|
5542
|
+
let expectedUnbilledCount = 0;
|
|
5543
|
+
const expectedUnbilledSamples = [];
|
|
5544
|
+
if (v.includeUnbilledRevenue && expectedBasis) {
|
|
5545
|
+
for (const m of months) {
|
|
5546
|
+
const { billed, ids } = billedServiceIn(m);
|
|
5547
|
+
if (expectedIn(m) > billed + 5e-3) {
|
|
5548
|
+
expectedUnbilledCount += 1;
|
|
5549
|
+
for (const i of ids) expectedUnbilledSamples.push(i);
|
|
5550
|
+
}
|
|
5551
|
+
}
|
|
5552
|
+
}
|
|
5553
|
+
warnings.push({ code: "expected_unbilled_revenue", count: expectedUnbilledCount, sample_ids: dedupeSortCap(expectedUnbilledSamples, v.limit) });
|
|
5554
|
+
const driftTickets = [...fetchedTickets.values()].filter((t) => num2(t["contractID"]) !== idNum);
|
|
5555
|
+
const unresolvedRefs = entries.filter((e) => num2(e["ticketID"]) > 0 && !fetchedTickets.has(num2(e["ticketID"])));
|
|
5556
|
+
warnings.push({
|
|
5557
|
+
code: "cross_contract_tickets",
|
|
5558
|
+
count: driftTickets.length + unresolvedRefs.length,
|
|
5559
|
+
sample_ids: dedupeSortCap([...driftTickets.map((t) => num2(t["id"])), ...unresolvedRefs.map((e) => num2(e["id"]))], v.limit)
|
|
5560
|
+
});
|
|
5561
|
+
const stale = [];
|
|
5562
|
+
if (openStatusSet !== null) {
|
|
5563
|
+
for (const t of contractTickets) {
|
|
5564
|
+
const status = t["status"];
|
|
5565
|
+
if (typeof status !== "number" || !openStatusSet.has(status)) continue;
|
|
5566
|
+
const lastDay = dateToDay(t["lastActivityDate"]);
|
|
5567
|
+
if (lastDay === null) continue;
|
|
5568
|
+
const days = asOfMs / 864e5 - lastDay;
|
|
5569
|
+
if (days > v.staleAfterDays) stale.push(num2(t["id"]));
|
|
5570
|
+
}
|
|
5571
|
+
}
|
|
5572
|
+
warnings.push({ code: "open_stale_tickets", count: stale.length, sample_ids: dedupeSortCap(stale, v.limit) });
|
|
5573
|
+
let estimateCount = 0;
|
|
5574
|
+
const estimateSample = [];
|
|
5575
|
+
let estimateNote;
|
|
5576
|
+
{
|
|
5577
|
+
const actualRevenue = monthly.reduce((a, r) => a + r.revenue_invoiced, 0);
|
|
5578
|
+
const actualCost = monthly.reduce((a, r) => a + r.total_cost, 0);
|
|
5579
|
+
const termStart = dateToDay(contractRow["startDate"]);
|
|
5580
|
+
const termEnd = dateToDay(contractRow["endDate"]);
|
|
5581
|
+
const fromDay = dateToDay(v.dateFrom);
|
|
5582
|
+
const toDay = dateToDay(v.dateTo);
|
|
5583
|
+
if (termStart !== null && termEnd !== null && fromDay !== null && toDay !== null) {
|
|
5584
|
+
const overlapStart = Math.max(termStart, fromDay);
|
|
5585
|
+
const overlapEnd = Math.min(termEnd, toDay);
|
|
5586
|
+
const termDays = termEnd - termStart + 1;
|
|
5587
|
+
const overlapDays = overlapEnd >= overlapStart ? overlapEnd - overlapStart + 1 : 0;
|
|
5588
|
+
if (termDays > 0 && overlapDays > 0) {
|
|
5589
|
+
const frac = overlapDays / termDays;
|
|
5590
|
+
const estRev = num2(contractRow["estimatedRevenue"]);
|
|
5591
|
+
const estCost = num2(contractRow["estimatedCost"]);
|
|
5592
|
+
const devRev = estRev > 0 ? Math.abs(actualRevenue - estRev * frac) / (estRev * frac) : null;
|
|
5593
|
+
const devCost = estCost > 0 ? Math.abs(actualCost - estCost * frac) / (estCost * frac) : null;
|
|
5594
|
+
if (devRev !== null && devRev > ESTIMATE_DEVIATION_THRESHOLD_PCT / 100 || devCost !== null && devCost > ESTIMATE_DEVIATION_THRESHOLD_PCT / 100) {
|
|
5595
|
+
estimateCount = 1;
|
|
5596
|
+
estimateSample.push(idNum);
|
|
5597
|
+
}
|
|
5598
|
+
estimateNote = `estimate vs actual (window-prorated ${overlapDays}/${termDays} days): revenue ${pctOrNa(devRev)} deviation (actual ${fmtNum(actualRevenue)} vs prorated ${fmtNum(estRev * frac)}), cost ${pctOrNa(devCost)} deviation (actual ${fmtNum(actualCost)} vs prorated ${fmtNum(estCost * frac)})`;
|
|
5599
|
+
}
|
|
5600
|
+
}
|
|
5601
|
+
}
|
|
5602
|
+
warnings.push({ code: "estimate_vs_actual", count: estimateCount, sample_ids: estimateSample, ...estimateCount === 1 && estimateNote !== void 0 ? { note: estimateNote } : {} });
|
|
5603
|
+
const entriesByTicket = /* @__PURE__ */ new Map();
|
|
5604
|
+
for (const e of entries) {
|
|
5605
|
+
const t = num2(e["ticketID"]);
|
|
5606
|
+
if (t <= 0) continue;
|
|
5607
|
+
const arr = _nullishCoalesce(entriesByTicket.get(t), () => ( []));
|
|
5608
|
+
arr.push(e);
|
|
5609
|
+
entriesByTicket.set(t, arr);
|
|
5610
|
+
}
|
|
5611
|
+
const expenseByTicket = /* @__PURE__ */ new Map();
|
|
5612
|
+
for (const x of expenses) {
|
|
5613
|
+
const t = num2(x["ticketID"]);
|
|
5614
|
+
if (t <= 0) continue;
|
|
5615
|
+
expenseByTicket.set(t, (_nullishCoalesce(expenseByTicket.get(t), () => ( 0))) + num2(x["internalCurrencyExpenseAmount"]));
|
|
5616
|
+
}
|
|
5617
|
+
const ticketCost = (t) => {
|
|
5618
|
+
const tid = num2(t["id"]);
|
|
5619
|
+
const es = _nullishCoalesce(entriesByTicket.get(tid), () => ( []));
|
|
5620
|
+
let cost = _nullishCoalesce(expenseByTicket.get(tid), () => ( 0));
|
|
5621
|
+
for (const e of es) cost += _nullishCoalesce(entryResolution.get(num2(e["id"])).cost, () => ( 0));
|
|
5622
|
+
return cost;
|
|
5623
|
+
};
|
|
5624
|
+
const ticketHours = (t) => (_nullishCoalesce(entriesByTicket.get(num2(t["id"])), () => ( []))).reduce((a, e) => a + hoursOf(e), 0);
|
|
5625
|
+
const allTickets = [...fetchedTickets.values()];
|
|
5626
|
+
const activityCategories = [];
|
|
5627
|
+
if (v.groupByActivity) {
|
|
5628
|
+
const byCat = /* @__PURE__ */ new Map();
|
|
5629
|
+
for (const t of allTickets) {
|
|
5630
|
+
const cat = num2(t["ticketCategory"]) > 0 ? num2(t["ticketCategory"]) : null;
|
|
5631
|
+
const arr = _nullishCoalesce(byCat.get(cat), () => ( []));
|
|
5632
|
+
arr.push(t);
|
|
5633
|
+
byCat.set(cat, arr);
|
|
5634
|
+
}
|
|
5635
|
+
for (const [cat, tickets] of byCat) {
|
|
5636
|
+
let entryCount = 0;
|
|
5637
|
+
let hours = 0;
|
|
5638
|
+
let cost = 0;
|
|
5639
|
+
for (const t of tickets) {
|
|
5640
|
+
const es = _nullishCoalesce(entriesByTicket.get(num2(t["id"])), () => ( []));
|
|
5641
|
+
entryCount += es.length;
|
|
5642
|
+
hours += es.reduce((a, e) => a + hoursOf(e), 0);
|
|
5643
|
+
cost += ticketCost(t);
|
|
5644
|
+
}
|
|
5645
|
+
activityCategories.push({
|
|
5646
|
+
ticketCategory: cat,
|
|
5647
|
+
ticketCount: tickets.length,
|
|
5648
|
+
entryCount,
|
|
5649
|
+
hours,
|
|
5650
|
+
cost: cents(cost),
|
|
5651
|
+
sample_ticketNumbers: dedupeSortCap(tickets.map((t) => num2(t["ticketNumber"])).filter((n) => n > 0), v.limit)
|
|
5652
|
+
});
|
|
5653
|
+
}
|
|
5654
|
+
activityCategories.sort((a, b) => b.cost - a.cost || (a.ticketCategory === null ? 1 : b.ticketCategory === null ? -1 : (_nullishCoalesce(a.ticketCategory, () => ( 0))) - (_nullishCoalesce(b.ticketCategory, () => ( 0)))));
|
|
5655
|
+
}
|
|
5656
|
+
const highestCostTickets = allTickets.map((t) => ({
|
|
5657
|
+
ticketId: num2(t["id"]),
|
|
5658
|
+
ticketNumber: num2(t["ticketNumber"]) > 0 ? num2(t["ticketNumber"]) : null,
|
|
5659
|
+
title: typeof t["title"] === "string" ? t["title"] : "",
|
|
5660
|
+
status: typeof t["status"] === "number" ? t["status"] : null,
|
|
5661
|
+
hours: ticketHours(t),
|
|
5662
|
+
cost: cents(ticketCost(t)),
|
|
5663
|
+
lastActivityDate: typeof t["lastActivityDate"] === "string" ? t["lastActivityDate"] : null
|
|
5664
|
+
})).sort((a, b) => b.cost - a.cost || a.ticketId - b.ticketId).slice(0, v.limit);
|
|
5665
|
+
const miscoding = /* @__PURE__ */ new Map();
|
|
5666
|
+
const putMiscoding = (e, reason) => {
|
|
5667
|
+
const eid = num2(e["id"]);
|
|
5668
|
+
if (eid <= 0 || miscoding.has(eid)) return;
|
|
5669
|
+
const c = num2(e["contractID"]);
|
|
5670
|
+
miscoding.set(eid, { entryId: eid, reason, ticketId: num2(e["ticketID"]) > 0 ? num2(e["ticketID"]) : null, contractId: c > 0 ? c : null, hours: num2(e["hoursWorked"]) });
|
|
5671
|
+
};
|
|
5672
|
+
for (const p of probeRows) putMiscoding(p, num2(p["contractID"]) > 0 ? "ticket_of_other_contract" : "no_contract_on_entry");
|
|
5673
|
+
for (const e of crossTimeEntries) putMiscoding(e, "ticket_of_other_contract");
|
|
5674
|
+
for (const e of unresolvedRefs) putMiscoding(e, "ticket_not_in_fetched_set");
|
|
5675
|
+
const possibleMiscoding = [...miscoding.values()].sort((a, b) => a.entryId - b.entryId).slice(0, v.limit);
|
|
5676
|
+
const openRenewal = [];
|
|
5677
|
+
if (openStatusSet !== null) {
|
|
5678
|
+
for (const t of contractTickets) {
|
|
5679
|
+
const status = t["status"];
|
|
5680
|
+
if (typeof status !== "number" || !openStatusSet.has(status)) continue;
|
|
5681
|
+
const last = t["lastActivityDate"];
|
|
5682
|
+
const lastDay = typeof last === "string" ? (asOfMs - Date.parse(last.slice(0, 10))) / 864e5 : null;
|
|
5683
|
+
const staleDays = lastDay !== null && lastDay > v.staleAfterDays ? Math.floor(lastDay) : null;
|
|
5684
|
+
openRenewal.push({
|
|
5685
|
+
kind: "ticket",
|
|
5686
|
+
id: num2(t["id"]),
|
|
5687
|
+
label: typeof t["title"] === "string" && t["title"] !== "" ? t["title"] : `ticket ${num2(t["ticketNumber"]) > 0 ? num2(t["ticketNumber"]) : num2(t["id"])}`,
|
|
5688
|
+
date: typeof last === "string" ? last.slice(0, 10) : null,
|
|
5689
|
+
detail: staleDays !== null ? `open \u2014 stale ${staleDays} days (last activity)` : "open"
|
|
5690
|
+
});
|
|
5691
|
+
}
|
|
5692
|
+
}
|
|
5693
|
+
for (const s of subscriptions) {
|
|
5694
|
+
openRenewal.push({
|
|
5695
|
+
kind: "subscription",
|
|
5696
|
+
id: num2(s["id"]),
|
|
5697
|
+
label: typeof s["subscriptionName"] === "string" && s["subscriptionName"] !== "" ? s["subscriptionName"] : `subscription ${num2(s["id"])}`,
|
|
5698
|
+
date: typeof s["expirationDate"] === "string" ? s["expirationDate"].slice(0, 10) : null,
|
|
5699
|
+
detail: `periodType: ${typeof s["periodType"] === "number" ? s["periodType"] : "unknown"} (period cost ${fmtNum(num2(s["periodCost"]))}${cancelledSubs.has(num2(s["id"])) ? " \u2014 not active, not in tooling_cost.vendor" : oneTimeSubs.has(num2(s["id"])) ? " \u2014 one-time, booked in its effective month" : subFactor.get(num2(s["id"])) == null ? " \u2014 unrecognised period, not in tooling_cost.vendor" : `, ${fmtNum(num2(s["periodCost"]) * subFactor.get(num2(s["id"])))}/month`})`
|
|
5700
|
+
});
|
|
5701
|
+
}
|
|
5702
|
+
const contractEndDay = dateToDay(contractRow["endDate"]);
|
|
5703
|
+
if (contractEndDay !== null) {
|
|
5704
|
+
openRenewal.push({
|
|
5705
|
+
kind: "contract_end",
|
|
5706
|
+
id: idNum,
|
|
5707
|
+
label: typeof contractRow["contractName"] === "string" && contractRow["contractName"] !== "" ? contractRow["contractName"] : `contract ${idNum}`,
|
|
5708
|
+
date: String(contractRow["endDate"]).slice(0, 10),
|
|
5709
|
+
detail: `the contract ends ${String(contractRow["endDate"]).slice(0, 10)}`
|
|
5710
|
+
});
|
|
5711
|
+
}
|
|
5712
|
+
const blocks = blocksPart.items;
|
|
5713
|
+
for (const b of blocks) {
|
|
5714
|
+
const purchased = num2(b["hours"]);
|
|
5715
|
+
const approved = num2(b["hoursApproved"]);
|
|
5716
|
+
const left = purchased - approved;
|
|
5717
|
+
openRenewal.push({
|
|
5718
|
+
kind: "included_hours_burn",
|
|
5719
|
+
id: num2(b["id"]),
|
|
5720
|
+
label: `hour block ${num2(b["id"])}`,
|
|
5721
|
+
date: typeof b["endDate"] === "string" ? b["endDate"].slice(0, 10) : null,
|
|
5722
|
+
detail: `${fmtHours(approved)} h approved of ${fmtHours(purchased)} h purchased (${left >= 0 ? `${fmtHours(left)} h left` : `${fmtHours(Math.abs(left))} h over`})`
|
|
5723
|
+
});
|
|
5724
|
+
}
|
|
5725
|
+
const purchasedHours = blocks.reduce((a, b) => a + num2(b["hours"]), 0);
|
|
5726
|
+
const approvedHours = blocks.reduce((a, b) => a + num2(b["hoursApproved"]), 0);
|
|
5727
|
+
const includedHours = !contractTypeKnown ? { value: null, absent: "CONTRACT_TYPE_UNKNOWN" } : !isBlockHours ? { value: null, absent: "NOT_BLOCK_HOURS_CONTRACT" } : blocksPart.status === "absent" ? { value: null, absent: blocksPart.absent } : { value: { purchased: purchasedHours, approved: approvedHours, remaining: purchasedHours - approvedHours } };
|
|
5728
|
+
return {
|
|
5729
|
+
contract,
|
|
5730
|
+
customer,
|
|
5731
|
+
...customerAbsent !== void 0 ? { customerAbsent } : {},
|
|
5732
|
+
contract_type: contractTypeKnown ? { id: contractType, label: contractTypeLabel } : { id: contractType > 0 ? contractType : null, label: null, absent: "CONTRACT_TYPE_UNKNOWN" },
|
|
5733
|
+
included_hours: includedHours,
|
|
5734
|
+
period: { dateFrom: v.dateFrom, dateTo: v.dateTo, months, asOf },
|
|
5735
|
+
currency: {
|
|
5736
|
+
companyCurrencyID: customer && typeof customer["currencyID"] === "number" ? customer["currencyID"] : null,
|
|
5737
|
+
note: "single-currency P&L in the INTERNAL currency: revenue is billing items internalCurrencyExtendedPrice and service units internalCurrencyPrice (each falling back to the local field when absent), unposted value the internalCurrencyContractHourlyRate; costs are internal (ourCost/role cost/internalCost, charge extendedCost, unit cost, internalCurrencyExpenseAmount). companyCurrencyID is the customer context stamp only"
|
|
5738
|
+
},
|
|
5739
|
+
monthly,
|
|
5740
|
+
activity_categories: activityCategories,
|
|
5741
|
+
highest_cost_tickets: highestCostTickets,
|
|
5742
|
+
possible_miscoding: possibleMiscoding,
|
|
5743
|
+
open_renewal_items: openRenewal,
|
|
5744
|
+
data_quality_warnings: warnings,
|
|
5745
|
+
costRateResolution,
|
|
5746
|
+
parts: {
|
|
5747
|
+
contract: "ok",
|
|
5748
|
+
customer: customerStatus,
|
|
5749
|
+
contractServices: servicesPart.status,
|
|
5750
|
+
contractServiceUnits: unitsPart.status,
|
|
5751
|
+
contractCharges: chargesPart.status,
|
|
5752
|
+
contractRoleCosts: roleCostsPart.status,
|
|
5753
|
+
contractRates: ratesPart.status,
|
|
5754
|
+
contractBlocks: blocksPart.status,
|
|
5755
|
+
billingItems: billingItems.status,
|
|
5756
|
+
invoices: invoicesPart.status,
|
|
5757
|
+
timeEntries: timeEntries.status,
|
|
5758
|
+
ticketsActivity: ticketsActivityPart.status,
|
|
5759
|
+
ticketsOpen: ticketsOpenPart.status,
|
|
5760
|
+
resources: resourcesPart.status,
|
|
5761
|
+
expenses: expensesPart.status,
|
|
5762
|
+
miscodingProbe: probePart.status,
|
|
5763
|
+
configurationItems: configurationItemsPart.status,
|
|
5764
|
+
subscriptions: subscriptionsPart.status
|
|
5765
|
+
},
|
|
5766
|
+
contractServices: servicesPart,
|
|
5767
|
+
contractServiceUnits: unitsPart,
|
|
5768
|
+
contractCharges: chargesPart,
|
|
5769
|
+
contractRoleCosts: roleCostsPart,
|
|
5770
|
+
contractRates: ratesPart,
|
|
5771
|
+
contractBlocks: blocksPart,
|
|
5772
|
+
billingItems,
|
|
5773
|
+
invoices: invoicesPart,
|
|
5774
|
+
timeEntries,
|
|
5775
|
+
ticketsActivity: ticketsActivityPart,
|
|
5776
|
+
ticketsOpen: ticketsOpenPart,
|
|
5777
|
+
resources: resourcesPart,
|
|
5778
|
+
expenses: expensesPart,
|
|
5779
|
+
miscodingProbe: probePart,
|
|
5780
|
+
configurationItems: configurationItemsPart,
|
|
5781
|
+
subscriptions: subscriptionsPart,
|
|
5782
|
+
wires: { issued: wires.issued, requests: wires.requests, budget: wires.budget, note: wires.note }
|
|
5783
|
+
};
|
|
5784
|
+
}
|
|
5785
|
+
|
|
4537
5786
|
// src/resources/contracts.ts
|
|
4538
|
-
var ContractsResource = class extends
|
|
5787
|
+
var ContractsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4539
5788
|
constructor(http, pageSize) {
|
|
4540
5789
|
super(http, {
|
|
4541
5790
|
key: "contracts",
|
|
@@ -4599,10 +5848,14 @@ var ContractsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
4599
5848
|
async search(query, opts) {
|
|
4600
5849
|
return this.searchBase(query, opts);
|
|
4601
5850
|
}
|
|
5851
|
+
/** Node-parity special op (hand-written in src/resources/special/contracts.ts). */
|
|
5852
|
+
profitability(id, opts) {
|
|
5853
|
+
return profitability(this, id, opts, this.http);
|
|
5854
|
+
}
|
|
4602
5855
|
};
|
|
4603
5856
|
|
|
4604
5857
|
// src/resources/contract_ticket_purchases.ts
|
|
4605
|
-
var ContractTicketPurchasesResource = class extends
|
|
5858
|
+
var ContractTicketPurchasesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4606
5859
|
constructor(http, pageSize) {
|
|
4607
5860
|
super(http, {
|
|
4608
5861
|
key: "contract_ticket_purchases",
|
|
@@ -4661,7 +5914,7 @@ var ContractTicketPurchasesResource = class extends _chunkYKEX4SK7cjs.BaseResour
|
|
|
4661
5914
|
};
|
|
4662
5915
|
|
|
4663
5916
|
// src/resources/countries.ts
|
|
4664
|
-
var CountriesResource = class extends
|
|
5917
|
+
var CountriesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4665
5918
|
constructor(http, pageSize) {
|
|
4666
5919
|
super(http, {
|
|
4667
5920
|
key: "countries",
|
|
@@ -4720,7 +5973,7 @@ var CountriesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
4720
5973
|
};
|
|
4721
5974
|
|
|
4722
5975
|
// src/resources/departments.ts
|
|
4723
|
-
var DepartmentsResource = class extends
|
|
5976
|
+
var DepartmentsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4724
5977
|
constructor(http, pageSize) {
|
|
4725
5978
|
super(http, {
|
|
4726
5979
|
key: "departments",
|
|
@@ -4787,7 +6040,7 @@ var DepartmentsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
4787
6040
|
};
|
|
4788
6041
|
|
|
4789
6042
|
// src/resources/domain_registrars.ts
|
|
4790
|
-
var DomainRegistrarsResource = class extends
|
|
6043
|
+
var DomainRegistrarsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4791
6044
|
constructor(http, pageSize) {
|
|
4792
6045
|
super(http, {
|
|
4793
6046
|
key: "domain_registrars",
|
|
@@ -4870,7 +6123,7 @@ var EntityInformationResource = class {
|
|
|
4870
6123
|
};
|
|
4871
6124
|
|
|
4872
6125
|
// src/resources/expense_item_attachments.ts
|
|
4873
|
-
var ExpenseItemAttachmentsResource = class extends
|
|
6126
|
+
var ExpenseItemAttachmentsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4874
6127
|
constructor(http, pageSize) {
|
|
4875
6128
|
super(http, {
|
|
4876
6129
|
key: "expense_item_attachments",
|
|
@@ -4932,7 +6185,7 @@ var ExpenseItemAttachmentsResource = class extends _chunkYKEX4SK7cjs.BaseResourc
|
|
|
4932
6185
|
};
|
|
4933
6186
|
|
|
4934
6187
|
// src/resources/expense_items.ts
|
|
4935
|
-
var ExpenseItemsResource = class extends
|
|
6188
|
+
var ExpenseItemsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4936
6189
|
constructor(http, pageSize) {
|
|
4937
6190
|
super(http, {
|
|
4938
6191
|
key: "expense_items",
|
|
@@ -4991,7 +6244,7 @@ var ExpenseItemsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
4991
6244
|
};
|
|
4992
6245
|
|
|
4993
6246
|
// src/resources/expense_reports.ts
|
|
4994
|
-
var ExpenseReportsResource = class extends
|
|
6247
|
+
var ExpenseReportsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
4995
6248
|
constructor(http, pageSize) {
|
|
4996
6249
|
super(http, {
|
|
4997
6250
|
key: "expense_reports",
|
|
@@ -5058,7 +6311,7 @@ var ExpenseReportsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
5058
6311
|
};
|
|
5059
6312
|
|
|
5060
6313
|
// src/resources/holiday_sets.ts
|
|
5061
|
-
var HolidaySetsResource = class extends
|
|
6314
|
+
var HolidaySetsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5062
6315
|
constructor(http, pageSize) {
|
|
5063
6316
|
super(http, {
|
|
5064
6317
|
key: "holiday_sets",
|
|
@@ -5127,7 +6380,7 @@ var HolidaySetsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
5127
6380
|
};
|
|
5128
6381
|
|
|
5129
6382
|
// src/resources/holidays.ts
|
|
5130
|
-
var HolidaysResource = class extends
|
|
6383
|
+
var HolidaysResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5131
6384
|
constructor(http, pageSize) {
|
|
5132
6385
|
super(http, {
|
|
5133
6386
|
key: "holidays",
|
|
@@ -5199,10 +6452,10 @@ var PATH_SUFFIX = {
|
|
|
5199
6452
|
transfer: "StockedItemsTransfer"
|
|
5200
6453
|
};
|
|
5201
6454
|
async function stockedItems(_resource, kind, parentId, data, opts = {}, http) {
|
|
5202
|
-
const numericParent =
|
|
6455
|
+
const numericParent = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, parentId, "parentId");
|
|
5203
6456
|
const suffix = PATH_SUFFIX[kind];
|
|
5204
6457
|
if (opts.dryRun === true) {
|
|
5205
|
-
return
|
|
6458
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0, {
|
|
5206
6459
|
operation: `inventory_products.stockedItems${suffix.slice("StockedItems".length)}`,
|
|
5207
6460
|
method: "POST",
|
|
5208
6461
|
path: `/V1.0/InventoryProducts/${numericParent}/${suffix}`,
|
|
@@ -5218,11 +6471,11 @@ async function stockedItems(_resource, kind, parentId, data, opts = {}, http) {
|
|
|
5218
6471
|
body: data,
|
|
5219
6472
|
operation: `inventory_products.stockedItems${suffix.slice("StockedItems".length)}`
|
|
5220
6473
|
});
|
|
5221
|
-
return
|
|
6474
|
+
return _chunkIHRXVIUUcjs.unwrapOperation.call(void 0, res);
|
|
5222
6475
|
}
|
|
5223
6476
|
|
|
5224
6477
|
// src/resources/inventory_products.ts
|
|
5225
|
-
var InventoryProductsResource = class extends
|
|
6478
|
+
var InventoryProductsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5226
6479
|
constructor(http, pageSize) {
|
|
5227
6480
|
super(http, {
|
|
5228
6481
|
key: "inventory_products",
|
|
@@ -5304,7 +6557,7 @@ var InventoryProductsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
5304
6557
|
|
|
5305
6558
|
// src/resources/special/invoices.ts
|
|
5306
6559
|
async function markup(_resource, id, format, http) {
|
|
5307
|
-
const numericId =
|
|
6560
|
+
const numericId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, id, "id");
|
|
5308
6561
|
const suffix = format === "html" ? "InvoiceMarkupHtml" : "InvoiceMarkupXml";
|
|
5309
6562
|
const res = await http.request({
|
|
5310
6563
|
method: "GET",
|
|
@@ -5313,7 +6566,7 @@ async function markup(_resource, id, format, http) {
|
|
|
5313
6566
|
});
|
|
5314
6567
|
const body = res;
|
|
5315
6568
|
if (body === null || typeof body !== "object" || typeof body.invoiceMarkup !== "string") {
|
|
5316
|
-
throw new (0,
|
|
6569
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskError)(
|
|
5317
6570
|
`Expected the InvoiceMarkupResultModel envelope { invoiceMarkup: string } for invoice ${numericId}; got a different shape`,
|
|
5318
6571
|
{ code: "INVALID_RESPONSE", category: "server", resourceIds: [numericId] }
|
|
5319
6572
|
);
|
|
@@ -5321,44 +6574,44 @@ async function markup(_resource, id, format, http) {
|
|
|
5321
6574
|
return body.invoiceMarkup;
|
|
5322
6575
|
}
|
|
5323
6576
|
async function pdf(_resource, id, http) {
|
|
5324
|
-
const numericId =
|
|
6577
|
+
const numericId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, id, "id");
|
|
5325
6578
|
const res = await http.request({
|
|
5326
6579
|
method: "GET",
|
|
5327
6580
|
path: `/V1.0/Invoices/${numericId}/InvoicePdf`,
|
|
5328
6581
|
operation: "invoices.pdf"
|
|
5329
6582
|
});
|
|
5330
|
-
return
|
|
6583
|
+
return _chunkIHRXVIUUcjs.decodeFileData.call(void 0, res);
|
|
5331
6584
|
}
|
|
5332
6585
|
async function windowQuery2(_resource, kind, http, opts) {
|
|
5333
|
-
const now = _nullishCoalesce(_optionalChain([opts, 'optionalAccess',
|
|
5334
|
-
const tz = _optionalChain([opts, 'optionalAccess',
|
|
6586
|
+
const now = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _46 => _46.now]), () => ( /* @__PURE__ */ new Date()));
|
|
6587
|
+
const tz = _optionalChain([opts, 'optionalAccess', _47 => _47.tz]) === void 0 ? void 0 : validateZone(opts.tz, `invoices.${kind}`);
|
|
5335
6588
|
return dateWindowQuery(
|
|
5336
6589
|
http,
|
|
5337
6590
|
"/V1.0/Invoices/query",
|
|
5338
6591
|
"invoiceDateTime",
|
|
5339
6592
|
kind,
|
|
5340
|
-
clampWindowLimit(_optionalChain([opts, 'optionalAccess',
|
|
6593
|
+
clampWindowLimit(_optionalChain([opts, 'optionalAccess', _48 => _48.limit])),
|
|
5341
6594
|
`invoices.${kind}`,
|
|
5342
6595
|
now,
|
|
5343
6596
|
tz
|
|
5344
6597
|
);
|
|
5345
6598
|
}
|
|
5346
6599
|
async function customRange2(_resource, from, to, http, opts) {
|
|
5347
|
-
const zone = _optionalChain([opts, 'optionalAccess',
|
|
6600
|
+
const zone = _optionalChain([opts, 'optionalAccess', _49 => _49.tz]) === void 0 ? void 0 : validateZone(opts.tz, "invoices.customRange");
|
|
5348
6601
|
return customRangeQuery(
|
|
5349
6602
|
http,
|
|
5350
6603
|
"/V1.0/Invoices/query",
|
|
5351
6604
|
"invoiceDateTime",
|
|
5352
6605
|
from,
|
|
5353
6606
|
to,
|
|
5354
|
-
clampWindowLimit(_optionalChain([opts, 'optionalAccess',
|
|
6607
|
+
clampWindowLimit(_optionalChain([opts, 'optionalAccess', _50 => _50.limit])),
|
|
5355
6608
|
"invoices.customRange",
|
|
5356
6609
|
zone
|
|
5357
6610
|
);
|
|
5358
6611
|
}
|
|
5359
6612
|
|
|
5360
6613
|
// src/resources/invoices.ts
|
|
5361
|
-
var InvoicesResource = class extends
|
|
6614
|
+
var InvoicesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5362
6615
|
constructor(http, pageSize) {
|
|
5363
6616
|
super(http, {
|
|
5364
6617
|
key: "invoices",
|
|
@@ -5488,7 +6741,7 @@ var ModulesResource = class {
|
|
|
5488
6741
|
};
|
|
5489
6742
|
|
|
5490
6743
|
// src/resources/notification_history.ts
|
|
5491
|
-
var NotificationHistoryResource = class extends
|
|
6744
|
+
var NotificationHistoryResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5492
6745
|
constructor(http, pageSize) {
|
|
5493
6746
|
super(http, {
|
|
5494
6747
|
key: "notification_history",
|
|
@@ -5527,7 +6780,7 @@ var NotificationHistoryResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
5527
6780
|
};
|
|
5528
6781
|
|
|
5529
6782
|
// src/resources/opportunities.ts
|
|
5530
|
-
var OpportunitiesResource = class extends
|
|
6783
|
+
var OpportunitiesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5531
6784
|
constructor(http, pageSize) {
|
|
5532
6785
|
super(http, {
|
|
5533
6786
|
key: "opportunities",
|
|
@@ -5589,7 +6842,7 @@ var OpportunitiesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
5589
6842
|
};
|
|
5590
6843
|
|
|
5591
6844
|
// src/resources/opportunity_attachments.ts
|
|
5592
|
-
var OpportunityAttachmentsResource = class extends
|
|
6845
|
+
var OpportunityAttachmentsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5593
6846
|
constructor(http, pageSize) {
|
|
5594
6847
|
super(http, {
|
|
5595
6848
|
key: "opportunity_attachments",
|
|
@@ -5651,7 +6904,7 @@ var OpportunityAttachmentsResource = class extends _chunkYKEX4SK7cjs.BaseResourc
|
|
|
5651
6904
|
};
|
|
5652
6905
|
|
|
5653
6906
|
// src/resources/opportunity_categories.ts
|
|
5654
|
-
var OpportunityCategoriesResource = class extends
|
|
6907
|
+
var OpportunityCategoriesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5655
6908
|
constructor(http, pageSize) {
|
|
5656
6909
|
super(http, {
|
|
5657
6910
|
key: "opportunity_categories",
|
|
@@ -5710,7 +6963,7 @@ var OpportunityCategoriesResource = class extends _chunkYKEX4SK7cjs.BaseResource
|
|
|
5710
6963
|
};
|
|
5711
6964
|
|
|
5712
6965
|
// src/resources/phases.ts
|
|
5713
|
-
var PhasesResource = class extends
|
|
6966
|
+
var PhasesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5714
6967
|
constructor(http, pageSize) {
|
|
5715
6968
|
super(http, {
|
|
5716
6969
|
key: "phases",
|
|
@@ -5769,7 +7022,7 @@ var PhasesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
5769
7022
|
};
|
|
5770
7023
|
|
|
5771
7024
|
// src/resources/products.ts
|
|
5772
|
-
var ProductsResource = class extends
|
|
7025
|
+
var ProductsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5773
7026
|
constructor(http, pageSize) {
|
|
5774
7027
|
super(http, {
|
|
5775
7028
|
key: "products",
|
|
@@ -5836,7 +7089,7 @@ var ProductsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
5836
7089
|
};
|
|
5837
7090
|
|
|
5838
7091
|
// src/resources/product_vendors.ts
|
|
5839
|
-
var ProductVendorsResource = class extends
|
|
7092
|
+
var ProductVendorsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5840
7093
|
constructor(http, pageSize) {
|
|
5841
7094
|
super(http, {
|
|
5842
7095
|
key: "product_vendors",
|
|
@@ -5895,7 +7148,7 @@ var ProductVendorsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
5895
7148
|
};
|
|
5896
7149
|
|
|
5897
7150
|
// src/resources/project_charges.ts
|
|
5898
|
-
var ProjectChargesResource = class extends
|
|
7151
|
+
var ProjectChargesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5899
7152
|
constructor(http, pageSize) {
|
|
5900
7153
|
super(http, {
|
|
5901
7154
|
key: "project_charges",
|
|
@@ -5966,7 +7219,7 @@ var ProjectChargesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
5966
7219
|
};
|
|
5967
7220
|
|
|
5968
7221
|
// src/resources/project_notes.ts
|
|
5969
|
-
var ProjectNotesResource = class extends
|
|
7222
|
+
var ProjectNotesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
5970
7223
|
constructor(http, pageSize) {
|
|
5971
7224
|
super(http, {
|
|
5972
7225
|
key: "project_notes",
|
|
@@ -6025,7 +7278,7 @@ var ProjectNotesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6025
7278
|
};
|
|
6026
7279
|
|
|
6027
7280
|
// src/resources/projects.ts
|
|
6028
|
-
var ProjectsResource = class extends
|
|
7281
|
+
var ProjectsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6029
7282
|
constructor(http, pageSize) {
|
|
6030
7283
|
super(http, {
|
|
6031
7284
|
key: "projects",
|
|
@@ -6102,13 +7355,13 @@ var ProjectsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6102
7355
|
const leadResource = await this.contextFetch("/V1.0/Resources", root["projectLeadResourceID"]);
|
|
6103
7356
|
const result = { project, company, opportunity, leadResource };
|
|
6104
7357
|
if (opts.names === true) {
|
|
6105
|
-
const builder =
|
|
7358
|
+
const builder = _chunkIHRXVIUUcjs.createNamePlan.call(void 0, );
|
|
6106
7359
|
builder.addResource(root["creatorResourceID"]);
|
|
6107
7360
|
builder.addFk("contract", root["contractID"]);
|
|
6108
|
-
const names = await
|
|
7361
|
+
const names = await _chunkIHRXVIUUcjs.resolveCompositeNames.call(void 0, this.http, builder.plan(), { maxNameReads: opts.maxNameReads });
|
|
6109
7362
|
const row = { ...project };
|
|
6110
|
-
|
|
6111
|
-
|
|
7363
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, row, "creatorResourceID", (v) => names.resourceName(v));
|
|
7364
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, row, "contractID", (v) => names.recordName("contract", v));
|
|
6112
7365
|
result.project = row;
|
|
6113
7366
|
result.names = names.section;
|
|
6114
7367
|
}
|
|
@@ -6117,7 +7370,7 @@ var ProjectsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6117
7370
|
};
|
|
6118
7371
|
|
|
6119
7372
|
// src/resources/purchase_approvals.ts
|
|
6120
|
-
var PurchaseApprovalsResource = class extends
|
|
7373
|
+
var PurchaseApprovalsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6121
7374
|
constructor(http, pageSize) {
|
|
6122
7375
|
super(http, {
|
|
6123
7376
|
key: "purchase_approvals",
|
|
@@ -6171,7 +7424,7 @@ var PurchaseApprovalsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6171
7424
|
};
|
|
6172
7425
|
|
|
6173
7426
|
// src/resources/purchase_order_item_receiving.ts
|
|
6174
|
-
var PurchaseOrderItemReceivingResource = class extends
|
|
7427
|
+
var PurchaseOrderItemReceivingResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6175
7428
|
constructor(http, pageSize) {
|
|
6176
7429
|
super(http, {
|
|
6177
7430
|
key: "purchase_order_item_receiving",
|
|
@@ -6221,7 +7474,7 @@ var PurchaseOrderItemReceivingResource = class extends _chunkYKEX4SK7cjs.BaseRes
|
|
|
6221
7474
|
};
|
|
6222
7475
|
|
|
6223
7476
|
// src/resources/purchase_order_items.ts
|
|
6224
|
-
var PurchaseOrderItemsResource = class extends
|
|
7477
|
+
var PurchaseOrderItemsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6225
7478
|
constructor(http, pageSize) {
|
|
6226
7479
|
super(http, {
|
|
6227
7480
|
key: "purchase_order_items",
|
|
@@ -6280,7 +7533,7 @@ var PurchaseOrderItemsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6280
7533
|
};
|
|
6281
7534
|
|
|
6282
7535
|
// src/resources/purchase_orders.ts
|
|
6283
|
-
var PurchaseOrdersResource = class extends
|
|
7536
|
+
var PurchaseOrdersResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6284
7537
|
constructor(http, pageSize) {
|
|
6285
7538
|
super(http, {
|
|
6286
7539
|
key: "purchase_orders",
|
|
@@ -6342,7 +7595,7 @@ var PurchaseOrdersResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6342
7595
|
};
|
|
6343
7596
|
|
|
6344
7597
|
// src/resources/quote_items.ts
|
|
6345
|
-
var QuoteItemsResource = class extends
|
|
7598
|
+
var QuoteItemsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6346
7599
|
constructor(http, pageSize) {
|
|
6347
7600
|
super(http, {
|
|
6348
7601
|
key: "quote_items",
|
|
@@ -6413,7 +7666,7 @@ var QuoteItemsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6413
7666
|
};
|
|
6414
7667
|
|
|
6415
7668
|
// src/resources/quote_locations.ts
|
|
6416
|
-
var QuoteLocationsResource = class extends
|
|
7669
|
+
var QuoteLocationsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6417
7670
|
constructor(http, pageSize) {
|
|
6418
7671
|
super(http, {
|
|
6419
7672
|
key: "quote_locations",
|
|
@@ -6478,7 +7731,7 @@ var QuoteLocationsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6478
7731
|
};
|
|
6479
7732
|
|
|
6480
7733
|
// src/resources/quotes.ts
|
|
6481
|
-
var QuotesResource = class extends
|
|
7734
|
+
var QuotesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6482
7735
|
constructor(http, pageSize) {
|
|
6483
7736
|
super(http, {
|
|
6484
7737
|
key: "quotes",
|
|
@@ -6545,7 +7798,7 @@ var QuotesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6545
7798
|
};
|
|
6546
7799
|
|
|
6547
7800
|
// src/resources/quote_templates.ts
|
|
6548
|
-
var QuoteTemplatesResource = class extends
|
|
7801
|
+
var QuoteTemplatesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6549
7802
|
constructor(http, pageSize) {
|
|
6550
7803
|
super(http, {
|
|
6551
7804
|
key: "quote_templates",
|
|
@@ -6589,7 +7842,7 @@ var QuoteTemplatesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6589
7842
|
};
|
|
6590
7843
|
|
|
6591
7844
|
// src/resources/resource_role_queues.ts
|
|
6592
|
-
var ResourceRoleQueuesResource = class extends
|
|
7845
|
+
var ResourceRoleQueuesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6593
7846
|
constructor(http, pageSize) {
|
|
6594
7847
|
super(http, {
|
|
6595
7848
|
key: "resource_role_queues",
|
|
@@ -6648,7 +7901,7 @@ var ResourceRoleQueuesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6648
7901
|
};
|
|
6649
7902
|
|
|
6650
7903
|
// src/resources/resource_roles.ts
|
|
6651
|
-
var ResourceRolesResource = class extends
|
|
7904
|
+
var ResourceRolesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6652
7905
|
constructor(http, pageSize) {
|
|
6653
7906
|
super(http, {
|
|
6654
7907
|
key: "resource_roles",
|
|
@@ -6690,7 +7943,7 @@ var ResourceRolesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6690
7943
|
};
|
|
6691
7944
|
|
|
6692
7945
|
// src/resources/resource_skills.ts
|
|
6693
|
-
var ResourceSkillsResource = class extends
|
|
7946
|
+
var ResourceSkillsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6694
7947
|
constructor(http, pageSize) {
|
|
6695
7948
|
super(http, {
|
|
6696
7949
|
key: "resource_skills",
|
|
@@ -6744,16 +7997,16 @@ var ResourceSkillsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6744
7997
|
var MAX_TRANSFER_IDS = 500;
|
|
6745
7998
|
function requirePositiveIds(ids, label) {
|
|
6746
7999
|
if (!Array.isArray(ids) || ids.length === 0) {
|
|
6747
|
-
throw new (0,
|
|
8000
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`${label}: at least one positive integer id is required`);
|
|
6748
8001
|
}
|
|
6749
8002
|
if (ids.length > MAX_TRANSFER_IDS) {
|
|
6750
|
-
throw new (0,
|
|
8003
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`${label}: at most ${MAX_TRANSFER_IDS} ids are accepted (bounded fan-out)`);
|
|
6751
8004
|
}
|
|
6752
8005
|
const out = [];
|
|
6753
8006
|
for (const raw of ids) {
|
|
6754
|
-
const id =
|
|
8007
|
+
const id = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, raw, `${label} id`);
|
|
6755
8008
|
if (typeof id === "number" && id < 1) {
|
|
6756
|
-
throw new (0,
|
|
8009
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`${label}: every id must be a positive integer (got ${String(raw)})`);
|
|
6757
8010
|
}
|
|
6758
8011
|
out.push(id);
|
|
6759
8012
|
}
|
|
@@ -6761,7 +8014,7 @@ function requirePositiveIds(ids, label) {
|
|
|
6761
8014
|
}
|
|
6762
8015
|
async function whoAmI(_resource, userName, http) {
|
|
6763
8016
|
const user = userName.trim();
|
|
6764
|
-
if (user === "") throw new (0,
|
|
8017
|
+
if (user === "") throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("whoAmI: the configured UserName is empty");
|
|
6765
8018
|
const value = user.includes("@") ? _nullishCoalesce(user.split("@")[0], () => ( "")) : user;
|
|
6766
8019
|
const res = await http.request({
|
|
6767
8020
|
method: "POST",
|
|
@@ -6770,11 +8023,11 @@ async function whoAmI(_resource, userName, http) {
|
|
|
6770
8023
|
body: { MaxRecords: 2, filter: [{ field: "userName", op: "eq", value }] },
|
|
6771
8024
|
operation: "resources.whoAmI"
|
|
6772
8025
|
});
|
|
6773
|
-
const matches =
|
|
8026
|
+
const matches = _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res).items;
|
|
6774
8027
|
if (matches.length === 0) return null;
|
|
6775
8028
|
if (matches.length > 1) {
|
|
6776
8029
|
const ids = matches.map((m) => m.id).filter((id) => typeof id === "number");
|
|
6777
|
-
throw new (0,
|
|
8030
|
+
throw new (0, _chunkIHRXVIUUcjs.ResolutionError)(
|
|
6778
8031
|
`whoAmI: "${value}" is ambiguous (matched ${matches.length} resources)`,
|
|
6779
8032
|
{ code: "RESOLUTION_AMBIGUOUS", resourceIds: ids }
|
|
6780
8033
|
);
|
|
@@ -6783,11 +8036,11 @@ async function whoAmI(_resource, userName, http) {
|
|
|
6783
8036
|
}
|
|
6784
8037
|
async function transferOwnership(_resource, companyIds, destinationResourceId, http, opts) {
|
|
6785
8038
|
const ids = requirePositiveIds(companyIds, "transferOwnership");
|
|
6786
|
-
const destination =
|
|
8039
|
+
const destination = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, destinationResourceId, "destinationResourceId");
|
|
6787
8040
|
if (typeof destination === "number" && destination < 1) {
|
|
6788
|
-
throw new (0,
|
|
8041
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("transferOwnership: destinationResourceId must be a positive integer");
|
|
6789
8042
|
}
|
|
6790
|
-
const dryRun = _nullishCoalesce(_optionalChain([opts, 'optionalAccess',
|
|
8043
|
+
const dryRun = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _51 => _51.dryRun]), () => ( true));
|
|
6791
8044
|
const changes = [];
|
|
6792
8045
|
const applied = [];
|
|
6793
8046
|
for (const id of ids) {
|
|
@@ -6797,7 +8050,7 @@ async function transferOwnership(_resource, companyIds, destinationResourceId, h
|
|
|
6797
8050
|
path: `/V1.0/Companies/${id}`,
|
|
6798
8051
|
operation: "resources.transferOwnership"
|
|
6799
8052
|
});
|
|
6800
|
-
const company =
|
|
8053
|
+
const company = _chunkIHRXVIUUcjs.unwrapItem.call(void 0, res, id);
|
|
6801
8054
|
const current = typeof company.ownerResourceID === "number" ? company.ownerResourceID : null;
|
|
6802
8055
|
changes.push({ id, fromOwnerResourceID: current, toOwnerResourceID: destination });
|
|
6803
8056
|
if (!dryRun) {
|
|
@@ -6807,11 +8060,11 @@ async function transferOwnership(_resource, companyIds, destinationResourceId, h
|
|
|
6807
8060
|
body: { id, ownerResourceID: destination },
|
|
6808
8061
|
operation: "resources.transferOwnership"
|
|
6809
8062
|
});
|
|
6810
|
-
|
|
8063
|
+
_chunkIHRXVIUUcjs.unwrapOperation.call(void 0, update);
|
|
6811
8064
|
applied.push(id);
|
|
6812
8065
|
}
|
|
6813
8066
|
} catch (err) {
|
|
6814
|
-
if (!dryRun && err instanceof
|
|
8067
|
+
if (!dryRun && err instanceof _chunkIHRXVIUUcjs.AutotaskError) {
|
|
6815
8068
|
err.resourceIds = [id];
|
|
6816
8069
|
err.suggestedAction = `Partial transfer: ${applied.length} of ${ids.length} companies were re-owned (ids: ${applied.join(", ") || "none"}); id ${id} failed. Re-run transferOwnership for the remaining ids (from ${id} on).`;
|
|
6817
8070
|
}
|
|
@@ -6821,7 +8074,7 @@ async function transferOwnership(_resource, companyIds, destinationResourceId, h
|
|
|
6821
8074
|
if (dryRun) {
|
|
6822
8075
|
const anyChange = changes.some((c) => c.fromOwnerResourceID !== c.toOwnerResourceID);
|
|
6823
8076
|
return {
|
|
6824
|
-
...
|
|
8077
|
+
..._chunkIHRXVIUUcjs.buildDryRunResult.call(void 0, {
|
|
6825
8078
|
operation: "resources.transferOwnership",
|
|
6826
8079
|
method: "PUT",
|
|
6827
8080
|
path: "/V1.0/Companies",
|
|
@@ -6845,7 +8098,7 @@ async function transferOwnership(_resource, companyIds, destinationResourceId, h
|
|
|
6845
8098
|
}
|
|
6846
8099
|
|
|
6847
8100
|
// src/resources/resources.ts
|
|
6848
|
-
var ResourcesResource = class extends
|
|
8101
|
+
var ResourcesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6849
8102
|
|
|
6850
8103
|
constructor(http, clientConfig, pageSize) {
|
|
6851
8104
|
super(http, {
|
|
@@ -6918,7 +8171,7 @@ var ResourcesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
6918
8171
|
|
|
6919
8172
|
// src/resources/special/resource_time_off_additional.ts
|
|
6920
8173
|
async function getByResource(_resource, resourceId, http) {
|
|
6921
|
-
const numericResource =
|
|
8174
|
+
const numericResource = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, resourceId, "resourceId");
|
|
6922
8175
|
const res = await http.request({
|
|
6923
8176
|
method: "GET",
|
|
6924
8177
|
path: `/V1.0/Resources/${numericResource}/TimeOffAdditional`,
|
|
@@ -6932,11 +8185,11 @@ async function getByResource(_resource, resourceId, http) {
|
|
|
6932
8185
|
if (typeof item === "object" && !Array.isArray(item)) return [item];
|
|
6933
8186
|
}
|
|
6934
8187
|
}
|
|
6935
|
-
return
|
|
8188
|
+
return _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res, "resource_time_off_additional.getByResource").items;
|
|
6936
8189
|
}
|
|
6937
8190
|
|
|
6938
8191
|
// src/resources/resource_time_off_additional.ts
|
|
6939
|
-
var ResourceTimeOffAdditionalResource = class extends
|
|
8192
|
+
var ResourceTimeOffAdditionalResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6940
8193
|
constructor(http, pageSize) {
|
|
6941
8194
|
super(http, {
|
|
6942
8195
|
key: "resource_time_off_additional",
|
|
@@ -6975,7 +8228,7 @@ var ResourceTimeOffAdditionalResource = class extends _chunkYKEX4SK7cjs.BaseReso
|
|
|
6975
8228
|
};
|
|
6976
8229
|
|
|
6977
8230
|
// src/resources/resource_time_off_approvers.ts
|
|
6978
|
-
var ResourceTimeOffApproversResource = class extends
|
|
8231
|
+
var ResourceTimeOffApproversResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
6979
8232
|
constructor(http, pageSize) {
|
|
6980
8233
|
super(http, {
|
|
6981
8234
|
key: "resource_time_off_approvers",
|
|
@@ -7018,29 +8271,29 @@ var ResourceTimeOffApproversResource = class extends _chunkYKEX4SK7cjs.BaseResou
|
|
|
7018
8271
|
|
|
7019
8272
|
// src/resources/special/resource_time_off_balances.ts
|
|
7020
8273
|
async function getByResource2(_resource, resourceId, http) {
|
|
7021
|
-
const numericResource =
|
|
8274
|
+
const numericResource = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, resourceId, "resourceId");
|
|
7022
8275
|
const res = await http.request({
|
|
7023
8276
|
method: "GET",
|
|
7024
8277
|
path: `/V1.0/Resources/${numericResource}/TimeOffBalances`,
|
|
7025
8278
|
operation: "resource_time_off_balances.getByResource"
|
|
7026
8279
|
});
|
|
7027
|
-
return
|
|
8280
|
+
return _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res, "resource_time_off_balances.getByResource").items;
|
|
7028
8281
|
}
|
|
7029
8282
|
async function getByYear(_resource, resourceId, year, http) {
|
|
7030
|
-
const numericResource =
|
|
8283
|
+
const numericResource = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, resourceId, "resourceId");
|
|
7031
8284
|
if (!Number.isSafeInteger(year) || year < 1) {
|
|
7032
|
-
throw new (0,
|
|
8285
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("getByYear: year must be a positive integer");
|
|
7033
8286
|
}
|
|
7034
8287
|
const res = await http.request({
|
|
7035
8288
|
method: "GET",
|
|
7036
8289
|
path: `/V1.0/Resources/${numericResource}/TimeOffBalances/${year}`,
|
|
7037
8290
|
operation: "resource_time_off_balances.getByYear"
|
|
7038
8291
|
});
|
|
7039
|
-
return
|
|
8292
|
+
return _chunkIHRXVIUUcjs.unwrapItem.call(void 0, res, year, "resource_time_off_balances.getByYear");
|
|
7040
8293
|
}
|
|
7041
8294
|
|
|
7042
8295
|
// src/resources/resource_time_off_balances.ts
|
|
7043
|
-
var ResourceTimeOffBalancesResource = class extends
|
|
8296
|
+
var ResourceTimeOffBalancesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7044
8297
|
constructor(http, pageSize) {
|
|
7045
8298
|
super(http, {
|
|
7046
8299
|
key: "resource_time_off_balances",
|
|
@@ -7078,7 +8331,7 @@ var ResourceTimeOffBalancesResource = class extends _chunkYKEX4SK7cjs.BaseResour
|
|
|
7078
8331
|
};
|
|
7079
8332
|
|
|
7080
8333
|
// src/resources/roles.ts
|
|
7081
|
-
var RolesResource = class extends
|
|
8334
|
+
var RolesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7082
8335
|
constructor(http, pageSize) {
|
|
7083
8336
|
super(http, {
|
|
7084
8337
|
key: "roles",
|
|
@@ -7145,7 +8398,7 @@ var RolesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7145
8398
|
};
|
|
7146
8399
|
|
|
7147
8400
|
// src/resources/service_calls.ts
|
|
7148
|
-
var ServiceCallsResource = class extends
|
|
8401
|
+
var ServiceCallsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7149
8402
|
constructor(http, pageSize) {
|
|
7150
8403
|
super(http, {
|
|
7151
8404
|
key: "service_calls",
|
|
@@ -7214,7 +8467,7 @@ var ServiceCallsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7214
8467
|
};
|
|
7215
8468
|
|
|
7216
8469
|
// src/resources/service_call_task_resources.ts
|
|
7217
|
-
var ServiceCallTaskResourcesResource = class extends
|
|
8470
|
+
var ServiceCallTaskResourcesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7218
8471
|
constructor(http, pageSize) {
|
|
7219
8472
|
super(http, {
|
|
7220
8473
|
key: "service_call_task_resources",
|
|
@@ -7271,7 +8524,7 @@ var ServiceCallTaskResourcesResource = class extends _chunkYKEX4SK7cjs.BaseResou
|
|
|
7271
8524
|
};
|
|
7272
8525
|
|
|
7273
8526
|
// src/resources/service_call_tasks.ts
|
|
7274
|
-
var ServiceCallTasksResource = class extends
|
|
8527
|
+
var ServiceCallTasksResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7275
8528
|
constructor(http, pageSize) {
|
|
7276
8529
|
super(http, {
|
|
7277
8530
|
key: "service_call_tasks",
|
|
@@ -7328,7 +8581,7 @@ var ServiceCallTasksResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7328
8581
|
};
|
|
7329
8582
|
|
|
7330
8583
|
// src/resources/service_call_ticket_resources.ts
|
|
7331
|
-
var ServiceCallTicketResourcesResource = class extends
|
|
8584
|
+
var ServiceCallTicketResourcesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7332
8585
|
constructor(http, pageSize) {
|
|
7333
8586
|
super(http, {
|
|
7334
8587
|
key: "service_call_ticket_resources",
|
|
@@ -7385,7 +8638,7 @@ var ServiceCallTicketResourcesResource = class extends _chunkYKEX4SK7cjs.BaseRes
|
|
|
7385
8638
|
};
|
|
7386
8639
|
|
|
7387
8640
|
// src/resources/service_call_tickets.ts
|
|
7388
|
-
var ServiceCallTicketsResource = class extends
|
|
8641
|
+
var ServiceCallTicketsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7389
8642
|
constructor(http, pageSize) {
|
|
7390
8643
|
super(http, {
|
|
7391
8644
|
key: "service_call_tickets",
|
|
@@ -7442,7 +8695,7 @@ var ServiceCallTicketsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7442
8695
|
};
|
|
7443
8696
|
|
|
7444
8697
|
// src/resources/service_level_agreement_results.ts
|
|
7445
|
-
var ServiceLevelAgreementResultsResource = class extends
|
|
8698
|
+
var ServiceLevelAgreementResultsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7446
8699
|
constructor(http, pageSize) {
|
|
7447
8700
|
super(http, {
|
|
7448
8701
|
key: "service_level_agreement_results",
|
|
@@ -7481,7 +8734,7 @@ var ServiceLevelAgreementResultsResource = class extends _chunkYKEX4SK7cjs.BaseR
|
|
|
7481
8734
|
};
|
|
7482
8735
|
|
|
7483
8736
|
// src/resources/services.ts
|
|
7484
|
-
var ServicesResource = class extends
|
|
8737
|
+
var ServicesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7485
8738
|
constructor(http, pageSize) {
|
|
7486
8739
|
super(http, {
|
|
7487
8740
|
key: "services",
|
|
@@ -7549,7 +8802,7 @@ var ServicesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7549
8802
|
};
|
|
7550
8803
|
|
|
7551
8804
|
// src/resources/skills.ts
|
|
7552
|
-
var SkillsResource = class extends
|
|
8805
|
+
var SkillsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7553
8806
|
constructor(http, pageSize) {
|
|
7554
8807
|
super(http, {
|
|
7555
8808
|
key: "skills",
|
|
@@ -7593,7 +8846,7 @@ var SkillsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7593
8846
|
};
|
|
7594
8847
|
|
|
7595
8848
|
// src/resources/subscription_periods.ts
|
|
7596
|
-
var SubscriptionPeriodsResource = class extends
|
|
8849
|
+
var SubscriptionPeriodsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7597
8850
|
constructor(http, pageSize) {
|
|
7598
8851
|
super(http, {
|
|
7599
8852
|
key: "subscription_periods",
|
|
@@ -7632,7 +8885,7 @@ var SubscriptionPeriodsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7632
8885
|
};
|
|
7633
8886
|
|
|
7634
8887
|
// src/resources/subscriptions.ts
|
|
7635
|
-
var SubscriptionsResource = class extends
|
|
8888
|
+
var SubscriptionsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7636
8889
|
constructor(http, pageSize) {
|
|
7637
8890
|
super(http, {
|
|
7638
8891
|
key: "subscriptions",
|
|
@@ -7701,7 +8954,7 @@ var SubscriptionsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7701
8954
|
};
|
|
7702
8955
|
|
|
7703
8956
|
// src/resources/survey_results.ts
|
|
7704
|
-
var SurveyResultsResource = class extends
|
|
8957
|
+
var SurveyResultsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7705
8958
|
constructor(http, pageSize) {
|
|
7706
8959
|
super(http, {
|
|
7707
8960
|
key: "survey_results",
|
|
@@ -7740,7 +8993,7 @@ var SurveyResultsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7740
8993
|
};
|
|
7741
8994
|
|
|
7742
8995
|
// src/resources/surveys.ts
|
|
7743
|
-
var SurveysResource = class extends
|
|
8996
|
+
var SurveysResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7744
8997
|
constructor(http, pageSize) {
|
|
7745
8998
|
super(http, {
|
|
7746
8999
|
key: "surveys",
|
|
@@ -7784,7 +9037,7 @@ var SurveysResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7784
9037
|
};
|
|
7785
9038
|
|
|
7786
9039
|
// src/resources/tag_aliases.ts
|
|
7787
|
-
var TagAliasesResource = class extends
|
|
9040
|
+
var TagAliasesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7788
9041
|
constructor(http, pageSize) {
|
|
7789
9042
|
super(http, {
|
|
7790
9043
|
key: "tag_aliases",
|
|
@@ -7841,7 +9094,7 @@ var TagAliasesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7841
9094
|
};
|
|
7842
9095
|
|
|
7843
9096
|
// src/resources/tag_groups.ts
|
|
7844
|
-
var TagGroupsResource = class extends
|
|
9097
|
+
var TagGroupsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7845
9098
|
constructor(http, pageSize) {
|
|
7846
9099
|
super(http, {
|
|
7847
9100
|
key: "tag_groups",
|
|
@@ -7910,7 +9163,7 @@ var TagGroupsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7910
9163
|
};
|
|
7911
9164
|
|
|
7912
9165
|
// src/resources/tags.ts
|
|
7913
|
-
var TagsResource = class extends
|
|
9166
|
+
var TagsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7914
9167
|
constructor(http, pageSize) {
|
|
7915
9168
|
super(http, {
|
|
7916
9169
|
key: "tags",
|
|
@@ -7979,7 +9232,7 @@ var TagsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
7979
9232
|
};
|
|
7980
9233
|
|
|
7981
9234
|
// src/resources/task_secondary_resources.ts
|
|
7982
|
-
var TaskSecondaryResourcesResource = class extends
|
|
9235
|
+
var TaskSecondaryResourcesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
7983
9236
|
constructor(http, pageSize) {
|
|
7984
9237
|
super(http, {
|
|
7985
9238
|
key: "task_secondary_resources",
|
|
@@ -8036,7 +9289,7 @@ var TaskSecondaryResourcesResource = class extends _chunkYKEX4SK7cjs.BaseResourc
|
|
|
8036
9289
|
};
|
|
8037
9290
|
|
|
8038
9291
|
// src/resources/tasks.ts
|
|
8039
|
-
var TasksResource = class extends
|
|
9292
|
+
var TasksResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8040
9293
|
constructor(http, pageSize) {
|
|
8041
9294
|
super(http, {
|
|
8042
9295
|
key: "tasks",
|
|
@@ -8124,7 +9377,7 @@ var ThresholdInformationResource = class {
|
|
|
8124
9377
|
};
|
|
8125
9378
|
|
|
8126
9379
|
// src/resources/ticket_additional_configuration_items.ts
|
|
8127
|
-
var TicketAdditionalConfigurationItemsResource = class extends
|
|
9380
|
+
var TicketAdditionalConfigurationItemsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8128
9381
|
constructor(http, pageSize) {
|
|
8129
9382
|
super(http, {
|
|
8130
9383
|
key: "ticket_additional_configuration_items",
|
|
@@ -8181,7 +9434,7 @@ var TicketAdditionalConfigurationItemsResource = class extends _chunkYKEX4SK7cjs
|
|
|
8181
9434
|
};
|
|
8182
9435
|
|
|
8183
9436
|
// src/resources/ticket_additional_contacts.ts
|
|
8184
|
-
var TicketAdditionalContactsResource = class extends
|
|
9437
|
+
var TicketAdditionalContactsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8185
9438
|
constructor(http, pageSize) {
|
|
8186
9439
|
super(http, {
|
|
8187
9440
|
key: "ticket_additional_contacts",
|
|
@@ -8238,7 +9491,7 @@ var TicketAdditionalContactsResource = class extends _chunkYKEX4SK7cjs.BaseResou
|
|
|
8238
9491
|
};
|
|
8239
9492
|
|
|
8240
9493
|
// src/resources/ticket_attachments.ts
|
|
8241
|
-
var TicketAttachmentsResource = class extends
|
|
9494
|
+
var TicketAttachmentsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8242
9495
|
constructor(http, pageSize) {
|
|
8243
9496
|
super(http, {
|
|
8244
9497
|
key: "ticket_attachments",
|
|
@@ -8300,7 +9553,7 @@ var TicketAttachmentsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
8300
9553
|
};
|
|
8301
9554
|
|
|
8302
9555
|
// src/resources/ticket_categories.ts
|
|
8303
|
-
var TicketCategoriesResource = class extends
|
|
9556
|
+
var TicketCategoriesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8304
9557
|
constructor(http, pageSize) {
|
|
8305
9558
|
super(http, {
|
|
8306
9559
|
key: "ticket_categories",
|
|
@@ -8359,7 +9612,7 @@ var TicketCategoriesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
8359
9612
|
};
|
|
8360
9613
|
|
|
8361
9614
|
// src/resources/ticket_category_field_defaults.ts
|
|
8362
|
-
var TicketCategoryFieldDefaultsResource = class extends
|
|
9615
|
+
var TicketCategoryFieldDefaultsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8363
9616
|
constructor(http, pageSize) {
|
|
8364
9617
|
super(http, {
|
|
8365
9618
|
key: "ticket_category_field_defaults",
|
|
@@ -8401,7 +9654,7 @@ var TicketCategoryFieldDefaultsResource = class extends _chunkYKEX4SK7cjs.BaseRe
|
|
|
8401
9654
|
};
|
|
8402
9655
|
|
|
8403
9656
|
// src/resources/ticket_change_request_approvals.ts
|
|
8404
|
-
var TicketChangeRequestApprovalsResource = class extends
|
|
9657
|
+
var TicketChangeRequestApprovalsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8405
9658
|
constructor(http, pageSize) {
|
|
8406
9659
|
super(http, {
|
|
8407
9660
|
key: "ticket_change_request_approvals",
|
|
@@ -8458,7 +9711,7 @@ var TicketChangeRequestApprovalsResource = class extends _chunkYKEX4SK7cjs.BaseR
|
|
|
8458
9711
|
};
|
|
8459
9712
|
|
|
8460
9713
|
// src/resources/ticket_charges.ts
|
|
8461
|
-
var TicketChargesResource = class extends
|
|
9714
|
+
var TicketChargesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8462
9715
|
constructor(http, pageSize) {
|
|
8463
9716
|
super(http, {
|
|
8464
9717
|
key: "ticket_charges",
|
|
@@ -8529,7 +9782,7 @@ var TicketChargesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
8529
9782
|
};
|
|
8530
9783
|
|
|
8531
9784
|
// src/resources/ticket_checklist_items.ts
|
|
8532
|
-
var TicketChecklistItemsResource = class extends
|
|
9785
|
+
var TicketChecklistItemsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8533
9786
|
constructor(http, pageSize) {
|
|
8534
9787
|
super(http, {
|
|
8535
9788
|
key: "ticket_checklist_items",
|
|
@@ -8595,7 +9848,7 @@ var TicketChecklistItemsResource = class extends _chunkYKEX4SK7cjs.BaseResource
|
|
|
8595
9848
|
};
|
|
8596
9849
|
|
|
8597
9850
|
// src/resources/ticket_checklist_libraries.ts
|
|
8598
|
-
var TicketChecklistLibrariesResource = class extends
|
|
9851
|
+
var TicketChecklistLibrariesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8599
9852
|
constructor(http, pageSize) {
|
|
8600
9853
|
super(http, {
|
|
8601
9854
|
key: "ticket_checklist_libraries",
|
|
@@ -8619,9 +9872,9 @@ var TicketChecklistLibrariesResource = class extends _chunkYKEX4SK7cjs.BaseResou
|
|
|
8619
9872
|
* `dryRun: true` returns the pinned envelope (document existence is unverifiable in the MVP
|
|
8620
9873
|
* surface — no documents read op — and never issues the POST). */
|
|
8621
9874
|
async attachToDocument(documentID, data, opts = {}) {
|
|
8622
|
-
const n =
|
|
9875
|
+
const n = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, documentID, "documentID");
|
|
8623
9876
|
if (opts.dryRun === true) {
|
|
8624
|
-
return
|
|
9877
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0, {
|
|
8625
9878
|
operation: "ticket_checklist_libraries.attachToDocument",
|
|
8626
9879
|
method: "POST",
|
|
8627
9880
|
path: `/V1.0/Documents/${n}/ChecklistLibraries`,
|
|
@@ -8638,7 +9891,7 @@ var TicketChecklistLibrariesResource = class extends _chunkYKEX4SK7cjs.BaseResou
|
|
|
8638
9891
|
body: { ...data },
|
|
8639
9892
|
operation: "ticket_checklist_libraries.attachToDocument"
|
|
8640
9893
|
});
|
|
8641
|
-
return
|
|
9894
|
+
return _chunkIHRXVIUUcjs.unwrapOperation.call(void 0, res);
|
|
8642
9895
|
}
|
|
8643
9896
|
/** Resolve a TicketChecklistLibrary from a numeric id (or, where the vendor indexes a primary text field,
|
|
8644
9897
|
* from a numeric id — this resource has no primary text field). A numeric id miss throws NOT_FOUND;
|
|
@@ -8654,7 +9907,7 @@ var TicketChecklistLibrariesResource = class extends _chunkYKEX4SK7cjs.BaseResou
|
|
|
8654
9907
|
};
|
|
8655
9908
|
|
|
8656
9909
|
// src/resources/ticket_history.ts
|
|
8657
|
-
var TicketHistoryResource = class extends
|
|
9910
|
+
var TicketHistoryResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8658
9911
|
constructor(http, pageSize) {
|
|
8659
9912
|
super(http, {
|
|
8660
9913
|
key: "ticket_history",
|
|
@@ -8693,7 +9946,7 @@ var TicketHistoryResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
8693
9946
|
};
|
|
8694
9947
|
|
|
8695
9948
|
// src/resources/ticket_note_attachments.ts
|
|
8696
|
-
var TicketNoteAttachmentsResource = class extends
|
|
9949
|
+
var TicketNoteAttachmentsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8697
9950
|
constructor(http, pageSize) {
|
|
8698
9951
|
super(http, {
|
|
8699
9952
|
key: "ticket_note_attachments",
|
|
@@ -8755,7 +10008,7 @@ var TicketNoteAttachmentsResource = class extends _chunkYKEX4SK7cjs.BaseResource
|
|
|
8755
10008
|
};
|
|
8756
10009
|
|
|
8757
10010
|
// src/resources/ticket_notes.ts
|
|
8758
|
-
var TicketNotesResource = class extends
|
|
10011
|
+
var TicketNotesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8759
10012
|
constructor(http, pageSize) {
|
|
8760
10013
|
super(http, {
|
|
8761
10014
|
key: "ticket_notes",
|
|
@@ -8814,7 +10067,7 @@ var TicketNotesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
8814
10067
|
};
|
|
8815
10068
|
|
|
8816
10069
|
// src/resources/ticket_note_webhooks.ts
|
|
8817
|
-
var TicketNoteWebhooksResource = class extends
|
|
10070
|
+
var TicketNoteWebhooksResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8818
10071
|
constructor(http, pageSize) {
|
|
8819
10072
|
super(http, {
|
|
8820
10073
|
key: "ticket_note_webhooks",
|
|
@@ -8890,7 +10143,7 @@ var TicketNoteWebhooksResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
8890
10143
|
};
|
|
8891
10144
|
|
|
8892
10145
|
// src/resources/ticket_secondary_resources.ts
|
|
8893
|
-
var TicketSecondaryResourcesResource = class extends
|
|
10146
|
+
var TicketSecondaryResourcesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
8894
10147
|
constructor(http, pageSize) {
|
|
8895
10148
|
super(http, {
|
|
8896
10149
|
key: "ticket_secondary_resources",
|
|
@@ -8957,9 +10210,9 @@ async function fetchTicket(http, id, operation) {
|
|
|
8957
10210
|
});
|
|
8958
10211
|
const body = res;
|
|
8959
10212
|
if (body === null || !("item" in body)) {
|
|
8960
|
-
throw new (0,
|
|
10213
|
+
throw new (0, _chunkIHRXVIUUcjs.NotFoundError)(`Ticket ${id} not found (unexpected envelope shape)`, { resourceIds: [id] });
|
|
8961
10214
|
}
|
|
8962
|
-
if (body.item === null || body.item === void 0) throw new (0,
|
|
10215
|
+
if (body.item === null || body.item === void 0) throw new (0, _chunkIHRXVIUUcjs.NotFoundError)(`Ticket ${id} not found`, { resourceIds: [id] });
|
|
8963
10216
|
return body.item;
|
|
8964
10217
|
}
|
|
8965
10218
|
async function ticketQueryItems(http, path, filter, maxRecords, operation) {
|
|
@@ -8970,29 +10223,29 @@ async function ticketQueryItems(http, path, filter, maxRecords, operation) {
|
|
|
8970
10223
|
body: { MaxRecords: maxRecords, filter },
|
|
8971
10224
|
operation
|
|
8972
10225
|
});
|
|
8973
|
-
return
|
|
10226
|
+
return _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res).items;
|
|
8974
10227
|
}
|
|
8975
10228
|
function isRouteUnavailable(err) {
|
|
8976
|
-
return
|
|
10229
|
+
return _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) && (err.httpStatus === 404 || err.httpStatus === 500);
|
|
8977
10230
|
}
|
|
8978
10231
|
function routeFact(route, path, err) {
|
|
8979
10232
|
return {
|
|
8980
10233
|
route,
|
|
8981
10234
|
path,
|
|
8982
|
-
httpStatus:
|
|
10235
|
+
httpStatus: _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) && typeof err.httpStatus === "number" ? err.httpStatus : null
|
|
8983
10236
|
};
|
|
8984
10237
|
}
|
|
8985
10238
|
function childDeclaresQuery(resourceKey) {
|
|
8986
|
-
return
|
|
10239
|
+
return _chunkCSRCMBZ2cjs.CAPABILITIES.some(
|
|
8987
10240
|
(c) => c.id === `${resourceKey}.query` && (c.status === "implemented" || c.status === "tested")
|
|
8988
10241
|
);
|
|
8989
10242
|
}
|
|
8990
10243
|
function planScopedPath(resourceKey, ticketId) {
|
|
8991
10244
|
if (!childDeclaresQuery(resourceKey)) return null;
|
|
8992
|
-
const entry =
|
|
10245
|
+
const entry = _chunkIHRXVIUUcjs.RELATIONSHIP_MAP[resourceKey];
|
|
8993
10246
|
const parent = entry === void 0 ? null : entry.parent;
|
|
8994
10247
|
if (parent === null || parent.resource !== "tickets" || parent.segment === null || parent.field === null) return null;
|
|
8995
|
-
const parentPath = _optionalChain([
|
|
10248
|
+
const parentPath = _optionalChain([_chunkIHRXVIUUcjs.RELATIONSHIP_MAP, 'access', _52 => _52[parent.resource], 'optionalAccess', _53 => _53.path]);
|
|
8996
10249
|
if (parentPath === null || parentPath === void 0) return null;
|
|
8997
10250
|
return `/V1.0/${parentPath}/${ticketId}/${parent.segment}`;
|
|
8998
10251
|
}
|
|
@@ -9031,14 +10284,14 @@ async function scopedCollectionRead(http, startPath, limit, operation, accept) {
|
|
|
9031
10284
|
break;
|
|
9032
10285
|
}
|
|
9033
10286
|
const body = await http.request({ method: "GET", path: target, operation });
|
|
9034
|
-
const { items: pageItems, pageDetails } =
|
|
10287
|
+
const { items: pageItems, pageDetails } = _chunkIHRXVIUUcjs.unwrapItems.call(void 0, body, operation);
|
|
9035
10288
|
nextCursor = pageDetails.nextPageUrl;
|
|
9036
10289
|
pages += 1;
|
|
9037
10290
|
const window = pageItems.slice(0, Math.max(0, limit - items.length));
|
|
9038
10291
|
for (const row of window) if (accept(row)) items.push(row);
|
|
9039
10292
|
if (items.length >= limit) break;
|
|
9040
10293
|
if (nextCursor === null || pageItems.length === 0) break;
|
|
9041
|
-
target =
|
|
10294
|
+
target = _chunkIHRXVIUUcjs.cursorToPath.call(void 0, http.baseUrl, nextCursor);
|
|
9042
10295
|
}
|
|
9043
10296
|
const capped = items.length >= limit || guard && nextCursor !== null;
|
|
9044
10297
|
return { items, capped };
|
|
@@ -9072,7 +10325,7 @@ function truncate(text, limit) {
|
|
|
9072
10325
|
}
|
|
9073
10326
|
async function slaHealthCheck(_resource, id, opts = {}, http) {
|
|
9074
10327
|
void opts;
|
|
9075
|
-
const ticketId =
|
|
10328
|
+
const ticketId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, id, "id");
|
|
9076
10329
|
await fetchTicket(http, ticketId, "tickets.slaHealthCheck");
|
|
9077
10330
|
const rows = await ticketQueryItems(
|
|
9078
10331
|
http,
|
|
@@ -9083,11 +10336,11 @@ async function slaHealthCheck(_resource, id, opts = {}, http) {
|
|
|
9083
10336
|
);
|
|
9084
10337
|
const slas = rows.map((row) => {
|
|
9085
10338
|
const bool = (v) => typeof v === "boolean" ? v : null;
|
|
9086
|
-
const
|
|
10339
|
+
const num3 = (v) => typeof v === "number" ? v : null;
|
|
9087
10340
|
const milestones = [
|
|
9088
|
-
{ name: "firstResponse", met: bool(row.isFirstResponseMet), elapsedHours:
|
|
9089
|
-
{ name: "resolution", met: bool(row.isResolutionMet), elapsedHours:
|
|
9090
|
-
{ name: "resolutionPlan", met: bool(row.isResolutionPlanMet), elapsedHours:
|
|
10341
|
+
{ name: "firstResponse", met: bool(row.isFirstResponseMet), elapsedHours: num3(row.firstResponseElapsedHours) },
|
|
10342
|
+
{ name: "resolution", met: bool(row.isResolutionMet), elapsedHours: num3(row.resolutionElapsedHours) },
|
|
10343
|
+
{ name: "resolutionPlan", met: bool(row.isResolutionPlanMet), elapsedHours: num3(row.resolutionPlanElapsedHours) }
|
|
9091
10344
|
];
|
|
9092
10345
|
return { id: Number(row.id), name: _nullishCoalesce(row.serviceLevelAgreementName, () => ( null)), milestones };
|
|
9093
10346
|
});
|
|
@@ -9097,9 +10350,9 @@ async function slaHealthCheck(_resource, id, opts = {}, http) {
|
|
|
9097
10350
|
async function summary(_resource, id, opts = {}, http) {
|
|
9098
10351
|
const limit = opts.summaryTextLimit === void 0 ? 500 : Math.trunc(opts.summaryTextLimit);
|
|
9099
10352
|
if (!Number.isInteger(limit) || limit < 1) {
|
|
9100
|
-
throw new (0,
|
|
10353
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`summaryTextLimit must be an integer >= 1 (got ${String(opts.summaryTextLimit)})`);
|
|
9101
10354
|
}
|
|
9102
|
-
const ticketId =
|
|
10355
|
+
const ticketId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, id, "id");
|
|
9103
10356
|
const ticket = await fetchTicket(http, ticketId, "tickets.summary");
|
|
9104
10357
|
const desc = truncate(ticket.description, limit);
|
|
9105
10358
|
const now = _nullishCoalesce(opts.now, () => ( /* @__PURE__ */ new Date()));
|
|
@@ -9126,13 +10379,13 @@ async function summary(_resource, id, opts = {}, http) {
|
|
|
9126
10379
|
}
|
|
9127
10380
|
async function timeline(_resource, id, opts = {}, http) {
|
|
9128
10381
|
const limit = opts.limit === void 0 ? 100 : Math.trunc(opts.limit);
|
|
9129
|
-
if (!Number.isInteger(limit) || limit < 1) throw new (0,
|
|
10382
|
+
if (!Number.isInteger(limit) || limit < 1) throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`limit must be an integer >= 1 (got ${String(opts.limit)})`);
|
|
9130
10383
|
const bounded = Math.min(limit, 500);
|
|
9131
10384
|
const textLimit = opts.textLimit === void 0 ? 500 : Math.trunc(opts.textLimit);
|
|
9132
10385
|
if (!Number.isInteger(textLimit) || textLimit < 1) {
|
|
9133
|
-
throw new (0,
|
|
10386
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`textLimit must be an integer >= 1 (got ${String(opts.textLimit)})`);
|
|
9134
10387
|
}
|
|
9135
|
-
const ticketId =
|
|
10388
|
+
const ticketId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, id, "id");
|
|
9136
10389
|
await fetchTicket(http, ticketId, "tickets.timeline");
|
|
9137
10390
|
const dateFilters = (field) => {
|
|
9138
10391
|
const f = [{ field: "ticketID", op: "eq", value: ticketId }];
|
|
@@ -9219,14 +10472,14 @@ function isPositiveInt(v) {
|
|
|
9219
10472
|
return typeof v === "number" && Number.isInteger(v) && v > 0;
|
|
9220
10473
|
}
|
|
9221
10474
|
function namedVendorFields(err) {
|
|
9222
|
-
if (!
|
|
9223
|
-
const entries = _nullishCoalesce(
|
|
10475
|
+
if (!_chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) || err.vendorError === void 0) return [];
|
|
10476
|
+
const entries = _nullishCoalesce(_chunkIHRXVIUUcjs.parseVendorErrors.call(void 0, err.vendorError), () => ( []));
|
|
9224
10477
|
const out = /* @__PURE__ */ new Set();
|
|
9225
10478
|
for (const e of entries) if (e.field !== void 0) out.add(e.field);
|
|
9226
10479
|
return [...out];
|
|
9227
10480
|
}
|
|
9228
10481
|
function vendorDetailOf(err) {
|
|
9229
|
-
return
|
|
10482
|
+
return _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) ? _chunkIHRXVIUUcjs.formatVendorDetail.call(void 0, err.vendorError) : void 0;
|
|
9230
10483
|
}
|
|
9231
10484
|
async function fetchItem(http, path, operation) {
|
|
9232
10485
|
const res = await http.request({ method: "GET", path, operation });
|
|
@@ -9247,8 +10500,8 @@ function operationId(res) {
|
|
|
9247
10500
|
return typeof body.itemId === "number" ? body.itemId : typeof body.id === "number" ? body.id : void 0;
|
|
9248
10501
|
}
|
|
9249
10502
|
function discoveryMerge(err, body, defaults) {
|
|
9250
|
-
if (!
|
|
9251
|
-
const entries =
|
|
10503
|
+
if (!_chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) || err.vendorError === void 0) return null;
|
|
10504
|
+
const entries = _chunkIHRXVIUUcjs.parseVendorErrors.call(void 0, err.vendorError);
|
|
9252
10505
|
if (entries === void 0) return null;
|
|
9253
10506
|
for (const entry of entries) {
|
|
9254
10507
|
const field = entry.field;
|
|
@@ -9260,7 +10513,7 @@ function discoveryMerge(err, body, defaults) {
|
|
|
9260
10513
|
}
|
|
9261
10514
|
function stepErrorText(code, err) {
|
|
9262
10515
|
const detail = vendorDetailOf(err);
|
|
9263
|
-
const base =
|
|
10516
|
+
const base = _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) ? err.message : String(err);
|
|
9264
10517
|
return detail ? `${code}: ${detail}` : `${code}: ${base}`;
|
|
9265
10518
|
}
|
|
9266
10519
|
var DEFAULT_TICKET_PRIORITY = 3;
|
|
@@ -9269,7 +10522,7 @@ var DEFAULT_NOTE_TYPE = 1;
|
|
|
9269
10522
|
var DEFAULT_PUBLISH = 1;
|
|
9270
10523
|
var PUBLISH_VALUES = /* @__PURE__ */ new Set([1, 2, 4]);
|
|
9271
10524
|
var SAFE_TICKET_CREATE_DEFAULTS = {};
|
|
9272
|
-
var QueueRequiredError = class extends
|
|
10525
|
+
var QueueRequiredError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
9273
10526
|
constructor(message, options = {}) {
|
|
9274
10527
|
super(message, {
|
|
9275
10528
|
code: "QUEUE_REQUIRED",
|
|
@@ -9280,13 +10533,13 @@ var QueueRequiredError = class extends _chunkYKEX4SK7cjs.AutotaskError {
|
|
|
9280
10533
|
this.name = "QueueRequiredError";
|
|
9281
10534
|
}
|
|
9282
10535
|
};
|
|
9283
|
-
var TicketResourceInvalidError = class extends
|
|
10536
|
+
var TicketResourceInvalidError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
9284
10537
|
constructor(message, options = {}) {
|
|
9285
10538
|
super(message, { code: "RESOURCE_INVALID", category: "validation", ...options });
|
|
9286
10539
|
this.name = "TicketResourceInvalidError";
|
|
9287
10540
|
}
|
|
9288
10541
|
};
|
|
9289
|
-
var TicketCreateValidationFailedError = class extends
|
|
10542
|
+
var TicketCreateValidationFailedError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
9290
10543
|
/** The vendor-named fields (empty when the 500 body named nothing parseable). */
|
|
9291
10544
|
|
|
9292
10545
|
constructor(message, vendorFields, options = {}) {
|
|
@@ -9296,43 +10549,43 @@ var TicketCreateValidationFailedError = class extends _chunkYKEX4SK7cjs.Autotask
|
|
|
9296
10549
|
}
|
|
9297
10550
|
};
|
|
9298
10551
|
async function openWithNoteAndAssign(resource, params, note, assign, opts, http) {
|
|
9299
|
-
const companyID =
|
|
9300
|
-
const title = _optionalChain([params, 'optionalAccess',
|
|
10552
|
+
const companyID = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, _optionalChain([params, 'optionalAccess', _54 => _54.companyID]), "params.companyID");
|
|
10553
|
+
const title = _optionalChain([params, 'optionalAccess', _55 => _55.title]);
|
|
9301
10554
|
if (typeof title !== "string" || title.trim() === "") {
|
|
9302
|
-
throw new (0,
|
|
10555
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("openWithNoteAndAssign: params.title is required (a non-empty string)", { operation: OP_OPEN });
|
|
9303
10556
|
}
|
|
9304
10557
|
const priority = _nullishCoalesce(params.priority, () => ( DEFAULT_TICKET_PRIORITY));
|
|
9305
10558
|
const status = _nullishCoalesce(params.status, () => ( DEFAULT_TICKET_STATUS));
|
|
9306
10559
|
if (!isPositiveInt(priority)) {
|
|
9307
|
-
throw new (0,
|
|
10560
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`openWithNoteAndAssign: params.priority must be a positive integer (got ${String(params.priority)})`, { operation: OP_OPEN });
|
|
9308
10561
|
}
|
|
9309
10562
|
if (!isPositiveInt(status)) {
|
|
9310
|
-
throw new (0,
|
|
10563
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`openWithNoteAndAssign: params.status must be a positive integer (got ${String(params.status)})`, { operation: OP_OPEN });
|
|
9311
10564
|
}
|
|
9312
10565
|
if (params.queueID !== void 0 && !isPositiveInt(params.queueID)) {
|
|
9313
|
-
throw new (0,
|
|
10566
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`openWithNoteAndAssign: params.queueID must be a positive integer (got ${String(params.queueID)})`, { operation: OP_OPEN });
|
|
9314
10567
|
}
|
|
9315
10568
|
if (note !== void 0) {
|
|
9316
10569
|
if (typeof note.description !== "string" || note.description.trim() === "") {
|
|
9317
|
-
throw new (0,
|
|
10570
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("openWithNoteAndAssign: note.description is required (a non-empty string)", { operation: OP_OPEN });
|
|
9318
10571
|
}
|
|
9319
10572
|
if (typeof note.title !== "string" || note.title.trim() === "") {
|
|
9320
|
-
throw new (0,
|
|
10573
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("openWithNoteAndAssign: note.title is required (a non-empty string) \u2014 the ww29 scoped note create 500s without it (S12-A live-verified: Missing Required Field: title; the S11-B proven note body is { title, description, noteType: 1, publish: 1 })", { operation: OP_OPEN });
|
|
9321
10574
|
}
|
|
9322
10575
|
if (note.noteType !== void 0 && !isPositiveInt(note.noteType)) {
|
|
9323
|
-
throw new (0,
|
|
10576
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`openWithNoteAndAssign: note.noteType must be a positive integer (got ${String(note.noteType)})`, { operation: OP_OPEN });
|
|
9324
10577
|
}
|
|
9325
10578
|
if (note.publish !== void 0 && !PUBLISH_VALUES.has(note.publish)) {
|
|
9326
|
-
throw new (0,
|
|
10579
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`openWithNoteAndAssign: note.publish must be an integer picklist value 1/2/4 (got ${String(note.publish)} \u2014 NOT a boolean)`, { operation: OP_OPEN });
|
|
9327
10580
|
}
|
|
9328
10581
|
}
|
|
9329
|
-
const assignee = assign === void 0 ? void 0 :
|
|
10582
|
+
const assignee = assign === void 0 ? void 0 : _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, assign.resourceID, "assign.resourceID");
|
|
9330
10583
|
if (assign !== void 0 && assignee !== void 0 && (typeof assignee === "number" ? assignee < 1 : false)) {
|
|
9331
|
-
throw new (0,
|
|
10584
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`openWithNoteAndAssign: assign.resourceID must be a positive integer (got ${String(assignee)})`, { operation: OP_OPEN });
|
|
9332
10585
|
}
|
|
9333
|
-
const roleID = _optionalChain([assign, 'optionalAccess',
|
|
10586
|
+
const roleID = _optionalChain([assign, 'optionalAccess', _56 => _56.roleID]);
|
|
9334
10587
|
if (assign !== void 0 && !isPositiveInt(roleID)) {
|
|
9335
|
-
throw new (0,
|
|
10588
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("openWithNoteAndAssign: assign.roleID is required (a positive integer) \u2014 the ww29 vendor requires BOTH assignedResourceID and assignedResourceRoleID when assigning a resource (S12-A live-verified: Data violation: When assigning a Resource, you must assign both a assignedResourceID and assignedResourceRoleID)", { operation: OP_OPEN });
|
|
9336
10589
|
}
|
|
9337
10590
|
if (assign !== void 0 && assignee !== void 0) {
|
|
9338
10591
|
const rid = assignee;
|
|
@@ -9367,7 +10620,7 @@ async function openWithNoteAndAssign(resource, params, note, assign, opts, http)
|
|
|
9367
10620
|
if (assign !== void 0) {
|
|
9368
10621
|
warnings.push(`the assignment is the v0.6.0 MERGE update (unredacted GET + collection PUT, 2 wire) setting assignedResourceID ${String(assignee)} + assignedResourceRoleID ${String(roleID)} (the vendor requires both \u2014 S12-A live-verified); a failure lands in steps[] as ASSIGN_FAILED (the applied ticketId is still returned).`);
|
|
9369
10622
|
}
|
|
9370
|
-
return
|
|
10623
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0,
|
|
9371
10624
|
{
|
|
9372
10625
|
operation: OP_OPEN,
|
|
9373
10626
|
method: "POST",
|
|
@@ -9409,8 +10662,8 @@ async function openWithNoteAndAssign(resource, params, note, assign, opts, http)
|
|
|
9409
10662
|
`openWithNoteAndAssign: the vendor rejected the ticket create naming 'queueID' (the ww29 live-required set is { title, status, priority, companyID, queueID }) and the node never guesses a queue${detail ? ` \u2014 ${detail}` : ""}`,
|
|
9410
10663
|
{
|
|
9411
10664
|
operation: OP_OPEN,
|
|
9412
|
-
httpStatus:
|
|
9413
|
-
vendorError:
|
|
10665
|
+
httpStatus: _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) ? err.httpStatus : void 0,
|
|
10666
|
+
vendorError: _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) ? err.vendorError : void 0
|
|
9414
10667
|
}
|
|
9415
10668
|
);
|
|
9416
10669
|
}
|
|
@@ -9425,8 +10678,8 @@ async function openWithNoteAndAssign(resource, params, note, assign, opts, http)
|
|
|
9425
10678
|
named,
|
|
9426
10679
|
{
|
|
9427
10680
|
operation: OP_OPEN,
|
|
9428
|
-
httpStatus:
|
|
9429
|
-
vendorError:
|
|
10681
|
+
httpStatus: _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) ? err.httpStatus : void 0,
|
|
10682
|
+
vendorError: _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) ? err.vendorError : void 0,
|
|
9430
10683
|
resourceIds: [companyID]
|
|
9431
10684
|
}
|
|
9432
10685
|
);
|
|
@@ -9448,10 +10701,10 @@ async function openWithNoteAndAssign(resource, params, note, assign, opts, http)
|
|
|
9448
10701
|
try {
|
|
9449
10702
|
const current = await fetchItemUnredacted(http, `/V1.0/Tickets/${ticketId}`, OP_OPEN);
|
|
9450
10703
|
if (current === null) {
|
|
9451
|
-
throw new (0,
|
|
10704
|
+
throw new (0, _chunkIHRXVIUUcjs.NotFoundError)(`openWithNoteAndAssign: ticket ${ticketId} vanished between the create and the assign merge read`, { operation: OP_OPEN, resourceIds: [ticketId] });
|
|
9452
10705
|
}
|
|
9453
10706
|
ticketNumber = typeof current.ticketNumber === "string" ? current.ticketNumber : null;
|
|
9454
|
-
const merged =
|
|
10707
|
+
const merged = _chunkIHRXVIUUcjs.mergePartialBody.call(void 0, current, { id: ticketId, assignedResourceID: assignee, assignedResourceRoleID: roleID });
|
|
9455
10708
|
merged.id = ticketId;
|
|
9456
10709
|
await http.request({ method: "PUT", path: "/V1.0/Tickets", body: merged, operation: OP_OPEN });
|
|
9457
10710
|
assigned = true;
|
|
@@ -9472,7 +10725,7 @@ async function openWithNoteAndAssign(resource, params, note, assign, opts, http)
|
|
|
9472
10725
|
var STATUS_REQUIRED_FIELDS = {
|
|
9473
10726
|
// <discovery output lands here — e.g. 8: { requiredFields: ['dueDateTime'], safeDefaults: { dueDateTime: '<now>' } }>
|
|
9474
10727
|
};
|
|
9475
|
-
var StatusUnknownError = class extends
|
|
10728
|
+
var StatusUnknownError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
9476
10729
|
/** The live picklist size (the message names it; the values + labels are via operations.fieldCatalog with labels: true). */
|
|
9477
10730
|
|
|
9478
10731
|
constructor(message, options = {}) {
|
|
@@ -9486,7 +10739,7 @@ var StatusUnknownError = class extends _chunkYKEX4SK7cjs.AutotaskError {
|
|
|
9486
10739
|
this.picklistCount = _nullishCoalesce(options.picklistCount, () => ( 0));
|
|
9487
10740
|
}
|
|
9488
10741
|
};
|
|
9489
|
-
var StatusFieldsRequiredError = class extends
|
|
10742
|
+
var StatusFieldsRequiredError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
9490
10743
|
|
|
9491
10744
|
|
|
9492
10745
|
|
|
@@ -9515,26 +10768,26 @@ async function readLiveStatusSet(resource) {
|
|
|
9515
10768
|
}
|
|
9516
10769
|
var GUARD_DEGRADED_WARNING = "the tenant's live status picklist metadata was unavailable (the local guard is degraded for this call \u2014 the W-A4 wall or a metadata failure); the vendor's own validation is the final authority on the status value";
|
|
9517
10770
|
async function changeStatus(resource, id, targetStatus, fields, opts, http) {
|
|
9518
|
-
const ticketId =
|
|
10771
|
+
const ticketId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, id, "id");
|
|
9519
10772
|
if (!isPositiveInt(targetStatus)) {
|
|
9520
|
-
throw new (0,
|
|
10773
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`changeStatus: targetStatus must be a positive integer (got ${String(targetStatus)})`, { operation: OP_STATUS });
|
|
9521
10774
|
}
|
|
9522
10775
|
let liveStatus = null;
|
|
9523
10776
|
try {
|
|
9524
10777
|
const ids = await readLiveStatusSet(resource);
|
|
9525
10778
|
if (ids.size > 0) liveStatus = ids;
|
|
9526
10779
|
} catch (err) {
|
|
9527
|
-
if (!
|
|
10780
|
+
if (!_chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) || err.code === "ABORTED") throw err;
|
|
9528
10781
|
}
|
|
9529
10782
|
if (liveStatus !== null && !liveStatus.has(targetStatus)) {
|
|
9530
|
-
_optionalChain([http, 'access',
|
|
10783
|
+
_optionalChain([http, 'access', _57 => _57.fieldCache, 'optionalAccess', _58 => _58.invalidate, 'call', _59 => _59("tickets")]);
|
|
9531
10784
|
let freshStatus = null;
|
|
9532
10785
|
let reReadFailed = false;
|
|
9533
10786
|
try {
|
|
9534
10787
|
const freshIds = await readLiveStatusSet(resource);
|
|
9535
10788
|
if (freshIds.size > 0) freshStatus = freshIds;
|
|
9536
10789
|
} catch (err) {
|
|
9537
|
-
if (!
|
|
10790
|
+
if (!_chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) || err.code === "ABORTED") throw err;
|
|
9538
10791
|
freshStatus = null;
|
|
9539
10792
|
reReadFailed = true;
|
|
9540
10793
|
}
|
|
@@ -9551,16 +10804,16 @@ async function changeStatus(resource, id, targetStatus, fields, opts, http) {
|
|
|
9551
10804
|
}
|
|
9552
10805
|
const guardDegraded = liveStatus === null;
|
|
9553
10806
|
if (fields !== void 0 && (typeof fields !== "object" || fields === null || Array.isArray(fields))) {
|
|
9554
|
-
throw new (0,
|
|
10807
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("changeStatus: fields must be a plain object of ticket fields (or omitted)", { operation: OP_STATUS });
|
|
9555
10808
|
}
|
|
9556
10809
|
const current = await fetchItemUnredacted(http, `/V1.0/Tickets/${ticketId}`, OP_STATUS);
|
|
9557
10810
|
if (current === null) {
|
|
9558
|
-
throw new (0,
|
|
10811
|
+
throw new (0, _chunkIHRXVIUUcjs.NotFoundError)(`changeStatus: ticket ${ticketId} was not found (tickets.get returned item: null)`, { operation: OP_STATUS, resourceIds: [ticketId] });
|
|
9559
10812
|
}
|
|
9560
10813
|
const previousStatus = typeof current.status === "number" ? current.status : null;
|
|
9561
10814
|
if (previousStatus === targetStatus) {
|
|
9562
10815
|
if (opts.dryRun === true) {
|
|
9563
|
-
return
|
|
10816
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0,
|
|
9564
10817
|
{
|
|
9565
10818
|
operation: OP_STATUS,
|
|
9566
10819
|
method: "PUT",
|
|
@@ -9593,7 +10846,7 @@ async function changeStatus(resource, id, targetStatus, fields, opts, http) {
|
|
|
9593
10846
|
for (const field of mapEntry.requiredFields) {
|
|
9594
10847
|
if (mergeData[field] !== void 0) continue;
|
|
9595
10848
|
if (current[field] !== null && current[field] !== void 0) continue;
|
|
9596
|
-
const safe = _optionalChain([mapEntry, 'access',
|
|
10849
|
+
const safe = _optionalChain([mapEntry, 'access', _60 => _60.safeDefaults, 'optionalAccess', _61 => _61[field]]);
|
|
9597
10850
|
if (safe === void 0) {
|
|
9598
10851
|
throw new StatusFieldsRequiredError(
|
|
9599
10852
|
`changeStatus: status ${targetStatus} requires the field '${field}' and the live-discovered map has no proven-safe default for it \u2014 the op is safe-without-the-map (never a blind full update): supply the value in fields and retry`,
|
|
@@ -9614,7 +10867,7 @@ async function changeStatus(resource, id, targetStatus, fields, opts, http) {
|
|
|
9614
10867
|
if (mapEntry === void 0) {
|
|
9615
10868
|
warnings.push(`status ${targetStatus} has no entry in the live-discovered required-field map yet \u2014 if the vendor 500 names a required field without a safe default, the apply throws the typed STATUS_FIELDS_REQUIRED (the caller supplies the value; never a blind retry).`);
|
|
9616
10869
|
}
|
|
9617
|
-
return
|
|
10870
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0,
|
|
9618
10871
|
{
|
|
9619
10872
|
operation: OP_STATUS,
|
|
9620
10873
|
method: "PUT",
|
|
@@ -9632,8 +10885,8 @@ async function changeStatus(resource, id, targetStatus, fields, opts, http) {
|
|
|
9632
10885
|
{ redactPersonalData: http.redactPersonalData }
|
|
9633
10886
|
);
|
|
9634
10887
|
}
|
|
9635
|
-
const safeDefaults = _nullishCoalesce(_optionalChain([mapEntry, 'optionalAccess',
|
|
9636
|
-
const body =
|
|
10888
|
+
const safeDefaults = _nullishCoalesce(_optionalChain([mapEntry, 'optionalAccess', _62 => _62.safeDefaults]), () => ( {}));
|
|
10889
|
+
const body = _chunkIHRXVIUUcjs.mergePartialBody.call(void 0, current, mergeData);
|
|
9637
10890
|
body.id = ticketId;
|
|
9638
10891
|
let merges = 0;
|
|
9639
10892
|
for (; ; ) {
|
|
@@ -9657,8 +10910,8 @@ async function changeStatus(resource, id, targetStatus, fields, opts, http) {
|
|
|
9657
10910
|
{ vendorFields: named, currentStatus: previousStatus, targetStatus, currentValues },
|
|
9658
10911
|
{
|
|
9659
10912
|
operation: OP_STATUS,
|
|
9660
|
-
httpStatus:
|
|
9661
|
-
vendorError:
|
|
10913
|
+
httpStatus: _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) ? err.httpStatus : void 0,
|
|
10914
|
+
vendorError: _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) ? err.vendorError : void 0,
|
|
9662
10915
|
resourceIds: [ticketId]
|
|
9663
10916
|
}
|
|
9664
10917
|
);
|
|
@@ -9668,7 +10921,7 @@ async function changeStatus(resource, id, targetStatus, fields, opts, http) {
|
|
|
9668
10921
|
}
|
|
9669
10922
|
const verify = await fetchItem(http, `/V1.0/Tickets/${ticketId}`, OP_STATUS);
|
|
9670
10923
|
if (verify === null) {
|
|
9671
|
-
throw new (0,
|
|
10924
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskError)(`changeStatus: the post-PUT read-back found no ticket ${ticketId} (the PUT 200ed but the record is gone)`, {
|
|
9672
10925
|
code: "INVALID_RESPONSE",
|
|
9673
10926
|
category: "server",
|
|
9674
10927
|
operation: OP_STATUS,
|
|
@@ -9677,7 +10930,7 @@ async function changeStatus(resource, id, targetStatus, fields, opts, http) {
|
|
|
9677
10930
|
}
|
|
9678
10931
|
const finalStatus = typeof verify.status === "number" ? verify.status : null;
|
|
9679
10932
|
if (finalStatus !== targetStatus) {
|
|
9680
|
-
throw new (0,
|
|
10933
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskError)(
|
|
9681
10934
|
`changeStatus: the post-PUT read-back shows status ${_nullishCoalesce(finalStatus, () => ( "unknown"))} (the vendor 200ed the PUT but did not apply ${targetStatus} \u2014 the F-A1 lesson: the 200 proves nothing)`,
|
|
9682
10935
|
{
|
|
9683
10936
|
code: "INVALID_RESPONSE",
|
|
@@ -9695,7 +10948,7 @@ var DEFAULT_PART_LIMIT = 50;
|
|
|
9695
10948
|
function partLimit(value, name) {
|
|
9696
10949
|
const n = value === void 0 ? DEFAULT_PART_LIMIT : Math.trunc(value);
|
|
9697
10950
|
if (!Number.isInteger(n) || n < 1) {
|
|
9698
|
-
throw new (0,
|
|
10951
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`fullContext: ${name} must be an integer >= 1 (got ${String(value)})`);
|
|
9699
10952
|
}
|
|
9700
10953
|
return n;
|
|
9701
10954
|
}
|
|
@@ -9711,7 +10964,7 @@ async function fullContext(resource, id, opts = {}, http) {
|
|
|
9711
10964
|
const noteLimit = partLimit(opts.noteLimit, "noteLimit");
|
|
9712
10965
|
const timeEntryLimit = partLimit(opts.timeEntryLimit, "timeEntryLimit");
|
|
9713
10966
|
const textLimit = partLimit(opts.textLimit, "textLimit");
|
|
9714
|
-
const ticketId =
|
|
10967
|
+
const ticketId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, id, "id");
|
|
9715
10968
|
const ctx = await resource.getContext(ticketId);
|
|
9716
10969
|
const op = "tickets.fullContext";
|
|
9717
10970
|
const ticketFilter = [{ field: "ticketID", op: "eq", value: ticketId }];
|
|
@@ -9765,7 +11018,7 @@ async function fullContext(resource, id, opts = {}, http) {
|
|
|
9765
11018
|
result.truncated = result.truncated || part.capped || historyRows.some((h) => h.detailTruncated === true);
|
|
9766
11019
|
}
|
|
9767
11020
|
if (opts.names === true) {
|
|
9768
|
-
const builder =
|
|
11021
|
+
const builder = _chunkIHRXVIUUcjs.createNamePlan.call(void 0, _chunkIHRXVIUUcjs.TICKET_LABEL_FIELDS);
|
|
9769
11022
|
const t = ctx.ticket;
|
|
9770
11023
|
builder.addResource(t["creatorResourceID"]);
|
|
9771
11024
|
builder.addFk("contract", t["contractID"]);
|
|
@@ -9777,20 +11030,20 @@ async function fullContext(resource, id, opts = {}, http) {
|
|
|
9777
11030
|
builder.addFk("billingCode", e["billingCodeID"]);
|
|
9778
11031
|
builder.addFk("contract", e["contractID"]);
|
|
9779
11032
|
}
|
|
9780
|
-
const names = await
|
|
11033
|
+
const names = await _chunkIHRXVIUUcjs.resolveCompositeNames.call(void 0, http, builder.plan(), { maxNameReads: opts.maxNameReads });
|
|
9781
11034
|
const ticketRow = { ...ctx.ticket };
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
for (const f of
|
|
11035
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, ticketRow, "creatorResourceID", (v) => names.resourceName(v));
|
|
11036
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, ticketRow, "contractID", (v) => names.recordName("contract", v));
|
|
11037
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, ticketRow, "billingCodeID", (v) => names.recordName("billingCode", v));
|
|
11038
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, ticketRow, "assignedResourceRoleID", (v) => names.recordName("role", v));
|
|
11039
|
+
for (const f of _chunkIHRXVIUUcjs.TICKET_LABEL_FIELDS) _chunkIHRXVIUUcjs.addLabelSibling.call(void 0, ticketRow, f, names);
|
|
9787
11040
|
result.ticket = ticketRow;
|
|
9788
11041
|
result.timeEntries.items = entriesPart.items.map((e) => {
|
|
9789
11042
|
const row = { ...e };
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
11043
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, row, "resourceID", (v) => names.resourceName(v));
|
|
11044
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, row, "roleID", (v) => names.recordName("role", v));
|
|
11045
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, row, "billingCodeID", (v) => names.recordName("billingCode", v));
|
|
11046
|
+
_chunkIHRXVIUUcjs.addNameSibling.call(void 0, row, "contractID", (v) => names.recordName("contract", v));
|
|
9794
11047
|
return row;
|
|
9795
11048
|
});
|
|
9796
11049
|
result.names = names.section;
|
|
@@ -9800,7 +11053,7 @@ async function fullContext(resource, id, opts = {}, http) {
|
|
|
9800
11053
|
}
|
|
9801
11054
|
|
|
9802
11055
|
// src/resources/tickets.ts
|
|
9803
|
-
var TicketsResource = class extends
|
|
11056
|
+
var TicketsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
9804
11057
|
constructor(http, pageSize) {
|
|
9805
11058
|
super(http, {
|
|
9806
11059
|
key: "tickets",
|
|
@@ -9906,7 +11159,7 @@ var TicketsResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
9906
11159
|
};
|
|
9907
11160
|
|
|
9908
11161
|
// src/resources/ticket_webhooks.ts
|
|
9909
|
-
var TicketWebhooksResource = class extends
|
|
11162
|
+
var TicketWebhooksResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
9910
11163
|
constructor(http, pageSize) {
|
|
9911
11164
|
super(http, {
|
|
9912
11165
|
key: "ticket_webhooks",
|
|
@@ -9992,62 +11245,62 @@ async function queryTimeEntries(_resource, filter, limit, operation, http) {
|
|
|
9992
11245
|
body: { MaxRecords: limit, filter },
|
|
9993
11246
|
operation
|
|
9994
11247
|
});
|
|
9995
|
-
const { items, pageDetails } =
|
|
11248
|
+
const { items, pageDetails } = _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res);
|
|
9996
11249
|
return { items, hasMore: pageDetails.nextPageUrl != null };
|
|
9997
11250
|
}
|
|
9998
11251
|
async function windowQuery3(_resource, kind, http, opts) {
|
|
9999
|
-
const now = _nullishCoalesce(_optionalChain([opts, 'optionalAccess',
|
|
10000
|
-
const tz = _optionalChain([opts, 'optionalAccess',
|
|
11252
|
+
const now = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _63 => _63.now]), () => ( /* @__PURE__ */ new Date()));
|
|
11253
|
+
const tz = _optionalChain([opts, 'optionalAccess', _64 => _64.tz]) === void 0 ? void 0 : validateZone(opts.tz, `time_entries.${kind}`);
|
|
10001
11254
|
const { from, to } = dateWindowBounds(kind, now, tz);
|
|
10002
11255
|
const filter = [
|
|
10003
11256
|
{ field: "dateWorked", op: "gte", value: from },
|
|
10004
11257
|
{ field: "dateWorked", op: "lte", value: to }
|
|
10005
11258
|
];
|
|
10006
|
-
const { items } = await queryTimeEntries(_resource, filter, clampWindowLimit(_optionalChain([opts, 'optionalAccess',
|
|
11259
|
+
const { items } = await queryTimeEntries(_resource, filter, clampWindowLimit(_optionalChain([opts, 'optionalAccess', _65 => _65.limit])), `time_entries.${kind}`, http);
|
|
10007
11260
|
return items;
|
|
10008
11261
|
}
|
|
10009
11262
|
async function customRange3(_resource, from, to, http, opts) {
|
|
10010
|
-
const zone = _optionalChain([opts, 'optionalAccess',
|
|
11263
|
+
const zone = _optionalChain([opts, 'optionalAccess', _66 => _66.tz]) === void 0 ? void 0 : validateZone(opts.tz, "time_entries.customRange");
|
|
10011
11264
|
const fromB = customRangeDay(from, "from", zone, "customRange");
|
|
10012
11265
|
const toB = customRangeDay(to, "to", zone, "customRange");
|
|
10013
11266
|
if (fromB.ms > toB.ms) {
|
|
10014
|
-
throw new (0,
|
|
11267
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("customRange: from must not be after to");
|
|
10015
11268
|
}
|
|
10016
11269
|
const toEndMs = zone === void 0 ? toB.ms + DAY_MS2 - 1 : localDayEndMs(toB.y, toB.mo, toB.d, zone);
|
|
10017
11270
|
const filter = [
|
|
10018
11271
|
{ field: "dateWorked", op: "gte", value: iso2(fromB.ms) },
|
|
10019
11272
|
{ field: "dateWorked", op: "lte", value: iso2(toEndMs) }
|
|
10020
11273
|
];
|
|
10021
|
-
const { items } = await queryTimeEntries(_resource, filter, clampWindowLimit(_optionalChain([opts, 'optionalAccess',
|
|
11274
|
+
const { items } = await queryTimeEntries(_resource, filter, clampWindowLimit(_optionalChain([opts, 'optionalAccess', _67 => _67.limit])), "time_entries.customRange", http);
|
|
10022
11275
|
return items;
|
|
10023
11276
|
}
|
|
10024
11277
|
async function postedDateStatusQuery(_resource, mode, http, opts) {
|
|
10025
11278
|
const filter = [
|
|
10026
11279
|
{ field: "postedDate", op: mode === "posted" ? "exist" : "notExist" }
|
|
10027
11280
|
];
|
|
10028
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
11281
|
+
if (_optionalChain([opts, 'optionalAccess', _68 => _68.ticketID]) !== void 0) filter.push({ field: "ticketID", op: "eq", value: opts.ticketID });
|
|
10029
11282
|
const operation = mode === "posted" ? "time_entries.getPosted" : "time_entries.getUnposted";
|
|
10030
|
-
const { items } = await queryTimeEntries(_resource, filter, clampWindowLimit(_optionalChain([opts, 'optionalAccess',
|
|
11283
|
+
const { items } = await queryTimeEntries(_resource, filter, clampWindowLimit(_optionalChain([opts, 'optionalAccess', _69 => _69.limit])), operation, http);
|
|
10031
11284
|
return items;
|
|
10032
11285
|
}
|
|
10033
11286
|
async function postedWithin(_resource, from, to, http, opts, opLabel = "time_entries.postedWithin") {
|
|
10034
11287
|
const OP2 = opLabel;
|
|
10035
|
-
const zone = _optionalChain([opts, 'optionalAccess',
|
|
11288
|
+
const zone = _optionalChain([opts, 'optionalAccess', _70 => _70.tz]) === void 0 ? void 0 : validateZone(opts.tz, OP2);
|
|
10036
11289
|
const fromB = customRangeDay(from, "from", zone, OP2);
|
|
10037
11290
|
const toB = customRangeDay(to, "to", zone, OP2);
|
|
10038
11291
|
if (fromB.ms > toB.ms) {
|
|
10039
|
-
throw new (0,
|
|
11292
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(`${OP2}: from (${iso2(fromB.ms)}) must not be after to (${iso2(toB.ms)})`, { operation: OP2 });
|
|
10040
11293
|
}
|
|
10041
11294
|
const windowToMs = zone === void 0 ? toB.ms + DAY_MS2 - 1 : localDayEndMs(toB.y, toB.mo, toB.d, zone);
|
|
10042
11295
|
const filter = [
|
|
10043
11296
|
{ field: "dateWorked", op: "gte", value: iso2(fromB.ms) },
|
|
10044
11297
|
{ field: "dateWorked", op: "lte", value: iso2(windowToMs) }
|
|
10045
11298
|
];
|
|
10046
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
10047
|
-
else if (_optionalChain([opts, 'optionalAccess',
|
|
10048
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
10049
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
10050
|
-
const { items, hasMore } = await queryTimeEntries(_resource, filter, clampWindowLimit(_optionalChain([opts, 'optionalAccess',
|
|
11299
|
+
if (_optionalChain([opts, 'optionalAccess', _71 => _71.posted]) === true) filter.push({ field: "postedDate", op: "exist" });
|
|
11300
|
+
else if (_optionalChain([opts, 'optionalAccess', _72 => _72.posted]) === false) filter.push({ field: "postedDate", op: "notExist" });
|
|
11301
|
+
if (_optionalChain([opts, 'optionalAccess', _73 => _73.ticketID]) !== void 0) filter.push({ field: "ticketID", op: "eq", value: opts.ticketID });
|
|
11302
|
+
if (_optionalChain([opts, 'optionalAccess', _74 => _74.resourceID]) !== void 0) filter.push({ field: "resourceID", op: "eq", value: opts.resourceID });
|
|
11303
|
+
const { items, hasMore } = await queryTimeEntries(_resource, filter, clampWindowLimit(_optionalChain([opts, 'optionalAccess', _75 => _75.limit])), OP2, http);
|
|
10051
11304
|
let postedCount = 0;
|
|
10052
11305
|
for (const item of items) {
|
|
10053
11306
|
const postedDate = item.postedDate;
|
|
@@ -10103,13 +11356,13 @@ var LINKAGE_OWNED_FIELDS = /* @__PURE__ */ new Set([
|
|
|
10103
11356
|
"roleID"
|
|
10104
11357
|
]);
|
|
10105
11358
|
var TIME_WINDOW_FIELDS = /* @__PURE__ */ new Set(["dateWorked", "startDateTime", "endDateTime", "hoursWorked"]);
|
|
10106
|
-
var ResourceInvalidError = class extends
|
|
11359
|
+
var ResourceInvalidError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
10107
11360
|
constructor(message, options = {}) {
|
|
10108
11361
|
super(message, { code: "RESOURCE_INVALID", category: "validation", ...options });
|
|
10109
11362
|
this.name = "ResourceInvalidError";
|
|
10110
11363
|
}
|
|
10111
11364
|
};
|
|
10112
|
-
var AllocationCodeError = class extends
|
|
11365
|
+
var AllocationCodeError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
10113
11366
|
/** The failure kind (the machine code is `ALLOCATION_CODE_<KIND>`). */
|
|
10114
11367
|
|
|
10115
11368
|
constructor(kind, message, options = {}) {
|
|
@@ -10118,7 +11371,7 @@ var AllocationCodeError = class extends _chunkYKEX4SK7cjs.AutotaskError {
|
|
|
10118
11371
|
this.kind = kind;
|
|
10119
11372
|
}
|
|
10120
11373
|
};
|
|
10121
|
-
var NoApplicableAllocationCodeError = class extends
|
|
11374
|
+
var NoApplicableAllocationCodeError = class extends _chunkIHRXVIUUcjs.AutotaskError {
|
|
10122
11375
|
/** The structured blocker details (filters tried + department sets). */
|
|
10123
11376
|
|
|
10124
11377
|
constructor(details, options = {}) {
|
|
@@ -10144,7 +11397,7 @@ async function boundedQuery(http, path, filter, totalCap, operation) {
|
|
|
10144
11397
|
let pages = 0;
|
|
10145
11398
|
for (; ; ) {
|
|
10146
11399
|
if (pages >= PAGE_GUARD) {
|
|
10147
|
-
throw new (0,
|
|
11400
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskError)(`createForResource: the ${path} walk hit the ${PAGE_GUARD}-page guard`, {
|
|
10148
11401
|
code: "RESOLUTION_TRUNCATED",
|
|
10149
11402
|
category: "resolution",
|
|
10150
11403
|
operation,
|
|
@@ -10155,11 +11408,11 @@ async function boundedQuery(http, path, filter, totalCap, operation) {
|
|
|
10155
11408
|
const res = await http.request({
|
|
10156
11409
|
method: "POST",
|
|
10157
11410
|
idempotent: true,
|
|
10158
|
-
path: isFirst ? path :
|
|
11411
|
+
path: isFirst ? path : _chunkIHRXVIUUcjs.cursorToPath.call(void 0, http.baseUrl, cursor),
|
|
10159
11412
|
body: { MaxRecords: pageSize, filter },
|
|
10160
11413
|
operation
|
|
10161
11414
|
});
|
|
10162
|
-
const { items: pageItems, pageDetails } =
|
|
11415
|
+
const { items: pageItems, pageDetails } = _chunkIHRXVIUUcjs.unwrapItems.call(void 0, res, operation);
|
|
10163
11416
|
items.push(...pageItems);
|
|
10164
11417
|
pages += 1;
|
|
10165
11418
|
if (items.length >= totalCap) break;
|
|
@@ -10272,8 +11525,8 @@ function windowDefaults(params) {
|
|
|
10272
11525
|
};
|
|
10273
11526
|
}
|
|
10274
11527
|
async function createForResource(resource, resourceID, params, opts = {}, http) {
|
|
10275
|
-
const rid =
|
|
10276
|
-
const pin = (value, label) => typeof value === "number" ?
|
|
11528
|
+
const rid = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, resourceID, "resourceID");
|
|
11529
|
+
const pin = (value, label) => typeof value === "number" ? _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, value, label) : void 0;
|
|
10277
11530
|
const pins = {
|
|
10278
11531
|
code: pin(params.internallAllocationCodeID, "internallAllocationCodeID"),
|
|
10279
11532
|
ticket: pin(params.ticketID, "ticketID"),
|
|
@@ -10282,19 +11535,19 @@ async function createForResource(resource, resourceID, params, opts = {}, http)
|
|
|
10282
11535
|
};
|
|
10283
11536
|
const pinCount = [pins.code, pins.ticket, pins.task].filter((v) => v !== void 0).length;
|
|
10284
11537
|
if (pinCount > 1) {
|
|
10285
|
-
throw new (0,
|
|
11538
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
10286
11539
|
"createForResource: exactly one linkage pin is honoured (internallAllocationCodeID | ticketID | taskID) \u2014 the vendor gate requires exactly one; pass one pin (or none for the default internal linkage)",
|
|
10287
11540
|
{ operation: OP }
|
|
10288
11541
|
);
|
|
10289
11542
|
}
|
|
10290
11543
|
if (pins.role !== void 0 && pins.code !== void 0) {
|
|
10291
|
-
throw new (0,
|
|
11544
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
10292
11545
|
"createForResource: a pinned roleID is only meaningful with the task/ticket linkage (internallAllocationCodeID pins the internal linkage and owns the code) \u2014 drop one",
|
|
10293
11546
|
{ operation: OP }
|
|
10294
11547
|
);
|
|
10295
11548
|
}
|
|
10296
11549
|
if (params.hoursWorked !== void 0 && (typeof params.hoursWorked !== "number" || !Number.isFinite(params.hoursWorked) || params.hoursWorked <= 0)) {
|
|
10297
|
-
throw new (0,
|
|
11550
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)(
|
|
10298
11551
|
`createForResource: hoursWorked must be a positive finite number (got ${String(params.hoursWorked)})`,
|
|
10299
11552
|
{ operation: OP }
|
|
10300
11553
|
);
|
|
@@ -10371,7 +11624,7 @@ async function createForResource(resource, resourceID, params, opts = {}, http)
|
|
|
10371
11624
|
if (usedLinkage === "internal" && linkage === "task") {
|
|
10372
11625
|
warnings.push("the task had zero applicable general allocation codes \u2014 the linkage fell back to internal (the sanctioned fallback; no taskID/roleID in the body).");
|
|
10373
11626
|
}
|
|
10374
|
-
return
|
|
11627
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0,
|
|
10375
11628
|
{
|
|
10376
11629
|
operation: OP,
|
|
10377
11630
|
method: "POST",
|
|
@@ -10410,7 +11663,7 @@ async function createForResource(resource, resourceID, params, opts = {}, http)
|
|
|
10410
11663
|
};
|
|
10411
11664
|
} catch (err) {
|
|
10412
11665
|
lastError = err;
|
|
10413
|
-
const text =
|
|
11666
|
+
const text = _chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) ? `${_nullishCoalesce(_chunkIHRXVIUUcjs.formatVendorDetail.call(void 0, err.vendorError), () => ( ""))} ${err.message}` : "";
|
|
10414
11667
|
const gate3 = ROLE_REJECTION_PATTERN.test(text);
|
|
10415
11668
|
if (usedLinkage !== "internal" && gate3) {
|
|
10416
11669
|
if (!taskRoleFetched && usedLinkage === "task" && pins.task !== void 0) {
|
|
@@ -10430,14 +11683,14 @@ async function createForResource(resource, resourceID, params, opts = {}, http)
|
|
|
10430
11683
|
throw err;
|
|
10431
11684
|
}
|
|
10432
11685
|
}
|
|
10433
|
-
if (
|
|
11686
|
+
if (_chunkIHRXVIUUcjs.isAutotaskError.call(void 0, lastError)) {
|
|
10434
11687
|
lastError.suggestedAction = (lastError.suggestedAction ? `${lastError.suggestedAction} ` : "") + `The createForResource attempt budget (${MAX_CREATE_ATTEMPTS} attempts: the role ladder + ${MAX_DISCOVERY_MERGES2} discovery merges) was exhausted \u2014 the vendor oracle rejected every candidate. Re-read the record/fields (operations.fieldCatalog, billing_codes.query with a filter) and retry with an explicit pin.`;
|
|
10435
11688
|
}
|
|
10436
11689
|
throw lastError;
|
|
10437
11690
|
}
|
|
10438
11691
|
function discoveryField(err, body, defaults) {
|
|
10439
|
-
if (!
|
|
10440
|
-
const entries =
|
|
11692
|
+
if (!_chunkIHRXVIUUcjs.isAutotaskError.call(void 0, err) || err.vendorError === void 0) return null;
|
|
11693
|
+
const entries = _chunkIHRXVIUUcjs.parseVendorErrors.call(void 0, err.vendorError);
|
|
10441
11694
|
if (entries === void 0) return null;
|
|
10442
11695
|
for (const entry of entries) {
|
|
10443
11696
|
const field = entry.field;
|
|
@@ -10450,7 +11703,7 @@ function discoveryField(err, body, defaults) {
|
|
|
10450
11703
|
}
|
|
10451
11704
|
|
|
10452
11705
|
// src/resources/time_entries.ts
|
|
10453
|
-
var TimeEntriesResource = class extends
|
|
11706
|
+
var TimeEntriesResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
10454
11707
|
constructor(http, pageSize) {
|
|
10455
11708
|
super(http, {
|
|
10456
11709
|
key: "time_entries",
|
|
@@ -10587,7 +11840,7 @@ var TimeEntriesResource = class extends _chunkYKEX4SK7cjs.BaseResource {
|
|
|
10587
11840
|
};
|
|
10588
11841
|
|
|
10589
11842
|
// src/resources/time_entry_attachments.ts
|
|
10590
|
-
var TimeEntryAttachmentsResource = class extends
|
|
11843
|
+
var TimeEntryAttachmentsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
10591
11844
|
constructor(http, pageSize) {
|
|
10592
11845
|
super(http, {
|
|
10593
11846
|
key: "time_entry_attachments",
|
|
@@ -10650,9 +11903,9 @@ var TimeEntryAttachmentsResource = class extends _chunkYKEX4SK7cjs.BaseResource
|
|
|
10650
11903
|
|
|
10651
11904
|
// src/resources/special/time_off_requests.ts
|
|
10652
11905
|
async function approve(_resource, id, opts = {}, http) {
|
|
10653
|
-
const numericId =
|
|
11906
|
+
const numericId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, id, "id");
|
|
10654
11907
|
if (opts.dryRun === true) {
|
|
10655
|
-
return
|
|
11908
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0, {
|
|
10656
11909
|
operation: "time_off_requests.approve",
|
|
10657
11910
|
method: "GET",
|
|
10658
11911
|
path: `/V1.0/TimeOffRequests/${numericId}/Approve`,
|
|
@@ -10667,16 +11920,16 @@ async function approve(_resource, id, opts = {}, http) {
|
|
|
10667
11920
|
path: `/V1.0/TimeOffRequests/${numericId}/Approve`,
|
|
10668
11921
|
operation: "time_off_requests.approve"
|
|
10669
11922
|
});
|
|
10670
|
-
return
|
|
11923
|
+
return _chunkIHRXVIUUcjs.unwrapOperation.call(void 0, res);
|
|
10671
11924
|
}
|
|
10672
11925
|
async function reject(_resource, id, reason, opts = {}, http) {
|
|
10673
|
-
const numericId =
|
|
11926
|
+
const numericId = _chunkIHRXVIUUcjs.parseIdentifier.call(void 0, id, "id");
|
|
10674
11927
|
const text = reason.trim();
|
|
10675
11928
|
if (text === "") {
|
|
10676
|
-
throw new (0,
|
|
11929
|
+
throw new (0, _chunkIHRXVIUUcjs.AutotaskConfigError)("reject: a non-empty reason is required (vendor TimeOffRequestRejectModel)");
|
|
10677
11930
|
}
|
|
10678
11931
|
if (opts.dryRun === true) {
|
|
10679
|
-
return
|
|
11932
|
+
return _chunkIHRXVIUUcjs.buildDryRunResult.call(void 0, {
|
|
10680
11933
|
operation: "time_off_requests.reject",
|
|
10681
11934
|
method: "POST",
|
|
10682
11935
|
path: `/V1.0/TimeOffRequests/${numericId}/Reject`,
|
|
@@ -10693,11 +11946,11 @@ async function reject(_resource, id, reason, opts = {}, http) {
|
|
|
10693
11946
|
body: { timeOffRequestID: numericId, reason: text },
|
|
10694
11947
|
operation: "time_off_requests.reject"
|
|
10695
11948
|
});
|
|
10696
|
-
return
|
|
11949
|
+
return _chunkIHRXVIUUcjs.unwrapOperation.call(void 0, res);
|
|
10697
11950
|
}
|
|
10698
11951
|
|
|
10699
11952
|
// src/resources/time_off_requests.ts
|
|
10700
|
-
var TimeOffRequestsResource = class extends
|
|
11953
|
+
var TimeOffRequestsResource = class extends _chunkIHRXVIUUcjs.BaseResource {
|
|
10701
11954
|
constructor(http, pageSize) {
|
|
10702
11955
|
super(http, {
|
|
10703
11956
|
key: "time_off_requests",
|