@ironcode/vas-lib 3.0.0-alpha.2 → 3.0.0-alpha.23
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/cjs/lib/control-value/vas-camera-control-value.model.d.ts +4 -2
- package/cjs/lib/control-value/vas-camera-control-value.model.d.ts.map +1 -1
- package/cjs/lib/control-value/vas-camera-control-value.model.js.map +1 -1
- package/cjs/lib/entity/vas-base.model.d.ts +1 -1
- package/cjs/lib/entity/vas-base.model.d.ts.map +1 -1
- package/cjs/lib/entity/vas-base.model.js.map +1 -1
- package/cjs/lib/entity/vas-field.dto.d.ts +3 -4
- package/cjs/lib/entity/vas-field.dto.d.ts.map +1 -1
- package/cjs/lib/entity/vas-field.dto.js.map +1 -1
- package/cjs/lib/entity/vas-field.model.js +1 -1
- package/cjs/lib/entity/vas-field.model.js.map +1 -1
- package/cjs/lib/entity/vas-form.model.d.ts +1 -1
- package/cjs/lib/entity/vas-form.model.d.ts.map +1 -1
- package/cjs/lib/entity/vas-form.model.js +1 -1
- package/cjs/lib/entity/vas-form.model.js.map +1 -1
- package/cjs/lib/entity/vas-job-copy.d.ts +12 -12
- package/cjs/lib/entity/vas-job-copy.d.ts.map +1 -1
- package/cjs/lib/entity/vas-job-copy.js.map +1 -1
- package/cjs/lib/entity/vas-job.dto.d.ts +12 -3
- package/cjs/lib/entity/vas-job.dto.d.ts.map +1 -1
- package/cjs/lib/entity/vas-job.dto.js.map +1 -1
- package/cjs/lib/entity/vas-job.model.d.ts +30 -13
- package/cjs/lib/entity/vas-job.model.d.ts.map +1 -1
- package/cjs/lib/entity/vas-job.model.js +273 -95
- package/cjs/lib/entity/vas-job.model.js.map +1 -1
- package/cjs/lib/model/estimate-control/estimate-control-value.dto.d.ts +14 -0
- package/cjs/lib/model/estimate-control/estimate-control-value.dto.d.ts.map +1 -0
- package/cjs/lib/model/estimate-control/estimate-control-value.dto.js +3 -0
- package/cjs/lib/model/estimate-control/estimate-control-value.dto.js.map +1 -0
- package/cjs/lib/model/estimate-control/estimate-control-value.model.d.ts +11 -0
- package/cjs/lib/model/estimate-control/estimate-control-value.model.d.ts.map +1 -0
- package/cjs/lib/model/estimate-control/estimate-control-value.model.js +84 -0
- package/cjs/lib/model/estimate-control/estimate-control-value.model.js.map +1 -0
- package/cjs/lib/model/estimate-control/estimate-item.dto.d.ts +17 -0
- package/cjs/lib/model/estimate-control/estimate-item.dto.d.ts.map +1 -0
- package/cjs/lib/model/estimate-control/estimate-item.dto.js +3 -0
- package/cjs/lib/model/estimate-control/estimate-item.dto.js.map +1 -0
- package/cjs/lib/model/estimate-control/estimate-item.model.d.ts +25 -0
- package/cjs/lib/model/estimate-control/estimate-item.model.d.ts.map +1 -0
- package/cjs/lib/model/estimate-control/estimate-item.model.js +126 -0
- package/cjs/lib/model/estimate-control/estimate-item.model.js.map +1 -0
- package/cjs/lib/model/estimate-control/estimate-source.d.ts +2 -0
- package/cjs/lib/model/estimate-control/estimate-source.d.ts.map +1 -0
- package/cjs/lib/model/estimate-control/estimate-source.js +3 -0
- package/cjs/lib/model/estimate-control/estimate-source.js.map +1 -0
- package/cjs/lib/model/estimate-control/estimate.dto.d.ts +38 -0
- package/cjs/lib/model/estimate-control/estimate.dto.d.ts.map +1 -0
- package/cjs/lib/model/estimate-control/estimate.dto.js +3 -0
- package/cjs/lib/model/estimate-control/estimate.dto.js.map +1 -0
- package/cjs/lib/model/estimate-control/estimate.model.d.ts +55 -0
- package/cjs/lib/model/estimate-control/estimate.model.d.ts.map +1 -0
- package/cjs/lib/model/estimate-control/estimate.model.js +278 -0
- package/cjs/lib/model/estimate-control/estimate.model.js.map +1 -0
- package/cjs/lib/model/estimate-control/estimate.types.d.ts +3 -0
- package/cjs/lib/model/estimate-control/estimate.types.d.ts.map +1 -0
- package/cjs/lib/model/estimate-control/estimate.types.js +3 -0
- package/cjs/lib/model/estimate-control/estimate.types.js.map +1 -0
- package/cjs/lib/model/estimate-control/index.d.ts +9 -0
- package/cjs/lib/model/estimate-control/index.d.ts.map +1 -0
- package/cjs/lib/model/estimate-control/index.js +11 -0
- package/cjs/lib/model/estimate-control/index.js.map +1 -0
- package/cjs/lib/model/index.d.ts +2 -0
- package/cjs/lib/model/index.d.ts.map +1 -1
- package/cjs/lib/model/index.js +2 -0
- package/cjs/lib/model/index.js.map +1 -1
- package/cjs/lib/model/report-invocation.d.ts +40 -0
- package/cjs/lib/model/report-invocation.d.ts.map +1 -0
- package/cjs/lib/model/report-invocation.js +3 -0
- package/cjs/lib/model/report-invocation.js.map +1 -0
- package/cjs/lib/utils/get-value-by-path.d.ts +5 -15
- package/cjs/lib/utils/get-value-by-path.d.ts.map +1 -1
- package/cjs/lib/utils/get-value-by-path.js +48 -59
- package/cjs/lib/utils/get-value-by-path.js.map +1 -1
- package/cjs/lib/utils/index.d.ts +8 -0
- package/cjs/lib/utils/index.d.ts.map +1 -0
- package/cjs/lib/utils/index.js +11 -0
- package/cjs/lib/utils/index.js.map +1 -0
- package/cjs/lib/utils/is-array-string.d.ts +3 -0
- package/cjs/lib/utils/is-array-string.d.ts.map +1 -1
- package/cjs/lib/utils/is-array-string.js +3 -0
- package/cjs/lib/utils/is-array-string.js.map +1 -1
- package/cjs/lib/utils/is-numeric.d.ts +2 -0
- package/cjs/lib/utils/is-numeric.d.ts.map +1 -0
- package/cjs/lib/utils/is-numeric.js +10 -0
- package/cjs/lib/utils/is-numeric.js.map +1 -0
- package/cjs/lib/utils/is-plain-object.d.ts +3 -0
- package/cjs/lib/utils/is-plain-object.d.ts.map +1 -1
- package/cjs/lib/utils/is-plain-object.js +3 -0
- package/cjs/lib/utils/is-plain-object.js.map +1 -1
- package/cjs/lib/utils/try-json.d.ts +2 -2
- package/cjs/lib/utils/try-json.js +2 -2
- package/cjs/lib/utils/try-json.js.map +1 -1
- package/cjs/public-api.d.ts +1 -0
- package/cjs/public-api.d.ts.map +1 -1
- package/cjs/public-api.js +1 -0
- package/cjs/public-api.js.map +1 -1
- package/fesm2022/ironcode-vas-lib.mjs +841 -149
- package/fesm2022/ironcode-vas-lib.mjs.map +1 -1
- package/lib/control-value/vas-camera-control-value.model.d.ts +4 -2
- package/lib/entity/vas-base.model.d.ts +1 -1
- package/lib/entity/vas-field.dto.d.ts +3 -4
- package/lib/entity/vas-form.model.d.ts +1 -1
- package/lib/entity/vas-job-copy.d.ts +12 -12
- package/lib/entity/vas-job.dto.d.ts +12 -3
- package/lib/entity/vas-job.model.d.ts +30 -13
- package/lib/model/estimate-control/estimate-control-value.dto.d.ts +13 -0
- package/lib/model/estimate-control/estimate-control-value.model.d.ts +10 -0
- package/lib/model/estimate-control/estimate-item.dto.d.ts +16 -0
- package/lib/model/estimate-control/estimate-item.model.d.ts +24 -0
- package/lib/model/estimate-control/estimate-source.d.ts +1 -0
- package/lib/model/estimate-control/estimate.dto.d.ts +37 -0
- package/lib/model/estimate-control/estimate.model.d.ts +54 -0
- package/lib/model/estimate-control/estimate.types.d.ts +2 -0
- package/lib/model/estimate-control/index.d.ts +8 -0
- package/lib/model/index.d.ts +2 -0
- package/lib/model/report-invocation.d.ts +39 -0
- package/lib/utils/get-value-by-path.d.ts +5 -15
- package/lib/utils/index.d.ts +7 -0
- package/lib/utils/is-array-string.d.ts +4 -0
- package/lib/utils/is-numeric.d.ts +1 -0
- package/lib/utils/is-plain-object.d.ts +3 -0
- package/lib/utils/omit.d.ts +7 -0
- package/lib/utils/try-json.d.ts +2 -2
- package/package.json +3 -2
- package/public-api.d.ts +1 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { UUID } from 'angular2-uuid';
|
|
2
2
|
import moment from 'moment';
|
|
3
|
+
import { Big } from 'big.js';
|
|
4
|
+
import { v4 } from 'uuid';
|
|
3
5
|
|
|
4
6
|
function isCameraControlValueV1(object) {
|
|
5
7
|
return object instanceof Object
|
|
@@ -1537,7 +1539,7 @@ class VasFieldModel extends VasJobDataModel {
|
|
|
1537
1539
|
* @return {VasFieldModel}
|
|
1538
1540
|
*/
|
|
1539
1541
|
static fromDto(fieldDto) {
|
|
1540
|
-
return new VasFieldModel(fieldDto.id || '', fieldDto.created || '', fieldDto.serverCreated || '', fieldDto.createdBy || '', fieldDto.modified || '', fieldDto.serverModified || '', fieldDto.modifiedBy || '', fieldDto.createdByName || '', fieldDto.modifiedByName || '', fieldDto.account || '', fieldDto.job || '', fieldDto.control || '', fieldDto.fieldJobPointers || [], fieldDto.value
|
|
1542
|
+
return new VasFieldModel(fieldDto.id || '', fieldDto.created || '', fieldDto.serverCreated || '', fieldDto.createdBy || '', fieldDto.modified || '', fieldDto.serverModified || '', fieldDto.modifiedBy || '', fieldDto.createdByName || '', fieldDto.modifiedByName || '', fieldDto.account || '', fieldDto.job || '', fieldDto.control || '', fieldDto.fieldJobPointers || [], fieldDto.value !== undefined ? fieldDto.value : null, fieldDto.version || 0, fieldDto.controlName || '', fieldDto.controlTitle || '', fieldDto.controlTypeName || '');
|
|
1541
1543
|
}
|
|
1542
1544
|
/**
|
|
1543
1545
|
* @return {VasFieldDto}
|
|
@@ -2243,7 +2245,7 @@ class VasFormModel extends VasRestrictedAccountObjectModel {
|
|
|
2243
2245
|
if (control.controlTypeName !== 'camera') {
|
|
2244
2246
|
return;
|
|
2245
2247
|
}
|
|
2246
|
-
paths.push(
|
|
2248
|
+
paths.push(control.name.split('.'));
|
|
2247
2249
|
});
|
|
2248
2250
|
});
|
|
2249
2251
|
return paths;
|
|
@@ -3258,69 +3260,546 @@ class VasJobTypeModel extends VasAccountObjectModel {
|
|
|
3258
3260
|
}
|
|
3259
3261
|
}
|
|
3260
3262
|
|
|
3263
|
+
function isNumeric(value) {
|
|
3264
|
+
if (typeof value === 'number') {
|
|
3265
|
+
return !isNaN(value);
|
|
3266
|
+
}
|
|
3267
|
+
return /^-?\d+$/.test(value.trim());
|
|
3268
|
+
}
|
|
3269
|
+
|
|
3270
|
+
function coalescePath(pathOrPaths) {
|
|
3271
|
+
let keys = [];
|
|
3272
|
+
if (typeof pathOrPaths === 'string') {
|
|
3273
|
+
keys = pathOrPaths.split('.');
|
|
3274
|
+
}
|
|
3275
|
+
else if (typeof pathOrPaths === 'number') {
|
|
3276
|
+
keys = [pathOrPaths];
|
|
3277
|
+
}
|
|
3278
|
+
else if (Array.isArray(pathOrPaths)) {
|
|
3279
|
+
keys = pathOrPaths;
|
|
3280
|
+
}
|
|
3281
|
+
else {
|
|
3282
|
+
throw Error('Expected string, number or array of strings or numbers');
|
|
3283
|
+
}
|
|
3284
|
+
const result = [];
|
|
3285
|
+
keys.forEach(key => {
|
|
3286
|
+
if (typeof key === 'number') {
|
|
3287
|
+
result.push(key);
|
|
3288
|
+
return;
|
|
3289
|
+
}
|
|
3290
|
+
if (key.endsWith(']')) {
|
|
3291
|
+
const match = /^([\w_#$-]+)\[([\w_#$-]+)]$/.exec(key.toString());
|
|
3292
|
+
if (match !== null) {
|
|
3293
|
+
result.push(match[1]);
|
|
3294
|
+
result.push(isNumeric(match[2]) ? parseInt(match[2], 10) : match[2]);
|
|
3295
|
+
return;
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
result.push(key);
|
|
3299
|
+
});
|
|
3300
|
+
return result;
|
|
3301
|
+
}
|
|
3261
3302
|
/**
|
|
3262
|
-
*
|
|
3263
|
-
*
|
|
3264
|
-
* getValueByPath(
|
|
3265
|
-
* ['foo', 'bar'],
|
|
3266
|
-
* {
|
|
3267
|
-
* foo: {
|
|
3268
|
-
* bar: 'value'
|
|
3269
|
-
* }
|
|
3270
|
-
* }
|
|
3271
|
-
* );
|
|
3303
|
+
* Get a value from an object by path.
|
|
3272
3304
|
*
|
|
3273
|
-
*
|
|
3274
|
-
*
|
|
3275
|
-
*
|
|
3276
|
-
* @return {T | undefined}
|
|
3305
|
+
* Path can be an array of strings or numbers.
|
|
3306
|
+
* Path can be a string using dot notation, which can include square brackets to
|
|
3307
|
+
* access array positions e.g. foo.bar[0].baz
|
|
3277
3308
|
*/
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3309
|
+
function getValueByPath(path, object) {
|
|
3310
|
+
const p = coalescePath(path);
|
|
3311
|
+
let scope = object === undefined ? null : object;
|
|
3312
|
+
let index = 0;
|
|
3313
|
+
const length = p.length;
|
|
3314
|
+
while (index < length) {
|
|
3315
|
+
if (scope === undefined || scope === null) {
|
|
3316
|
+
return undefined;
|
|
3282
3317
|
}
|
|
3283
|
-
|
|
3284
|
-
|
|
3318
|
+
scope = scope[p[index++]];
|
|
3319
|
+
}
|
|
3320
|
+
return scope;
|
|
3321
|
+
}
|
|
3322
|
+
|
|
3323
|
+
const b$2 = (value = '0') => {
|
|
3324
|
+
try {
|
|
3325
|
+
if (typeof value === 'string') {
|
|
3326
|
+
return new Big(value.replace(/[^\d^.]/g, ''));
|
|
3285
3327
|
}
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3328
|
+
return new Big(value);
|
|
3329
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3330
|
+
}
|
|
3331
|
+
catch (e) {
|
|
3332
|
+
console.error(`failed to construct Big from value '${value}'`);
|
|
3333
|
+
return new Big('0');
|
|
3334
|
+
}
|
|
3335
|
+
};
|
|
3336
|
+
class EstimateItemModel {
|
|
3337
|
+
id;
|
|
3338
|
+
description;
|
|
3339
|
+
type;
|
|
3340
|
+
quantity;
|
|
3341
|
+
quantityAdjusted;
|
|
3342
|
+
units;
|
|
3343
|
+
unitsAdjusted;
|
|
3344
|
+
price;
|
|
3345
|
+
priceAdjusted;
|
|
3346
|
+
workCategory;
|
|
3347
|
+
costCategory;
|
|
3348
|
+
comment;
|
|
3349
|
+
vatExcluded;
|
|
3350
|
+
constructor(id, description, type, quantity, quantityAdjusted, units, unitsAdjusted, price, priceAdjusted, workCategory, costCategory, comment, vatExcluded) {
|
|
3351
|
+
this.id = id;
|
|
3352
|
+
this.description = description;
|
|
3353
|
+
this.type = type;
|
|
3354
|
+
this.quantity = quantity;
|
|
3355
|
+
this.quantityAdjusted = quantityAdjusted;
|
|
3356
|
+
this.units = units;
|
|
3357
|
+
this.unitsAdjusted = unitsAdjusted;
|
|
3358
|
+
this.price = price;
|
|
3359
|
+
this.priceAdjusted = priceAdjusted;
|
|
3360
|
+
this.workCategory = workCategory;
|
|
3361
|
+
this.costCategory = costCategory;
|
|
3362
|
+
this.comment = comment;
|
|
3363
|
+
this.vatExcluded = vatExcluded;
|
|
3364
|
+
}
|
|
3365
|
+
getTotalUnits(adjusted = false) {
|
|
3366
|
+
return adjusted ?
|
|
3367
|
+
b$2(this.quantityAdjusted || '0').mul(this.unitsAdjusted || '0').toFixed(2) :
|
|
3368
|
+
b$2(this.quantity || '0').mul(this.units || '0').toFixed(2);
|
|
3369
|
+
}
|
|
3370
|
+
getLineValue(labourRate = '1', timeBasis = '1', adjusted = false, vatExcluded) {
|
|
3371
|
+
const cat = this.costCategory || 'none';
|
|
3372
|
+
if (this.workCategory === 'removed') {
|
|
3373
|
+
return '0';
|
|
3292
3374
|
}
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
if (!val0) {
|
|
3296
|
-
return undefined;
|
|
3297
|
-
}
|
|
3298
|
-
const val1 = val0[path[1]];
|
|
3299
|
-
if (!val1) {
|
|
3300
|
-
return undefined;
|
|
3301
|
-
}
|
|
3302
|
-
return val1[path[2]];
|
|
3375
|
+
if (vatExcluded !== undefined && this.vatExcluded !== vatExcluded) {
|
|
3376
|
+
return '0';
|
|
3303
3377
|
}
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3378
|
+
const units = (adjusted ? this.unitsAdjusted : this.units) || 0;
|
|
3379
|
+
const quantity = (adjusted ? this.quantityAdjusted : this.quantity) || 0;
|
|
3380
|
+
const price = (adjusted ? this.priceAdjusted : this.price) || '';
|
|
3381
|
+
try {
|
|
3382
|
+
switch (cat) {
|
|
3383
|
+
case 'labour': {
|
|
3384
|
+
return price != '' ?
|
|
3385
|
+
price :
|
|
3386
|
+
b$2(quantity || '0')
|
|
3387
|
+
.mul(units || '0')
|
|
3388
|
+
.mul(labourRate || '0')
|
|
3389
|
+
.div(timeBasis)
|
|
3390
|
+
.toFixed(2);
|
|
3391
|
+
}
|
|
3392
|
+
case 'pm': {
|
|
3393
|
+
return b$2(price || '0')
|
|
3394
|
+
.mul(quantity || '0')
|
|
3395
|
+
.toFixed(2);
|
|
3396
|
+
}
|
|
3397
|
+
case 'parts': {
|
|
3398
|
+
return b$2(price || '0')
|
|
3399
|
+
.mul(quantity || '0')
|
|
3400
|
+
.toFixed(2);
|
|
3401
|
+
}
|
|
3402
|
+
case 'specialist': {
|
|
3403
|
+
return b$2(price || '0')
|
|
3404
|
+
.mul(quantity || '0')
|
|
3405
|
+
.toFixed(2);
|
|
3406
|
+
}
|
|
3407
|
+
default: {
|
|
3408
|
+
return '0';
|
|
3409
|
+
}
|
|
3316
3410
|
}
|
|
3317
|
-
return val2[path[3]];
|
|
3318
3411
|
}
|
|
3319
|
-
|
|
3320
|
-
|
|
3412
|
+
catch (e) {
|
|
3413
|
+
console.warn(e);
|
|
3321
3414
|
}
|
|
3415
|
+
return '0';
|
|
3416
|
+
}
|
|
3417
|
+
toDto() {
|
|
3418
|
+
return {
|
|
3419
|
+
id: this.id,
|
|
3420
|
+
description: this.description,
|
|
3421
|
+
type: this.type,
|
|
3422
|
+
quantity: this.quantity,
|
|
3423
|
+
quantityAdjusted: this.quantityAdjusted,
|
|
3424
|
+
units: this.units,
|
|
3425
|
+
unitsAdjusted: this.unitsAdjusted,
|
|
3426
|
+
price: this.price,
|
|
3427
|
+
priceAdjusted: this.priceAdjusted,
|
|
3428
|
+
workCategory: this.workCategory,
|
|
3429
|
+
costCategory: this.costCategory,
|
|
3430
|
+
comment: this.comment,
|
|
3431
|
+
vatExcluded: this.vatExcluded
|
|
3432
|
+
};
|
|
3433
|
+
}
|
|
3434
|
+
static create() {
|
|
3435
|
+
return new EstimateItemModel(v4(), '', '', 1, 1, 0, 0, '', '', 'none', 'none', '', false);
|
|
3436
|
+
}
|
|
3437
|
+
static fromDto(dto) {
|
|
3438
|
+
return new EstimateItemModel(dto.id || v4(), dto.description || '', dto.type || '', dto.quantity || 0, dto.quantityAdjusted || 0, dto.units || 0, dto.unitsAdjusted || 0, dto.price || '', dto.priceAdjusted || '', dto.workCategory || 'none', dto.costCategory || 'none', dto.comment || '', dto.vatExcluded || false);
|
|
3439
|
+
}
|
|
3440
|
+
static equal(a, b) {
|
|
3441
|
+
return (a?.id === b?.id &&
|
|
3442
|
+
a?.description === b?.description &&
|
|
3443
|
+
a?.type === b?.type &&
|
|
3444
|
+
a?.quantity === b?.quantity &&
|
|
3445
|
+
a?.quantityAdjusted === b?.quantityAdjusted &&
|
|
3446
|
+
a?.units === b?.units &&
|
|
3447
|
+
a?.unitsAdjusted === b?.unitsAdjusted &&
|
|
3448
|
+
a?.price === b?.price &&
|
|
3449
|
+
a?.priceAdjusted === b?.priceAdjusted &&
|
|
3450
|
+
a?.workCategory === b?.workCategory &&
|
|
3451
|
+
a?.costCategory === b?.costCategory &&
|
|
3452
|
+
a?.comment === b?.comment);
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
|
|
3456
|
+
const b$1 = (value = '0') => {
|
|
3457
|
+
try {
|
|
3458
|
+
if (typeof value === 'string') {
|
|
3459
|
+
return new Big(value.replace(/[^\d^.]/g, ''));
|
|
3460
|
+
}
|
|
3461
|
+
return new Big(value);
|
|
3462
|
+
}
|
|
3463
|
+
catch (e) {
|
|
3464
|
+
console.error(`failed to construct Big from value '${value}'`);
|
|
3465
|
+
return new Big('0');
|
|
3322
3466
|
}
|
|
3323
3467
|
};
|
|
3468
|
+
function isLabourWorkCategory(value) {
|
|
3469
|
+
return ['check', 'rr', 'repair', 'removed'].includes(value);
|
|
3470
|
+
}
|
|
3471
|
+
function isPaintWorkCategory(value) {
|
|
3472
|
+
return ['blend', 'paint'].includes(value);
|
|
3473
|
+
}
|
|
3474
|
+
class EstimateModel {
|
|
3475
|
+
id = v4();
|
|
3476
|
+
source = 'manual';
|
|
3477
|
+
label = '';
|
|
3478
|
+
comment = '';
|
|
3479
|
+
timestamp = moment().toISOString();
|
|
3480
|
+
version = 1;
|
|
3481
|
+
net = '0.00';
|
|
3482
|
+
vat = '0.00';
|
|
3483
|
+
gross = '0.00';
|
|
3484
|
+
labourRate = '1';
|
|
3485
|
+
vatRate = '0.00';
|
|
3486
|
+
sundryRate = '0.00';
|
|
3487
|
+
sundryMax = '0.00';
|
|
3488
|
+
sundryFixed = '0.00';
|
|
3489
|
+
sundryMethod = 'fixed';
|
|
3490
|
+
partsDiscount = '0.00';
|
|
3491
|
+
paintDiscount = '0.00';
|
|
3492
|
+
timeBasis = '1';
|
|
3493
|
+
adjusted = false;
|
|
3494
|
+
items = [];
|
|
3495
|
+
summaryNet = {
|
|
3496
|
+
labour: '0.00',
|
|
3497
|
+
none: '0.00',
|
|
3498
|
+
parts: '0.00',
|
|
3499
|
+
pm: '0.00',
|
|
3500
|
+
pl: '0.00',
|
|
3501
|
+
specialist: '0.00',
|
|
3502
|
+
other: '0.00',
|
|
3503
|
+
gross: '0.00',
|
|
3504
|
+
net: '0.00',
|
|
3505
|
+
hours: '0.00',
|
|
3506
|
+
vat: '0.00',
|
|
3507
|
+
labourRate: '0.00',
|
|
3508
|
+
};
|
|
3509
|
+
summary = {
|
|
3510
|
+
labour: '0.00',
|
|
3511
|
+
none: '0.00',
|
|
3512
|
+
parts: '0.00',
|
|
3513
|
+
pm: '0.00',
|
|
3514
|
+
pl: '0.00',
|
|
3515
|
+
specialist: '0.00',
|
|
3516
|
+
other: '0.00',
|
|
3517
|
+
gross: '0.00',
|
|
3518
|
+
net: '0.00',
|
|
3519
|
+
hours: '0.00',
|
|
3520
|
+
vat: '0.00',
|
|
3521
|
+
labourRate: '0.00',
|
|
3522
|
+
};
|
|
3523
|
+
summaryAdjusted = {
|
|
3524
|
+
labour: '0.00',
|
|
3525
|
+
none: '0.00',
|
|
3526
|
+
parts: '0.00',
|
|
3527
|
+
pm: '0.00',
|
|
3528
|
+
pl: '0.00',
|
|
3529
|
+
specialist: '0.00',
|
|
3530
|
+
other: '0.00',
|
|
3531
|
+
gross: '0.00',
|
|
3532
|
+
net: '0.00',
|
|
3533
|
+
hours: '0.00',
|
|
3534
|
+
vat: '0.00',
|
|
3535
|
+
labourRate: '0.00',
|
|
3536
|
+
};
|
|
3537
|
+
get timeBasisSafe() {
|
|
3538
|
+
return (this.timeBasis || '1') === '0' ? '1' : this.timeBasis;
|
|
3539
|
+
}
|
|
3540
|
+
static create(source = 'manual') {
|
|
3541
|
+
const model = new EstimateModel();
|
|
3542
|
+
model.source = source;
|
|
3543
|
+
return model;
|
|
3544
|
+
}
|
|
3545
|
+
static fromDto(dto) {
|
|
3546
|
+
const model = new this();
|
|
3547
|
+
Object.assign(model, {
|
|
3548
|
+
...dto,
|
|
3549
|
+
items: dto.items?.map(item => EstimateItemModel.fromDto(item)),
|
|
3550
|
+
});
|
|
3551
|
+
model.calculate();
|
|
3552
|
+
return model;
|
|
3553
|
+
}
|
|
3554
|
+
addItem(modelOrDto, opts) {
|
|
3555
|
+
this.items.push(modelOrDto instanceof EstimateItemModel ?
|
|
3556
|
+
modelOrDto :
|
|
3557
|
+
EstimateItemModel.fromDto(modelOrDto));
|
|
3558
|
+
if (!opts || (opts && opts.calculate)) {
|
|
3559
|
+
this.calculate();
|
|
3560
|
+
}
|
|
3561
|
+
}
|
|
3562
|
+
addItems(items, opts) {
|
|
3563
|
+
this.items = this.items.concat(items);
|
|
3564
|
+
if (!opts || (opts && opts.calculate)) {
|
|
3565
|
+
this.calculate();
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
calculate() {
|
|
3569
|
+
this.summaryNet = this.getSummaryNet(false);
|
|
3570
|
+
if (this.adjusted) {
|
|
3571
|
+
this.summaryAdjusted = this.getSummary(this.summaryNet, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount, true);
|
|
3572
|
+
}
|
|
3573
|
+
this.summary = this.getSummary(this.summaryNet, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount, false);
|
|
3574
|
+
this.net = this.summary.net;
|
|
3575
|
+
this.vat = this.summary.vat;
|
|
3576
|
+
this.gross = this.summary.gross;
|
|
3577
|
+
}
|
|
3578
|
+
/**
|
|
3579
|
+
* Returns the net summary (before sundries and discounts) of the estimate.
|
|
3580
|
+
* By summary, we mean grouping the costs by cost category.
|
|
3581
|
+
*
|
|
3582
|
+
* @param adjusted if the values should be calculated using the original or
|
|
3583
|
+
* adjusted values
|
|
3584
|
+
*/
|
|
3585
|
+
getSummaryNet(adjusted = false) {
|
|
3586
|
+
const summary = this.items.reduce((map, item) => {
|
|
3587
|
+
map[item.costCategory] = b$1(map[item.costCategory] || '0')
|
|
3588
|
+
.add(item.getLineValue(this.labourRate, this.timeBasisSafe, adjusted, this.source === 'gtmotive' ? false : undefined))
|
|
3589
|
+
.toFixed(2);
|
|
3590
|
+
return map;
|
|
3591
|
+
}, {
|
|
3592
|
+
labour: '0.00',
|
|
3593
|
+
none: '0.00',
|
|
3594
|
+
parts: '0.00',
|
|
3595
|
+
pm: '0.00',
|
|
3596
|
+
pl: '0.00',
|
|
3597
|
+
specialist: '0.00',
|
|
3598
|
+
other: '0.00',
|
|
3599
|
+
net: '0.00',
|
|
3600
|
+
vat: '0.00',
|
|
3601
|
+
gross: '0.00',
|
|
3602
|
+
hours: '0.00',
|
|
3603
|
+
labourRate: '0',
|
|
3604
|
+
});
|
|
3605
|
+
if (this.source === 'audatex') {
|
|
3606
|
+
const mechHours = this.items
|
|
3607
|
+
.reduce((h, item) => {
|
|
3608
|
+
return isLabourWorkCategory(item.workCategory) ?
|
|
3609
|
+
h.add(b$1(item.quantity || '0').mul(item.units || '0')) :
|
|
3610
|
+
h;
|
|
3611
|
+
}, b$1())
|
|
3612
|
+
.div(this.timeBasisSafe || '1')
|
|
3613
|
+
.round(2);
|
|
3614
|
+
const paintHours = this.items
|
|
3615
|
+
.reduce((h, item) => {
|
|
3616
|
+
return isPaintWorkCategory(item.workCategory) ?
|
|
3617
|
+
h.add(b$1(item.quantity || '0').mul(item.units || '0')) :
|
|
3618
|
+
h;
|
|
3619
|
+
}, b$1())
|
|
3620
|
+
.div(this.timeBasisSafe || '1')
|
|
3621
|
+
.round(1);
|
|
3622
|
+
const mechCost = mechHours.mul(this.labourRate || '0');
|
|
3623
|
+
const paintCost = paintHours.mul(this.labourRate || '0');
|
|
3624
|
+
summary.labour = mechCost.add(paintCost).toFixed(2);
|
|
3625
|
+
}
|
|
3626
|
+
return summary;
|
|
3627
|
+
}
|
|
3628
|
+
/**
|
|
3629
|
+
* Applies the sundry and discount values to the net summary.
|
|
3630
|
+
*/
|
|
3631
|
+
getSummary(summaryNet, sundryRate, sundryMax, sundryFixed, sundryMethod, partsDiscount, paintDiscount, adjusted) {
|
|
3632
|
+
const partsDisc = b$1('1').minus(partsDiscount || '0');
|
|
3633
|
+
const paintDisc = b$1('1').minus(paintDiscount || '0');
|
|
3634
|
+
let partsSundry = '0.00';
|
|
3635
|
+
if (sundryMethod === 'percentage') {
|
|
3636
|
+
partsSundry = b$1(summaryNet.parts).mul(sundryRate || '1').toFixed(2);
|
|
3637
|
+
}
|
|
3638
|
+
else if (sundryMethod === 'percentage-with-max') {
|
|
3639
|
+
partsSundry = b$1(summaryNet.parts).mul(sundryRate || '1').toFixed(2);
|
|
3640
|
+
partsSundry = Math.min(parseFloat(sundryMax || '0'), parseFloat(partsSundry)).toFixed(2);
|
|
3641
|
+
}
|
|
3642
|
+
else if (sundryMethod === 'fixed') {
|
|
3643
|
+
partsSundry = b$1(sundryFixed).toFixed(2);
|
|
3644
|
+
}
|
|
3645
|
+
const parts = b$1(summaryNet.parts).add(partsSundry);
|
|
3646
|
+
const net = b$1(0)
|
|
3647
|
+
.add(summaryNet.labour)
|
|
3648
|
+
.add(summaryNet.none)
|
|
3649
|
+
.add(parts)
|
|
3650
|
+
.add(summaryNet.pm)
|
|
3651
|
+
.add(summaryNet.specialist)
|
|
3652
|
+
.toFixed(2);
|
|
3653
|
+
const vat = b$1(net || '0')
|
|
3654
|
+
.mul(this.vatRate || '0')
|
|
3655
|
+
.toFixed(2);
|
|
3656
|
+
let gross = b$1(net || '0').add(vat || '0').toFixed(2);
|
|
3657
|
+
// calculate the total value of lines that are VAT excluded
|
|
3658
|
+
const vatExcludeTotal = this.items.reduce((p, c) => c.vatExcluded ?
|
|
3659
|
+
p.add(c.getLineValue(this.labourRate, this.timeBasisSafe, adjusted, true)) :
|
|
3660
|
+
p, b$1());
|
|
3661
|
+
gross = b$1(gross).add(vatExcludeTotal).toFixed(2);
|
|
3662
|
+
return {
|
|
3663
|
+
labour: summaryNet.labour,
|
|
3664
|
+
none: summaryNet.none,
|
|
3665
|
+
parts: b$1(parts).mul(partsDisc).toFixed(2),
|
|
3666
|
+
pm: b$1(summaryNet.pm).mul(paintDisc).toFixed(2),
|
|
3667
|
+
pl: summaryNet.pl,
|
|
3668
|
+
specialist: summaryNet.specialist,
|
|
3669
|
+
other: summaryNet.other,
|
|
3670
|
+
net: net,
|
|
3671
|
+
vat: vat,
|
|
3672
|
+
gross: gross,
|
|
3673
|
+
labourRate: this.labourRate,
|
|
3674
|
+
hours: this.getTotalHours(adjusted)
|
|
3675
|
+
};
|
|
3676
|
+
}
|
|
3677
|
+
toDto() {
|
|
3678
|
+
return {
|
|
3679
|
+
id: this.id,
|
|
3680
|
+
source: this.source,
|
|
3681
|
+
label: this.label,
|
|
3682
|
+
comment: this.comment,
|
|
3683
|
+
timestamp: this.timestamp,
|
|
3684
|
+
version: this.version,
|
|
3685
|
+
net: this.net,
|
|
3686
|
+
vat: this.vat,
|
|
3687
|
+
gross: this.gross,
|
|
3688
|
+
labourRate: this.labourRate,
|
|
3689
|
+
vatRate: this.vatRate,
|
|
3690
|
+
sundryRate: this.sundryRate,
|
|
3691
|
+
sundryMax: this.sundryMax,
|
|
3692
|
+
sundryFixed: this.sundryFixed,
|
|
3693
|
+
sundryMethod: this.sundryMethod,
|
|
3694
|
+
partsDiscount: this.partsDiscount,
|
|
3695
|
+
paintDiscount: this.paintDiscount,
|
|
3696
|
+
timeBasis: this.timeBasisSafe,
|
|
3697
|
+
items: this.items.map(i => i.toDto()),
|
|
3698
|
+
adjusted: this.adjusted,
|
|
3699
|
+
summary: this.summary,
|
|
3700
|
+
summaryAdjusted: this.summaryAdjusted
|
|
3701
|
+
};
|
|
3702
|
+
}
|
|
3703
|
+
getTotalHours(adjusted = false) {
|
|
3704
|
+
if (this.source === 'audatex') {
|
|
3705
|
+
const mechUnitsHours = this.items
|
|
3706
|
+
.filter(item => item.workCategory !== 'paint')
|
|
3707
|
+
.reduce((h, item) => h.add(b$1(item.getTotalUnits(adjusted))), b$1())
|
|
3708
|
+
.round(2)
|
|
3709
|
+
.div(this.timeBasisSafe);
|
|
3710
|
+
const paintHours = this.items
|
|
3711
|
+
.filter(item => item.workCategory === 'paint')
|
|
3712
|
+
.reduce((h, item) => h.add(b$1(item.getTotalUnits(adjusted))), b$1())
|
|
3713
|
+
.round(1)
|
|
3714
|
+
.div(this.timeBasisSafe);
|
|
3715
|
+
return mechUnitsHours.add(paintHours).toFixed(2);
|
|
3716
|
+
}
|
|
3717
|
+
const units = this.items
|
|
3718
|
+
.filter(i => i.costCategory === 'labour')
|
|
3719
|
+
.reduce((p, c) => p.add(b$1(c.getTotalUnits(adjusted))), b$1('0'))
|
|
3720
|
+
.toFixed(2);
|
|
3721
|
+
return b$1(units).div(this.timeBasisSafe).toFixed(2);
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
|
|
3725
|
+
const b = (value = '0') => new Big(value);
|
|
3726
|
+
/**
|
|
3727
|
+
* Utility class for computing the summary value for an estimate control given
|
|
3728
|
+
* the first and last estimates
|
|
3729
|
+
*/
|
|
3730
|
+
class EstimateControlValueModel {
|
|
3731
|
+
static calculateSummary(original, latest) {
|
|
3732
|
+
const o = original.summary;
|
|
3733
|
+
const l = latest.adjusted ?
|
|
3734
|
+
latest.summaryAdjusted :
|
|
3735
|
+
latest.summary;
|
|
3736
|
+
const s = {
|
|
3737
|
+
labour: b(o.labour).minus(l.labour).toFixed(2),
|
|
3738
|
+
none: b(o.none).minus(l.none).toFixed(2),
|
|
3739
|
+
parts: b(o.parts).minus(l.parts).toFixed(2),
|
|
3740
|
+
pm: b(o.pm).minus(l.pm).toFixed(2),
|
|
3741
|
+
pl: b(o.pm).minus(l.pl).toFixed(2),
|
|
3742
|
+
specialist: b(o.specialist).minus(l.specialist).toFixed(2),
|
|
3743
|
+
other: b(o.other).minus(l.other).toFixed(2),
|
|
3744
|
+
net: b(o.net).minus(l.net).toFixed(2),
|
|
3745
|
+
vat: b(o.vat).minus(l.vat).toFixed(2),
|
|
3746
|
+
gross: b(o.gross).minus(l.gross).toFixed(2),
|
|
3747
|
+
hours: b(o.hours).minus(l.hours).toFixed(0),
|
|
3748
|
+
labourRate: b(o.labourRate).minus(l.labourRate).toFixed(0)
|
|
3749
|
+
};
|
|
3750
|
+
return {
|
|
3751
|
+
original: o,
|
|
3752
|
+
latest: l,
|
|
3753
|
+
savings: s
|
|
3754
|
+
};
|
|
3755
|
+
}
|
|
3756
|
+
static getEmptySummary() {
|
|
3757
|
+
return {
|
|
3758
|
+
original: {
|
|
3759
|
+
labour: '0.00',
|
|
3760
|
+
none: '0.00',
|
|
3761
|
+
parts: '0.00',
|
|
3762
|
+
pm: '0.00',
|
|
3763
|
+
pl: '0.00',
|
|
3764
|
+
specialist: '0.00',
|
|
3765
|
+
other: '0.00',
|
|
3766
|
+
net: '0.00',
|
|
3767
|
+
vat: '0.00',
|
|
3768
|
+
gross: '0.00',
|
|
3769
|
+
hours: '0',
|
|
3770
|
+
labourRate: '0.00'
|
|
3771
|
+
},
|
|
3772
|
+
latest: {
|
|
3773
|
+
labour: '0.00',
|
|
3774
|
+
none: '0.00',
|
|
3775
|
+
parts: '0.00',
|
|
3776
|
+
pm: '0.00',
|
|
3777
|
+
pl: '0.00',
|
|
3778
|
+
specialist: '0.00',
|
|
3779
|
+
other: '0.00',
|
|
3780
|
+
net: '0.00',
|
|
3781
|
+
vat: '0.00',
|
|
3782
|
+
gross: '0.00',
|
|
3783
|
+
hours: '0',
|
|
3784
|
+
labourRate: '0.00'
|
|
3785
|
+
},
|
|
3786
|
+
savings: {
|
|
3787
|
+
labour: '0.00',
|
|
3788
|
+
none: '0.00',
|
|
3789
|
+
parts: '0.00',
|
|
3790
|
+
pm: '0.00',
|
|
3791
|
+
pl: '0.00',
|
|
3792
|
+
specialist: '0.00',
|
|
3793
|
+
other: '0.00',
|
|
3794
|
+
net: '0.00',
|
|
3795
|
+
vat: '0.00',
|
|
3796
|
+
gross: '0.00',
|
|
3797
|
+
hours: '0',
|
|
3798
|
+
labourRate: '0.00'
|
|
3799
|
+
}
|
|
3800
|
+
};
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3324
3803
|
|
|
3325
3804
|
const getEmptyGeoLocation = () => ({
|
|
3326
3805
|
accuracy: 0,
|
|
@@ -3335,8 +3814,44 @@ const getEmptyGeoLocation = () => ({
|
|
|
3335
3814
|
});
|
|
3336
3815
|
|
|
3337
3816
|
/**
|
|
3338
|
-
*
|
|
3339
|
-
|
|
3817
|
+
* Return true IFF the array contains only strings
|
|
3818
|
+
*/
|
|
3819
|
+
const isArrayString = (value) => {
|
|
3820
|
+
return Array.isArray(value) && value.every(i => typeof i === 'string');
|
|
3821
|
+
};
|
|
3822
|
+
|
|
3823
|
+
/**
|
|
3824
|
+
* Return true if the argument is a plain object {}, i.e. not an array, null.
|
|
3825
|
+
*/
|
|
3826
|
+
function isPlainObject(value) {
|
|
3827
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
/**
|
|
3831
|
+
* Return an object omitting properties specified by key(s)
|
|
3832
|
+
*
|
|
3833
|
+
* @param obj object to be processed
|
|
3834
|
+
* @param omitKey key or array of keys to be omitted
|
|
3835
|
+
*/
|
|
3836
|
+
const omit = (obj, omitKey) => {
|
|
3837
|
+
return Object.keys(obj).reduce((result, key) => {
|
|
3838
|
+
if (Array.isArray(omitKey)) {
|
|
3839
|
+
if (!omitKey.includes(key)) {
|
|
3840
|
+
result[key] = obj[key];
|
|
3841
|
+
}
|
|
3842
|
+
}
|
|
3843
|
+
else {
|
|
3844
|
+
if (omitKey !== key) {
|
|
3845
|
+
result[key] = obj[key];
|
|
3846
|
+
}
|
|
3847
|
+
}
|
|
3848
|
+
return result;
|
|
3849
|
+
}, {});
|
|
3850
|
+
};
|
|
3851
|
+
|
|
3852
|
+
/**
|
|
3853
|
+
* Try to parse the value as JSON if it looks like a JSON encoded string, return
|
|
3854
|
+
* the original value if it's not a JSON string or parsing fails.
|
|
3340
3855
|
*/
|
|
3341
3856
|
const tryJson = (value) => {
|
|
3342
3857
|
if (typeof value === 'string' && ['{', '['].includes(value.substring(0, 1))) {
|
|
@@ -3350,21 +3865,35 @@ const tryJson = (value) => {
|
|
|
3350
3865
|
return value;
|
|
3351
3866
|
};
|
|
3352
3867
|
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3868
|
+
const nullables = new Set([
|
|
3869
|
+
'created',
|
|
3870
|
+
'modified',
|
|
3871
|
+
'reference',
|
|
3872
|
+
'jobDate',
|
|
3873
|
+
'followUpDate',
|
|
3874
|
+
'followUpStatus',
|
|
3875
|
+
'followUpNote',
|
|
3876
|
+
]);
|
|
3357
3877
|
let jobStaticProps;
|
|
3358
|
-
function
|
|
3878
|
+
function getStaticProps() {
|
|
3359
3879
|
if (jobStaticProps) {
|
|
3360
3880
|
return jobStaticProps;
|
|
3361
3881
|
}
|
|
3362
|
-
return jobStaticProps = new Set(
|
|
3882
|
+
return jobStaticProps = new Set([
|
|
3883
|
+
...Object.getOwnPropertyNames(VasJobDocumentModel.empty()),
|
|
3884
|
+
'assignee'
|
|
3885
|
+
]);
|
|
3886
|
+
}
|
|
3887
|
+
function isArrayOfFields(value) {
|
|
3888
|
+
return !!value && Array.isArray(value);
|
|
3889
|
+
}
|
|
3890
|
+
function isDictionaryOfFields(value) {
|
|
3891
|
+
return !!value && isPlainObject(value);
|
|
3363
3892
|
}
|
|
3364
3893
|
/**
|
|
3365
|
-
*
|
|
3894
|
+
* VasJobBaseModel
|
|
3366
3895
|
*/
|
|
3367
|
-
class
|
|
3896
|
+
class VasJobBaseModel extends VasRestrictedAccountObjectModel {
|
|
3368
3897
|
id;
|
|
3369
3898
|
created;
|
|
3370
3899
|
serverCreated;
|
|
@@ -3379,6 +3908,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3379
3908
|
reference;
|
|
3380
3909
|
jobDate;
|
|
3381
3910
|
jobStatus;
|
|
3911
|
+
jobStatusLastUpdate;
|
|
3382
3912
|
jobType;
|
|
3383
3913
|
assigneeId;
|
|
3384
3914
|
formId;
|
|
@@ -3386,6 +3916,9 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3386
3916
|
pendingFields;
|
|
3387
3917
|
childModified;
|
|
3388
3918
|
version;
|
|
3919
|
+
followUpDate;
|
|
3920
|
+
followUpStatus;
|
|
3921
|
+
followUpNote;
|
|
3389
3922
|
geoLocation;
|
|
3390
3923
|
files;
|
|
3391
3924
|
fields;
|
|
@@ -3394,7 +3927,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3394
3927
|
reports;
|
|
3395
3928
|
tasks;
|
|
3396
3929
|
instruction;
|
|
3397
|
-
constructor(id, created, serverCreated, createdBy, modified, serverModified, modifiedBy, createdByName, modifiedByName, account, accessGroup, reference, jobDate, jobStatus, jobType, assigneeId, formId, timeZoneOffset, pendingFields, childModified, version, geoLocation, files, fields, jobEmails, notes, reports, tasks, instruction) {
|
|
3930
|
+
constructor(id, created, serverCreated, createdBy, modified, serverModified, modifiedBy, createdByName, modifiedByName, account, accessGroup, reference, jobDate, jobStatus, jobStatusLastUpdate, jobType, assigneeId, formId, timeZoneOffset, pendingFields, childModified, version, followUpDate, followUpStatus, followUpNote, geoLocation, files, fields, jobEmails, notes, reports, tasks, instruction) {
|
|
3398
3931
|
super(id, created, serverCreated, createdBy, modified, serverModified, modifiedBy, createdByName, modifiedByName, account, accessGroup);
|
|
3399
3932
|
this.id = id;
|
|
3400
3933
|
this.created = created;
|
|
@@ -3410,6 +3943,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3410
3943
|
this.reference = reference;
|
|
3411
3944
|
this.jobDate = jobDate;
|
|
3412
3945
|
this.jobStatus = jobStatus;
|
|
3946
|
+
this.jobStatusLastUpdate = jobStatusLastUpdate;
|
|
3413
3947
|
this.jobType = jobType;
|
|
3414
3948
|
this.assigneeId = assigneeId;
|
|
3415
3949
|
this.formId = formId;
|
|
@@ -3417,6 +3951,9 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3417
3951
|
this.pendingFields = pendingFields;
|
|
3418
3952
|
this.childModified = childModified;
|
|
3419
3953
|
this.version = version;
|
|
3954
|
+
this.followUpDate = followUpDate;
|
|
3955
|
+
this.followUpStatus = followUpStatus;
|
|
3956
|
+
this.followUpNote = followUpNote;
|
|
3420
3957
|
this.geoLocation = geoLocation;
|
|
3421
3958
|
this.files = files;
|
|
3422
3959
|
this.fields = fields;
|
|
@@ -3436,52 +3973,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3436
3973
|
* Return the list of Job properties
|
|
3437
3974
|
*/
|
|
3438
3975
|
get staticProperties() {
|
|
3439
|
-
|
|
3440
|
-
return jobStaticProps;
|
|
3441
|
-
}
|
|
3442
|
-
return jobStaticProps = new Set(Object.getOwnPropertyNames(VasJobModel.empty()));
|
|
3443
|
-
}
|
|
3444
|
-
/**
|
|
3445
|
-
* @return {VasJobModel}
|
|
3446
|
-
*/
|
|
3447
|
-
static empty() {
|
|
3448
|
-
return new VasJobModel('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', moment().utcOffset(), 0, '', 0, getEmptyGeoLocation(), [], {}, [], [], [], [], null);
|
|
3449
|
-
}
|
|
3450
|
-
static fromDto(dto) {
|
|
3451
|
-
// we have changed the job model and stopped using the dynamic properties
|
|
3452
|
-
// from form group names to hold fields. Instead, we store a simple object
|
|
3453
|
-
// where the control name (minus the "fields." prefix) is the key, and the
|
|
3454
|
-
// field value is the value. However, we have to cater for data that may
|
|
3455
|
-
// be persisted in the old structure, or an API response where fields is an
|
|
3456
|
-
// array of VasFieldDto.
|
|
3457
|
-
// 1: if dto.fields is already an object, we use the existing value
|
|
3458
|
-
const fields = isPlainObject(dto.fields) ?
|
|
3459
|
-
dto.fields :
|
|
3460
|
-
{};
|
|
3461
|
-
// 2: if dto.fields is an array, we're handling a vas-rest response, we
|
|
3462
|
-
// iterate over the fields and update the fields object.
|
|
3463
|
-
Array.isArray(dto.fields) && dto.fields.forEach((field) => {
|
|
3464
|
-
fields[field.controlName.replace('fields.', '')] = tryJson(field.value);
|
|
3465
|
-
});
|
|
3466
|
-
// 3: if `fields` still has no keys, we're restoring a VasJobDto object that
|
|
3467
|
-
// was saved in the old "form-group" style, where dynamic keys are
|
|
3468
|
-
// derived from the form-group names. We'll iterate over those keys, and
|
|
3469
|
-
// update the `fields` object. Once this model is serialized back to a
|
|
3470
|
-
// dto, it will have the new shape.
|
|
3471
|
-
if (Object.keys(fields).length === 0) {
|
|
3472
|
-
Object
|
|
3473
|
-
.keys(dto)
|
|
3474
|
-
.filter(key => !getJobStaticProperties().has(key))
|
|
3475
|
-
.forEach(groupName => {
|
|
3476
|
-
Object
|
|
3477
|
-
.keys(dto[groupName])
|
|
3478
|
-
.forEach(controlName => {
|
|
3479
|
-
const cn = controlName.replace('fields.', '');
|
|
3480
|
-
fields[cn] = dto[groupName][controlName];
|
|
3481
|
-
});
|
|
3482
|
-
});
|
|
3483
|
-
}
|
|
3484
|
-
return new VasJobModel(dto.id || '', dto.created || '', dto.serverCreated || '', dto.createdBy || '', dto.modified || '', dto.serverModified || '', dto.modifiedBy || '', dto.createdByName || '', dto.modifiedByName || '', dto.account || '', dto.accessGroup || '', dto.reference || '', dto.jobDate || '', dto.jobStatus || '', dto.jobType || '', dto.assigneeId || '', dto.formId || dto.lastForm || '', dto.timeZoneOffset || moment().utcOffset(), dto.pendingFields || 0, dto.childModified || '', dto.version || 0, dto.geoLocation || getEmptyGeoLocation(), dto.files || [], fields, dto.jobEmails || [], dto.notes || [], dto.reports || [], dto.tasks || [], dto.instruction || null);
|
|
3976
|
+
return getStaticProps();
|
|
3485
3977
|
}
|
|
3486
3978
|
/**
|
|
3487
3979
|
* Returns an object describing how many attachments were added to this job
|
|
@@ -3522,39 +4014,6 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3522
4014
|
getValueByPath(path = []) {
|
|
3523
4015
|
return getValueByPath(Array.isArray(path) ? path : path.split('.'), this);
|
|
3524
4016
|
}
|
|
3525
|
-
toDto() {
|
|
3526
|
-
return {
|
|
3527
|
-
id: this.id,
|
|
3528
|
-
created: this.created,
|
|
3529
|
-
createdBy: this.createdBy,
|
|
3530
|
-
modified: this.modified,
|
|
3531
|
-
modifiedBy: this.modifiedBy,
|
|
3532
|
-
serverCreated: this.serverCreated,
|
|
3533
|
-
serverModified: this.serverModified,
|
|
3534
|
-
createdByName: this.createdByName,
|
|
3535
|
-
modifiedByName: this.modifiedByName,
|
|
3536
|
-
account: this.account,
|
|
3537
|
-
accessGroup: this.accessGroup,
|
|
3538
|
-
reference: this.reference,
|
|
3539
|
-
jobDate: this.jobDate,
|
|
3540
|
-
jobStatus: this.jobStatus,
|
|
3541
|
-
jobType: this.jobType,
|
|
3542
|
-
assigneeId: this.assigneeId,
|
|
3543
|
-
formId: this.formId,
|
|
3544
|
-
timeZoneOffset: this.timeZoneOffset,
|
|
3545
|
-
pendingFields: this.pendingFields,
|
|
3546
|
-
childModified: this.childModified,
|
|
3547
|
-
version: this.version,
|
|
3548
|
-
geoLocation: this.geoLocation,
|
|
3549
|
-
files: this.files,
|
|
3550
|
-
fields: this.fields,
|
|
3551
|
-
jobEmails: this.jobEmails,
|
|
3552
|
-
notes: this.notes,
|
|
3553
|
-
reports: this.reports,
|
|
3554
|
-
tasks: this.tasks,
|
|
3555
|
-
instruction: this.instruction
|
|
3556
|
-
};
|
|
3557
|
-
}
|
|
3558
4017
|
/**
|
|
3559
4018
|
* This method will parse a syntax that allows us to build strings from the
|
|
3560
4019
|
* values of from the job model. For example if the job model was:
|
|
@@ -3587,7 +4046,6 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3587
4046
|
if (!value || typeof value !== 'string') {
|
|
3588
4047
|
return '';
|
|
3589
4048
|
}
|
|
3590
|
-
const fields = this.fields;
|
|
3591
4049
|
return value.replace(/({[^}]*})/g, (match, token) => {
|
|
3592
4050
|
const syntax = token.substring(1, token.length - 1);
|
|
3593
4051
|
let [key, filter] = syntax.split('|');
|
|
@@ -3613,8 +4071,8 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3613
4071
|
if (objectKey === 'job') {
|
|
3614
4072
|
result = (this.getValueByPath(path) || '').toString();
|
|
3615
4073
|
}
|
|
3616
|
-
else if (objectKey === 'fields'
|
|
3617
|
-
result = (getValueByPath(
|
|
4074
|
+
else if (objectKey === 'fields') {
|
|
4075
|
+
result = (this.getValueByPath(['fields', ...path]) || '').toString();
|
|
3618
4076
|
}
|
|
3619
4077
|
else if (objectKey.length && options.objects && options.objects[objectKey] !== undefined) {
|
|
3620
4078
|
result = (getValueByPath(path, options.objects[objectKey]) || '').toString();
|
|
@@ -3672,8 +4130,242 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3672
4130
|
'assigneeId',
|
|
3673
4131
|
'timeZoneOffset',
|
|
3674
4132
|
'pendingFields',
|
|
3675
|
-
'formId'
|
|
3676
|
-
|
|
4133
|
+
'formId',
|
|
4134
|
+
'followUpDate',
|
|
4135
|
+
'followUpStatus',
|
|
4136
|
+
'followUpNote',
|
|
4137
|
+
], (value, key) => value[key] === null && nullables.has(key) ? '~' : value[key]);
|
|
4138
|
+
}
|
|
4139
|
+
}
|
|
4140
|
+
class VasJobRelationalModel extends VasJobBaseModel {
|
|
4141
|
+
getValueByPath(path = []) {
|
|
4142
|
+
const parts = Array.isArray(path) ? path : path.split('.');
|
|
4143
|
+
if (parts[0] === 'fields') {
|
|
4144
|
+
return this.getFieldValueByPath(parts[1], parts.slice(2));
|
|
4145
|
+
}
|
|
4146
|
+
return getValueByPath(parts, this);
|
|
4147
|
+
}
|
|
4148
|
+
getFieldsMap() {
|
|
4149
|
+
return this.fields.reduce((p, c) => {
|
|
4150
|
+
p[c.controlName] = c.value;
|
|
4151
|
+
return p;
|
|
4152
|
+
}, {});
|
|
4153
|
+
}
|
|
4154
|
+
getFieldValueByPath(controlName, path) {
|
|
4155
|
+
for (const field of this.fields) {
|
|
4156
|
+
if (field.controlName === controlName) {
|
|
4157
|
+
if (path.length === 0) {
|
|
4158
|
+
return field.value;
|
|
4159
|
+
}
|
|
4160
|
+
if (field.value === null) {
|
|
4161
|
+
return path.length >= 1 ? undefined : null;
|
|
4162
|
+
}
|
|
4163
|
+
if (isPlainObject(field.value)) {
|
|
4164
|
+
return getValueByPath(path, field.value);
|
|
4165
|
+
}
|
|
4166
|
+
return undefined;
|
|
4167
|
+
}
|
|
4168
|
+
}
|
|
4169
|
+
return undefined;
|
|
4170
|
+
}
|
|
4171
|
+
static fromDto(dto) {
|
|
4172
|
+
if (dto.fields !== undefined && !Array.isArray(dto.fields)) {
|
|
4173
|
+
throw Error('fields must be an array');
|
|
4174
|
+
}
|
|
4175
|
+
return new VasJobRelationalModel(dto.id || '', dto.created || '', dto.serverCreated || '', dto.createdBy || '', dto.modified || '', dto.serverModified || '', dto.modifiedBy || '', dto.createdByName || '', dto.modifiedByName || '', dto.account || '', dto.accessGroup || '', dto.reference || '', dto.jobDate || '', dto.jobStatus || '', dto.jobStatusLastUpdate || '', dto.jobType || '', dto.assigneeId || '', dto.formId || dto.lastForm || '', dto.timeZoneOffset || moment().utcOffset(), dto.pendingFields || 0, dto.childModified || '', dto.version || 0, dto.followUpDate || '', dto.followUpStatus || '', dto.followUpNote || '', dto.geoLocation || getEmptyGeoLocation(), dto.files || [], (dto.fields || []).map(f => VasFieldModel.fromDto(f)), dto.jobEmails || [], dto.notes || [], dto.reports || [], dto.tasks || [], dto.instruction || null);
|
|
4176
|
+
}
|
|
4177
|
+
static empty() {
|
|
4178
|
+
return new VasJobRelationalModel('', // id
|
|
4179
|
+
'', // created
|
|
4180
|
+
'', // serverCreated
|
|
4181
|
+
'', // createdBy
|
|
4182
|
+
'', // modified
|
|
4183
|
+
'', // serverModified
|
|
4184
|
+
'', // modifiedBy
|
|
4185
|
+
'', // createdByName
|
|
4186
|
+
'', // modifiedByName
|
|
4187
|
+
'', // account
|
|
4188
|
+
'', // accessGroup
|
|
4189
|
+
'', // reference
|
|
4190
|
+
'', // jobDate
|
|
4191
|
+
'', // jobStatus
|
|
4192
|
+
'', // jobStatusLastUpdate
|
|
4193
|
+
'', // jobType
|
|
4194
|
+
'', // assigneeId
|
|
4195
|
+
'', // formId
|
|
4196
|
+
moment().utcOffset(), // timeZoneOffset
|
|
4197
|
+
0, // pendingFields: number,
|
|
4198
|
+
'', // childModified: string,
|
|
4199
|
+
0, // version: number,
|
|
4200
|
+
'', // followUpDate: string,
|
|
4201
|
+
'', // followUpStatus: string,
|
|
4202
|
+
'', // followUpNote: string,
|
|
4203
|
+
getEmptyGeoLocation(), // geoLocation: GeoLocation,
|
|
4204
|
+
[], // files: Array<VasFileDto>,
|
|
4205
|
+
[], // fields: FType,
|
|
4206
|
+
[], // jobEmails: Array<VasJobEmailDto>,
|
|
4207
|
+
[], // notes: Array<VasNoteDto>,
|
|
4208
|
+
[], // reports: Array<VasReportDto>,
|
|
4209
|
+
[], // tasks: Array<VasTaskDto>,
|
|
4210
|
+
null // instruction: VasInstructionDto | null
|
|
4211
|
+
);
|
|
4212
|
+
}
|
|
4213
|
+
toDto() {
|
|
4214
|
+
return {
|
|
4215
|
+
id: this.id,
|
|
4216
|
+
created: this.created,
|
|
4217
|
+
createdBy: this.createdBy,
|
|
4218
|
+
modified: this.modified,
|
|
4219
|
+
modifiedBy: this.modifiedBy,
|
|
4220
|
+
serverCreated: this.serverCreated,
|
|
4221
|
+
serverModified: this.serverModified,
|
|
4222
|
+
createdByName: this.createdByName,
|
|
4223
|
+
modifiedByName: this.modifiedByName,
|
|
4224
|
+
account: this.account,
|
|
4225
|
+
accessGroup: this.accessGroup,
|
|
4226
|
+
reference: this.reference,
|
|
4227
|
+
jobDate: this.jobDate,
|
|
4228
|
+
jobStatus: this.jobStatus,
|
|
4229
|
+
jobStatusLastUpdate: this.jobStatusLastUpdate,
|
|
4230
|
+
jobType: this.jobType,
|
|
4231
|
+
assigneeId: this.assigneeId,
|
|
4232
|
+
formId: this.formId,
|
|
4233
|
+
timeZoneOffset: this.timeZoneOffset,
|
|
4234
|
+
pendingFields: this.pendingFields,
|
|
4235
|
+
childModified: this.childModified,
|
|
4236
|
+
version: this.version,
|
|
4237
|
+
followUpDate: this.followUpDate,
|
|
4238
|
+
followUpStatus: this.followUpStatus,
|
|
4239
|
+
followUpNote: this.followUpNote,
|
|
4240
|
+
geoLocation: this.geoLocation,
|
|
4241
|
+
files: this.files,
|
|
4242
|
+
fields: this.fields.map(f => f.toDto()),
|
|
4243
|
+
jobEmails: this.jobEmails,
|
|
4244
|
+
notes: this.notes,
|
|
4245
|
+
reports: this.reports,
|
|
4246
|
+
tasks: this.tasks,
|
|
4247
|
+
instruction: this.instruction
|
|
4248
|
+
};
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
4251
|
+
class VasJobDocumentModel extends VasJobBaseModel {
|
|
4252
|
+
static fromRelationalDto(dto) {
|
|
4253
|
+
return new VasJobDocumentModel(dto.id || '', dto.created || '', dto.serverCreated || '', dto.createdBy || '', dto.modified || '', dto.serverModified || '', dto.modifiedBy || '', dto.createdByName || '', dto.modifiedByName || '', dto.account || '', dto.accessGroup || '', dto.reference || '', dto.jobDate || '', dto.jobStatus || '', dto.jobStatusLastUpdate || '', dto.jobType || '', dto.assigneeId || '', dto.formId || dto.lastForm || '', dto.timeZoneOffset || moment().utcOffset(), dto.pendingFields || 0, dto.childModified || '', dto.version || 0, dto.followUpDate || '', dto.followUpStatus || '', dto.followUpNote || '', dto.geoLocation || getEmptyGeoLocation(), dto.files || [], (dto.fields || []).reduce((p, c) => {
|
|
4254
|
+
p[c.controlName.replace('fields.', '')] = c.value;
|
|
4255
|
+
return p;
|
|
4256
|
+
}, {}), dto.jobEmails || [], dto.notes || [], dto.reports || [], dto.tasks || [], dto.instruction || null);
|
|
4257
|
+
}
|
|
4258
|
+
static fromDto(dto, options = { disableMigrateCheck: false }) {
|
|
4259
|
+
let fields = {};
|
|
4260
|
+
if (dto.fields !== undefined) {
|
|
4261
|
+
if (isArrayOfFields(dto.fields)) {
|
|
4262
|
+
for (const field of dto.fields) {
|
|
4263
|
+
fields[field.controlName.replace('fields.', '')] =
|
|
4264
|
+
tryJson(field.value);
|
|
4265
|
+
}
|
|
4266
|
+
}
|
|
4267
|
+
else if (isDictionaryOfFields(dto.fields)) {
|
|
4268
|
+
fields = dto.fields;
|
|
4269
|
+
}
|
|
4270
|
+
}
|
|
4271
|
+
// this code is checking if a have a document in the old dynamic job style,
|
|
4272
|
+
// i.e. where there are keys in the job object that come from the form-group
|
|
4273
|
+
// names. I did consider comparing the number of keys in the dto vs the
|
|
4274
|
+
// number of expected keys, but this will fail if we try to read old objects
|
|
4275
|
+
// that don't have new properties added. So we always check by default. We
|
|
4276
|
+
// can skip this check by setting disableMigrateCheck in the options.
|
|
4277
|
+
if (!options || !options.disableMigrateCheck) {
|
|
4278
|
+
const ddto = dto;
|
|
4279
|
+
const actualKeys = Object.keys(ddto);
|
|
4280
|
+
actualKeys.reduce((f, groupName) => {
|
|
4281
|
+
if (getStaticProps().has(groupName)) {
|
|
4282
|
+
return f;
|
|
4283
|
+
}
|
|
4284
|
+
Object
|
|
4285
|
+
.keys(ddto[groupName])
|
|
4286
|
+
.forEach(controlName => {
|
|
4287
|
+
if (!controlName.startsWith('fields.')) {
|
|
4288
|
+
return;
|
|
4289
|
+
}
|
|
4290
|
+
f[controlName.slice(7)] = ddto[groupName][controlName];
|
|
4291
|
+
});
|
|
4292
|
+
return f;
|
|
4293
|
+
}, fields);
|
|
4294
|
+
}
|
|
4295
|
+
return new VasJobDocumentModel(dto.id || '', dto.created || '', dto.serverCreated || '', dto.createdBy || '', dto.modified || '', dto.serverModified || '', dto.modifiedBy || '', dto.createdByName || '', dto.modifiedByName || '', dto.account || '', dto.accessGroup || '', dto.reference || '', dto.jobDate || '', dto.jobStatus || '', dto.jobStatusLastUpdate || '', dto.jobType || '', dto.assigneeId || '', dto.formId || dto.lastForm || '', dto.timeZoneOffset || moment().utcOffset(), dto.pendingFields || 0, dto.childModified || '', dto.version || 0, dto.followUpDate || '', dto.followUpStatus || '', dto.followUpNote || '', dto.geoLocation || getEmptyGeoLocation(), dto.files || [], fields, dto.jobEmails || [], dto.notes || [], dto.reports || [], dto.tasks || [], dto.instruction || null);
|
|
4296
|
+
}
|
|
4297
|
+
static empty() {
|
|
4298
|
+
return new VasJobDocumentModel('', // id
|
|
4299
|
+
'', // created
|
|
4300
|
+
'', // serverCreated
|
|
4301
|
+
'', // createdBy
|
|
4302
|
+
'', // modified
|
|
4303
|
+
'', // serverModified
|
|
4304
|
+
'', // modifiedBy
|
|
4305
|
+
'', // createdByName
|
|
4306
|
+
'', // modifiedByName
|
|
4307
|
+
'', // account
|
|
4308
|
+
'', // accessGroup
|
|
4309
|
+
'', // reference
|
|
4310
|
+
'', // jobDate
|
|
4311
|
+
'', // jobStatus
|
|
4312
|
+
'', // jobStatusLastUpdate
|
|
4313
|
+
'', // jobType
|
|
4314
|
+
'', // assigneeId
|
|
4315
|
+
'', // formId
|
|
4316
|
+
moment().utcOffset(), // timeZoneOffset
|
|
4317
|
+
0, // pendingFields: number,
|
|
4318
|
+
'', // childModified: string,
|
|
4319
|
+
0, // version: number,
|
|
4320
|
+
'', // followUpDate: string,
|
|
4321
|
+
'', // followUpStatus: string,
|
|
4322
|
+
'', // followUpNote: string,
|
|
4323
|
+
getEmptyGeoLocation(), // geoLocation: GeoLocation,
|
|
4324
|
+
[], // files: Array<VasFileDto>,
|
|
4325
|
+
{}, // fields: FType,
|
|
4326
|
+
[], // jobEmails: Array<VasJobEmailDto>,
|
|
4327
|
+
[], // notes: Array<VasNoteDto>,
|
|
4328
|
+
[], // reports: Array<VasReportDto>,
|
|
4329
|
+
[], // tasks: Array<VasTaskDto>,
|
|
4330
|
+
null // instruction: VasInstructionDto | null
|
|
4331
|
+
);
|
|
4332
|
+
}
|
|
4333
|
+
toDto() {
|
|
4334
|
+
return {
|
|
4335
|
+
id: this.id,
|
|
4336
|
+
created: this.created,
|
|
4337
|
+
createdBy: this.createdBy,
|
|
4338
|
+
modified: this.modified,
|
|
4339
|
+
modifiedBy: this.modifiedBy,
|
|
4340
|
+
serverCreated: this.serverCreated,
|
|
4341
|
+
serverModified: this.serverModified,
|
|
4342
|
+
createdByName: this.createdByName,
|
|
4343
|
+
modifiedByName: this.modifiedByName,
|
|
4344
|
+
account: this.account,
|
|
4345
|
+
accessGroup: this.accessGroup,
|
|
4346
|
+
reference: this.reference,
|
|
4347
|
+
jobDate: this.jobDate,
|
|
4348
|
+
jobStatus: this.jobStatus,
|
|
4349
|
+
jobStatusLastUpdate: this.jobStatusLastUpdate,
|
|
4350
|
+
jobType: this.jobType,
|
|
4351
|
+
assigneeId: this.assigneeId,
|
|
4352
|
+
formId: this.formId,
|
|
4353
|
+
timeZoneOffset: this.timeZoneOffset,
|
|
4354
|
+
pendingFields: this.pendingFields,
|
|
4355
|
+
childModified: this.childModified,
|
|
4356
|
+
version: this.version,
|
|
4357
|
+
followUpDate: this.followUpDate,
|
|
4358
|
+
followUpStatus: this.followUpStatus,
|
|
4359
|
+
followUpNote: this.followUpNote,
|
|
4360
|
+
geoLocation: this.geoLocation,
|
|
4361
|
+
files: this.files,
|
|
4362
|
+
fields: this.fields,
|
|
4363
|
+
jobEmails: this.jobEmails,
|
|
4364
|
+
notes: this.notes,
|
|
4365
|
+
reports: this.reports,
|
|
4366
|
+
tasks: this.tasks,
|
|
4367
|
+
instruction: this.instruction
|
|
4368
|
+
};
|
|
3677
4369
|
}
|
|
3678
4370
|
}
|
|
3679
4371
|
|
|
@@ -4284,5 +4976,5 @@ class VasVehicleModel extends VasAccountObjectModel {
|
|
|
4284
4976
|
* Generated bundle index. Do not edit.
|
|
4285
4977
|
*/
|
|
4286
4978
|
|
|
4287
|
-
export { VasAccessGroupModel, VasAccountIndexingMode, VasAccountObjectModel, VasBaseModel, VasBranchModel, VasContactModel, VasContactTypeModel, VasControlConfigDirection, VasControlModel, VasControlTypeModel, VasFieldModel, VasFileModel, VasFireUserModel, VasFormConfigModel, VasFormModel, VasGroupModel, VasInstructionJobFieldModel, VasInstructionJobModel, VasInstructionModel, VasInstructionProviderModel, VasInvitationModel, VasInvitationTypeEnum, VasJobActionControlsStepModel, VasJobActionEmailFormStepModel, VasJobActionInstructionStepModel, VasJobActionModel, VasJobActionNotePromptStepModel, VasJobActionSetDatetimeStepModel, VasJobActionSetJobStatusStepModel, VasJobActionSetValueStepModel, VasJobActionWebhookStepModel, VasJobCopyModel, VasJobDataModel, VasJobEmailModel,
|
|
4979
|
+
export { EstimateControlValueModel, EstimateItemModel, EstimateModel, VasAccessGroupModel, VasAccountIndexingMode, VasAccountObjectModel, VasBaseModel, VasBranchModel, VasContactModel, VasContactTypeModel, VasControlConfigDirection, VasControlModel, VasControlTypeModel, VasFieldModel, VasFileModel, VasFireUserModel, VasFormConfigModel, VasFormModel, VasGroupModel, VasInstructionJobFieldModel, VasInstructionJobModel, VasInstructionModel, VasInstructionProviderModel, VasInvitationModel, VasInvitationTypeEnum, VasJobActionControlsStepModel, VasJobActionEmailFormStepModel, VasJobActionInstructionStepModel, VasJobActionModel, VasJobActionNotePromptStepModel, VasJobActionSetDatetimeStepModel, VasJobActionSetJobStatusStepModel, VasJobActionSetValueStepModel, VasJobActionWebhookStepModel, VasJobBaseModel, VasJobCopyModel, VasJobDataModel, VasJobDocumentModel, VasJobEmailModel, VasJobRelationalModel, VasJobStatusModel, VasJobTypeModel, VasLookupModel, VasLookupTypeModel, VasMembershipModel, VasNoteModel, VasReportLayoutModel, VasReportModel, VasReportRequestModel, VasRestrictedAccountObjectModel, VasTaskModel, VasTaskTypeModel, VasUserModel, VasVehicleModel, getEmptyGeoLocation, getValueByPath, isArrayString, isCameraControlValueV1, isCameraControlValueV2, isFileDto, isJobAutomationStep, isJobControlsStep, isJobEmailFormStep, isJobInstructionStep, isJobNotePromptStep, isJobSetDatetimeStep, isJobSetJobStatusStep, isJobSetValueStep, isJobWebhookStep, isNumeric, isPlainObject, omit, only, prepareFieldApiValue, stepModelFactory, tryJson };
|
|
4288
4980
|
//# sourceMappingURL=ironcode-vas-lib.mjs.map
|