@ironcode/vas-lib 3.0.0-alpha.6 → 3.0.0-alpha.9
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/entity/vas-job.dto.d.ts +3 -0
- 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 +4 -1
- package/cjs/lib/entity/vas-job.model.d.ts.map +1 -1
- package/cjs/lib/entity/vas-job.model.js +99 -14
- package/cjs/lib/entity/vas-job.model.js.map +1 -1
- package/cjs/lib/model/estimate-control/estimate-item.model.js +1 -1
- package/cjs/lib/model/estimate-control/estimate-item.model.js.map +1 -1
- package/cjs/lib/model/estimate-control/estimate.model.d.ts +2 -1
- package/cjs/lib/model/estimate-control/estimate.model.d.ts.map +1 -1
- package/cjs/lib/model/estimate-control/estimate.model.js +12 -12
- package/cjs/lib/model/estimate-control/estimate.model.js.map +1 -1
- package/fesm2022/ironcode-vas-lib.mjs +156 -67
- package/fesm2022/ironcode-vas-lib.mjs.map +1 -1
- package/lib/entity/vas-job.dto.d.ts +3 -0
- package/lib/entity/vas-job.model.d.ts +4 -1
- package/lib/model/estimate-control/estimate.model.d.ts +2 -1
- package/package.json +1 -1
|
@@ -83,6 +83,9 @@ class EstimateModel {
|
|
|
83
83
|
labourRate: '0.00',
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
|
+
get timeBasisSafe() {
|
|
87
|
+
return (this.timeBasis || '1') === '0' ? '1' : this.timeBasis;
|
|
88
|
+
}
|
|
86
89
|
static create(source = 'manual') {
|
|
87
90
|
const model = new EstimateModel();
|
|
88
91
|
model.source = source;
|
|
@@ -90,7 +93,7 @@ class EstimateModel {
|
|
|
90
93
|
}
|
|
91
94
|
static fromDto(dto) {
|
|
92
95
|
var _a;
|
|
93
|
-
const model = new
|
|
96
|
+
const model = new this();
|
|
94
97
|
Object.assign(model, Object.assign(Object.assign({}, dto), { items: (_a = dto.items) === null || _a === void 0 ? void 0 : _a.map(item => estimate_item_model_1.EstimateItemModel.fromDto(item)) }));
|
|
95
98
|
model.calculate();
|
|
96
99
|
return model;
|
|
@@ -110,9 +113,6 @@ class EstimateModel {
|
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
calculate() {
|
|
113
|
-
if (this.source === 'gtmotive') {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
116
|
this.summaryNet = this.getSummaryNet(false);
|
|
117
117
|
if (this.adjusted) {
|
|
118
118
|
this.summaryAdjusted = this.getSummary(this.summaryNet, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount, this.adjusted);
|
|
@@ -138,7 +138,7 @@ class EstimateModel {
|
|
|
138
138
|
getSummaryNet(adjusted = false) {
|
|
139
139
|
const summary = this.items.reduce((map, item) => {
|
|
140
140
|
map[item.costCategory] = b(map[item.costCategory] || '0')
|
|
141
|
-
.add(item.getLineValue(this.labourRate, this.
|
|
141
|
+
.add(item.getLineValue(this.labourRate, this.timeBasisSafe, adjusted))
|
|
142
142
|
.toFixed(2);
|
|
143
143
|
return map;
|
|
144
144
|
}, {
|
|
@@ -159,12 +159,12 @@ class EstimateModel {
|
|
|
159
159
|
const mechHours = this.items
|
|
160
160
|
.filter(item => item.workCategory !== 'paint')
|
|
161
161
|
.reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())
|
|
162
|
-
.div(this.
|
|
162
|
+
.div(this.timeBasisSafe || '1')
|
|
163
163
|
.round(2);
|
|
164
164
|
const paintHours = this.items
|
|
165
165
|
.filter(item => item.workCategory === 'paint')
|
|
166
166
|
.reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())
|
|
167
|
-
.div(this.
|
|
167
|
+
.div(this.timeBasisSafe || '1')
|
|
168
168
|
.round(1);
|
|
169
169
|
const mechCost = mechHours.mul(this.labourRate || '0');
|
|
170
170
|
const paintCost = paintHours.mul(this.labourRate || '0');
|
|
@@ -185,7 +185,7 @@ class EstimateModel {
|
|
|
185
185
|
}
|
|
186
186
|
else if (sundryMethod === 'percentage-with-max') {
|
|
187
187
|
partsSundry = b(summaryNet.parts).mul(sundryRate || '1').toFixed(2);
|
|
188
|
-
partsSundry = Math.min(parseFloat(sundryMax || '0'), parseFloat(partsSundry)).toFixed();
|
|
188
|
+
partsSundry = Math.min(parseFloat(sundryMax || '0'), parseFloat(partsSundry)).toFixed(2);
|
|
189
189
|
}
|
|
190
190
|
else if (sundryMethod === 'fixed') {
|
|
191
191
|
partsSundry = b(sundryFixed).toFixed(2);
|
|
@@ -236,7 +236,7 @@ class EstimateModel {
|
|
|
236
236
|
sundryMethod: this.sundryMethod,
|
|
237
237
|
partsDiscount: this.partsDiscount,
|
|
238
238
|
paintDiscount: this.paintDiscount,
|
|
239
|
-
timeBasis: this.
|
|
239
|
+
timeBasis: this.timeBasisSafe,
|
|
240
240
|
items: this.items.map(i => i.toDto()),
|
|
241
241
|
adjusted: this.adjusted,
|
|
242
242
|
summary: this.summary,
|
|
@@ -249,19 +249,19 @@ class EstimateModel {
|
|
|
249
249
|
.filter(item => item.workCategory !== 'paint')
|
|
250
250
|
.reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())
|
|
251
251
|
.round(2)
|
|
252
|
-
.div(this.
|
|
252
|
+
.div(this.timeBasisSafe);
|
|
253
253
|
const paintHours = this.items
|
|
254
254
|
.filter(item => item.workCategory === 'paint')
|
|
255
255
|
.reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())
|
|
256
256
|
.round(1)
|
|
257
|
-
.div(this.
|
|
257
|
+
.div(this.timeBasisSafe);
|
|
258
258
|
return mechUnitsHours.add(paintHours).toFixed(2);
|
|
259
259
|
}
|
|
260
260
|
const units = this.items
|
|
261
261
|
.filter(i => i.costCategory === 'labour')
|
|
262
262
|
.reduce((p, c) => p.add(b(c.getTotalUnits(adjusted))), b('0'))
|
|
263
263
|
.toFixed(2);
|
|
264
|
-
return b(units).div(this.
|
|
264
|
+
return b(units).div(this.timeBasisSafe).toFixed(2);
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
exports.EstimateModel = EstimateModel;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estimate.model.js","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/estimate.model.ts"],"names":[],"mappings":"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","sourcesContent":["import { Big } from 'big.js';\nimport moment from 'moment';\nimport { v4 as uuid } from 'uuid';\nimport { EstimateItemModel } from './estimate-item.model';\nimport { CostCategorySummary, EstimateDto, EstimateSummaryDto } from './estimate.dto';\nimport { EstimateItemDto } from './estimate-item.dto';\n\nexport declare type EstimateSundryMethod = 'percentage' | 'percentage-with-max' | 'fixed';\n\nexport declare type EstimateSource = 'audatex' | 'glassmatix' | 'gtmotive' | 'manual' | 'ibody';\n\nconst b = (value: string | number | Big = '0') => {\n try {\n if (typeof value === 'string') {\n return new Big(value.replace(/[^\\d^.]/g, ''));\n }\n return new Big(value);\n } catch (e) {\n console.error(`failed to construct Big from value '${value}'`);\n return new Big('0');\n }\n};\n\n\nexport class EstimateModel {\n\n public id: string = uuid();\n public source: EstimateSource = 'manual';\n public label: string = '';\n public comment: string = '';\n public timestamp: string = moment().toISOString();\n public version: number = 1;\n public net: string = '0.00';\n public vat: string = '0.00';\n public gross: string = '0.00';\n public labourRate: string = '1';\n public vatRate: string = '0.00';\n public sundryRate: string = '0.00';\n public sundryMax: string = '0.00';\n public sundryFixed: string = '0.00';\n public sundryMethod: EstimateSundryMethod = 'fixed';\n public partsDiscount: string = '0.00';\n public paintDiscount: string = '0.00';\n public timeBasis: string = '1';\n public adjusted = false;\n public items: Array<EstimateItemModel> = [];\n public summaryNet: EstimateSummaryDto = {\n labour: '0.00',\n none: '0.00',\n parts: '0.00',\n pm: '0.00',\n pl: '0.00',\n specialist: '0.00',\n other: '0.00',\n gross: '0.00',\n net: '0.00',\n hours: '0.00',\n vat: '0.00',\n labourRate: '0.00',\n };\n public summary: EstimateSummaryDto = {\n labour: '0.00',\n none: '0.00',\n parts: '0.00',\n pm: '0.00',\n pl: '0.00',\n specialist: '0.00',\n other: '0.00',\n gross: '0.00',\n net: '0.00',\n hours: '0.00',\n vat: '0.00',\n labourRate: '0.00',\n };\n public summaryAdjusted: EstimateSummaryDto = {\n labour: '0.00',\n none: '0.00',\n parts: '0.00',\n pm: '0.00',\n pl: '0.00',\n specialist: '0.00',\n other: '0.00',\n gross: '0.00',\n net: '0.00',\n hours: '0.00',\n vat: '0.00',\n labourRate: '0.00',\n };\n\n static create(source: EstimateSource = 'manual'): EstimateModel {\n const model = new EstimateModel();\n model.source = source;\n return model;\n }\n\n static fromDto(dto: Partial<EstimateDto>): EstimateModel {\n const model = new EstimateModel();\n Object.assign(model, {\n ...dto,\n items: dto.items?.map(item => EstimateItemModel.fromDto(item)),\n });\n model.calculate();\n return model;\n }\n\n addItem(\n modelOrDto: EstimateItemModel | Partial<EstimateItemDto>,\n opts?: { calculate?: boolean }\n ) {\n this.items.push(modelOrDto instanceof EstimateItemModel ?\n modelOrDto :\n EstimateItemModel.fromDto(modelOrDto)\n );\n if (!opts || (opts && opts.calculate)) {\n this.calculate();\n }\n }\n\n addItems(items: Array<EstimateItemModel>, opts?: { calculate?: boolean }) {\n this.items = this.items.concat(items);\n if (!opts || (opts && opts.calculate)) {\n this.calculate();\n }\n }\n\n calculate(): void {\n\n if (this.source === 'gtmotive') {\n return;\n }\n\n this.summaryNet = this.getSummaryNet(false);\n\n if (this.adjusted) {\n this.summaryAdjusted = this.getSummary(\n this.summaryNet,\n this.sundryRate,\n this.sundryMax,\n this.sundryFixed,\n this.sundryMethod,\n this.partsDiscount,\n this.paintDiscount,\n this.adjusted\n );\n }\n this.summary = this.getSummary(\n this.summaryNet,\n this.sundryRate,\n this.sundryMax,\n this.sundryFixed,\n this.sundryMethod,\n this.partsDiscount,\n this.paintDiscount,\n this.adjusted\n );\n\n this.net = b(0)\n .add(this.summary.labour)\n .add(this.summary.none)\n .add(this.summary.parts)\n .add(this.summary.pm)\n .add(this.summary.specialist)\n .toFixed(2);\n this.vat = b(this.net || '0').mul(this.vatRate || '0').toFixed(2);\n this.gross = b(this.net || '0').add(this.vat || '0').toFixed(2);\n }\n\n /**\n * Returns the net summary (before sundries and discounts) of the estimate.\n * By summary, we mean grouping the costs by cost category.\n *\n * @param adjusted if the values should be calculated using the original or\n * adjusted values\n */\n getSummaryNet(adjusted = false): EstimateSummaryDto {\n const summary = this.items.reduce((map, item) => {\n map[item.costCategory] = b(map[item.costCategory] || '0')\n .add(item.getLineValue(this.labourRate, this.timeBasis, adjusted))\n .toFixed(2);\n return map;\n }, {\n labour: '0.00',\n none: '0.00',\n parts: '0.00',\n pm: '0.00',\n pl: '0.00',\n specialist: '0.00',\n other: '0.00',\n net: '0.00',\n vat: '0.00',\n gross: '0.00',\n hours: '0.00',\n labourRate: '0',\n } as EstimateSummaryDto);\n\n if (this.source === 'audatex') {\n const mechHours = this.items\n .filter(item => item.workCategory !== 'paint')\n .reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())\n .div(this.timeBasis || '1')\n .round(2);\n const paintHours = this.items\n .filter(item => item.workCategory === 'paint')\n .reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())\n .div(this.timeBasis || '1')\n .round(1);\n\n const mechCost = mechHours.mul(this.labourRate || '0');\n const paintCost = paintHours.mul(this.labourRate || '0');\n summary.labour = mechCost.add(paintCost).toFixed(2);\n }\n return summary;\n }\n\n /**\n * Applies the sundry and discount values to the net summary.\n\n */\n getSummary(\n summaryNet: EstimateDto['summary'],\n sundryRate: string,\n sundryMax: string,\n sundryFixed: string,\n sundryMethod: EstimateSundryMethod,\n partsDiscount: string,\n paintDiscount: string,\n adjusted: boolean\n ): EstimateDto['summary'] {\n const partsDisc = b('1').minus(partsDiscount || '0');\n const paintDisc = b('1').minus(paintDiscount || '0');\n\n let partsSundry = '0.00';\n\n if (sundryMethod === 'percentage') {\n partsSundry = b(summaryNet.parts).mul(sundryRate || '1').toFixed(2);\n } else if (sundryMethod === 'percentage-with-max') {\n partsSundry = b(summaryNet.parts).mul(sundryRate || '1').toFixed(2);\n partsSundry = Math.min(\n parseFloat(sundryMax || '0'),\n parseFloat(partsSundry)\n ).toFixed();\n } else if (sundryMethod === 'fixed') {\n partsSundry = b(sundryFixed).toFixed(2);\n }\n\n const parts = b(summaryNet.parts).add(partsSundry);\n\n const net = b(0)\n .add(summaryNet.labour)\n .add(summaryNet.none)\n .add(parts)\n .add(summaryNet.pm)\n .add(summaryNet.specialist)\n .toFixed(2);\n const vat = b(net || '0')\n .mul(this.vatRate || '0')\n .toFixed(2);\n const gross = b(net || '0').add(vat || '0').toFixed(2);\n\n return {\n labour: summaryNet.labour,\n none: summaryNet.none,\n parts: b(parts).mul(partsDisc).toFixed(2),\n pm: b(summaryNet.pm).mul(paintDisc).toFixed(2),\n pl: summaryNet.pl,\n specialist: summaryNet.specialist,\n other: summaryNet.other,\n net: net,\n vat: vat,\n gross: gross,\n labourRate: this.labourRate,\n hours: this.getTotalHours(adjusted)\n };\n }\n\n toDto(): EstimateDto {\n return {\n id: this.id,\n source: this.source,\n label: this.label,\n comment: this.comment,\n timestamp: this.timestamp,\n version: this.version,\n net: this.net,\n vat: this.vat,\n gross: this.gross,\n labourRate: this.labourRate,\n vatRate: this.vatRate,\n sundryRate: this.sundryRate,\n sundryMax: this.sundryMax,\n sundryFixed: this.sundryFixed,\n sundryMethod: this.sundryMethod,\n partsDiscount: this.partsDiscount,\n paintDiscount: this.paintDiscount,\n timeBasis: this.timeBasis,\n items: this.items.map(i => i.toDto()),\n adjusted: this.adjusted,\n summary: this.summary,\n summaryAdjusted: this.summaryAdjusted\n };\n }\n\n getTotalHours(adjusted = false): string {\n if (this.source === 'audatex') {\n const mechUnitsHours = this.items\n .filter(item => item.workCategory !== 'paint')\n .reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())\n .round(2)\n .div(this.timeBasis || '1');\n const paintHours = this.items\n .filter(item => item.workCategory === 'paint')\n .reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())\n .round(1)\n .div(this.timeBasis || '1');\n return mechUnitsHours.add(paintHours).toFixed(2);\n }\n const units = this.items\n .filter(i => i.costCategory === 'labour')\n .reduce((p, c) => p.add(b(c.getTotalUnits(adjusted))), b('0'))\n .toFixed(2);\n return b(units).div(this.timeBasis || '1').toFixed(2);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"estimate.model.js","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/estimate.model.ts"],"names":[],"mappings":"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","sourcesContent":["import { Big } from 'big.js';\nimport moment from 'moment';\nimport { v4 as uuid } from 'uuid';\nimport { EstimateItemModel } from './estimate-item.model';\nimport { CostCategorySummary, EstimateDto, EstimateSummaryDto } from './estimate.dto';\nimport { EstimateItemDto } from './estimate-item.dto';\n\nexport declare type EstimateSundryMethod = 'percentage' | 'percentage-with-max' | 'fixed';\n\nexport declare type EstimateSource = 'audatex' | 'glassmatix' | 'gtmotive' | 'manual' | 'ibody';\n\nconst b = (value: string | number | Big = '0') => {\n try {\n if (typeof value === 'string') {\n return new Big(value.replace(/[^\\d^.]/g, ''));\n }\n return new Big(value);\n } catch (e) {\n console.error(`failed to construct Big from value '${value}'`);\n return new Big('0');\n }\n};\n\n\nexport class EstimateModel {\n\n public id: string = uuid();\n public source: EstimateSource = 'manual';\n public label: string = '';\n public comment: string = '';\n public timestamp: string = moment().toISOString();\n public version: number = 1;\n public net: string = '0.00';\n public vat: string = '0.00';\n public gross: string = '0.00';\n public labourRate: string = '1';\n public vatRate: string = '0.00';\n public sundryRate: string = '0.00';\n public sundryMax: string = '0.00';\n public sundryFixed: string = '0.00';\n public sundryMethod: EstimateSundryMethod = 'fixed';\n public partsDiscount: string = '0.00';\n public paintDiscount: string = '0.00';\n public timeBasis: string = '1';\n public adjusted = false;\n public items: Array<EstimateItemModel> = [];\n public summaryNet: EstimateSummaryDto = {\n labour: '0.00',\n none: '0.00',\n parts: '0.00',\n pm: '0.00',\n pl: '0.00',\n specialist: '0.00',\n other: '0.00',\n gross: '0.00',\n net: '0.00',\n hours: '0.00',\n vat: '0.00',\n labourRate: '0.00',\n };\n public summary: EstimateSummaryDto = {\n labour: '0.00',\n none: '0.00',\n parts: '0.00',\n pm: '0.00',\n pl: '0.00',\n specialist: '0.00',\n other: '0.00',\n gross: '0.00',\n net: '0.00',\n hours: '0.00',\n vat: '0.00',\n labourRate: '0.00',\n };\n public summaryAdjusted: EstimateSummaryDto = {\n labour: '0.00',\n none: '0.00',\n parts: '0.00',\n pm: '0.00',\n pl: '0.00',\n specialist: '0.00',\n other: '0.00',\n gross: '0.00',\n net: '0.00',\n hours: '0.00',\n vat: '0.00',\n labourRate: '0.00',\n };\n\n get timeBasisSafe(): string {\n return (this.timeBasis || '1') === '0' ? '1' : this.timeBasis;\n }\n\n static create(source: EstimateSource = 'manual'): EstimateModel {\n const model = new EstimateModel();\n model.source = source;\n return model;\n }\n\n static fromDto<T extends EstimateModel>(\n this: new () => T,\n dto: Partial<EstimateDto>\n ): T {\n const model = new this();\n Object.assign(model, {\n ...dto,\n items: dto.items?.map(item => EstimateItemModel.fromDto(item)),\n });\n model.calculate();\n return model;\n }\n\n addItem(\n modelOrDto: EstimateItemModel | Partial<EstimateItemDto>,\n opts?: { calculate?: boolean }\n ) {\n this.items.push(modelOrDto instanceof EstimateItemModel ?\n modelOrDto :\n EstimateItemModel.fromDto(modelOrDto)\n );\n if (!opts || (opts && opts.calculate)) {\n this.calculate();\n }\n }\n\n addItems(items: Array<EstimateItemModel>, opts?: { calculate?: boolean }) {\n this.items = this.items.concat(items);\n if (!opts || (opts && opts.calculate)) {\n this.calculate();\n }\n }\n\n calculate(): void {\n\n this.summaryNet = this.getSummaryNet(false);\n\n if (this.adjusted) {\n this.summaryAdjusted = this.getSummary(\n this.summaryNet,\n this.sundryRate,\n this.sundryMax,\n this.sundryFixed,\n this.sundryMethod,\n this.partsDiscount,\n this.paintDiscount,\n this.adjusted\n );\n }\n this.summary = this.getSummary(\n this.summaryNet,\n this.sundryRate,\n this.sundryMax,\n this.sundryFixed,\n this.sundryMethod,\n this.partsDiscount,\n this.paintDiscount,\n this.adjusted\n );\n\n this.net = b(0)\n .add(this.summary.labour)\n .add(this.summary.none)\n .add(this.summary.parts)\n .add(this.summary.pm)\n .add(this.summary.specialist)\n .toFixed(2);\n this.vat = b(this.net || '0').mul(this.vatRate || '0').toFixed(2);\n this.gross = b(this.net || '0').add(this.vat || '0').toFixed(2);\n }\n\n /**\n * Returns the net summary (before sundries and discounts) of the estimate.\n * By summary, we mean grouping the costs by cost category.\n *\n * @param adjusted if the values should be calculated using the original or\n * adjusted values\n */\n getSummaryNet(adjusted = false): EstimateSummaryDto {\n const summary = this.items.reduce((map, item) => {\n map[item.costCategory] = b(map[item.costCategory] || '0')\n .add(item.getLineValue(this.labourRate, this.timeBasisSafe, adjusted))\n .toFixed(2);\n return map;\n }, {\n labour: '0.00',\n none: '0.00',\n parts: '0.00',\n pm: '0.00',\n pl: '0.00',\n specialist: '0.00',\n other: '0.00',\n net: '0.00',\n vat: '0.00',\n gross: '0.00',\n hours: '0.00',\n labourRate: '0',\n } as EstimateSummaryDto);\n\n if (this.source === 'audatex') {\n const mechHours = this.items\n .filter(item => item.workCategory !== 'paint')\n .reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())\n .div(this.timeBasisSafe || '1')\n .round(2);\n const paintHours = this.items\n .filter(item => item.workCategory === 'paint')\n .reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())\n .div(this.timeBasisSafe || '1')\n .round(1);\n\n const mechCost = mechHours.mul(this.labourRate || '0');\n const paintCost = paintHours.mul(this.labourRate || '0');\n summary.labour = mechCost.add(paintCost).toFixed(2);\n }\n return summary;\n }\n\n /**\n * Applies the sundry and discount values to the net summary.\n\n */\n getSummary(\n summaryNet: EstimateDto['summary'],\n sundryRate: string,\n sundryMax: string,\n sundryFixed: string,\n sundryMethod: EstimateSundryMethod,\n partsDiscount: string,\n paintDiscount: string,\n adjusted: boolean\n ): EstimateDto['summary'] {\n const partsDisc = b('1').minus(partsDiscount || '0');\n const paintDisc = b('1').minus(paintDiscount || '0');\n\n let partsSundry = '0.00';\n\n if (sundryMethod === 'percentage') {\n partsSundry = b(summaryNet.parts).mul(sundryRate || '1').toFixed(2);\n } else if (sundryMethod === 'percentage-with-max') {\n partsSundry = b(summaryNet.parts).mul(sundryRate || '1').toFixed(2);\n partsSundry = Math.min(\n parseFloat(sundryMax || '0'),\n parseFloat(partsSundry)\n ).toFixed(2);\n } else if (sundryMethod === 'fixed') {\n partsSundry = b(sundryFixed).toFixed(2);\n }\n\n const parts = b(summaryNet.parts).add(partsSundry);\n\n const net = b(0)\n .add(summaryNet.labour)\n .add(summaryNet.none)\n .add(parts)\n .add(summaryNet.pm)\n .add(summaryNet.specialist)\n .toFixed(2);\n const vat = b(net || '0')\n .mul(this.vatRate || '0')\n .toFixed(2);\n const gross = b(net || '0').add(vat || '0').toFixed(2);\n\n return {\n labour: summaryNet.labour,\n none: summaryNet.none,\n parts: b(parts).mul(partsDisc).toFixed(2),\n pm: b(summaryNet.pm).mul(paintDisc).toFixed(2),\n pl: summaryNet.pl,\n specialist: summaryNet.specialist,\n other: summaryNet.other,\n net: net,\n vat: vat,\n gross: gross,\n labourRate: this.labourRate,\n hours: this.getTotalHours(adjusted)\n };\n }\n\n toDto(): EstimateDto {\n return {\n id: this.id,\n source: this.source,\n label: this.label,\n comment: this.comment,\n timestamp: this.timestamp,\n version: this.version,\n net: this.net,\n vat: this.vat,\n gross: this.gross,\n labourRate: this.labourRate,\n vatRate: this.vatRate,\n sundryRate: this.sundryRate,\n sundryMax: this.sundryMax,\n sundryFixed: this.sundryFixed,\n sundryMethod: this.sundryMethod,\n partsDiscount: this.partsDiscount,\n paintDiscount: this.paintDiscount,\n timeBasis: this.timeBasisSafe,\n items: this.items.map(i => i.toDto()),\n adjusted: this.adjusted,\n summary: this.summary,\n summaryAdjusted: this.summaryAdjusted\n };\n }\n\n getTotalHours(adjusted = false): string {\n if (this.source === 'audatex') {\n const mechUnitsHours = this.items\n .filter(item => item.workCategory !== 'paint')\n .reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())\n .round(2)\n .div(this.timeBasisSafe);\n const paintHours = this.items\n .filter(item => item.workCategory === 'paint')\n .reduce((h, item) => h.add(b(item.getTotalUnits(adjusted))), b())\n .round(1)\n .div(this.timeBasisSafe);\n return mechUnitsHours.add(paintHours).toFixed(2);\n }\n const units = this.items\n .filter(i => i.costCategory === 'labour')\n .reduce((p, c) => p.add(b(c.getTotalUnits(adjusted))), b('0'))\n .toFixed(2);\n return b(units).div(this.timeBasisSafe).toFixed(2);\n }\n}\n"]}
|
|
@@ -3381,7 +3381,7 @@ class EstimateItemModel {
|
|
|
3381
3381
|
b$2(quantity || '0')
|
|
3382
3382
|
.mul(units || '0')
|
|
3383
3383
|
.mul(labourRate || '0')
|
|
3384
|
-
.div(timeBasis
|
|
3384
|
+
.div(timeBasis)
|
|
3385
3385
|
.toFixed(2);
|
|
3386
3386
|
}
|
|
3387
3387
|
case 'pm': {
|
|
@@ -3522,13 +3522,16 @@ class EstimateModel {
|
|
|
3522
3522
|
vat: '0.00',
|
|
3523
3523
|
labourRate: '0.00',
|
|
3524
3524
|
};
|
|
3525
|
+
get timeBasisSafe() {
|
|
3526
|
+
return (this.timeBasis || '1') === '0' ? '1' : this.timeBasis;
|
|
3527
|
+
}
|
|
3525
3528
|
static create(source = 'manual') {
|
|
3526
3529
|
const model = new EstimateModel();
|
|
3527
3530
|
model.source = source;
|
|
3528
3531
|
return model;
|
|
3529
3532
|
}
|
|
3530
3533
|
static fromDto(dto) {
|
|
3531
|
-
const model = new
|
|
3534
|
+
const model = new this();
|
|
3532
3535
|
Object.assign(model, {
|
|
3533
3536
|
...dto,
|
|
3534
3537
|
items: dto.items?.map(item => EstimateItemModel.fromDto(item)),
|
|
@@ -3551,9 +3554,6 @@ class EstimateModel {
|
|
|
3551
3554
|
}
|
|
3552
3555
|
}
|
|
3553
3556
|
calculate() {
|
|
3554
|
-
if (this.source === 'gtmotive') {
|
|
3555
|
-
return;
|
|
3556
|
-
}
|
|
3557
3557
|
this.summaryNet = this.getSummaryNet(false);
|
|
3558
3558
|
if (this.adjusted) {
|
|
3559
3559
|
this.summaryAdjusted = this.getSummary(this.summaryNet, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount, this.adjusted);
|
|
@@ -3579,7 +3579,7 @@ class EstimateModel {
|
|
|
3579
3579
|
getSummaryNet(adjusted = false) {
|
|
3580
3580
|
const summary = this.items.reduce((map, item) => {
|
|
3581
3581
|
map[item.costCategory] = b$1(map[item.costCategory] || '0')
|
|
3582
|
-
.add(item.getLineValue(this.labourRate, this.
|
|
3582
|
+
.add(item.getLineValue(this.labourRate, this.timeBasisSafe, adjusted))
|
|
3583
3583
|
.toFixed(2);
|
|
3584
3584
|
return map;
|
|
3585
3585
|
}, {
|
|
@@ -3600,12 +3600,12 @@ class EstimateModel {
|
|
|
3600
3600
|
const mechHours = this.items
|
|
3601
3601
|
.filter(item => item.workCategory !== 'paint')
|
|
3602
3602
|
.reduce((h, item) => h.add(b$1(item.getTotalUnits(adjusted))), b$1())
|
|
3603
|
-
.div(this.
|
|
3603
|
+
.div(this.timeBasisSafe || '1')
|
|
3604
3604
|
.round(2);
|
|
3605
3605
|
const paintHours = this.items
|
|
3606
3606
|
.filter(item => item.workCategory === 'paint')
|
|
3607
3607
|
.reduce((h, item) => h.add(b$1(item.getTotalUnits(adjusted))), b$1())
|
|
3608
|
-
.div(this.
|
|
3608
|
+
.div(this.timeBasisSafe || '1')
|
|
3609
3609
|
.round(1);
|
|
3610
3610
|
const mechCost = mechHours.mul(this.labourRate || '0');
|
|
3611
3611
|
const paintCost = paintHours.mul(this.labourRate || '0');
|
|
@@ -3626,7 +3626,7 @@ class EstimateModel {
|
|
|
3626
3626
|
}
|
|
3627
3627
|
else if (sundryMethod === 'percentage-with-max') {
|
|
3628
3628
|
partsSundry = b$1(summaryNet.parts).mul(sundryRate || '1').toFixed(2);
|
|
3629
|
-
partsSundry = Math.min(parseFloat(sundryMax || '0'), parseFloat(partsSundry)).toFixed();
|
|
3629
|
+
partsSundry = Math.min(parseFloat(sundryMax || '0'), parseFloat(partsSundry)).toFixed(2);
|
|
3630
3630
|
}
|
|
3631
3631
|
else if (sundryMethod === 'fixed') {
|
|
3632
3632
|
partsSundry = b$1(sundryFixed).toFixed(2);
|
|
@@ -3677,7 +3677,7 @@ class EstimateModel {
|
|
|
3677
3677
|
sundryMethod: this.sundryMethod,
|
|
3678
3678
|
partsDiscount: this.partsDiscount,
|
|
3679
3679
|
paintDiscount: this.paintDiscount,
|
|
3680
|
-
timeBasis: this.
|
|
3680
|
+
timeBasis: this.timeBasisSafe,
|
|
3681
3681
|
items: this.items.map(i => i.toDto()),
|
|
3682
3682
|
adjusted: this.adjusted,
|
|
3683
3683
|
summary: this.summary,
|
|
@@ -3690,19 +3690,19 @@ class EstimateModel {
|
|
|
3690
3690
|
.filter(item => item.workCategory !== 'paint')
|
|
3691
3691
|
.reduce((h, item) => h.add(b$1(item.getTotalUnits(adjusted))), b$1())
|
|
3692
3692
|
.round(2)
|
|
3693
|
-
.div(this.
|
|
3693
|
+
.div(this.timeBasisSafe);
|
|
3694
3694
|
const paintHours = this.items
|
|
3695
3695
|
.filter(item => item.workCategory === 'paint')
|
|
3696
3696
|
.reduce((h, item) => h.add(b$1(item.getTotalUnits(adjusted))), b$1())
|
|
3697
3697
|
.round(1)
|
|
3698
|
-
.div(this.
|
|
3698
|
+
.div(this.timeBasisSafe);
|
|
3699
3699
|
return mechUnitsHours.add(paintHours).toFixed(2);
|
|
3700
3700
|
}
|
|
3701
3701
|
const units = this.items
|
|
3702
3702
|
.filter(i => i.costCategory === 'labour')
|
|
3703
3703
|
.reduce((p, c) => p.add(b$1(c.getTotalUnits(adjusted))), b$1('0'))
|
|
3704
3704
|
.toFixed(2);
|
|
3705
|
-
return b$1(units).div(this.
|
|
3705
|
+
return b$1(units).div(this.timeBasisSafe).toFixed(2);
|
|
3706
3706
|
}
|
|
3707
3707
|
}
|
|
3708
3708
|
|
|
@@ -3797,6 +3797,13 @@ const getEmptyGeoLocation = () => ({
|
|
|
3797
3797
|
timestamp: ''
|
|
3798
3798
|
});
|
|
3799
3799
|
|
|
3800
|
+
/**
|
|
3801
|
+
* Return true IFF the array contains only strings
|
|
3802
|
+
*/
|
|
3803
|
+
const isArrayString = (value) => {
|
|
3804
|
+
return Array.isArray(value) && value.every(i => typeof i === 'string');
|
|
3805
|
+
};
|
|
3806
|
+
|
|
3800
3807
|
/**
|
|
3801
3808
|
* Return true if the argument is a plain object {}, i.e. not an array, null.
|
|
3802
3809
|
*/
|
|
@@ -3804,6 +3811,53 @@ function isPlainObject(value) {
|
|
|
3804
3811
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3805
3812
|
}
|
|
3806
3813
|
|
|
3814
|
+
/**
|
|
3815
|
+
* Return an object omitting properties specified by key(s)
|
|
3816
|
+
*
|
|
3817
|
+
* @param obj object to be processed
|
|
3818
|
+
* @param omitKey key or array of keys to be omitted
|
|
3819
|
+
*/
|
|
3820
|
+
const omit = (obj, omitKey) => {
|
|
3821
|
+
return Object.keys(obj).reduce((result, key) => {
|
|
3822
|
+
if (Array.isArray(omitKey)) {
|
|
3823
|
+
if (!omitKey.includes(key)) {
|
|
3824
|
+
result[key] = obj[key];
|
|
3825
|
+
}
|
|
3826
|
+
}
|
|
3827
|
+
else {
|
|
3828
|
+
if (omitKey !== key) {
|
|
3829
|
+
result[key] = obj[key];
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
return result;
|
|
3833
|
+
}, {});
|
|
3834
|
+
};
|
|
3835
|
+
|
|
3836
|
+
/**
|
|
3837
|
+
* Try to parse the value as JSON if it looks like a JSON encoded string, return
|
|
3838
|
+
* the original value if it's not a JSON string or parsing fails.
|
|
3839
|
+
*/
|
|
3840
|
+
const tryJson = (value) => {
|
|
3841
|
+
if (typeof value === 'string' && ['{', '['].includes(value.substring(0, 1))) {
|
|
3842
|
+
try {
|
|
3843
|
+
return JSON.parse(value);
|
|
3844
|
+
}
|
|
3845
|
+
catch (e) {
|
|
3846
|
+
return value;
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
return value;
|
|
3850
|
+
};
|
|
3851
|
+
|
|
3852
|
+
const nullables = new Set([
|
|
3853
|
+
'created',
|
|
3854
|
+
'modified',
|
|
3855
|
+
'reference',
|
|
3856
|
+
'jobDate',
|
|
3857
|
+
'followUpDate',
|
|
3858
|
+
'followUpStatus',
|
|
3859
|
+
'followUpNote',
|
|
3860
|
+
]);
|
|
3807
3861
|
let jobStaticProps;
|
|
3808
3862
|
/**
|
|
3809
3863
|
* VasJobBaseModel
|
|
@@ -3831,6 +3885,9 @@ class VasJobBaseModel extends VasRestrictedAccountObjectModel {
|
|
|
3831
3885
|
pendingFields;
|
|
3832
3886
|
childModified;
|
|
3833
3887
|
version;
|
|
3888
|
+
followUpDate;
|
|
3889
|
+
followUpStatus;
|
|
3890
|
+
followUpNote;
|
|
3834
3891
|
geoLocation;
|
|
3835
3892
|
files;
|
|
3836
3893
|
fields;
|
|
@@ -3839,7 +3896,7 @@ class VasJobBaseModel extends VasRestrictedAccountObjectModel {
|
|
|
3839
3896
|
reports;
|
|
3840
3897
|
tasks;
|
|
3841
3898
|
instruction;
|
|
3842
|
-
constructor(id, created, serverCreated, createdBy, modified, serverModified, modifiedBy, createdByName, modifiedByName, account, accessGroup, reference, jobDate, jobStatus, jobStatusLastUpdate, jobType, assigneeId, formId, timeZoneOffset, pendingFields, childModified, version, geoLocation, files, fields, jobEmails, notes, reports, tasks, instruction) {
|
|
3899
|
+
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) {
|
|
3843
3900
|
super(id, created, serverCreated, createdBy, modified, serverModified, modifiedBy, createdByName, modifiedByName, account, accessGroup);
|
|
3844
3901
|
this.id = id;
|
|
3845
3902
|
this.created = created;
|
|
@@ -3863,6 +3920,9 @@ class VasJobBaseModel extends VasRestrictedAccountObjectModel {
|
|
|
3863
3920
|
this.pendingFields = pendingFields;
|
|
3864
3921
|
this.childModified = childModified;
|
|
3865
3922
|
this.version = version;
|
|
3923
|
+
this.followUpDate = followUpDate;
|
|
3924
|
+
this.followUpStatus = followUpStatus;
|
|
3925
|
+
this.followUpNote = followUpNote;
|
|
3866
3926
|
this.geoLocation = geoLocation;
|
|
3867
3927
|
this.files = files;
|
|
3868
3928
|
this.fields = fields;
|
|
@@ -3959,7 +4019,6 @@ class VasJobBaseModel extends VasRestrictedAccountObjectModel {
|
|
|
3959
4019
|
if (!value || typeof value !== 'string') {
|
|
3960
4020
|
return '';
|
|
3961
4021
|
}
|
|
3962
|
-
const fields = this.fields;
|
|
3963
4022
|
return value.replace(/({[^}]*})/g, (match, token) => {
|
|
3964
4023
|
const syntax = token.substring(1, token.length - 1);
|
|
3965
4024
|
let [key, filter] = syntax.split('|');
|
|
@@ -4044,8 +4103,11 @@ class VasJobBaseModel extends VasRestrictedAccountObjectModel {
|
|
|
4044
4103
|
'assigneeId',
|
|
4045
4104
|
'timeZoneOffset',
|
|
4046
4105
|
'pendingFields',
|
|
4047
|
-
'formId'
|
|
4048
|
-
|
|
4106
|
+
'formId',
|
|
4107
|
+
'followUpDate',
|
|
4108
|
+
'followUpStatus',
|
|
4109
|
+
'followUpNote',
|
|
4110
|
+
], (value, key) => value[key] === null && nullables.has(key) ? '~' : value[key]);
|
|
4049
4111
|
}
|
|
4050
4112
|
}
|
|
4051
4113
|
class VasJobRelationalModel extends VasJobBaseModel {
|
|
@@ -4083,10 +4145,43 @@ class VasJobRelationalModel extends VasJobBaseModel {
|
|
|
4083
4145
|
if (dto.fields !== undefined && !Array.isArray(dto.fields)) {
|
|
4084
4146
|
throw Error('fields must be an array');
|
|
4085
4147
|
}
|
|
4086
|
-
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.geoLocation || getEmptyGeoLocation(), dto.files || [], (dto.fields || []).map(f => VasFieldModel.fromDto(f)), dto.jobEmails || [], dto.notes || [], dto.reports || [], dto.tasks || [], dto.instruction || null);
|
|
4148
|
+
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);
|
|
4087
4149
|
}
|
|
4088
4150
|
static empty() {
|
|
4089
|
-
return new VasJobRelationalModel('',
|
|
4151
|
+
return new VasJobRelationalModel('', // id
|
|
4152
|
+
'', // created
|
|
4153
|
+
'', // serverCreated
|
|
4154
|
+
'', // createdBy
|
|
4155
|
+
'', // modified
|
|
4156
|
+
'', // serverModified
|
|
4157
|
+
'', // modifiedBy
|
|
4158
|
+
'', // createdByName
|
|
4159
|
+
'', // modifiedByName
|
|
4160
|
+
'', // account
|
|
4161
|
+
'', // accessGroup
|
|
4162
|
+
'', // reference
|
|
4163
|
+
'', // jobDate
|
|
4164
|
+
'', // jobStatus
|
|
4165
|
+
'', // jobStatusLastUpdate
|
|
4166
|
+
'', // jobType
|
|
4167
|
+
'', // assigneeId
|
|
4168
|
+
'', // formId
|
|
4169
|
+
moment().utcOffset(), // timeZoneOffset
|
|
4170
|
+
0, // pendingFields: number,
|
|
4171
|
+
'', // childModified: string,
|
|
4172
|
+
0, // version: number,
|
|
4173
|
+
'', // followUpDate: string,
|
|
4174
|
+
'', // followUpStatus: string,
|
|
4175
|
+
'', // followUpNote: string,
|
|
4176
|
+
getEmptyGeoLocation(), // geoLocation: GeoLocation,
|
|
4177
|
+
[], // files: Array<VasFileDto>,
|
|
4178
|
+
[], // fields: FType,
|
|
4179
|
+
[], // jobEmails: Array<VasJobEmailDto>,
|
|
4180
|
+
[], // notes: Array<VasNoteDto>,
|
|
4181
|
+
[], // reports: Array<VasReportDto>,
|
|
4182
|
+
[], // tasks: Array<VasTaskDto>,
|
|
4183
|
+
null // instruction: VasInstructionDto | null
|
|
4184
|
+
);
|
|
4090
4185
|
}
|
|
4091
4186
|
toDto() {
|
|
4092
4187
|
return {
|
|
@@ -4112,6 +4207,9 @@ class VasJobRelationalModel extends VasJobBaseModel {
|
|
|
4112
4207
|
pendingFields: this.pendingFields,
|
|
4113
4208
|
childModified: this.childModified,
|
|
4114
4209
|
version: this.version,
|
|
4210
|
+
followUpDate: this.followUpDate,
|
|
4211
|
+
followUpStatus: this.followUpStatus,
|
|
4212
|
+
followUpNote: this.followUpNote,
|
|
4115
4213
|
geoLocation: this.geoLocation,
|
|
4116
4214
|
files: this.files,
|
|
4117
4215
|
fields: this.fields.map(f => f.toDto()),
|
|
@@ -4125,7 +4223,7 @@ class VasJobRelationalModel extends VasJobBaseModel {
|
|
|
4125
4223
|
}
|
|
4126
4224
|
class VasJobDocumentModel extends VasJobBaseModel {
|
|
4127
4225
|
static fromRelationalDto(dto) {
|
|
4128
|
-
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.geoLocation || getEmptyGeoLocation(), dto.files || [], (dto.fields || []).reduce((p, c) => {
|
|
4226
|
+
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) => {
|
|
4129
4227
|
p[c.controlName.replace('fields.', '')] = c.value;
|
|
4130
4228
|
return p;
|
|
4131
4229
|
}, {}), dto.jobEmails || [], dto.notes || [], dto.reports || [], dto.tasks || [], dto.instruction || null);
|
|
@@ -4134,10 +4232,43 @@ class VasJobDocumentModel extends VasJobBaseModel {
|
|
|
4134
4232
|
if (dto.fields !== undefined && !isPlainObject(dto.fields)) {
|
|
4135
4233
|
throw Error('fields must be an object');
|
|
4136
4234
|
}
|
|
4137
|
-
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.geoLocation || getEmptyGeoLocation(), dto.files || [], dto.fields || {}, dto.jobEmails || [], dto.notes || [], dto.reports || [], dto.tasks || [], dto.instruction || null);
|
|
4235
|
+
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 || {}, dto.jobEmails || [], dto.notes || [], dto.reports || [], dto.tasks || [], dto.instruction || null);
|
|
4138
4236
|
}
|
|
4139
4237
|
static empty() {
|
|
4140
|
-
return new VasJobDocumentModel('',
|
|
4238
|
+
return new VasJobDocumentModel('', // id
|
|
4239
|
+
'', // created
|
|
4240
|
+
'', // serverCreated
|
|
4241
|
+
'', // createdBy
|
|
4242
|
+
'', // modified
|
|
4243
|
+
'', // serverModified
|
|
4244
|
+
'', // modifiedBy
|
|
4245
|
+
'', // createdByName
|
|
4246
|
+
'', // modifiedByName
|
|
4247
|
+
'', // account
|
|
4248
|
+
'', // accessGroup
|
|
4249
|
+
'', // reference
|
|
4250
|
+
'', // jobDate
|
|
4251
|
+
'', // jobStatus
|
|
4252
|
+
'', // jobStatusLastUpdate
|
|
4253
|
+
'', // jobType
|
|
4254
|
+
'', // assigneeId
|
|
4255
|
+
'', // formId
|
|
4256
|
+
moment().utcOffset(), // timeZoneOffset
|
|
4257
|
+
0, // pendingFields: number,
|
|
4258
|
+
'', // childModified: string,
|
|
4259
|
+
0, // version: number,
|
|
4260
|
+
'', // followUpDate: string,
|
|
4261
|
+
'', // followUpStatus: string,
|
|
4262
|
+
'', // followUpNote: string,
|
|
4263
|
+
getEmptyGeoLocation(), // geoLocation: GeoLocation,
|
|
4264
|
+
[], // files: Array<VasFileDto>,
|
|
4265
|
+
{}, // fields: FType,
|
|
4266
|
+
[], // jobEmails: Array<VasJobEmailDto>,
|
|
4267
|
+
[], // notes: Array<VasNoteDto>,
|
|
4268
|
+
[], // reports: Array<VasReportDto>,
|
|
4269
|
+
[], // tasks: Array<VasTaskDto>,
|
|
4270
|
+
null // instruction: VasInstructionDto | null
|
|
4271
|
+
);
|
|
4141
4272
|
}
|
|
4142
4273
|
toDto() {
|
|
4143
4274
|
return {
|
|
@@ -4163,6 +4294,9 @@ class VasJobDocumentModel extends VasJobBaseModel {
|
|
|
4163
4294
|
pendingFields: this.pendingFields,
|
|
4164
4295
|
childModified: this.childModified,
|
|
4165
4296
|
version: this.version,
|
|
4297
|
+
followUpDate: this.followUpDate,
|
|
4298
|
+
followUpStatus: this.followUpStatus,
|
|
4299
|
+
followUpNote: this.followUpNote,
|
|
4166
4300
|
geoLocation: this.geoLocation,
|
|
4167
4301
|
files: this.files,
|
|
4168
4302
|
fields: this.fields,
|
|
@@ -4778,51 +4912,6 @@ class VasVehicleModel extends VasAccountObjectModel {
|
|
|
4778
4912
|
}
|
|
4779
4913
|
}
|
|
4780
4914
|
|
|
4781
|
-
/**
|
|
4782
|
-
* Return true IFF the array contains only strings
|
|
4783
|
-
*/
|
|
4784
|
-
const isArrayString = (value) => {
|
|
4785
|
-
return Array.isArray(value) && value.every(i => typeof i === 'string');
|
|
4786
|
-
};
|
|
4787
|
-
|
|
4788
|
-
/**
|
|
4789
|
-
* Return an object omitting properties specified by key(s)
|
|
4790
|
-
*
|
|
4791
|
-
* @param obj object to be processed
|
|
4792
|
-
* @param omitKey key or array of keys to be omitted
|
|
4793
|
-
*/
|
|
4794
|
-
const omit = (obj, omitKey) => {
|
|
4795
|
-
return Object.keys(obj).reduce((result, key) => {
|
|
4796
|
-
if (Array.isArray(omitKey)) {
|
|
4797
|
-
if (!omitKey.includes(key)) {
|
|
4798
|
-
result[key] = obj[key];
|
|
4799
|
-
}
|
|
4800
|
-
}
|
|
4801
|
-
else {
|
|
4802
|
-
if (omitKey !== key) {
|
|
4803
|
-
result[key] = obj[key];
|
|
4804
|
-
}
|
|
4805
|
-
}
|
|
4806
|
-
return result;
|
|
4807
|
-
}, {});
|
|
4808
|
-
};
|
|
4809
|
-
|
|
4810
|
-
/**
|
|
4811
|
-
* Try to parse the value as JSON if it looks like a JSON encoded string, return
|
|
4812
|
-
* the original value if it's not a JSON string or parsing fails.
|
|
4813
|
-
*/
|
|
4814
|
-
const tryJson = (value) => {
|
|
4815
|
-
if (typeof value === 'string' && ['{', '['].includes(value.substring(0, 1))) {
|
|
4816
|
-
try {
|
|
4817
|
-
return JSON.parse(value);
|
|
4818
|
-
}
|
|
4819
|
-
catch (e) {
|
|
4820
|
-
return value;
|
|
4821
|
-
}
|
|
4822
|
-
}
|
|
4823
|
-
return value;
|
|
4824
|
-
};
|
|
4825
|
-
|
|
4826
4915
|
/**
|
|
4827
4916
|
* Generated bundle index. Do not edit.
|
|
4828
4917
|
*/
|