@ironcode/vas-lib 3.0.0-alpha.1 → 3.0.0-alpha.3
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-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-job.model.js +1 -1
- 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 +16 -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 +24 -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 +121 -0
- package/cjs/lib/model/estimate-control/estimate-item.model.js.map +1 -0
- package/cjs/lib/model/estimate-control/estimate.dto.d.ts +37 -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 +265 -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 +8 -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 +49 -60
- 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 +548 -56
- 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-field.dto.d.ts +3 -4
- 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 +15 -0
- package/lib/model/estimate-control/estimate-item.model.d.ts +23 -0
- package/lib/model/estimate-control/estimate.dto.d.ts +36 -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 +7 -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
|
|
@@ -3258,69 +3260,527 @@ 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
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
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 (!(scope === undefined || scope === null) && index < length) {
|
|
3315
|
+
scope = scope[p[index++]];
|
|
3316
|
+
}
|
|
3317
|
+
if (!(index && index == length) || scope === null) {
|
|
3318
|
+
return undefined;
|
|
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
|
+
constructor(id, description, type, quantity, quantityAdjusted, units, unitsAdjusted, price, priceAdjusted, workCategory, costCategory, comment) {
|
|
3350
|
+
this.id = id;
|
|
3351
|
+
this.description = description;
|
|
3352
|
+
this.type = type;
|
|
3353
|
+
this.quantity = quantity;
|
|
3354
|
+
this.quantityAdjusted = quantityAdjusted;
|
|
3355
|
+
this.units = units;
|
|
3356
|
+
this.unitsAdjusted = unitsAdjusted;
|
|
3357
|
+
this.price = price;
|
|
3358
|
+
this.priceAdjusted = priceAdjusted;
|
|
3359
|
+
this.workCategory = workCategory;
|
|
3360
|
+
this.costCategory = costCategory;
|
|
3361
|
+
this.comment = comment;
|
|
3362
|
+
}
|
|
3363
|
+
getTotalUnits(adjusted = false) {
|
|
3364
|
+
return adjusted ?
|
|
3365
|
+
b$2(this.quantityAdjusted || '0').mul(this.unitsAdjusted || '0').toFixed(2) :
|
|
3366
|
+
b$2(this.quantity || '0').mul(this.units || '0').toFixed(2);
|
|
3367
|
+
}
|
|
3368
|
+
getLineValue(labourRate = '1', timeBasis = '1', adjusted = false) {
|
|
3369
|
+
const cat = this.costCategory || 'none';
|
|
3370
|
+
if (this.workCategory === 'removed') {
|
|
3371
|
+
return '0';
|
|
3292
3372
|
}
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3373
|
+
const units = (adjusted ? this.unitsAdjusted : this.units) || 0;
|
|
3374
|
+
const quantity = (adjusted ? this.quantityAdjusted : this.quantity) || 0;
|
|
3375
|
+
const price = (adjusted ? this.priceAdjusted : this.price) || '';
|
|
3376
|
+
try {
|
|
3377
|
+
switch (cat) {
|
|
3378
|
+
case 'labour': {
|
|
3379
|
+
return price != '' ?
|
|
3380
|
+
price :
|
|
3381
|
+
b$2(quantity || '0')
|
|
3382
|
+
.mul(units || '0')
|
|
3383
|
+
.mul(labourRate || '0')
|
|
3384
|
+
.div(timeBasis || '1')
|
|
3385
|
+
.toFixed(2);
|
|
3386
|
+
}
|
|
3387
|
+
case 'pm': {
|
|
3388
|
+
return b$2(price || '0')
|
|
3389
|
+
.mul(quantity || '0')
|
|
3390
|
+
.toFixed(2);
|
|
3391
|
+
}
|
|
3392
|
+
case 'parts': {
|
|
3393
|
+
return b$2(price || '0')
|
|
3394
|
+
.mul(quantity || '0')
|
|
3395
|
+
.toFixed(2);
|
|
3396
|
+
}
|
|
3397
|
+
case 'specialist': {
|
|
3398
|
+
return b$2(price || '0')
|
|
3399
|
+
.mul(quantity || '0')
|
|
3400
|
+
.toFixed(2);
|
|
3401
|
+
}
|
|
3402
|
+
default: {
|
|
3403
|
+
return '0';
|
|
3404
|
+
}
|
|
3301
3405
|
}
|
|
3302
|
-
return val1[path[2]];
|
|
3303
3406
|
}
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
if (!val0) {
|
|
3307
|
-
return undefined;
|
|
3308
|
-
}
|
|
3309
|
-
const val1 = val0[path[1]];
|
|
3310
|
-
if (!val1) {
|
|
3311
|
-
return undefined;
|
|
3312
|
-
}
|
|
3313
|
-
const val2 = val1[path[2]];
|
|
3314
|
-
if (!val2) {
|
|
3315
|
-
return undefined;
|
|
3316
|
-
}
|
|
3317
|
-
return val2[path[3]];
|
|
3407
|
+
catch (e) {
|
|
3408
|
+
console.warn(e);
|
|
3318
3409
|
}
|
|
3319
|
-
|
|
3320
|
-
|
|
3410
|
+
return '0';
|
|
3411
|
+
}
|
|
3412
|
+
toDto() {
|
|
3413
|
+
return {
|
|
3414
|
+
id: this.id,
|
|
3415
|
+
description: this.description,
|
|
3416
|
+
type: this.type,
|
|
3417
|
+
quantity: this.quantity,
|
|
3418
|
+
quantityAdjusted: this.quantityAdjusted,
|
|
3419
|
+
units: this.units,
|
|
3420
|
+
unitsAdjusted: this.unitsAdjusted,
|
|
3421
|
+
price: this.price,
|
|
3422
|
+
priceAdjusted: this.priceAdjusted,
|
|
3423
|
+
workCategory: this.workCategory,
|
|
3424
|
+
costCategory: this.costCategory,
|
|
3425
|
+
comment: this.comment
|
|
3426
|
+
};
|
|
3427
|
+
}
|
|
3428
|
+
static create() {
|
|
3429
|
+
return new EstimateItemModel(v4(), '', '', 1, 1, 0, 0, '', '', 'none', 'none', '');
|
|
3430
|
+
}
|
|
3431
|
+
static fromDto(dto) {
|
|
3432
|
+
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 || '');
|
|
3433
|
+
}
|
|
3434
|
+
static equal(a, b) {
|
|
3435
|
+
return (a?.id === b?.id &&
|
|
3436
|
+
a?.description === b?.description &&
|
|
3437
|
+
a?.type === b?.type &&
|
|
3438
|
+
a?.quantity === b?.quantity &&
|
|
3439
|
+
a?.quantityAdjusted === b?.quantityAdjusted &&
|
|
3440
|
+
a?.units === b?.units &&
|
|
3441
|
+
a?.unitsAdjusted === b?.unitsAdjusted &&
|
|
3442
|
+
a?.price === b?.price &&
|
|
3443
|
+
a?.priceAdjusted === b?.priceAdjusted &&
|
|
3444
|
+
a?.workCategory === b?.workCategory &&
|
|
3445
|
+
a?.costCategory === b?.costCategory &&
|
|
3446
|
+
a?.comment === b?.comment);
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
|
|
3450
|
+
const b$1 = (value = '0') => {
|
|
3451
|
+
try {
|
|
3452
|
+
if (typeof value === 'string') {
|
|
3453
|
+
return new Big(value.replace(/[^\d^.]/g, ''));
|
|
3321
3454
|
}
|
|
3455
|
+
return new Big(value);
|
|
3456
|
+
}
|
|
3457
|
+
catch (e) {
|
|
3458
|
+
console.error(`failed to construct Big from value '${value}'`);
|
|
3459
|
+
return new Big('0');
|
|
3322
3460
|
}
|
|
3323
3461
|
};
|
|
3462
|
+
class EstimateModel {
|
|
3463
|
+
id = v4();
|
|
3464
|
+
source = 'manual';
|
|
3465
|
+
label = '';
|
|
3466
|
+
comment = '';
|
|
3467
|
+
timestamp = moment().toISOString();
|
|
3468
|
+
version = 1;
|
|
3469
|
+
net = '0.00';
|
|
3470
|
+
vat = '0.00';
|
|
3471
|
+
gross = '0.00';
|
|
3472
|
+
labourRate = '1';
|
|
3473
|
+
vatRate = '0.00';
|
|
3474
|
+
sundryRate = '0.00';
|
|
3475
|
+
sundryMax = '0.00';
|
|
3476
|
+
sundryFixed = '0.00';
|
|
3477
|
+
sundryMethod = 'fixed';
|
|
3478
|
+
partsDiscount = '0.00';
|
|
3479
|
+
paintDiscount = '0.00';
|
|
3480
|
+
timeBasis = '1';
|
|
3481
|
+
adjusted = false;
|
|
3482
|
+
items = [];
|
|
3483
|
+
summaryNet = {
|
|
3484
|
+
labour: '0.00',
|
|
3485
|
+
none: '0.00',
|
|
3486
|
+
parts: '0.00',
|
|
3487
|
+
pm: '0.00',
|
|
3488
|
+
pl: '0.00',
|
|
3489
|
+
specialist: '0.00',
|
|
3490
|
+
other: '0.00',
|
|
3491
|
+
gross: '0.00',
|
|
3492
|
+
net: '0.00',
|
|
3493
|
+
hours: '0.00',
|
|
3494
|
+
vat: '0.00',
|
|
3495
|
+
labourRate: '0.00',
|
|
3496
|
+
};
|
|
3497
|
+
summary = {
|
|
3498
|
+
labour: '0.00',
|
|
3499
|
+
none: '0.00',
|
|
3500
|
+
parts: '0.00',
|
|
3501
|
+
pm: '0.00',
|
|
3502
|
+
pl: '0.00',
|
|
3503
|
+
specialist: '0.00',
|
|
3504
|
+
other: '0.00',
|
|
3505
|
+
gross: '0.00',
|
|
3506
|
+
net: '0.00',
|
|
3507
|
+
hours: '0.00',
|
|
3508
|
+
vat: '0.00',
|
|
3509
|
+
labourRate: '0.00',
|
|
3510
|
+
};
|
|
3511
|
+
summaryAdjusted = {
|
|
3512
|
+
labour: '0.00',
|
|
3513
|
+
none: '0.00',
|
|
3514
|
+
parts: '0.00',
|
|
3515
|
+
pm: '0.00',
|
|
3516
|
+
pl: '0.00',
|
|
3517
|
+
specialist: '0.00',
|
|
3518
|
+
other: '0.00',
|
|
3519
|
+
gross: '0.00',
|
|
3520
|
+
net: '0.00',
|
|
3521
|
+
hours: '0.00',
|
|
3522
|
+
vat: '0.00',
|
|
3523
|
+
labourRate: '0.00',
|
|
3524
|
+
};
|
|
3525
|
+
static create(source = 'manual') {
|
|
3526
|
+
const model = new EstimateModel();
|
|
3527
|
+
model.source = source;
|
|
3528
|
+
return model;
|
|
3529
|
+
}
|
|
3530
|
+
static fromDto(dto) {
|
|
3531
|
+
const model = new EstimateModel();
|
|
3532
|
+
Object.assign(model, {
|
|
3533
|
+
...dto,
|
|
3534
|
+
items: dto.items?.map(item => EstimateItemModel.fromDto(item)),
|
|
3535
|
+
});
|
|
3536
|
+
model.calculate();
|
|
3537
|
+
return model;
|
|
3538
|
+
}
|
|
3539
|
+
addItem(modelOrDto, opts) {
|
|
3540
|
+
this.items.push(modelOrDto instanceof EstimateItemModel ?
|
|
3541
|
+
modelOrDto :
|
|
3542
|
+
EstimateItemModel.fromDto(modelOrDto));
|
|
3543
|
+
if (!opts || (opts && opts.calculate)) {
|
|
3544
|
+
this.calculate();
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
addItems(items, opts) {
|
|
3548
|
+
this.items = this.items.concat(items);
|
|
3549
|
+
if (!opts || (opts && opts.calculate)) {
|
|
3550
|
+
this.calculate();
|
|
3551
|
+
}
|
|
3552
|
+
}
|
|
3553
|
+
calculate() {
|
|
3554
|
+
this.summaryNet = this.getSummaryNet(false);
|
|
3555
|
+
if (this.adjusted) {
|
|
3556
|
+
this.summaryAdjusted = this.getSummary(this.summaryNet, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount, this.adjusted);
|
|
3557
|
+
}
|
|
3558
|
+
this.summary = this.getSummary(this.summaryNet, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount, this.adjusted);
|
|
3559
|
+
this.net = b$1(0)
|
|
3560
|
+
.add(this.summary.labour)
|
|
3561
|
+
.add(this.summary.none)
|
|
3562
|
+
.add(this.summary.parts)
|
|
3563
|
+
.add(this.summary.pm)
|
|
3564
|
+
.add(this.summary.specialist)
|
|
3565
|
+
.toFixed(2);
|
|
3566
|
+
this.vat = b$1(this.net || '0').mul(this.vatRate || '0').toFixed(2);
|
|
3567
|
+
this.gross = b$1(this.net || '0').add(this.vat || '0').toFixed(2);
|
|
3568
|
+
}
|
|
3569
|
+
/**
|
|
3570
|
+
* Returns the net summary (before sundries and discounts) of the estimate.
|
|
3571
|
+
* By summary, we mean grouping the costs by cost category.
|
|
3572
|
+
*
|
|
3573
|
+
* @param adjusted if the values should be calculated using the original or
|
|
3574
|
+
* adjusted values
|
|
3575
|
+
*/
|
|
3576
|
+
getSummaryNet(adjusted = false) {
|
|
3577
|
+
const summary = this.items.reduce((map, item) => {
|
|
3578
|
+
map[item.costCategory] = b$1(map[item.costCategory] || '0')
|
|
3579
|
+
.add(item.getLineValue(this.labourRate, this.timeBasis, adjusted))
|
|
3580
|
+
.toFixed(2);
|
|
3581
|
+
return map;
|
|
3582
|
+
}, {
|
|
3583
|
+
labour: '0.00',
|
|
3584
|
+
none: '0.00',
|
|
3585
|
+
parts: '0.00',
|
|
3586
|
+
pm: '0.00',
|
|
3587
|
+
pl: '0.00',
|
|
3588
|
+
specialist: '0.00',
|
|
3589
|
+
other: '0.00',
|
|
3590
|
+
net: '0.00',
|
|
3591
|
+
vat: '0.00',
|
|
3592
|
+
gross: '0.00',
|
|
3593
|
+
hours: '0.00',
|
|
3594
|
+
labourRate: '0',
|
|
3595
|
+
});
|
|
3596
|
+
if (this.source === 'audatex') {
|
|
3597
|
+
const mechHours = this.items
|
|
3598
|
+
.filter(item => item.workCategory !== 'paint')
|
|
3599
|
+
.reduce((h, item) => h.add(b$1(item.getTotalUnits(adjusted))), b$1())
|
|
3600
|
+
.div(this.timeBasis || '1')
|
|
3601
|
+
.round(2);
|
|
3602
|
+
const paintHours = this.items
|
|
3603
|
+
.filter(item => item.workCategory === 'paint')
|
|
3604
|
+
.reduce((h, item) => h.add(b$1(item.getTotalUnits(adjusted))), b$1())
|
|
3605
|
+
.div(this.timeBasis || '1')
|
|
3606
|
+
.round(1);
|
|
3607
|
+
const mechCost = mechHours.mul(this.labourRate || '0');
|
|
3608
|
+
const paintCost = paintHours.mul(this.labourRate || '0');
|
|
3609
|
+
summary.labour = mechCost.add(paintCost).toFixed(2);
|
|
3610
|
+
}
|
|
3611
|
+
return summary;
|
|
3612
|
+
}
|
|
3613
|
+
/**
|
|
3614
|
+
* Applies the sundry and discount values to the net summary.
|
|
3615
|
+
|
|
3616
|
+
*/
|
|
3617
|
+
getSummary(summaryNet, sundryRate, sundryMax, sundryFixed, sundryMethod, partsDiscount, paintDiscount, adjusted) {
|
|
3618
|
+
const partsDisc = b$1('1').minus(partsDiscount || '0');
|
|
3619
|
+
const paintDisc = b$1('1').minus(paintDiscount || '0');
|
|
3620
|
+
let partsSundry = '0.00';
|
|
3621
|
+
if (sundryMethod === 'percentage') {
|
|
3622
|
+
partsSundry = b$1(summaryNet.parts).mul(sundryRate || '1').toFixed(2);
|
|
3623
|
+
}
|
|
3624
|
+
else if (sundryMethod === 'percentage-with-max') {
|
|
3625
|
+
partsSundry = b$1(summaryNet.parts).mul(sundryRate || '1').toFixed(2);
|
|
3626
|
+
partsSundry = Math.min(parseFloat(sundryMax || '0'), parseFloat(partsSundry)).toFixed();
|
|
3627
|
+
}
|
|
3628
|
+
else if (sundryMethod === 'fixed') {
|
|
3629
|
+
partsSundry = b$1(sundryFixed).toFixed(2);
|
|
3630
|
+
}
|
|
3631
|
+
const parts = b$1(summaryNet.parts).add(partsSundry);
|
|
3632
|
+
const net = b$1(0)
|
|
3633
|
+
.add(summaryNet.labour)
|
|
3634
|
+
.add(summaryNet.none)
|
|
3635
|
+
.add(parts)
|
|
3636
|
+
.add(summaryNet.pm)
|
|
3637
|
+
.add(summaryNet.specialist)
|
|
3638
|
+
.toFixed(2);
|
|
3639
|
+
const vat = b$1(net || '0')
|
|
3640
|
+
.mul(this.vatRate || '0')
|
|
3641
|
+
.toFixed(2);
|
|
3642
|
+
const gross = b$1(net || '0').add(vat || '0').toFixed(2);
|
|
3643
|
+
return {
|
|
3644
|
+
labour: summaryNet.labour,
|
|
3645
|
+
none: summaryNet.none,
|
|
3646
|
+
parts: b$1(parts).mul(partsDisc).toFixed(2),
|
|
3647
|
+
pm: b$1(summaryNet.pm).mul(paintDisc).toFixed(2),
|
|
3648
|
+
pl: summaryNet.pl,
|
|
3649
|
+
specialist: summaryNet.specialist,
|
|
3650
|
+
other: summaryNet.other,
|
|
3651
|
+
net: net,
|
|
3652
|
+
vat: vat,
|
|
3653
|
+
gross: gross,
|
|
3654
|
+
labourRate: this.labourRate,
|
|
3655
|
+
hours: this.getTotalHours(adjusted)
|
|
3656
|
+
};
|
|
3657
|
+
}
|
|
3658
|
+
toDto() {
|
|
3659
|
+
return {
|
|
3660
|
+
id: this.id,
|
|
3661
|
+
source: this.source,
|
|
3662
|
+
label: this.label,
|
|
3663
|
+
comment: this.comment,
|
|
3664
|
+
timestamp: this.timestamp,
|
|
3665
|
+
version: this.version,
|
|
3666
|
+
net: this.net,
|
|
3667
|
+
vat: this.vat,
|
|
3668
|
+
gross: this.gross,
|
|
3669
|
+
labourRate: this.labourRate,
|
|
3670
|
+
vatRate: this.vatRate,
|
|
3671
|
+
sundryRate: this.sundryRate,
|
|
3672
|
+
sundryMax: this.sundryMax,
|
|
3673
|
+
sundryFixed: this.sundryFixed,
|
|
3674
|
+
sundryMethod: this.sundryMethod,
|
|
3675
|
+
partsDiscount: this.partsDiscount,
|
|
3676
|
+
paintDiscount: this.paintDiscount,
|
|
3677
|
+
timeBasis: this.timeBasis,
|
|
3678
|
+
items: this.items.map(i => i.toDto()),
|
|
3679
|
+
adjusted: this.adjusted,
|
|
3680
|
+
summary: this.summary,
|
|
3681
|
+
summaryAdjusted: this.summaryAdjusted
|
|
3682
|
+
};
|
|
3683
|
+
}
|
|
3684
|
+
getTotalHours(adjusted = false) {
|
|
3685
|
+
if (this.source === 'audatex') {
|
|
3686
|
+
const mechUnitsHours = this.items
|
|
3687
|
+
.filter(item => item.workCategory !== 'paint')
|
|
3688
|
+
.reduce((h, item) => h.add(b$1(item.getTotalUnits(adjusted))), b$1())
|
|
3689
|
+
.round(2)
|
|
3690
|
+
.div(this.timeBasis || '1');
|
|
3691
|
+
const paintHours = this.items
|
|
3692
|
+
.filter(item => item.workCategory === 'paint')
|
|
3693
|
+
.reduce((h, item) => h.add(b$1(item.getTotalUnits(adjusted))), b$1())
|
|
3694
|
+
.round(1)
|
|
3695
|
+
.div(this.timeBasis || '1');
|
|
3696
|
+
return mechUnitsHours.add(paintHours).toFixed(2);
|
|
3697
|
+
}
|
|
3698
|
+
const units = this.items
|
|
3699
|
+
.filter(i => i.costCategory === 'labour')
|
|
3700
|
+
.reduce((p, c) => p.add(b$1(c.getTotalUnits(adjusted))), b$1('0'))
|
|
3701
|
+
.toFixed(2);
|
|
3702
|
+
return b$1(units).div(this.timeBasis || '1').toFixed(2);
|
|
3703
|
+
}
|
|
3704
|
+
}
|
|
3705
|
+
|
|
3706
|
+
const b = (value = '0') => new Big(value);
|
|
3707
|
+
/**
|
|
3708
|
+
* Utility class for computing the summary value for an estimate control given
|
|
3709
|
+
* the first and last estimates
|
|
3710
|
+
*/
|
|
3711
|
+
class EstimateControlValueModel {
|
|
3712
|
+
static calculateSummary(original, latest) {
|
|
3713
|
+
const o = original.summary;
|
|
3714
|
+
const l = latest.adjusted ?
|
|
3715
|
+
latest.summaryAdjusted :
|
|
3716
|
+
latest.summary;
|
|
3717
|
+
const s = {
|
|
3718
|
+
labour: b(o.labour).minus(l.labour).toFixed(2),
|
|
3719
|
+
none: b(o.none).minus(l.none).toFixed(2),
|
|
3720
|
+
parts: b(o.parts).minus(l.parts).toFixed(2),
|
|
3721
|
+
pm: b(o.pm).minus(l.pm).toFixed(2),
|
|
3722
|
+
pl: b(o.pm).minus(l.pl).toFixed(2),
|
|
3723
|
+
specialist: b(o.specialist).minus(l.specialist).toFixed(2),
|
|
3724
|
+
other: b(o.other).minus(l.other).toFixed(2),
|
|
3725
|
+
net: b(o.net).minus(l.net).toFixed(2),
|
|
3726
|
+
vat: b(o.vat).minus(l.vat).toFixed(2),
|
|
3727
|
+
gross: b(o.gross).minus(l.gross).toFixed(2),
|
|
3728
|
+
hours: b(o.hours).minus(l.hours).toFixed(0),
|
|
3729
|
+
labourRate: b(o.labourRate).minus(l.labourRate).toFixed(0)
|
|
3730
|
+
};
|
|
3731
|
+
return {
|
|
3732
|
+
original: o,
|
|
3733
|
+
latest: l,
|
|
3734
|
+
savings: s
|
|
3735
|
+
};
|
|
3736
|
+
}
|
|
3737
|
+
static getEmptySummary() {
|
|
3738
|
+
return {
|
|
3739
|
+
original: {
|
|
3740
|
+
labour: '0.00',
|
|
3741
|
+
none: '0.00',
|
|
3742
|
+
parts: '0.00',
|
|
3743
|
+
pm: '0.00',
|
|
3744
|
+
pl: '0.00',
|
|
3745
|
+
specialist: '0.00',
|
|
3746
|
+
other: '0.00',
|
|
3747
|
+
net: '0.00',
|
|
3748
|
+
vat: '0.00',
|
|
3749
|
+
gross: '0.00',
|
|
3750
|
+
hours: '0',
|
|
3751
|
+
labourRate: '0.00'
|
|
3752
|
+
},
|
|
3753
|
+
latest: {
|
|
3754
|
+
labour: '0.00',
|
|
3755
|
+
none: '0.00',
|
|
3756
|
+
parts: '0.00',
|
|
3757
|
+
pm: '0.00',
|
|
3758
|
+
pl: '0.00',
|
|
3759
|
+
specialist: '0.00',
|
|
3760
|
+
other: '0.00',
|
|
3761
|
+
net: '0.00',
|
|
3762
|
+
vat: '0.00',
|
|
3763
|
+
gross: '0.00',
|
|
3764
|
+
hours: '0',
|
|
3765
|
+
labourRate: '0.00'
|
|
3766
|
+
},
|
|
3767
|
+
savings: {
|
|
3768
|
+
labour: '0.00',
|
|
3769
|
+
none: '0.00',
|
|
3770
|
+
parts: '0.00',
|
|
3771
|
+
pm: '0.00',
|
|
3772
|
+
pl: '0.00',
|
|
3773
|
+
specialist: '0.00',
|
|
3774
|
+
other: '0.00',
|
|
3775
|
+
net: '0.00',
|
|
3776
|
+
vat: '0.00',
|
|
3777
|
+
gross: '0.00',
|
|
3778
|
+
hours: '0',
|
|
3779
|
+
labourRate: '0.00'
|
|
3780
|
+
}
|
|
3781
|
+
};
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3324
3784
|
|
|
3325
3785
|
const getEmptyGeoLocation = () => ({
|
|
3326
3786
|
accuracy: 0,
|
|
@@ -3335,8 +3795,8 @@ const getEmptyGeoLocation = () => ({
|
|
|
3335
3795
|
});
|
|
3336
3796
|
|
|
3337
3797
|
/**
|
|
3338
|
-
* Try to parse the value as JSON if it looks like a JSON encoded string
|
|
3339
|
-
*
|
|
3798
|
+
* Try to parse the value as JSON if it looks like a JSON encoded string, return
|
|
3799
|
+
* the original value if it's not a JSON string or parsing fails.
|
|
3340
3800
|
*/
|
|
3341
3801
|
const tryJson = (value) => {
|
|
3342
3802
|
if (typeof value === 'string' && ['{', '['].includes(value.substring(0, 1))) {
|
|
@@ -3350,6 +3810,9 @@ const tryJson = (value) => {
|
|
|
3350
3810
|
return value;
|
|
3351
3811
|
};
|
|
3352
3812
|
|
|
3813
|
+
/**
|
|
3814
|
+
* Return true if the argument is a plain object {}, i.e. not an array, null.
|
|
3815
|
+
*/
|
|
3353
3816
|
function isPlainObject(value) {
|
|
3354
3817
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3355
3818
|
}
|
|
@@ -3477,7 +3940,7 @@ class VasJobModel extends VasRestrictedAccountObjectModel {
|
|
|
3477
3940
|
.keys(dto[groupName])
|
|
3478
3941
|
.forEach(controlName => {
|
|
3479
3942
|
const cn = controlName.replace('fields.', '');
|
|
3480
|
-
fields[cn] = dto[groupName][
|
|
3943
|
+
fields[cn] = dto[groupName][controlName];
|
|
3481
3944
|
});
|
|
3482
3945
|
});
|
|
3483
3946
|
}
|
|
@@ -4280,9 +4743,38 @@ class VasVehicleModel extends VasAccountObjectModel {
|
|
|
4280
4743
|
}
|
|
4281
4744
|
}
|
|
4282
4745
|
|
|
4746
|
+
/**
|
|
4747
|
+
* Return true IFF the array contains only strings
|
|
4748
|
+
*/
|
|
4749
|
+
const isArrayString = (value) => {
|
|
4750
|
+
return Array.isArray(value) && value.every(i => typeof i === 'string');
|
|
4751
|
+
};
|
|
4752
|
+
|
|
4753
|
+
/**
|
|
4754
|
+
* Return an object omitting properties specified by key(s)
|
|
4755
|
+
*
|
|
4756
|
+
* @param obj object to be processed
|
|
4757
|
+
* @param omitKey key or array of keys to be omitted
|
|
4758
|
+
*/
|
|
4759
|
+
const omit = (obj, omitKey) => {
|
|
4760
|
+
return Object.keys(obj).reduce((result, key) => {
|
|
4761
|
+
if (Array.isArray(omitKey)) {
|
|
4762
|
+
if (!omitKey.includes(key)) {
|
|
4763
|
+
result[key] = obj[key];
|
|
4764
|
+
}
|
|
4765
|
+
}
|
|
4766
|
+
else {
|
|
4767
|
+
if (omitKey !== key) {
|
|
4768
|
+
result[key] = obj[key];
|
|
4769
|
+
}
|
|
4770
|
+
}
|
|
4771
|
+
return result;
|
|
4772
|
+
}, {});
|
|
4773
|
+
};
|
|
4774
|
+
|
|
4283
4775
|
/**
|
|
4284
4776
|
* Generated bundle index. Do not edit.
|
|
4285
4777
|
*/
|
|
4286
4778
|
|
|
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, VasJobModel, VasJobStatusModel, VasJobTypeModel, VasLookupModel, VasLookupTypeModel, VasMembershipModel, VasNoteModel, VasReportLayoutModel, VasReportModel, VasReportRequestModel, VasRestrictedAccountObjectModel, VasTaskModel, VasTaskTypeModel, VasUserModel, VasVehicleModel, getEmptyGeoLocation, isCameraControlValueV1, isCameraControlValueV2, isFileDto, isJobAutomationStep, isJobControlsStep, isJobEmailFormStep, isJobInstructionStep, isJobNotePromptStep, isJobSetDatetimeStep, isJobSetJobStatusStep, isJobSetValueStep, isJobWebhookStep, prepareFieldApiValue, stepModelFactory };
|
|
4779
|
+
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, VasJobCopyModel, VasJobDataModel, VasJobEmailModel, VasJobModel, 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
4780
|
//# sourceMappingURL=ironcode-vas-lib.mjs.map
|