@ironcode/vas-lib 3.0.0-alpha.9 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.model.d.ts +3 -1
- package/cjs/lib/entity/vas-job.model.d.ts.map +1 -1
- package/cjs/lib/entity/vas-job.model.js +53 -9
- package/cjs/lib/entity/vas-job.model.js.map +1 -1
- package/cjs/lib/model/estimate-control/estimate-item.dto.d.ts +1 -0
- package/cjs/lib/model/estimate-control/estimate-item.dto.d.ts.map +1 -1
- package/cjs/lib/model/estimate-control/estimate-item.dto.js.map +1 -1
- package/cjs/lib/model/estimate-control/estimate-item.model.d.ts +3 -2
- package/cjs/lib/model/estimate-control/estimate-item.model.d.ts.map +1 -1
- package/cjs/lib/model/estimate-control/estimate-item.model.js +13 -6
- package/cjs/lib/model/estimate-control/estimate-item.model.js.map +1 -1
- 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 +2 -1
- package/cjs/lib/model/estimate-control/estimate.dto.d.ts.map +1 -1
- package/cjs/lib/model/estimate-control/estimate.dto.js.map +1 -1
- package/cjs/lib/model/estimate-control/estimate.model.d.ts +2 -3
- package/cjs/lib/model/estimate-control/estimate.model.d.ts.map +1 -1
- package/cjs/lib/model/estimate-control/estimate.model.js +31 -18
- package/cjs/lib/model/estimate-control/estimate.model.js.map +1 -1
- package/cjs/lib/model/estimate-control/index.d.ts +1 -0
- package/cjs/lib/model/estimate-control/index.d.ts.map +1 -1
- package/cjs/lib/model/estimate-control/index.js.map +1 -1
- package/fesm2022/ironcode-vas-lib.mjs +99 -34
- package/fesm2022/ironcode-vas-lib.mjs.map +1 -1
- package/lib/entity/vas-job.model.d.ts +3 -1
- package/lib/model/estimate-control/estimate-item.dto.d.ts +1 -0
- package/lib/model/estimate-control/estimate-item.model.d.ts +3 -2
- package/lib/model/estimate-control/estimate-source.d.ts +1 -0
- package/lib/model/estimate-control/estimate.dto.d.ts +2 -1
- package/lib/model/estimate-control/estimate.model.d.ts +2 -3
- package/lib/model/estimate-control/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estimate.dto.js","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/estimate.dto.ts"],"names":[],"mappings":"","sourcesContent":["import { EstimateItemDto } from './estimate-item.dto';\nimport {
|
|
1
|
+
{"version":3,"file":"estimate.dto.js","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/estimate.dto.ts"],"names":[],"mappings":"","sourcesContent":["import { EstimateItemDto } from './estimate-item.dto';\nimport { EstimateSundryMethod } from './estimate.model';\nimport { EstimateCostCategory } from './estimate.types';\nimport { EstimateSource } from './estimate-source';\n\nexport type CostCategorySummary = Record<EstimateCostCategory, string>;\n\nexport interface CostCategorySummaryTotals {\n net: string;\n vat: string;\n gross: string;\n hours: string;\n labourRate: string;\n}\n\nexport type EstimateSummaryDto = CostCategorySummary & CostCategorySummaryTotals;\n\nexport interface EstimateDto {\n id: string;\n source: EstimateSource;\n label: string;\n comment: string;\n timestamp: string;\n version: number;\n net: string;\n vat: string;\n gross: string;\n labourRate: string;\n vatRate: string;\n sundryRate: string;\n sundryMax: string;\n sundryFixed: string;\n sundryMethod: EstimateSundryMethod;\n partsDiscount: string;\n paintDiscount: string;\n timeBasis: string;\n adjusted: boolean;\n items: Array<EstimateItemDto>;\n summary: EstimateSummaryDto;\n summaryAdjusted: EstimateSummaryDto | null;\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { EstimateItemModel } from './estimate-item.model';
|
|
2
2
|
import { EstimateDto, EstimateSummaryDto } from './estimate.dto';
|
|
3
3
|
import { EstimateItemDto } from './estimate-item.dto';
|
|
4
|
-
|
|
5
|
-
export declare type
|
|
4
|
+
import { EstimateSource } from './estimate-source';
|
|
5
|
+
export declare type EstimateSundryMethod = 'fixed' | 'percentage' | 'percentage-with-max';
|
|
6
6
|
export declare class EstimateModel {
|
|
7
7
|
id: string;
|
|
8
8
|
source: EstimateSource;
|
|
@@ -47,7 +47,6 @@ export declare class EstimateModel {
|
|
|
47
47
|
getSummaryNet(adjusted?: boolean): EstimateSummaryDto;
|
|
48
48
|
/**
|
|
49
49
|
* Applies the sundry and discount values to the net summary.
|
|
50
|
-
|
|
51
50
|
*/
|
|
52
51
|
getSummary(summaryNet: EstimateDto['summary'], sundryRate: string, sundryMax: string, sundryFixed: string, sundryMethod: EstimateSundryMethod, partsDiscount: string, paintDiscount: string, adjusted: boolean): EstimateDto['summary'];
|
|
53
52
|
toDto(): EstimateDto;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estimate.model.d.ts","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/estimate.model.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,
|
|
1
|
+
{"version":3,"file":"estimate.model.d.ts","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/estimate.model.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,CAAC,OAAO,MAAM,oBAAoB,GACtC,OAAO,GACP,YAAY,GACZ,qBAAqB,CAAC;AAsBxB,qBAAa,aAAa;IAEjB,EAAE,EAAE,MAAM,CAAU;IACpB,MAAM,EAAE,cAAc,CAAY;IAClC,KAAK,EAAE,MAAM,CAAM;IACnB,OAAO,EAAE,MAAM,CAAM;IACrB,SAAS,EAAE,MAAM,CAA0B;IAC3C,OAAO,EAAE,MAAM,CAAK;IACpB,GAAG,EAAE,MAAM,CAAU;IACrB,GAAG,EAAE,MAAM,CAAU;IACrB,KAAK,EAAE,MAAM,CAAU;IACvB,UAAU,EAAE,MAAM,CAAO;IACzB,OAAO,EAAE,MAAM,CAAU;IACzB,UAAU,EAAE,MAAM,CAAU;IAC5B,SAAS,EAAE,MAAM,CAAU;IAC3B,WAAW,EAAE,MAAM,CAAU;IAC7B,YAAY,EAAE,oBAAoB,CAAW;IAC7C,aAAa,EAAE,MAAM,CAAU;IAC/B,aAAa,EAAE,MAAM,CAAU;IAC/B,SAAS,EAAE,MAAM,CAAO;IACxB,QAAQ,UAAS;IACjB,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAM;IACrC,UAAU,EAAE,kBAAkB,CAanC;IACK,OAAO,EAAE,kBAAkB,CAahC;IACK,eAAe,EAAE,kBAAkB,CAaxC;IAEF,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,MAAM,CAAC,MAAM,CAAC,MAAM,GAAE,cAAyB,GAAG,aAAa;IAM/D,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,aAAa,EACpC,IAAI,EAAE,UAAU,CAAC,EACjB,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,GACxB,CAAC;IAUJ,OAAO,CACL,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,EACxD,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE;IAWhC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE;IAOxE,SAAS,IAAI,IAAI;IAiCjB;;;;;;OAMG;IACH,aAAa,CAAC,QAAQ,UAAQ,GAAG,kBAAkB;IAyDnD;;OAEG;IACH,UAAU,CACR,UAAU,EAAE,WAAW,CAAC,SAAS,CAAC,EAClC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,oBAAoB,EAClC,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,OAAO,GAChB,WAAW,CAAC,SAAS,CAAC;IAiEzB,KAAK,IAAI,WAAW;IA2BpB,aAAa,CAAC,QAAQ,UAAQ,GAAG,MAAM;CAoBxC"}
|
|
@@ -18,6 +18,12 @@ const b = (value = '0') => {
|
|
|
18
18
|
return new big_js_1.Big('0');
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
|
+
function isLabourWorkCategory(value) {
|
|
22
|
+
return ['check', 'rr', 'repair', 'removed'].includes(value);
|
|
23
|
+
}
|
|
24
|
+
function isPaintWorkCategory(value) {
|
|
25
|
+
return ['blend', 'paint'].includes(value);
|
|
26
|
+
}
|
|
21
27
|
class EstimateModel {
|
|
22
28
|
constructor() {
|
|
23
29
|
this.id = (0, uuid_1.v4)();
|
|
@@ -115,18 +121,13 @@ class EstimateModel {
|
|
|
115
121
|
calculate() {
|
|
116
122
|
this.summaryNet = this.getSummaryNet(false);
|
|
117
123
|
if (this.adjusted) {
|
|
118
|
-
|
|
124
|
+
const summaryNetAdjusted = this.getSummaryNet(true);
|
|
125
|
+
this.summaryAdjusted = this.getSummary(summaryNetAdjusted, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount, true);
|
|
119
126
|
}
|
|
120
|
-
this.summary = this.getSummary(this.summaryNet, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount,
|
|
121
|
-
this.net =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
.add(this.summary.parts)
|
|
125
|
-
.add(this.summary.pm)
|
|
126
|
-
.add(this.summary.specialist)
|
|
127
|
-
.toFixed(2);
|
|
128
|
-
this.vat = b(this.net || '0').mul(this.vatRate || '0').toFixed(2);
|
|
129
|
-
this.gross = b(this.net || '0').add(this.vat || '0').toFixed(2);
|
|
127
|
+
this.summary = this.getSummary(this.summaryNet, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount, false);
|
|
128
|
+
this.net = this.summary.net;
|
|
129
|
+
this.vat = this.summary.vat;
|
|
130
|
+
this.gross = this.summary.gross;
|
|
130
131
|
}
|
|
131
132
|
/**
|
|
132
133
|
* Returns the net summary (before sundries and discounts) of the estimate.
|
|
@@ -138,7 +139,7 @@ class EstimateModel {
|
|
|
138
139
|
getSummaryNet(adjusted = false) {
|
|
139
140
|
const summary = this.items.reduce((map, item) => {
|
|
140
141
|
map[item.costCategory] = b(map[item.costCategory] || '0')
|
|
141
|
-
.add(item.getLineValue(this.labourRate, this.timeBasisSafe, adjusted))
|
|
142
|
+
.add(item.getLineValue(this.labourRate, this.timeBasisSafe, adjusted, this.source === 'gtmotive' ? false : undefined))
|
|
142
143
|
.toFixed(2);
|
|
143
144
|
return map;
|
|
144
145
|
}, {
|
|
@@ -157,13 +158,19 @@ class EstimateModel {
|
|
|
157
158
|
});
|
|
158
159
|
if (this.source === 'audatex') {
|
|
159
160
|
const mechHours = this.items
|
|
160
|
-
.
|
|
161
|
-
|
|
161
|
+
.reduce((h, item) => {
|
|
162
|
+
return isLabourWorkCategory(item.workCategory) ?
|
|
163
|
+
h.add(b(item.getTotalUnits(adjusted))) :
|
|
164
|
+
h;
|
|
165
|
+
}, b())
|
|
162
166
|
.div(this.timeBasisSafe || '1')
|
|
163
167
|
.round(2);
|
|
164
168
|
const paintHours = this.items
|
|
165
|
-
.
|
|
166
|
-
|
|
169
|
+
.reduce((h, item) => {
|
|
170
|
+
return isPaintWorkCategory(item.workCategory) ?
|
|
171
|
+
h.add(b(item.getTotalUnits(adjusted))) :
|
|
172
|
+
h;
|
|
173
|
+
}, b())
|
|
167
174
|
.div(this.timeBasisSafe || '1')
|
|
168
175
|
.round(1);
|
|
169
176
|
const mechCost = mechHours.mul(this.labourRate || '0');
|
|
@@ -174,7 +181,6 @@ class EstimateModel {
|
|
|
174
181
|
}
|
|
175
182
|
/**
|
|
176
183
|
* Applies the sundry and discount values to the net summary.
|
|
177
|
-
|
|
178
184
|
*/
|
|
179
185
|
getSummary(summaryNet, sundryRate, sundryMax, sundryFixed, sundryMethod, partsDiscount, paintDiscount, adjusted) {
|
|
180
186
|
const partsDisc = b('1').minus(partsDiscount || '0');
|
|
@@ -196,12 +202,19 @@ class EstimateModel {
|
|
|
196
202
|
.add(summaryNet.none)
|
|
197
203
|
.add(parts)
|
|
198
204
|
.add(summaryNet.pm)
|
|
205
|
+
.add(summaryNet.pl)
|
|
199
206
|
.add(summaryNet.specialist)
|
|
207
|
+
.add(summaryNet.other)
|
|
200
208
|
.toFixed(2);
|
|
201
209
|
const vat = b(net || '0')
|
|
202
210
|
.mul(this.vatRate || '0')
|
|
203
211
|
.toFixed(2);
|
|
204
|
-
|
|
212
|
+
let gross = b(net || '0').add(vat || '0').toFixed(2);
|
|
213
|
+
// calculate the total value of lines that are VAT excluded
|
|
214
|
+
const vatExcludeTotal = this.items.reduce((p, c) => c.vatExcluded ?
|
|
215
|
+
p.add(c.getLineValue(this.labourRate, this.timeBasisSafe, adjusted, true)) :
|
|
216
|
+
p, b());
|
|
217
|
+
gross = b(gross).add(vatExcludeTotal).toFixed(2);
|
|
205
218
|
return {
|
|
206
219
|
labour: summaryNet.labour,
|
|
207
220
|
none: summaryNet.none,
|
|
@@ -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 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"]}
|
|
1
|
+
{"version":3,"file":"estimate.model.js","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/estimate.model.ts"],"names":[],"mappings":";;;;AAAA,mCAA6B;AAC7B,4DAA4B;AAC5B,+BAAkC;AAClC,+DAA0D;AAW1D,MAAM,CAAC,GAAG,CAAC,QAA+B,GAAG,EAAE,EAAE;IAC/C,IAAI,CAAC;QACH,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,IAAI,YAAG,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,IAAI,YAAG,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,uCAAuC,KAAK,GAAG,CAAC,CAAC;QAC/D,OAAO,IAAI,YAAG,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;AACH,CAAC,CAAC;AAEF,SAAS,oBAAoB,CAAC,KAA2B;IACvD,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,mBAAmB,CAAC,KAA2B;IACtD,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,MAAa,aAAa;IAA1B;QAES,OAAE,GAAW,IAAA,SAAI,GAAE,CAAC;QACpB,WAAM,GAAmB,QAAQ,CAAC;QAClC,UAAK,GAAW,EAAE,CAAC;QACnB,YAAO,GAAW,EAAE,CAAC;QACrB,cAAS,GAAW,IAAA,gBAAM,GAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,YAAO,GAAW,CAAC,CAAC;QACpB,QAAG,GAAW,MAAM,CAAC;QACrB,QAAG,GAAW,MAAM,CAAC;QACrB,UAAK,GAAW,MAAM,CAAC;QACvB,eAAU,GAAW,GAAG,CAAC;QACzB,YAAO,GAAW,MAAM,CAAC;QACzB,eAAU,GAAW,MAAM,CAAC;QAC5B,cAAS,GAAW,MAAM,CAAC;QAC3B,gBAAW,GAAW,MAAM,CAAC;QAC7B,iBAAY,GAAyB,OAAO,CAAC;QAC7C,kBAAa,GAAW,MAAM,CAAC;QAC/B,kBAAa,GAAW,MAAM,CAAC;QAC/B,cAAS,GAAW,GAAG,CAAC;QACxB,aAAQ,GAAG,KAAK,CAAC;QACjB,UAAK,GAA6B,EAAE,CAAC;QACrC,eAAU,GAAuB;YACtC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,MAAM;YACb,EAAE,EAAE,MAAM;YACV,EAAE,EAAE,MAAM;YACV,UAAU,EAAE,MAAM;YAClB,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,MAAM;YACX,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,MAAM;YACX,UAAU,EAAE,MAAM;SACnB,CAAC;QACK,YAAO,GAAuB;YACnC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,MAAM;YACb,EAAE,EAAE,MAAM;YACV,EAAE,EAAE,MAAM;YACV,UAAU,EAAE,MAAM;YAClB,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,MAAM;YACX,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,MAAM;YACX,UAAU,EAAE,MAAM;SACnB,CAAC;QACK,oBAAe,GAAuB;YAC3C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,MAAM;YACb,EAAE,EAAE,MAAM;YACV,EAAE,EAAE,MAAM;YACV,UAAU,EAAE,MAAM;YAClB,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,MAAM;YACX,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,MAAM;YACX,UAAU,EAAE,MAAM;SACnB,CAAC;IA0QJ,CAAC;IAxQC,IAAI,aAAa;QACf,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;IAChE,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,SAAyB,QAAQ;QAC7C,MAAM,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;QAClC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,OAAO,CAEZ,GAAyB;;QAEzB,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,MAAM,CAAC,MAAM,CAAC,KAAK,kCACd,GAAG,KACN,KAAK,EAAE,MAAA,GAAG,CAAC,KAAK,0CAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,uCAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAC9D,CAAC;QACH,KAAK,CAAC,SAAS,EAAE,CAAC;QAClB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CACL,UAAwD,EACxD,IAA8B;QAE9B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,YAAY,uCAAiB,CAAC,CAAC;YACvD,UAAU,CAAC,CAAC;YACZ,uCAAiB,CAAC,OAAO,CAAC,UAAU,CAAC,CACtC,CAAC;QACF,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,KAA+B,EAAE,IAA8B;QACtE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAED,SAAS;QAEP,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE5C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YACpD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU,CACpC,kBAAkB,EAClB,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,aAAa,EAClB,IAAI,CACL,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAC5B,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,aAAa,EAClB,KAAK,CACN,CAAC;QAEF,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;QAC5B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACH,aAAa,CAAC,QAAQ,GAAG,KAAK;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;YAC9C,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC;iBACtD,GAAG,CAAC,IAAI,CAAC,YAAY,CACpB,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,aAAa,EAClB,QAAQ,EACR,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC/C,CAAC;iBACD,OAAO,CAAC,CAAC,CAAC,CAAC;YACd,OAAO,GAAG,CAAC;QACb,CAAC,EAAE;YACD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,MAAM;YACb,EAAE,EAAE,MAAM;YACV,EAAE,EAAE,MAAM;YACV,UAAU,EAAE,MAAM;YAClB,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,MAAM;YACX,GAAG,EAAE,MAAM;YACX,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,MAAM;YACb,UAAU,EAAE,GAAG;SACM,CAAC,CAAC;QAEzB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK;iBACzB,MAAM,CACL,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE;gBACV,OAAO,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;oBAC9C,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;oBACxC,CAAC,CAAC;YACN,CAAC,EACD,CAAC,EAAE,CACJ;iBACA,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,GAAG,CAAC;iBAC9B,KAAK,CAAC,CAAC,CAAC,CAAC;YACZ,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK;iBAC1B,MAAM,CACL,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE;gBACV,OAAO,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;oBAC7C,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;oBACxC,CAAC,CAAC;YACN,CAAC,EACD,CAAC,EAAE,CACJ;iBACA,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,GAAG,CAAC;iBAC9B,KAAK,CAAC,CAAC,CAAC,CAAC;YAEZ,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;YACvD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;YACzD,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,UAAU,CACR,UAAkC,EAClC,UAAkB,EAClB,SAAiB,EACjB,WAAmB,EACnB,YAAkC,EAClC,aAAqB,EACrB,aAAqB,EACrB,QAAiB;QAEjB,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,GAAG,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,GAAG,CAAC,CAAC;QAErD,IAAI,WAAW,GAAG,MAAM,CAAC;QAEzB,IAAI,YAAY,KAAK,YAAY,EAAE,CAAC;YAClC,WAAW,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtE,CAAC;aAAM,IAAI,YAAY,KAAK,qBAAqB,EAAE,CAAC;YAClD,WAAW,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACpE,WAAW,GAAG,IAAI,CAAC,GAAG,CACpB,UAAU,CAAC,SAAS,IAAI,GAAG,CAAC,EAC5B,UAAU,CAAC,WAAW,CAAC,CACxB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;aAAM,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;YACpC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,KAAK,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAEnD,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;aACb,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;aACtB,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;aACpB,GAAG,CAAC,KAAK,CAAC;aACV,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;aAClB,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;aAClB,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC;aAC1B,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC;aACrB,OAAO,CAAC,CAAC,CAAC,CAAC;QACd,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;aACtB,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC;aACxB,OAAO,CAAC,CAAC,CAAC,CAAC;QACd,IAAI,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAErD,2DAA2D;QAC3D,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CACvC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,CAAC,CAAC,WAAW,CAAC,CAAC;YACb,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAClB,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,aAAa,EAClB,QAAQ,EACR,IAAI,CACL,CAAC,CAAC,CAAC;YACJ,CAAC,EACL,CAAC,EAAE,CACJ,CAAC;QACF,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAEjD,OAAO;YACL,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACzC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YAC9C,EAAE,EAAE,UAAU,CAAC,EAAE;YACjB,UAAU,EAAE,UAAU,CAAC,UAAU;YACjC,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,GAAG,EAAE,GAAG;YACR,GAAG,EAAE,GAAG;YACR,KAAK,EAAE,KAAK;YACZ,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;SACpC,CAAC;IACJ,CAAC;IAED,KAAK;QACH,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,SAAS,EAAE,IAAI,CAAC,aAAa;YAC7B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;YACrC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,QAAQ,GAAG,KAAK;QAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK;iBAC9B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,KAAK,OAAO,CAAC;iBAC7C,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;iBAChE,KAAK,CAAC,CAAC,CAAC;iBACR,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK;iBAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,KAAK,OAAO,CAAC;iBAC7C,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;iBAChE,KAAK,CAAC,CAAC,CAAC;iBACR,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC3B,OAAO,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK;aACrB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,QAAQ,CAAC;aACxC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;aAC7D,OAAO,CAAC,CAAC,CAAC,CAAC;QACd,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;CACF;AAzUD,sCAyUC","sourcesContent":["import { Big } from 'big.js';\nimport moment from 'moment';\nimport { v4 as uuid } from 'uuid';\nimport { EstimateItemModel } from './estimate-item.model';\nimport { EstimateDto, EstimateSummaryDto } from './estimate.dto';\nimport { EstimateItemDto } from './estimate-item.dto';\nimport { EstimateWorkCategory } from './estimate.types';\nimport { EstimateSource } from './estimate-source';\n\nexport declare type EstimateSundryMethod =\n 'fixed' |\n 'percentage' |\n 'percentage-with-max';\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\nfunction isLabourWorkCategory(value: EstimateWorkCategory): boolean {\n return ['check', 'rr', 'repair', 'removed'].includes(value);\n}\n\nfunction isPaintWorkCategory(value: EstimateWorkCategory): boolean {\n return ['blend', 'paint'].includes(value);\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 const summaryNetAdjusted = this.getSummaryNet(true);\n this.summaryAdjusted = this.getSummary(\n summaryNetAdjusted,\n this.sundryRate,\n this.sundryMax,\n this.sundryFixed,\n this.sundryMethod,\n this.partsDiscount,\n this.paintDiscount,\n true\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 false\n );\n\n this.net = this.summary.net;\n this.vat = this.summary.vat;\n this.gross = this.summary.gross;\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(\n this.labourRate,\n this.timeBasisSafe,\n adjusted,\n this.source === 'gtmotive' ? false : undefined\n ))\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 .reduce(\n (h, item) => {\n return isLabourWorkCategory(item.workCategory) ?\n h.add(b(item.getTotalUnits(adjusted))) :\n h;\n },\n b()\n )\n .div(this.timeBasisSafe || '1')\n .round(2);\n const paintHours = this.items\n .reduce(\n (h, item) => {\n return isPaintWorkCategory(item.workCategory) ?\n h.add(b(item.getTotalUnits(adjusted))) :\n h;\n },\n b()\n )\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 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.pl)\n .add(summaryNet.specialist)\n .add(summaryNet.other)\n .toFixed(2);\n const vat = b(net || '0')\n .mul(this.vatRate || '0')\n .toFixed(2);\n let gross = b(net || '0').add(vat || '0').toFixed(2);\n\n // calculate the total value of lines that are VAT excluded\n const vatExcludeTotal = this.items.reduce(\n (p, c) =>\n c.vatExcluded ?\n p.add(c.getLineValue(\n this.labourRate,\n this.timeBasisSafe,\n adjusted,\n true\n )) :\n p,\n b()\n );\n gross = b(gross).add(vatExcludeTotal).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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/index.ts"],"names":[],"mappings":";;;AAAA,yDAA+B;AAC/B,2DAAiC;AACjC,2DAAiC;AACjC,uEAA6C;AAC7C,yEAA+C;AAC/C,8DAAoC;AACpC,gEAAsC","sourcesContent":["export * from './estimate.dto';\nexport * from './estimate.model';\nexport * from './estimate.types';\nexport * from './estimate-control-value.dto';\nexport * from './estimate-control-value.model';\nexport * from './estimate-item.dto';\nexport * from './estimate-item.model';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../projects/vas-lib/src/lib/model/estimate-control/index.ts"],"names":[],"mappings":";;;AAAA,yDAA+B;AAC/B,2DAAiC;AACjC,2DAAiC;AACjC,uEAA6C;AAC7C,yEAA+C;AAC/C,8DAAoC;AACpC,gEAAsC","sourcesContent":["export * from './estimate.dto';\nexport * from './estimate.model';\nexport * from './estimate.types';\nexport * from './estimate-control-value.dto';\nexport * from './estimate-control-value.model';\nexport * from './estimate-item.dto';\nexport * from './estimate-item.model';\nexport { EstimateSource } from './estimate-source';\n"]}
|
|
@@ -2245,7 +2245,7 @@ class VasFormModel extends VasRestrictedAccountObjectModel {
|
|
|
2245
2245
|
if (control.controlTypeName !== 'camera') {
|
|
2246
2246
|
return;
|
|
2247
2247
|
}
|
|
2248
|
-
paths.push(
|
|
2248
|
+
paths.push(control.name.split('.'));
|
|
2249
2249
|
});
|
|
2250
2250
|
});
|
|
2251
2251
|
return paths;
|
|
@@ -3346,7 +3346,8 @@ class EstimateItemModel {
|
|
|
3346
3346
|
workCategory;
|
|
3347
3347
|
costCategory;
|
|
3348
3348
|
comment;
|
|
3349
|
-
|
|
3349
|
+
vatExcluded;
|
|
3350
|
+
constructor(id, description, type, quantity, quantityAdjusted, units, unitsAdjusted, price, priceAdjusted, workCategory, costCategory, comment, vatExcluded) {
|
|
3350
3351
|
this.id = id;
|
|
3351
3352
|
this.description = description;
|
|
3352
3353
|
this.type = type;
|
|
@@ -3359,17 +3360,21 @@ class EstimateItemModel {
|
|
|
3359
3360
|
this.workCategory = workCategory;
|
|
3360
3361
|
this.costCategory = costCategory;
|
|
3361
3362
|
this.comment = comment;
|
|
3363
|
+
this.vatExcluded = vatExcluded;
|
|
3362
3364
|
}
|
|
3363
3365
|
getTotalUnits(adjusted = false) {
|
|
3364
3366
|
return adjusted ?
|
|
3365
3367
|
b$2(this.quantityAdjusted || '0').mul(this.unitsAdjusted || '0').toFixed(2) :
|
|
3366
3368
|
b$2(this.quantity || '0').mul(this.units || '0').toFixed(2);
|
|
3367
3369
|
}
|
|
3368
|
-
getLineValue(labourRate = '1', timeBasis = '1', adjusted = false) {
|
|
3370
|
+
getLineValue(labourRate = '1', timeBasis = '1', adjusted = false, vatExcluded) {
|
|
3369
3371
|
const cat = this.costCategory || 'none';
|
|
3370
3372
|
if (this.workCategory === 'removed') {
|
|
3371
3373
|
return '0';
|
|
3372
3374
|
}
|
|
3375
|
+
if (vatExcluded !== undefined && this.vatExcluded !== vatExcluded) {
|
|
3376
|
+
return '0';
|
|
3377
|
+
}
|
|
3373
3378
|
const units = (adjusted ? this.unitsAdjusted : this.units) || 0;
|
|
3374
3379
|
const quantity = (adjusted ? this.quantityAdjusted : this.quantity) || 0;
|
|
3375
3380
|
const price = (adjusted ? this.priceAdjusted : this.price) || '';
|
|
@@ -3394,7 +3399,9 @@ class EstimateItemModel {
|
|
|
3394
3399
|
.mul(quantity || '0')
|
|
3395
3400
|
.toFixed(2);
|
|
3396
3401
|
}
|
|
3397
|
-
case 'specialist':
|
|
3402
|
+
case 'specialist':
|
|
3403
|
+
case 'pl':
|
|
3404
|
+
case 'other': {
|
|
3398
3405
|
return b$2(price || '0')
|
|
3399
3406
|
.mul(quantity || '0')
|
|
3400
3407
|
.toFixed(2);
|
|
@@ -3422,14 +3429,15 @@ class EstimateItemModel {
|
|
|
3422
3429
|
priceAdjusted: this.priceAdjusted,
|
|
3423
3430
|
workCategory: this.workCategory,
|
|
3424
3431
|
costCategory: this.costCategory,
|
|
3425
|
-
comment: this.comment
|
|
3432
|
+
comment: this.comment,
|
|
3433
|
+
vatExcluded: this.vatExcluded
|
|
3426
3434
|
};
|
|
3427
3435
|
}
|
|
3428
3436
|
static create() {
|
|
3429
|
-
return new EstimateItemModel(v4(), '', '', 1, 1, 0, 0, '', '', 'none', 'none', '');
|
|
3437
|
+
return new EstimateItemModel(v4(), '', '', 1, 1, 0, 0, '', '', 'none', 'none', '', false);
|
|
3430
3438
|
}
|
|
3431
3439
|
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 || '');
|
|
3440
|
+
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);
|
|
3433
3441
|
}
|
|
3434
3442
|
static equal(a, b) {
|
|
3435
3443
|
return (a?.id === b?.id &&
|
|
@@ -3459,6 +3467,12 @@ const b$1 = (value = '0') => {
|
|
|
3459
3467
|
return new Big('0');
|
|
3460
3468
|
}
|
|
3461
3469
|
};
|
|
3470
|
+
function isLabourWorkCategory(value) {
|
|
3471
|
+
return ['check', 'rr', 'repair', 'removed'].includes(value);
|
|
3472
|
+
}
|
|
3473
|
+
function isPaintWorkCategory(value) {
|
|
3474
|
+
return ['blend', 'paint'].includes(value);
|
|
3475
|
+
}
|
|
3462
3476
|
class EstimateModel {
|
|
3463
3477
|
id = v4();
|
|
3464
3478
|
source = 'manual';
|
|
@@ -3556,18 +3570,13 @@ class EstimateModel {
|
|
|
3556
3570
|
calculate() {
|
|
3557
3571
|
this.summaryNet = this.getSummaryNet(false);
|
|
3558
3572
|
if (this.adjusted) {
|
|
3559
|
-
|
|
3573
|
+
const summaryNetAdjusted = this.getSummaryNet(true);
|
|
3574
|
+
this.summaryAdjusted = this.getSummary(summaryNetAdjusted, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount, true);
|
|
3560
3575
|
}
|
|
3561
|
-
this.summary = this.getSummary(this.summaryNet, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount,
|
|
3562
|
-
this.net =
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
.add(this.summary.parts)
|
|
3566
|
-
.add(this.summary.pm)
|
|
3567
|
-
.add(this.summary.specialist)
|
|
3568
|
-
.toFixed(2);
|
|
3569
|
-
this.vat = b$1(this.net || '0').mul(this.vatRate || '0').toFixed(2);
|
|
3570
|
-
this.gross = b$1(this.net || '0').add(this.vat || '0').toFixed(2);
|
|
3576
|
+
this.summary = this.getSummary(this.summaryNet, this.sundryRate, this.sundryMax, this.sundryFixed, this.sundryMethod, this.partsDiscount, this.paintDiscount, false);
|
|
3577
|
+
this.net = this.summary.net;
|
|
3578
|
+
this.vat = this.summary.vat;
|
|
3579
|
+
this.gross = this.summary.gross;
|
|
3571
3580
|
}
|
|
3572
3581
|
/**
|
|
3573
3582
|
* Returns the net summary (before sundries and discounts) of the estimate.
|
|
@@ -3579,7 +3588,7 @@ class EstimateModel {
|
|
|
3579
3588
|
getSummaryNet(adjusted = false) {
|
|
3580
3589
|
const summary = this.items.reduce((map, item) => {
|
|
3581
3590
|
map[item.costCategory] = b$1(map[item.costCategory] || '0')
|
|
3582
|
-
.add(item.getLineValue(this.labourRate, this.timeBasisSafe, adjusted))
|
|
3591
|
+
.add(item.getLineValue(this.labourRate, this.timeBasisSafe, adjusted, this.source === 'gtmotive' ? false : undefined))
|
|
3583
3592
|
.toFixed(2);
|
|
3584
3593
|
return map;
|
|
3585
3594
|
}, {
|
|
@@ -3598,13 +3607,19 @@ class EstimateModel {
|
|
|
3598
3607
|
});
|
|
3599
3608
|
if (this.source === 'audatex') {
|
|
3600
3609
|
const mechHours = this.items
|
|
3601
|
-
.
|
|
3602
|
-
|
|
3610
|
+
.reduce((h, item) => {
|
|
3611
|
+
return isLabourWorkCategory(item.workCategory) ?
|
|
3612
|
+
h.add(b$1(item.getTotalUnits(adjusted))) :
|
|
3613
|
+
h;
|
|
3614
|
+
}, b$1())
|
|
3603
3615
|
.div(this.timeBasisSafe || '1')
|
|
3604
3616
|
.round(2);
|
|
3605
3617
|
const paintHours = this.items
|
|
3606
|
-
.
|
|
3607
|
-
|
|
3618
|
+
.reduce((h, item) => {
|
|
3619
|
+
return isPaintWorkCategory(item.workCategory) ?
|
|
3620
|
+
h.add(b$1(item.getTotalUnits(adjusted))) :
|
|
3621
|
+
h;
|
|
3622
|
+
}, b$1())
|
|
3608
3623
|
.div(this.timeBasisSafe || '1')
|
|
3609
3624
|
.round(1);
|
|
3610
3625
|
const mechCost = mechHours.mul(this.labourRate || '0');
|
|
@@ -3615,7 +3630,6 @@ class EstimateModel {
|
|
|
3615
3630
|
}
|
|
3616
3631
|
/**
|
|
3617
3632
|
* Applies the sundry and discount values to the net summary.
|
|
3618
|
-
|
|
3619
3633
|
*/
|
|
3620
3634
|
getSummary(summaryNet, sundryRate, sundryMax, sundryFixed, sundryMethod, partsDiscount, paintDiscount, adjusted) {
|
|
3621
3635
|
const partsDisc = b$1('1').minus(partsDiscount || '0');
|
|
@@ -3637,12 +3651,19 @@ class EstimateModel {
|
|
|
3637
3651
|
.add(summaryNet.none)
|
|
3638
3652
|
.add(parts)
|
|
3639
3653
|
.add(summaryNet.pm)
|
|
3654
|
+
.add(summaryNet.pl)
|
|
3640
3655
|
.add(summaryNet.specialist)
|
|
3656
|
+
.add(summaryNet.other)
|
|
3641
3657
|
.toFixed(2);
|
|
3642
3658
|
const vat = b$1(net || '0')
|
|
3643
3659
|
.mul(this.vatRate || '0')
|
|
3644
3660
|
.toFixed(2);
|
|
3645
|
-
|
|
3661
|
+
let gross = b$1(net || '0').add(vat || '0').toFixed(2);
|
|
3662
|
+
// calculate the total value of lines that are VAT excluded
|
|
3663
|
+
const vatExcludeTotal = this.items.reduce((p, c) => c.vatExcluded ?
|
|
3664
|
+
p.add(c.getLineValue(this.labourRate, this.timeBasisSafe, adjusted, true)) :
|
|
3665
|
+
p, b$1());
|
|
3666
|
+
gross = b$1(gross).add(vatExcludeTotal).toFixed(2);
|
|
3646
3667
|
return {
|
|
3647
3668
|
labour: summaryNet.labour,
|
|
3648
3669
|
none: summaryNet.none,
|
|
@@ -3859,6 +3880,21 @@ const nullables = new Set([
|
|
|
3859
3880
|
'followUpNote',
|
|
3860
3881
|
]);
|
|
3861
3882
|
let jobStaticProps;
|
|
3883
|
+
function getStaticProps() {
|
|
3884
|
+
if (jobStaticProps) {
|
|
3885
|
+
return jobStaticProps;
|
|
3886
|
+
}
|
|
3887
|
+
return jobStaticProps = new Set([
|
|
3888
|
+
...Object.getOwnPropertyNames(VasJobDocumentModel.empty()),
|
|
3889
|
+
'assignee'
|
|
3890
|
+
]);
|
|
3891
|
+
}
|
|
3892
|
+
function isArrayOfFields(value) {
|
|
3893
|
+
return !!value && Array.isArray(value);
|
|
3894
|
+
}
|
|
3895
|
+
function isDictionaryOfFields(value) {
|
|
3896
|
+
return !!value && isPlainObject(value);
|
|
3897
|
+
}
|
|
3862
3898
|
/**
|
|
3863
3899
|
* VasJobBaseModel
|
|
3864
3900
|
*/
|
|
@@ -3942,11 +3978,7 @@ class VasJobBaseModel extends VasRestrictedAccountObjectModel {
|
|
|
3942
3978
|
* Return the list of Job properties
|
|
3943
3979
|
*/
|
|
3944
3980
|
get staticProperties() {
|
|
3945
|
-
|
|
3946
|
-
return jobStaticProps;
|
|
3947
|
-
}
|
|
3948
|
-
return jobStaticProps =
|
|
3949
|
-
new Set(Object.getOwnPropertyNames(VasJobDocumentModel.empty()));
|
|
3981
|
+
return getStaticProps();
|
|
3950
3982
|
}
|
|
3951
3983
|
/**
|
|
3952
3984
|
* Returns an object describing how many attachments were added to this job
|
|
@@ -4228,11 +4260,44 @@ class VasJobDocumentModel extends VasJobBaseModel {
|
|
|
4228
4260
|
return p;
|
|
4229
4261
|
}, {}), dto.jobEmails || [], dto.notes || [], dto.reports || [], dto.tasks || [], dto.instruction || null);
|
|
4230
4262
|
}
|
|
4231
|
-
static fromDto(dto) {
|
|
4232
|
-
|
|
4233
|
-
|
|
4263
|
+
static fromDto(dto, options = { disableMigrateCheck: false }) {
|
|
4264
|
+
let fields = {};
|
|
4265
|
+
if (dto.fields !== undefined) {
|
|
4266
|
+
if (isArrayOfFields(dto.fields)) {
|
|
4267
|
+
for (const field of dto.fields) {
|
|
4268
|
+
fields[field.controlName.replace('fields.', '')] =
|
|
4269
|
+
tryJson(field.value);
|
|
4270
|
+
}
|
|
4271
|
+
}
|
|
4272
|
+
else if (isDictionaryOfFields(dto.fields)) {
|
|
4273
|
+
fields = dto.fields;
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
4276
|
+
// this code is checking if a have a document in the old dynamic job style,
|
|
4277
|
+
// i.e. where there are keys in the job object that come from the form-group
|
|
4278
|
+
// names. I did consider comparing the number of keys in the dto vs the
|
|
4279
|
+
// number of expected keys, but this will fail if we try to read old objects
|
|
4280
|
+
// that don't have new properties added. So we always check by default. We
|
|
4281
|
+
// can skip this check by setting disableMigrateCheck in the options.
|
|
4282
|
+
if (!options || !options.disableMigrateCheck) {
|
|
4283
|
+
const ddto = dto;
|
|
4284
|
+
const actualKeys = Object.keys(ddto);
|
|
4285
|
+
actualKeys.reduce((f, groupName) => {
|
|
4286
|
+
if (getStaticProps().has(groupName)) {
|
|
4287
|
+
return f;
|
|
4288
|
+
}
|
|
4289
|
+
Object
|
|
4290
|
+
.keys(ddto[groupName])
|
|
4291
|
+
.forEach(controlName => {
|
|
4292
|
+
if (!controlName.startsWith('fields.')) {
|
|
4293
|
+
return;
|
|
4294
|
+
}
|
|
4295
|
+
f[controlName.slice(7)] = ddto[groupName][controlName];
|
|
4296
|
+
});
|
|
4297
|
+
return f;
|
|
4298
|
+
}, fields);
|
|
4234
4299
|
}
|
|
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 || [],
|
|
4300
|
+
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);
|
|
4236
4301
|
}
|
|
4237
4302
|
static empty() {
|
|
4238
4303
|
return new VasJobDocumentModel('', // id
|