@xapp/stentor-service-fieldpulse 1.64.0

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.
@@ -0,0 +1,689 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.FieldPulseService = void 0;
16
+ /*! Copyright (c) 2024, XAPP AI */
17
+ const stentor_service_fetch_1 = require("stentor-service-fetch");
18
+ const stentor_logger_1 = require("stentor-logger");
19
+ const axios_1 = __importDefault(require("axios"));
20
+ const ai_1 = require("./ai");
21
+ const moment_1 = __importDefault(require("moment"));
22
+ const JobTypes_1 = require("./Data/JobTypes");
23
+ const base_url = "https://ywe3crmpll.execute-api.us-east-2.amazonaws.com/stage/";
24
+ const lead_source = "XAPP AI";
25
+ const default_tag_color = "#0983b6"; // XAPP Blue
26
+ const util_1 = require("./util");
27
+ class FieldPulseService extends stentor_service_fetch_1.FetchService {
28
+ constructor(props) {
29
+ super(props);
30
+ this.props = Object.assign({}, props);
31
+ if (!this.props.channel) {
32
+ this.props.channel = "Chat";
33
+ }
34
+ }
35
+ getAvailability(range, options) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ var _a, _b, _c, _d, _e, _f;
38
+ const daysOut = this.props.lookAheadDays | 20; // Default to 20 days out
39
+ const availability = {
40
+ range,
41
+ unavailabilities: []
42
+ };
43
+ if (!options) {
44
+ options = {
45
+ blockedDays: []
46
+ };
47
+ }
48
+ // Get all appointments on or after the start date
49
+ const startDate = ((_a = range === null || range === void 0 ? void 0 : range.start) === null || _a === void 0 ? void 0 : _a.date) ? (0, moment_1.default)(range.start.date).unix() : new Date().getTime();
50
+ const appointments = yield this.getJobs({
51
+ createdOnOrAfter: (0, moment_1.default)(startDate).unix()
52
+ });
53
+ if (appointments.status !== "Success") {
54
+ return Promise.resolve(availability); // All available if we fail
55
+ }
56
+ // Booking dates as yyyy-mm-dd
57
+ const bookings = [];
58
+ // Any full days?
59
+ // loop through the appointments and add the full days to the unavailabilities
60
+ (_c = (_b = appointments.data) === null || _b === void 0 ? void 0 : _b.response) === null || _c === void 0 ? void 0 : _c.forEach((appointment) => {
61
+ bookings.push((0, moment_1.default)(appointment.start_time).format("YYYY-MM-DD"));
62
+ });
63
+ // Add locked days for job type (usually skip next N). This needs a map (jobType: skippedDays) in the CRM constructor
64
+ if ((options === null || options === void 0 ? void 0 : options.jobType) && ((_d = this.props) === null || _d === void 0 ? void 0 : _d.delayedJobTypes)) {
65
+ if (this.props.delayedJobTypes.indexOf((_e = options === null || options === void 0 ? void 0 : options.jobType) === null || _e === void 0 ? void 0 : _e.id) !== -1) {
66
+ const nextDays = (0, util_1.getNextDays)(3);
67
+ const skippedDays = nextDays.map((date) => ({
68
+ date,
69
+ available: false
70
+ }));
71
+ availability.unavailabilities = availability.unavailabilities.concat(skippedDays);
72
+ }
73
+ }
74
+ // Add class specific blocked days
75
+ if ((_f = options === null || options === void 0 ? void 0 : options.jobType) === null || _f === void 0 ? void 0 : _f.class) {
76
+ let daysToSkip = 0;
77
+ switch (options.jobType.class) {
78
+ case "ESTIMATION":
79
+ case "MAINTENANCE":
80
+ case "INSTALLATION":
81
+ daysToSkip = 5;
82
+ break;
83
+ case "REPAIR":
84
+ daysToSkip = 2;
85
+ break;
86
+ default:
87
+ daysToSkip = 0;
88
+ break;
89
+ }
90
+ const nextDays = (0, util_1.getNextDays)(daysToSkip);
91
+ const skippedDays = nextDays.map((date) => ({
92
+ date,
93
+ available: false
94
+ }));
95
+ availability.unavailabilities = availability.unavailabilities.concat(skippedDays);
96
+ }
97
+ // Update blocked days on calendar based on availability
98
+ options = this.setBlockedDays(daysOut, availability, bookings, options);
99
+ // Add explicitly specified blocked days (holidays)
100
+ const blockedDays = (options === null || options === void 0 ? void 0 : options.blockedDays) || this.props.blockedDays;
101
+ if (blockedDays) {
102
+ const holidays = blockedDays.map((date) => ({
103
+ date,
104
+ available: false
105
+ }));
106
+ availability.unavailabilities = availability.unavailabilities.concat(holidays);
107
+ }
108
+ return Promise.resolve(availability);
109
+ });
110
+ }
111
+ setBlockedDays(daysOut, availability, bookings, options) {
112
+ const nextDays = (0, util_1.getNextDays)(daysOut);
113
+ // Init empty array
114
+ if (!options.blockedDays) {
115
+ options.blockedDays = [];
116
+ }
117
+ // Go through next {daysOut} days and check if there are any days to block
118
+ nextDays.forEach((date) => {
119
+ // Count how many matching bookings we have for the day
120
+ const dayUnavailable = bookings.filter((x) => x === date.date).length >= (this.props.maxJobsPerDay | 4);
121
+ const match = availability.unavailabilities.find((d) => d.date.date === date.date);
122
+ if (match && !match.available) {
123
+ options.blockedDays.push(date);
124
+ }
125
+ else if (dayUnavailable) {
126
+ options.blockedDays.push(date);
127
+ }
128
+ });
129
+ return options;
130
+ }
131
+ getJobType(message, externalLead) {
132
+ return __awaiter(this, void 0, void 0, function* () {
133
+ const jobTypes = (0, JobTypes_1.getJobTypes)();
134
+ const aiService = new ai_1.AIService({
135
+ apiKey: process.env.OPENAI_API_KEY,
136
+ jobTypes
137
+ });
138
+ const response = yield aiService.selectJobCategoryFromDescription(message, Object.keys(jobTypes.Category));
139
+ let jobType;
140
+ if (response === null || response === void 0 ? void 0 : response.id) {
141
+ jobType = {
142
+ id: response.id,
143
+ name: response.name
144
+ };
145
+ }
146
+ switch (response === null || response === void 0 ? void 0 : response.name) {
147
+ case "Install":
148
+ jobType.class = "INSTALLATION";
149
+ break;
150
+ case "Repair":
151
+ jobType.class = "REPAIR";
152
+ break;
153
+ case "Diagnostic":
154
+ jobType.class = "ESTIMATION";
155
+ break;
156
+ case "Maintenance":
157
+ jobType.class = "MAINTENANCE";
158
+ break;
159
+ default:
160
+ break;
161
+ }
162
+ if (jobType === null || jobType === void 0 ? void 0 : jobType.id) {
163
+ return jobType;
164
+ }
165
+ else {
166
+ return;
167
+ }
168
+ });
169
+ }
170
+ // Send the lead or scheduling request
171
+ send(externalLead, extras) {
172
+ return __awaiter(this, void 0, void 0, function* () {
173
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
174
+ const customerQuery = {};
175
+ const crmResponse = {
176
+ status: "Failure",
177
+ message: ""
178
+ };
179
+ try {
180
+ let transcript = "";
181
+ (_a = externalLead.transcript) === null || _a === void 0 ? void 0 : _a.forEach((x) => {
182
+ var _a, _b;
183
+ return (transcript += `${((_a = x.from) === null || _a === void 0 ? void 0 : _a.id) != this.props.appId && ((_b = x.from) === null || _b === void 0 ? void 0 : _b.id) != "bot" ? "user: " : this.props.appId + ": "} ${x.message} \n`);
184
+ });
185
+ // Parse first/last name
186
+ const names = (0, util_1.getName)(externalLead);
187
+ const address = (_b = externalLead.fields.find((x) => x.name == "ADDRESS")) === null || _b === void 0 ? void 0 : _b.value;
188
+ const phone = (_c = externalLead.fields.find((x) => x.name == "PHONE")) === null || _c === void 0 ? void 0 : _c.value;
189
+ const email = (_d = externalLead.fields.find((x) => x.name == "EMAIL")) === null || _d === void 0 ? void 0 : _d.value;
190
+ const message = (_e = externalLead.fields.find((x) => x.name == "MESSAGE")) === null || _e === void 0 ? void 0 : _e.value;
191
+ const dateTime = (_f = externalLead.fields.find((x) => x.name == "DATETIME")) === null || _f === void 0 ? void 0 : _f.value;
192
+ const preferredTime = (_g = externalLead.fields.find((x) => x.name == "PREFERRED_TIME")) === null || _g === void 0 ? void 0 : _g.value;
193
+ const consentApproval = (_h = externalLead.fields.find((x) => x.name == "CONSENT_APPROVAL")) === null || _h === void 0 ? void 0 : _h.value;
194
+ let parsedAddress;
195
+ try {
196
+ parsedAddress = yield (0, util_1.parseAddress)(address);
197
+ }
198
+ catch (err) {
199
+ (0, stentor_logger_1.log)().error(`FieldPulse: Invalid address "${address}"`);
200
+ }
201
+ const crmRequest = {
202
+ first_name: names.firstName,
203
+ last_name: names.lastName,
204
+ phone,
205
+ email,
206
+ job_notes: message,
207
+ notes: transcript.substring(0, 600), // Limit to 600 characters (api constraint)
208
+ lead_source,
209
+ status: "lead",
210
+ customfields: [
211
+ {
212
+ id: 1,
213
+ value: lead_source
214
+ }
215
+ ]
216
+ };
217
+ if (parsedAddress) {
218
+ crmRequest.address_1 = parsedAddress.addressLine1;
219
+ crmRequest.city = parsedAddress.placeName;
220
+ crmRequest.state = parsedAddress.stateAbbreviation;
221
+ crmRequest.zip_code = parsedAddress.zipCode;
222
+ }
223
+ // Check if customer exists
224
+ if (phone) {
225
+ customerQuery.phone = phone;
226
+ }
227
+ if (email) {
228
+ customerQuery.email = email;
229
+ }
230
+ const customerMatches = yield this.getCustomers(customerQuery);
231
+ // Customer exists, use this account
232
+ if (customerMatches.status === "Success" && ((_j = customerMatches.data) === null || _j === void 0 ? void 0 : _j.length) > 0) {
233
+ crmRequest.id = customerMatches.data[0].id;
234
+ yield this.updCustomer(crmRequest);
235
+ }
236
+ else {
237
+ const addCustomerResponse = yield this.addCustomer(crmRequest);
238
+ crmRequest.id = addCustomerResponse.data.response.id;
239
+ }
240
+ yield this.processJobRequest({
241
+ dateTime,
242
+ consentApproval: consentApproval && consentApproval.includes("agreed"),
243
+ message,
244
+ crmRequest,
245
+ parsedAddress,
246
+ preferredTime
247
+ });
248
+ crmResponse.status = "Success";
249
+ }
250
+ catch (err) {
251
+ (0, stentor_logger_1.log)().error(`FieldPulse error send(): ${err}`);
252
+ crmResponse.message = err;
253
+ }
254
+ return crmResponse;
255
+ });
256
+ }
257
+ processJobRequest(request) {
258
+ return __awaiter(this, void 0, void 0, function* () {
259
+ var _a, _b, _c, _d, _e;
260
+ let location_id = "";
261
+ if (request.dateTime && request.consentApproval) {
262
+ const jobs = (0, JobTypes_1.getJobTypes)();
263
+ const aiService = new ai_1.AIService({
264
+ jobTypes: jobs,
265
+ apiKey: this.props.openAI.apiKey
266
+ });
267
+ const aiResponse = yield aiService.labelJob(request.message);
268
+ let jobNote = request.message;
269
+ if (aiResponse.success && aiResponse.jobCategory) {
270
+ jobNote = `${aiResponse.serviceType} - ${aiResponse.jobCategory} - ${aiResponse.jobService}`;
271
+ }
272
+ const customerAddresses = yield this.getCustomerAddresses(request.crmRequest.id.toString());
273
+ if (customerAddresses.status === "Success" && ((_a = customerAddresses.data.response) === null || _a === void 0 ? void 0 : _a.length) > 0) {
274
+ location_id = customerAddresses.data.response[0].id;
275
+ }
276
+ else {
277
+ const addLocationResponse = yield this.addLocation({
278
+ title: request.parsedAddress.addressLine1,
279
+ object_type: "customer",
280
+ object_id: request.crmRequest.id,
281
+ address_1: request.parsedAddress.addressLine1,
282
+ city: request.parsedAddress.placeName,
283
+ state: request.parsedAddress.stateAbbreviation,
284
+ zip_code: request.parsedAddress.zipCode,
285
+ is_main_location: true
286
+ });
287
+ location_id = addLocationResponse.data.id;
288
+ }
289
+ const appointmentTime = (0, moment_1.default)(request.dateTime); // Localized time
290
+ const zoneOffset = 0;
291
+ let offsetHours;
292
+ if (request.preferredTime) {
293
+ if (request.preferredTime.includes("morning")) {
294
+ offsetHours = 8 + zoneOffset;
295
+ }
296
+ else if (request.preferredTime.includes("afternoon")) {
297
+ offsetHours = 14 + zoneOffset;
298
+ }
299
+ else {
300
+ offsetHours = 8 + zoneOffset; // first available = morning
301
+ }
302
+ }
303
+ else {
304
+ offsetHours = 8; // no time part
305
+ }
306
+ appointmentTime.add(offsetHours, "hours");
307
+ const requestTime = appointmentTime ? appointmentTime.utc().format() : undefined;
308
+ const tags = yield this.getTags();
309
+ // Set Attribution Tag
310
+ const xappTag = tags.data.response.find((tag) => tag.title === "XAPP");
311
+ let tag = 0;
312
+ if (xappTag) {
313
+ tag = xappTag.id;
314
+ }
315
+ else {
316
+ const addTagResponse = yield this.addTag({
317
+ type: "job",
318
+ title: lead_source,
319
+ color: default_tag_color
320
+ });
321
+ tag = addTagResponse.data.response.id;
322
+ }
323
+ yield this.addJob({
324
+ customer_id: request.crmRequest.id,
325
+ status: 1,
326
+ start_time: (0, moment_1.default)(requestTime).unix(),
327
+ end_time: (0, moment_1.default)(requestTime).add(2, "hours").unix(),
328
+ job_type: jobNote,
329
+ billing: 1,
330
+ tags: [tag],
331
+ notes: request.message,
332
+ location_id: Number(location_id),
333
+ location: `${(_b = request.crmRequest) === null || _b === void 0 ? void 0 : _b.address_1} ${(_c = request.crmRequest) === null || _c === void 0 ? void 0 : _c.city}, ${(_d = request.crmRequest) === null || _d === void 0 ? void 0 : _d.state} ${(_e = request.crmRequest) === null || _e === void 0 ? void 0 : _e.zip_code}`
334
+ });
335
+ }
336
+ });
337
+ }
338
+ getCustomers(query_1) {
339
+ return __awaiter(this, arguments, void 0, function* (query, page = 1) {
340
+ var _a;
341
+ const FieldPulseResponse = { status: "Failure" };
342
+ let q = "";
343
+ if (query.name)
344
+ q = query.name;
345
+ else if (query.phone)
346
+ q = query.phone;
347
+ else if (query.email)
348
+ q = query.email;
349
+ try {
350
+ const config = {
351
+ method: "get",
352
+ url: `${base_url}customers?search=${q}&page=${page}`,
353
+ headers: {
354
+ Accept: "application/json",
355
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`
356
+ }
357
+ };
358
+ const response = yield (0, axios_1.default)(config);
359
+ FieldPulseResponse.status = "Success";
360
+ FieldPulseResponse.data = (_a = response.data.response) === null || _a === void 0 ? void 0 : _a.map((x) => {
361
+ return {
362
+ id: x === null || x === void 0 ? void 0 : x.id,
363
+ company_id: x.company_id,
364
+ first_name: x.first_name,
365
+ last_name: x.last_name,
366
+ email: x.email,
367
+ phone: x.phone,
368
+ notes: x.notes,
369
+ address_1: x.address_1,
370
+ address_2: x.address_2,
371
+ city: x.city,
372
+ state: x.state,
373
+ zip_code: x.zip_code,
374
+ company_name: x.company_name,
375
+ tags: x.tags,
376
+ lead_source: x.lead_source,
377
+ job_notes: x.job_notes,
378
+ created_at: x.created_at,
379
+ updated_at: x.updated_at
380
+ };
381
+ });
382
+ }
383
+ catch (err) {
384
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error searching customers ${err}`);
385
+ FieldPulseResponse.error = err;
386
+ }
387
+ return FieldPulseResponse;
388
+ });
389
+ }
390
+ getCustomerAddresses(id) {
391
+ return __awaiter(this, void 0, void 0, function* () {
392
+ const FieldPulseResponse = { status: "Failure" };
393
+ try {
394
+ const config = {
395
+ method: "get",
396
+ url: `${base_url}locations?object_type=customer&object_id=${id}`,
397
+ headers: {
398
+ Accept: "application/json",
399
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`
400
+ }
401
+ };
402
+ const response = yield (0, axios_1.default)(config);
403
+ FieldPulseResponse.status = "Success";
404
+ FieldPulseResponse.data = response.data;
405
+ }
406
+ catch (err) {
407
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error getting customer addresses ${err}`);
408
+ FieldPulseResponse.error = err;
409
+ }
410
+ return FieldPulseResponse;
411
+ });
412
+ }
413
+ addCustomer(customer) {
414
+ return __awaiter(this, void 0, void 0, function* () {
415
+ const FieldPulseResponse = { status: "Failure" };
416
+ // Set Address
417
+ if (customer.address_1) {
418
+ customer.locations = [
419
+ {
420
+ title: customer.address_1,
421
+ address_1: customer.address_1,
422
+ city: customer.city,
423
+ state: customer.state,
424
+ zip_code: customer.zip_code,
425
+ is_main_location: true
426
+ }
427
+ ];
428
+ customer.billing_address_1 = customer.address_1;
429
+ customer.billing_city = customer.city;
430
+ customer.billing_state = customer.state;
431
+ customer.billing_zip_code = customer.zip_code;
432
+ }
433
+ try {
434
+ const config = {
435
+ method: "post",
436
+ url: `${base_url}customers`,
437
+ headers: {
438
+ Accept: "application/json",
439
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`,
440
+ "Content-Type": "application/json"
441
+ },
442
+ data: JSON.stringify(customer)
443
+ };
444
+ const response = yield (0, axios_1.default)(config);
445
+ if (!response.data.error) {
446
+ FieldPulseResponse.status = "Success";
447
+ FieldPulseResponse.data = response.data;
448
+ }
449
+ }
450
+ catch (err) {
451
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error adding customer ${err}`);
452
+ FieldPulseResponse.error = err;
453
+ }
454
+ return FieldPulseResponse;
455
+ });
456
+ }
457
+ updCustomer(customer) {
458
+ return __awaiter(this, void 0, void 0, function* () {
459
+ const FieldPulseResponse = { status: "Failure" };
460
+ try {
461
+ customer.status = "current customer";
462
+ const config = {
463
+ method: "put",
464
+ url: `${base_url}customers/${customer.id}`,
465
+ headers: {
466
+ Accept: "application/json",
467
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`,
468
+ "Content-Type": "application/json"
469
+ },
470
+ data: JSON.stringify(customer)
471
+ };
472
+ const response = yield (0, axios_1.default)(config);
473
+ if (!response.data.error) {
474
+ FieldPulseResponse.status = "Success";
475
+ FieldPulseResponse.data = response.data;
476
+ }
477
+ }
478
+ catch (err) {
479
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error updating customer ${err}`);
480
+ FieldPulseResponse.error = err;
481
+ }
482
+ return FieldPulseResponse;
483
+ });
484
+ }
485
+ getLeadSources() {
486
+ return __awaiter(this, arguments, void 0, function* (page = 1) {
487
+ const FieldPulseResponse = { status: "Failure" };
488
+ try {
489
+ const config = {
490
+ method: "get",
491
+ url: `${base_url}lead_source?page=${page}`,
492
+ headers: {
493
+ Accept: "application/json",
494
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`
495
+ }
496
+ };
497
+ const response = yield (0, axios_1.default)(config);
498
+ FieldPulseResponse.status = "Success";
499
+ FieldPulseResponse.data = response.data;
500
+ }
501
+ catch (err) {
502
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error getting lead sources ${err}`);
503
+ FieldPulseResponse.error = err;
504
+ }
505
+ return FieldPulseResponse;
506
+ });
507
+ }
508
+ getTags() {
509
+ return __awaiter(this, arguments, void 0, function* (page = 1) {
510
+ const FieldPulseResponse = { status: "Failure" };
511
+ try {
512
+ const config = {
513
+ method: "get",
514
+ url: `${base_url}tags?page=${page}&limit=100`,
515
+ headers: {
516
+ Accept: "application/json",
517
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`
518
+ }
519
+ };
520
+ const response = yield (0, axios_1.default)(config);
521
+ FieldPulseResponse.status = "Success";
522
+ FieldPulseResponse.data = response.data;
523
+ }
524
+ catch (err) {
525
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error getting tags ${err}`);
526
+ FieldPulseResponse.error = err;
527
+ }
528
+ return FieldPulseResponse;
529
+ });
530
+ }
531
+ getJobs(query_1) {
532
+ return __awaiter(this, arguments, void 0, function* (query, page = 1) {
533
+ const FieldPulseResponse = { status: "Failure" };
534
+ try {
535
+ let url = `${base_url}jobs?page=${page}`;
536
+ // Filter by date?
537
+ if (query === null || query === void 0 ? void 0 : query.createdOnOrAfter) {
538
+ url += `&created_from=${query.createdOnOrAfter}`;
539
+ }
540
+ // Filter by search query?
541
+ if (query === null || query === void 0 ? void 0 : query.search) {
542
+ url += `&search=${query.search}`;
543
+ }
544
+ const config = {
545
+ method: "get",
546
+ url,
547
+ headers: {
548
+ Accept: "application/json",
549
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`
550
+ }
551
+ };
552
+ const response = yield (0, axios_1.default)(config);
553
+ FieldPulseResponse.status = "Success";
554
+ FieldPulseResponse.data = response.data;
555
+ }
556
+ catch (err) {
557
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error getting jobs ${err}`);
558
+ FieldPulseResponse.error = err;
559
+ }
560
+ return FieldPulseResponse;
561
+ });
562
+ }
563
+ getEstimates() {
564
+ return __awaiter(this, arguments, void 0, function* (page = 1) {
565
+ const FieldPulseResponse = { status: "Failure" };
566
+ try {
567
+ const config = {
568
+ method: "get",
569
+ url: `${base_url}estimates?page=${page}`,
570
+ headers: {
571
+ Accept: "application/json",
572
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`
573
+ }
574
+ };
575
+ const response = yield (0, axios_1.default)(config);
576
+ FieldPulseResponse.status = "Success";
577
+ FieldPulseResponse.data = response.data;
578
+ }
579
+ catch (err) {
580
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error getting estimates ${err}`);
581
+ FieldPulseResponse.error = err;
582
+ }
583
+ return FieldPulseResponse;
584
+ });
585
+ }
586
+ getEmployees() {
587
+ return __awaiter(this, arguments, void 0, function* (page = 1) {
588
+ const FieldPulseResponse = { status: "Failure" };
589
+ try {
590
+ const config = {
591
+ method: "get",
592
+ url: `${base_url}teams?page=${page}&limit=100`,
593
+ headers: {
594
+ Accept: "application/json",
595
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`
596
+ }
597
+ };
598
+ const response = yield (0, axios_1.default)(config);
599
+ FieldPulseResponse.status = "Success";
600
+ FieldPulseResponse.data = response.data;
601
+ }
602
+ catch (err) {
603
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error getting employees ${err}`);
604
+ FieldPulseResponse.error = err;
605
+ }
606
+ return FieldPulseResponse;
607
+ });
608
+ }
609
+ addJob(job) {
610
+ return __awaiter(this, void 0, void 0, function* () {
611
+ const FieldPulseResponse = { status: "Failure" };
612
+ try {
613
+ const config = {
614
+ method: "post",
615
+ url: `${base_url}jobs`,
616
+ headers: {
617
+ Accept: "application/json",
618
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`,
619
+ "Content-Type": "application/json"
620
+ },
621
+ data: JSON.stringify(job)
622
+ };
623
+ const response = yield (0, axios_1.default)(config);
624
+ FieldPulseResponse.status = "Success";
625
+ FieldPulseResponse.data = response.data;
626
+ }
627
+ catch (err) {
628
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error adding job ${err}`);
629
+ FieldPulseResponse.error = err;
630
+ }
631
+ return FieldPulseResponse;
632
+ });
633
+ }
634
+ addTag(tag) {
635
+ return __awaiter(this, void 0, void 0, function* () {
636
+ const FieldPulseResponse = { status: "Failure" };
637
+ try {
638
+ if (!tag.color) {
639
+ tag.color = default_tag_color;
640
+ }
641
+ const config = {
642
+ method: "post",
643
+ url: `${base_url}tags`,
644
+ headers: {
645
+ Accept: "application/json",
646
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`,
647
+ "Content-Type": "application/json"
648
+ },
649
+ data: JSON.stringify(tag)
650
+ };
651
+ const response = yield (0, axios_1.default)(config);
652
+ FieldPulseResponse.status = "Success";
653
+ FieldPulseResponse.data = response.data;
654
+ }
655
+ catch (err) {
656
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error adding tag ${err}`);
657
+ FieldPulseResponse.error = err;
658
+ }
659
+ return FieldPulseResponse;
660
+ });
661
+ }
662
+ addLocation(address) {
663
+ return __awaiter(this, void 0, void 0, function* () {
664
+ const FieldPulseResponse = { status: "Failure" };
665
+ try {
666
+ const config = {
667
+ method: "post",
668
+ url: `${base_url}locations`,
669
+ headers: {
670
+ Accept: "application/json",
671
+ "x-api-key": `${(yield this.props.authenticate()).accessToken}`,
672
+ "Content-Type": "application/json"
673
+ },
674
+ data: JSON.stringify(address)
675
+ };
676
+ const response = yield (0, axios_1.default)(config);
677
+ FieldPulseResponse.status = "Success";
678
+ FieldPulseResponse.data = response.data;
679
+ }
680
+ catch (err) {
681
+ (0, stentor_logger_1.log)().error(`FieldPulse: Error adding customer address ${err}`);
682
+ FieldPulseResponse.error = err;
683
+ }
684
+ return FieldPulseResponse;
685
+ });
686
+ }
687
+ }
688
+ exports.FieldPulseService = FieldPulseService;
689
+ //# sourceMappingURL=FieldPulseService.js.map