taxtank-core 0.24.3 → 0.26.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.
Files changed (161) hide show
  1. package/bundles/taxtank-core.umd.js +3067 -2561
  2. package/bundles/taxtank-core.umd.js.map +1 -1
  3. package/esm2015/lib/collections/client-invite.collection.js +1 -4
  4. package/esm2015/lib/collections/depreciation.collection.js +11 -1
  5. package/esm2015/lib/collections/index.js +3 -0
  6. package/esm2015/lib/collections/loan/loan-payment.collection.js +14 -1
  7. package/esm2015/lib/collections/loan/loan.collection.js +11 -1
  8. package/esm2015/lib/collections/report/vehicle-expense/vehicle-expense.collection.js +1 -1
  9. package/esm2015/lib/collections/transaction/transaction.collection.js +20 -1
  10. package/esm2015/lib/collections/vehicle/index.js +3 -0
  11. package/esm2015/lib/collections/vehicle/vehicle-claim.collection.js +27 -0
  12. package/esm2015/lib/collections/vehicle/vehicle-logbook.collection.js +106 -0
  13. package/esm2015/lib/db/Enums/bank-account-type.enum.js +3 -2
  14. package/esm2015/lib/db/Enums/vehicle-claim-details-method.enum.js +6 -0
  15. package/esm2015/lib/db/Models/sole/sole-business.js +1 -1
  16. package/esm2015/lib/db/Models/sole/sole-invoice-template.js +1 -1
  17. package/esm2015/lib/db/Models/transaction/transaction-base.js +15 -2
  18. package/esm2015/lib/db/Models/vehicle/vehicle-claim-details.js +4 -0
  19. package/esm2015/lib/db/Models/vehicle/vehicle-claim.js +1 -1
  20. package/esm2015/lib/db/Models/vehicle/vehicle-logbook.js +1 -1
  21. package/esm2015/lib/db/Models/vehicle/vehicle.js +1 -1
  22. package/esm2015/lib/forms/abstract.form.js +23 -1
  23. package/esm2015/lib/forms/bank/bank-account/bank-account-add-manual.form.js +8 -5
  24. package/esm2015/lib/forms/bank/bank-account/bank-account-allocation.form.js +16 -9
  25. package/esm2015/lib/forms/bank/bank-account/bank-account-import.form.js +8 -3
  26. package/esm2015/lib/forms/index.js +3 -4
  27. package/esm2015/lib/forms/loan/index.js +2 -0
  28. package/esm2015/lib/forms/loan/loan.form.js +86 -0
  29. package/esm2015/lib/forms/report/my-tax/my-tax-deductions.form.js +2 -2
  30. package/esm2015/lib/forms/sole/index.js +3 -1
  31. package/esm2015/lib/forms/sole/sole-business-allocations.form.js +65 -0
  32. package/esm2015/lib/forms/sole/sole-invoice-template.form.js +13 -0
  33. package/esm2015/lib/forms/vehicle/index.js +5 -0
  34. package/esm2015/lib/forms/vehicle/vehicle-claim-details.form.js +21 -0
  35. package/esm2015/lib/forms/vehicle/vehicle-claim.form.js +12 -102
  36. package/esm2015/lib/forms/vehicle/vehicle-logbook.form.js +56 -0
  37. package/esm2015/lib/forms/vehicle/vehicle.form.js +5 -2
  38. package/esm2015/lib/models/bank/bank-account-types.const.js +1 -2
  39. package/esm2015/lib/models/bank/bank-account.js +10 -5
  40. package/esm2015/lib/models/bank/type-loan.const.js +1 -2
  41. package/esm2015/lib/models/endpoint/endpoints.const.js +13 -4
  42. package/esm2015/lib/models/event/app-event-type.enum.js +7 -4
  43. package/esm2015/lib/models/index.js +2 -1
  44. package/esm2015/lib/models/loan/loan.js +36 -2
  45. package/esm2015/lib/models/report/my-tax/my-tax-deductions/my-tax-deductions.js +5 -5
  46. package/esm2015/lib/models/sole/sole-business.js +2 -2
  47. package/esm2015/lib/models/sole/sole-invoice-template.js +5 -2
  48. package/esm2015/lib/models/vehicle/index.js +6 -0
  49. package/esm2015/lib/models/vehicle/logbook-period.js +23 -0
  50. package/esm2015/lib/models/vehicle/vehicle-claim-details.js +26 -0
  51. package/esm2015/lib/models/vehicle/vehicle-claim.js +64 -0
  52. package/esm2015/lib/models/vehicle/vehicle-logbook.js +32 -0
  53. package/esm2015/lib/models/vehicle/vehicle.js +10 -0
  54. package/esm2015/lib/services/http/depreciation/depreciation.service.js +10 -5
  55. package/esm2015/lib/services/http/firm/client-invite/client-invite.service.js +15 -1
  56. package/esm2015/lib/services/http/firm/client-movement/client-movement.service.js +13 -10
  57. package/esm2015/lib/services/http/index.js +2 -1
  58. package/esm2015/lib/services/http/sole/index.js +2 -1
  59. package/esm2015/lib/services/http/sole/sole-invoice-template/sole-invoice-template.service.js +21 -0
  60. package/esm2015/lib/services/http/tax-review/tax-review.service.js +11 -3
  61. package/esm2015/lib/services/http/transaction/transaction.service.js +12 -1
  62. package/esm2015/lib/services/http/vehicle/index.js +5 -0
  63. package/esm2015/lib/services/http/vehicle/vehicle-claim-details.service.js +91 -0
  64. package/esm2015/lib/services/http/vehicle/vehicle-claim.service.js +65 -6
  65. package/esm2015/lib/services/http/vehicle/vehicle-logbook.service.js +11 -47
  66. package/esm2015/lib/services/http/vehicle/vehicle.service.js +2 -52
  67. package/esm2015/lib/services/index.js +2 -1
  68. package/esm2015/lib/services/vehicle/index.js +2 -0
  69. package/esm2015/lib/services/vehicle/logbook-best-period.service.js +72 -0
  70. package/esm2015/lib/validators/index.js +3 -1
  71. package/esm2015/lib/validators/min-date/messages.enum.js +5 -0
  72. package/esm2015/lib/validators/min-date/min-date.validator.js +14 -0
  73. package/esm2015/public-api.js +3 -14
  74. package/fesm2015/taxtank-core.js +2253 -1814
  75. package/fesm2015/taxtank-core.js.map +1 -1
  76. package/lib/collections/client-invite.collection.d.ts +0 -3
  77. package/lib/collections/depreciation.collection.d.ts +6 -1
  78. package/lib/collections/index.d.ts +1 -0
  79. package/lib/collections/loan/loan-payment.collection.d.ts +4 -0
  80. package/lib/collections/loan/loan.collection.d.ts +6 -0
  81. package/lib/collections/report/vehicle-expense/vehicle-expense.collection.d.ts +1 -1
  82. package/lib/collections/transaction/transaction.collection.d.ts +9 -0
  83. package/lib/collections/vehicle/index.d.ts +2 -0
  84. package/lib/collections/vehicle/vehicle-claim.collection.d.ts +14 -0
  85. package/lib/collections/vehicle/vehicle-logbook.collection.d.ts +38 -0
  86. package/lib/db/Enums/bank-account-type.enum.d.ts +0 -1
  87. package/lib/db/Enums/vehicle-claim-details-method.enum.d.ts +4 -0
  88. package/lib/db/Models/sole/sole-business.d.ts +2 -0
  89. package/lib/db/Models/sole/sole-invoice-template.d.ts +1 -0
  90. package/lib/db/Models/transaction/transaction-base.d.ts +2 -0
  91. package/lib/db/Models/vehicle/vehicle-claim-details.d.ts +10 -0
  92. package/lib/db/Models/vehicle/vehicle-claim.d.ts +3 -5
  93. package/lib/db/Models/vehicle/vehicle-logbook.d.ts +3 -2
  94. package/lib/forms/abstract.form.d.ts +12 -0
  95. package/lib/forms/index.d.ts +2 -3
  96. package/lib/forms/loan/index.d.ts +1 -0
  97. package/lib/forms/loan/loan.form.d.ts +25 -0
  98. package/lib/forms/sole/index.d.ts +2 -0
  99. package/lib/forms/sole/sole-business-allocations.form.d.ts +17 -0
  100. package/lib/forms/sole/sole-invoice-template.form.d.ts +5 -0
  101. package/lib/forms/vehicle/index.d.ts +4 -0
  102. package/lib/forms/vehicle/vehicle-claim-details.form.d.ts +13 -0
  103. package/lib/forms/vehicle/vehicle-claim.form.d.ts +8 -38
  104. package/lib/forms/vehicle/vehicle-logbook.form.d.ts +20 -0
  105. package/lib/forms/vehicle/vehicle.form.d.ts +4 -1
  106. package/lib/models/bank/bank-account.d.ts +3 -2
  107. package/lib/models/event/app-event-type.enum.d.ts +6 -3
  108. package/lib/models/index.d.ts +1 -0
  109. package/lib/models/loan/loan.d.ts +26 -0
  110. package/lib/models/report/my-tax/my-tax-deductions/my-tax-deductions.d.ts +3 -2
  111. package/lib/models/sole/sole-business.d.ts +1 -1
  112. package/lib/models/sole/sole-invoice-template.d.ts +1 -0
  113. package/lib/models/vehicle/index.d.ts +5 -0
  114. package/lib/models/vehicle/logbook-period.d.ts +15 -0
  115. package/lib/models/vehicle/vehicle-claim-details.d.ts +8 -0
  116. package/lib/models/{logbook → vehicle}/vehicle-claim.d.ts +11 -17
  117. package/lib/models/vehicle/vehicle-logbook.d.ts +17 -0
  118. package/lib/models/{logbook → vehicle}/vehicle.d.ts +0 -5
  119. package/lib/services/http/depreciation/depreciation.service.d.ts +1 -1
  120. package/lib/services/http/firm/client-invite/client-invite.service.d.ts +7 -1
  121. package/lib/services/http/firm/client-movement/client-movement.service.d.ts +2 -4
  122. package/lib/services/http/index.d.ts +1 -0
  123. package/lib/services/http/sole/index.d.ts +1 -0
  124. package/lib/services/http/sole/sole-invoice-template/sole-invoice-template.service.d.ts +11 -0
  125. package/lib/services/http/tax-review/tax-review.service.d.ts +1 -0
  126. package/lib/services/http/transaction/transaction.service.d.ts +1 -0
  127. package/lib/services/http/vehicle/index.d.ts +4 -0
  128. package/lib/services/http/vehicle/vehicle-claim-details.service.d.ts +34 -0
  129. package/lib/services/http/vehicle/vehicle-claim.service.d.ts +22 -5
  130. package/lib/services/http/vehicle/vehicle-logbook.service.d.ts +6 -15
  131. package/lib/services/http/vehicle/vehicle.service.d.ts +2 -20
  132. package/lib/services/index.d.ts +1 -0
  133. package/lib/services/vehicle/index.d.ts +1 -0
  134. package/lib/services/vehicle/logbook-best-period.service.d.ts +28 -0
  135. package/lib/validators/index.d.ts +2 -0
  136. package/lib/validators/min-date/messages.enum.d.ts +3 -0
  137. package/lib/validators/min-date/min-date.validator.d.ts +5 -0
  138. package/package.json +1 -1
  139. package/public-api.d.ts +2 -13
  140. package/esm2015/lib/collections/vehicle-logbook.collection.js +0 -88
  141. package/esm2015/lib/collections/vehicle.collection.js +0 -9
  142. package/esm2015/lib/db/Enums/vehicle-claim-method.enum.js +0 -6
  143. package/esm2015/lib/forms/bank/bank-account/bank-account-loan.form.js +0 -23
  144. package/esm2015/lib/models/logbook/default-vehicle-expense.js +0 -20
  145. package/esm2015/lib/models/logbook/logbook-period.js +0 -18
  146. package/esm2015/lib/models/logbook/logbook-purpose-options.const.js +0 -6
  147. package/esm2015/lib/models/logbook/vehicle-claim.js +0 -94
  148. package/esm2015/lib/models/logbook/vehicle-logbook.js +0 -22
  149. package/esm2015/lib/models/logbook/vehicle.js +0 -17
  150. package/esm2015/lib/services/http/user/users-invite/users-invite.service.js +0 -23
  151. package/esm2015/lib/services/http/vehicle/messages.enum.js +0 -13
  152. package/lib/collections/vehicle-logbook.collection.d.ts +0 -30
  153. package/lib/collections/vehicle.collection.d.ts +0 -6
  154. package/lib/db/Enums/vehicle-claim-method.enum.d.ts +0 -4
  155. package/lib/forms/bank/bank-account/bank-account-loan.form.d.ts +0 -8
  156. package/lib/models/logbook/default-vehicle-expense.d.ts +0 -5
  157. package/lib/models/logbook/logbook-period.d.ts +0 -10
  158. package/lib/models/logbook/logbook-purpose-options.const.d.ts +0 -4
  159. package/lib/models/logbook/vehicle-logbook.d.ts +0 -12
  160. package/lib/services/http/user/users-invite/users-invite.service.d.ts +0 -13
  161. package/lib/services/http/vehicle/messages.enum.d.ts +0 -11
@@ -1,27 +1,28 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, Inject, NgModule, EventEmitter } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
4
+ import { CommonModule, DatePipe } from '@angular/common';
5
5
  import * as i1 from '@angular/common/http';
6
6
  import { HttpParams, HttpErrorResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
7
7
  import { ReplaySubject, Subject, BehaviorSubject, throwError, combineLatest, of, Observable, forkJoin, from } from 'rxjs';
8
- import { map, filter, catchError, take, switchMap, finalize, mergeMap, distinctUntilChanged } from 'rxjs/operators';
8
+ import { map, filter, catchError, take, switchMap, finalize, mergeMap, skip, distinctUntilChanged } from 'rxjs/operators';
9
9
  import { plainToClass, classToPlain, Type, Exclude, Transform, Expose } from 'class-transformer';
10
10
  import { JwtHelperService } from '@auth0/angular-jwt';
11
11
  import { __decorate, __awaiter } from 'tslib';
12
12
  import get from 'lodash/get';
13
13
  import last from 'lodash/last';
14
- import * as moment from 'moment';
15
- import { DateRange } from 'moment-range';
16
14
  import flatten from 'lodash/flatten';
17
15
  import hasIn from 'lodash/hasIn';
18
16
  import first from 'lodash/first';
17
+ import * as moment from 'moment';
18
+ import { DateRange } from 'moment-range';
19
19
  import uniqBy from 'lodash/uniqBy';
20
20
  import concat from 'lodash/concat';
21
21
  import { throwError as throwError$1 } from 'rxjs/internal/observable/throwError';
22
22
  import cloneDeep$1 from 'lodash/cloneDeep';
23
23
  import compact from 'lodash/compact';
24
- import { Validators, FormGroup, FormArray, FormControl } from '@angular/forms';
24
+ import { Validators, FormGroup, FormControl, FormArray } from '@angular/forms';
25
+ import isEqual from 'lodash/isEqual';
25
26
  import fromPairs from 'lodash/fromPairs';
26
27
  import _ from 'lodash';
27
28
  import { EventSourcePolyfill } from 'event-source-polyfill/src/eventsource.min.js';
@@ -245,9 +246,12 @@ var AppEventTypeEnum;
245
246
  AppEventTypeEnum[AppEventTypeEnum["USER_UPDATED"] = 46] = "USER_UPDATED";
246
247
  AppEventTypeEnum[AppEventTypeEnum["VEHICLE_CLAIM_UPDATED"] = 47] = "VEHICLE_CLAIM_UPDATED";
247
248
  AppEventTypeEnum[AppEventTypeEnum["VEHICLE_CLAIM_CREATED"] = 48] = "VEHICLE_CLAIM_CREATED";
248
- AppEventTypeEnum[AppEventTypeEnum["VEHICLE_LOGBOOK_CREATED"] = 49] = "VEHICLE_LOGBOOK_CREATED";
249
- AppEventTypeEnum[AppEventTypeEnum["VEHICLE_LOGBOOK_UPDATED"] = 50] = "VEHICLE_LOGBOOK_UPDATED";
250
- AppEventTypeEnum[AppEventTypeEnum["VEHICLE_LOGBOOK_DELETED"] = 51] = "VEHICLE_LOGBOOK_DELETED";
249
+ AppEventTypeEnum[AppEventTypeEnum["VEHICLE_CLAIM_DETAILS_UPDATED"] = 49] = "VEHICLE_CLAIM_DETAILS_UPDATED";
250
+ AppEventTypeEnum[AppEventTypeEnum["VEHICLE_CLAIM_DETAILS_CREATED"] = 50] = "VEHICLE_CLAIM_DETAILS_CREATED";
251
+ AppEventTypeEnum[AppEventTypeEnum["VEHICLE_LOGBOOK_CREATED"] = 51] = "VEHICLE_LOGBOOK_CREATED";
252
+ AppEventTypeEnum[AppEventTypeEnum["VEHICLE_LOGBOOK_UPDATED"] = 52] = "VEHICLE_LOGBOOK_UPDATED";
253
+ AppEventTypeEnum[AppEventTypeEnum["VEHICLE_LOGBOOK_DELETED"] = 53] = "VEHICLE_LOGBOOK_DELETED";
254
+ AppEventTypeEnum[AppEventTypeEnum["VEHICLE_LOGBOOK_BEST_PERIOD_UPDATED"] = 54] = "VEHICLE_LOGBOOK_BEST_PERIOD_UPDATED";
251
255
  })(AppEventTypeEnum || (AppEventTypeEnum = {}));
252
256
 
253
257
  class EventDispatcherService {
@@ -672,6 +676,10 @@ const ENDPOINTS = {
672
676
  SOLE_BUSINESSES_GET: new Endpoint('GET', '\\/sole-businesses'),
673
677
  SOLE_BUSINESSES_POST: new Endpoint('POST', '\\/sole-businesses'),
674
678
  SOLE_BUSINESSES_PUT: new Endpoint('PUT', '\\/sole-businesses\\d+'),
679
+ SOLE_INVOICE_TEMPLATES_GET: new Endpoint('GET', '\\/sole-invoice-templates'),
680
+ SOLE_INVOICE_TEMPLATES_POST: new Endpoint('POST', '\\/sole-invoice-templates'),
681
+ SOLE_INVOICE_TEMPLATES_PUT: new Endpoint('PUT', '\\/sole-invoice-templates\\d+'),
682
+ SOLE_INVOICE_TEMPLATES_DELETE: new Endpoint('DELETE', '\\/sole-invoice-templates\\d+'),
675
683
  TAX_CALCULATION_POST: new Endpoint('POST', '\\/tax-calculation'),
676
684
  TAX_REVIEWS_GET: new Endpoint('GET', '\\/tax-reviews'),
677
685
  TAX_REVIEWS_DELETE: new Endpoint('DELETE', '\\/tax-reviews\\/\\d+'),
@@ -709,9 +717,14 @@ const ENDPOINTS = {
709
717
  VEHICLES_PUT: new Endpoint('PUT', '\\/vehicles\\/\\d+'),
710
718
  VEHICLE_CLAIMS_GET: new Endpoint('GET', '\\/vehicle-claims'),
711
719
  VEHICLE_CLAIMS_POST: new Endpoint('POST', '\\/vehicle-claims'),
712
- VEHICLE_LOGBOOK_POST: new Endpoint('POST', '\\/vehicles\\/\\d+\\/logbooks'),
713
- VEHICLE_LOGBOOK_PUT: new Endpoint('PUT', '\\/vehicles\\/\\d+\\/logbooks\\/\\d+'),
714
- VEHICLE_CLAIMS_PUT: new Endpoint('PUT', '\\/vehicle-claims\\/\\d+')
720
+ VEHICLE_CLAIMS_PUT: new Endpoint('PUT', '\\/vehicle-claims\\/\\d+'),
721
+ VEHICLE_LOGBOOKS_GET: new Endpoint('GET', '\\/vehicles\\/logbooks'),
722
+ VEHICLE_LOGBOOKS_POST: new Endpoint('POST', '\\/vehicles\\/logbooks'),
723
+ VEHICLE_LOGBOOKS_PUT: new Endpoint('PUT', '\\/vehicles\\/logbooks\\/\\d+'),
724
+ VEHICLE_LOGBOOKS_DELETE: new Endpoint('DELETE', '\\/vehicles\\/logbooks\\/\\d+'),
725
+ VEHICLE_CLAIM_DETAILS_GET: new Endpoint('GET', '\\/vehicle-claim-details'),
726
+ VEHICLE_CLAIM_DETAILS_POST: new Endpoint('POST', '\\/vehicle-claim-details'),
727
+ VEHICLE_CLAIM_DETAILS_PUT: new Endpoint('PUT', '\\/vehicle-claim-details\\/\\d+'),
715
728
  };
716
729
 
717
730
  class PreloaderService {
@@ -1125,7 +1138,8 @@ var BankAccountTypeEnum;
1125
1138
  BankAccountTypeEnum[BankAccountTypeEnum["TRANSACTION"] = 1] = "TRANSACTION";
1126
1139
  BankAccountTypeEnum[BankAccountTypeEnum["SAVINGS"] = 2] = "SAVINGS";
1127
1140
  BankAccountTypeEnum[BankAccountTypeEnum["CREDIT_CARD"] = 3] = "CREDIT_CARD";
1128
- BankAccountTypeEnum[BankAccountTypeEnum["MORTGAGE"] = 4] = "MORTGAGE";
1141
+ // @TODO Alex: should be removed by backend (TT-2107)
1142
+ // MORTGAGE = 4,
1129
1143
  BankAccountTypeEnum[BankAccountTypeEnum["LOAN"] = 5] = "LOAN";
1130
1144
  BankAccountTypeEnum[BankAccountTypeEnum["INVESTMENT"] = 6] = "INVESTMENT";
1131
1145
  BankAccountTypeEnum[BankAccountTypeEnum["TERM_DEPOSIT"] = 7] = "TERM_DEPOSIT";
@@ -1220,207 +1234,510 @@ class FinancialYear {
1220
1234
  }
1221
1235
  FinancialYear.startMonthIndex = 6;
1222
1236
 
1223
- class Loan extends Loan$1 {
1237
+ /**
1238
+ * List of collections grouped by passed property
1239
+ */
1240
+ class CollectionDictionary {
1224
1241
  /**
1225
- * Check if loan type is related to LoanVehicleTypeEnum
1242
+ * @param collection The Collection instance to be grouped
1243
+ * @param path Path to the property to be grouped (Examples: 'transaction', 'property.category')
1244
+ * @param prop Optional: Field to group by (Default 'id', Examples: 'id', 'amount', 'date')
1226
1245
  */
1227
- isVehicle() {
1228
- return this.type in LoanVehicleTypeEnum;
1246
+ constructor(collection, path = 'id') {
1247
+ /**
1248
+ * List of grouped collections
1249
+ */
1250
+ this.items = {};
1251
+ this.collectionConstructor = collection.constructor;
1252
+ // Nothing to group when collection is empty
1253
+ if (!collection.length) {
1254
+ return;
1255
+ }
1256
+ // Do nothing if provided path was not found in the 1st collection's item
1257
+ if (!hasIn(collection.items[0], path.split('.')[0])) {
1258
+ return;
1259
+ }
1260
+ this.groupItems(collection, path);
1229
1261
  }
1230
1262
  /**
1231
- * Get the last payment for passed financial year
1232
- * @param year financial year for filter
1263
+ * List of collections keys
1233
1264
  */
1234
- getLastPaymentByYear(year) {
1235
- const finYear = new FinancialYear(new Date(year.toString()));
1236
- return last(this.payments.filter((payment) => payment.date > finYear.startDate && payment.date < finYear.endDate));
1265
+ get keys() {
1266
+ return Object.keys(this.items);
1237
1267
  }
1238
- }
1239
- __decorate([
1240
- Type(() => LoanPayment)
1241
- ], Loan.prototype, "payments", void 0);
1242
- __decorate([
1243
- Type(() => Date)
1244
- ], Loan.prototype, "commencementDate", void 0);
1245
- __decorate([
1246
- Type(() => LoanPayout)
1247
- ], Loan.prototype, "payout", void 0);
1248
-
1249
- var TankTypeEnum;
1250
- (function (TankTypeEnum) {
1251
- TankTypeEnum[TankTypeEnum["PROPERTY"] = 1] = "PROPERTY";
1252
- TankTypeEnum[TankTypeEnum["WORK"] = 2] = "WORK";
1253
- TankTypeEnum[TankTypeEnum["OTHER"] = 3] = "OTHER";
1254
- TankTypeEnum[TankTypeEnum["SOLE"] = 4] = "SOLE";
1255
- })(TankTypeEnum || (TankTypeEnum = {}));
1256
-
1257
- class BankAccountBalance extends AbstractModel {
1258
- }
1259
-
1260
- class BankAccountProperty$1 extends AbstractModel {
1261
- }
1262
-
1263
- class Property$1 extends AbstractModel {
1264
- }
1265
-
1266
- class PropertySubscription$1 extends AbstractModel {
1267
- }
1268
-
1269
- class User$1 extends AbstractModel {
1270
- }
1271
-
1272
- var UserStatusEnum;
1273
- (function (UserStatusEnum) {
1274
- UserStatusEnum[UserStatusEnum["INACTIVE"] = 0] = "INACTIVE";
1275
- UserStatusEnum[UserStatusEnum["ON_BOARDING"] = 1] = "ON_BOARDING";
1276
- UserStatusEnum[UserStatusEnum["ACTIVE"] = 2] = "ACTIVE";
1277
- })(UserStatusEnum || (UserStatusEnum = {}));
1278
-
1279
- var UserRolesEnum;
1280
- (function (UserRolesEnum) {
1281
- UserRolesEnum["FIRM_OWNER"] = "ROLE_FIRM_OWNER";
1282
- UserRolesEnum["FIRM_MANAGER"] = "ROLE_FIRM_MANAGER";
1283
- UserRolesEnum["CLIENT"] = "ROLE_CLIENT";
1284
- UserRolesEnum["EMPLOYEE"] = "ROLE_EMPLOYEE";
1285
- UserRolesEnum["ACCOUNTANT"] = "ROLE_ACCOUNTANT";
1286
- UserRolesEnum["ADVISOR"] = "ROLE_ADVISOR";
1287
- UserRolesEnum["USER"] = "ROLE_USER";
1288
- UserRolesEnum["SUBSCRIPTION"] = "ROLE_USER_SUBSCRIPTION";
1289
- UserRolesEnum["WORK_TANK"] = "ROLE_USER_WORK";
1290
- UserRolesEnum["PROPERTY_TANK"] = "ROLE_USER_PROPERTY";
1291
- UserRolesEnum["SOLE_TANK"] = "ROLE_USER_SOLE";
1292
- UserRolesEnum["SWITCH_USER"] = "ROLE_PREVIOUS_ADMIN";
1293
- })(UserRolesEnum || (UserRolesEnum = {}));
1294
-
1295
- class Address$1 extends AbstractModel {
1296
- }
1297
-
1298
- class Country$1 extends AbstractModel {
1299
- }
1300
-
1301
- class Country extends Country$1 {
1302
1268
  /**
1303
- * Return country name with phone code
1269
+ * Get collection by key or return empty collection if key does not exist
1304
1270
  */
1305
- get countryWithCode() {
1306
- return `${this.name} (+${this.callingCode})`;
1271
+ get(key) {
1272
+ return this.items[key] ? this.items[key] : this.createCollection([]);
1307
1273
  }
1308
1274
  /**
1309
- * Check if country calling code is Australian or not
1275
+ * Add new item by key
1310
1276
  */
1311
- isAustralianCode() {
1312
- return this.callingCode === '61';
1313
- }
1314
- }
1315
-
1316
- var AddressTypeEnum;
1317
- (function (AddressTypeEnum) {
1318
- AddressTypeEnum[AddressTypeEnum["STREET"] = 1] = "STREET";
1319
- AddressTypeEnum[AddressTypeEnum["POSTAL"] = 2] = "POSTAL";
1320
- })(AddressTypeEnum || (AddressTypeEnum = {}));
1321
-
1322
- class Address extends Address$1 {
1323
- constructor() {
1324
- super(...arguments);
1325
- this.type = AddressTypeEnum.STREET;
1326
- }
1327
- toString() {
1328
- return [this.unitNumber, this.address, this.city, this.state, this.postcode].filter(Boolean).join(', ');
1329
- }
1330
- get name() {
1331
- return `${this.unitNumber ? this.unitNumber + '/' : ''}${this.address}`;
1277
+ add(key, value) {
1278
+ this.items[key] = value;
1332
1279
  }
1333
- get nameLong() {
1334
- return `${this.name}, ${this.city}, ${this.state}`;
1280
+ /**
1281
+ * Join several collections by ids
1282
+ */
1283
+ merge(keys) {
1284
+ return this.createCollection(flatten(keys.map((id) => this.get(id.toString()).items)));
1335
1285
  }
1336
- }
1337
- __decorate([
1338
- Type((() => Country))
1339
- ], Address.prototype, "country", void 0);
1340
-
1341
- const USER_WORK_POSITION = {
1342
- [UserRolesEnum.EMPLOYEE]: 'Employee',
1343
- [UserRolesEnum.FIRM_MANAGER]: 'Manager',
1344
- [UserRolesEnum.FIRM_OWNER]: 'Firm Owner'
1345
- };
1346
-
1347
- class ClientDetails$1 extends AbstractModel {
1348
- }
1349
-
1350
- class ClientDetails extends ClientDetails$1 {
1351
- }
1352
-
1353
- class EmployeeDetails$1 extends AbstractModel {
1354
- }
1355
-
1356
- class Firm$1 extends AbstractModel {
1357
- }
1358
-
1359
- class Phone$1 extends AbstractModel {
1360
- }
1361
-
1362
- var PhoneTypeEnum;
1363
- (function (PhoneTypeEnum) {
1364
- PhoneTypeEnum[PhoneTypeEnum["MOBILE"] = 1] = "MOBILE";
1365
- PhoneTypeEnum[PhoneTypeEnum["OFFICE"] = 2] = "OFFICE";
1366
- })(PhoneTypeEnum || (PhoneTypeEnum = {}));
1367
-
1368
- class Phone extends Phone$1 {
1369
- constructor() {
1370
- super(...arguments);
1371
- this.type = PhoneTypeEnum.MOBILE;
1286
+ /**
1287
+ * Create instance of collection
1288
+ */
1289
+ createCollection(items = []) {
1290
+ return new this.collectionConstructor(items);
1372
1291
  }
1373
- toString() {
1374
- return `+${this.country.callingCode} ${this.number}`;
1292
+ get length() {
1293
+ return this.keys.length;
1375
1294
  }
1376
- }
1377
-
1378
- class Firm extends Firm$1 {
1379
1295
  /**
1380
- * get firm photo link
1296
+ * @Todo find a better solution to get list of the sorted keys
1297
+ * Get array of the "keys" by provided order
1381
1298
  */
1382
- getPhoto() {
1383
- return this.photo;
1299
+ getSortedKeys(isDesc = false) {
1300
+ return this.keys.sort((a, b) => {
1301
+ if (a > b) {
1302
+ return !isDesc ? 1 : -1;
1303
+ }
1304
+ if (a < b) {
1305
+ return !isDesc ? -1 : 1;
1306
+ }
1307
+ return 0;
1308
+ });
1384
1309
  }
1385
1310
  /**
1386
- * get firm initials
1311
+ * Group collection items by passed path into items object
1387
1312
  */
1388
- getPhotoPlaceholder() {
1389
- return `${this.name[0].toUpperCase()}${this.name[1]}`;
1313
+ groupItems(collection, path) {
1314
+ // Create empty initial object for groups
1315
+ const obj = {};
1316
+ // Group collection items
1317
+ collection.items.forEach((item) => {
1318
+ let key = get(item, path);
1319
+ // if object does not have property for grouping it will be grouped as 'other'
1320
+ if (key === undefined) {
1321
+ key = 'other';
1322
+ }
1323
+ if (!obj[key]) {
1324
+ obj[key] = [];
1325
+ }
1326
+ obj[key].push(item);
1327
+ });
1328
+ // Create collections from groups
1329
+ Object.keys(obj).forEach((key) => {
1330
+ this.items[key] = this.createCollection(obj[key]);
1331
+ });
1390
1332
  }
1391
1333
  }
1392
- __decorate([
1393
- Type(() => User)
1394
- ], Firm.prototype, "owner", void 0);
1395
- __decorate([
1396
- Type(() => Address)
1397
- ], Firm.prototype, "address", void 0);
1398
- __decorate([
1399
- Type(() => Phone)
1400
- ], Firm.prototype, "phone", void 0);
1401
-
1402
- class EmployeeDetails extends EmployeeDetails$1 {
1403
- }
1404
- __decorate([
1405
- Type(() => Firm)
1406
- ], EmployeeDetails.prototype, "firm", void 0);
1407
-
1408
- class ServiceSubscription$1 extends AbstractModel {
1409
- }
1410
-
1411
- class ServiceSubscriptionItem$1 extends AbstractModel {
1412
- }
1413
-
1414
- class ServicePrice$1 extends AbstractModel {
1415
- }
1416
-
1417
- class ServiceProduct$1 extends AbstractModel {
1418
- }
1419
1334
 
1420
- var ServiceProductStatusEnum;
1421
- (function (ServiceProductStatusEnum) {
1422
- ServiceProductStatusEnum[ServiceProductStatusEnum["ARCHIVED"] = 0] = "ARCHIVED";
1423
- ServiceProductStatusEnum[ServiceProductStatusEnum["ACTIVE"] = 1] = "ACTIVE";
1335
+ const DEFAULT_INDEX = 'other';
1336
+ /**
1337
+ * Base collection class. Contains common properties and methods for all collections
1338
+ */
1339
+ class Collection {
1340
+ constructor(items = []) {
1341
+ this.items = items;
1342
+ }
1343
+ /**
1344
+ * Iterator that allow to iterate collection items
1345
+ */
1346
+ [Symbol.iterator]() {
1347
+ return this.items.values();
1348
+ }
1349
+ create(items = []) {
1350
+ return new this.constructor(items);
1351
+ }
1352
+ get length() {
1353
+ return this.items.length;
1354
+ }
1355
+ toArray() {
1356
+ return [...this.items];
1357
+ }
1358
+ get first() {
1359
+ return first(this.items);
1360
+ }
1361
+ get last() {
1362
+ return last(this.items);
1363
+ }
1364
+ getIds() {
1365
+ return this.items.map((item) => item['id']);
1366
+ }
1367
+ mapBy(path) {
1368
+ return this.items.map((item) => get(item, path));
1369
+ }
1370
+ sortBy(field = 'id', isDesc = true) {
1371
+ sort(this.items, field, isDesc);
1372
+ return this;
1373
+ }
1374
+ /**
1375
+ * Get total sum of items by field
1376
+ */
1377
+ sumBy(path) {
1378
+ return +this.items.reduce((sum, item) => sum + Number(get(item, path)), 0).toFixed(2);
1379
+ }
1380
+ groupBy(path = '') {
1381
+ return new CollectionDictionary(this, path);
1382
+ }
1383
+ indexBy(path) {
1384
+ // Create empty initial object for groups
1385
+ const result = {};
1386
+ this.toArray().forEach((model) => {
1387
+ result[get(model, path, DEFAULT_INDEX)] = model;
1388
+ });
1389
+ return result;
1390
+ }
1391
+ filter(callback) {
1392
+ return this.create(this.items.filter(callback));
1393
+ }
1394
+ filterBy(path, values) {
1395
+ return this.filter((item) => (Array.isArray(values) ? values : [values]).includes(get(item, path)));
1396
+ }
1397
+ filterByRange(path, from, to) {
1398
+ return this.filter((item) => get(item, path) >= from && get(item, path) <= to);
1399
+ }
1400
+ find(callback) {
1401
+ return this.items.find(callback);
1402
+ }
1403
+ findBy(path, value) {
1404
+ return this.items.find((model) => value === get(model, path));
1405
+ }
1406
+ findIndexBy(path, value) {
1407
+ var _a;
1408
+ return (_a = this.items.findIndex((item) => get(item, path) === value)) !== null && _a !== void 0 ? _a : null;
1409
+ }
1410
+ push(...items) {
1411
+ this.items.push(...items);
1412
+ return this.create(this.items);
1413
+ }
1414
+ replaceBy(path, value, item) {
1415
+ const index = this.findIndexBy(path, value);
1416
+ if (index >= 0) {
1417
+ this.items.splice(index, 1, item);
1418
+ }
1419
+ return this;
1420
+ }
1421
+ remove(items) {
1422
+ return this.filter((model) => !items.map((item) => item.id).includes(model.id));
1423
+ }
1424
+ removeBy(path, values) {
1425
+ return this.filter((item) => !(Array.isArray(values) ? values : [values]).includes(get(item, path)));
1426
+ }
1427
+ minBy(path) {
1428
+ return this.items.reduce((prev, current) => (get(prev, path) < get(current, path) ? prev : current));
1429
+ }
1430
+ maxBy(path) {
1431
+ return this.items.reduce((prev, current) => (get(prev, path) > get(current, path) ? prev : current));
1432
+ }
1433
+ }
1434
+
1435
+ class ExportDataTable {
1436
+ }
1437
+
1438
+ class ExportableCollection extends Collection {
1439
+ getExportFooter(type) {
1440
+ return [];
1441
+ }
1442
+ ;
1443
+ export(type) {
1444
+ return plainToClass(ExportDataTable, {
1445
+ header: this.getExportHeader(type),
1446
+ body: this.getExportBody(type),
1447
+ footer: [this.getExportFooter(type)]
1448
+ });
1449
+ }
1450
+ }
1451
+
1452
+ /**
1453
+ * export table column
1454
+ */
1455
+ class ExportCell {
1456
+ }
1457
+
1458
+ /**
1459
+ * type of export table column value
1460
+ */
1461
+ var ExportCellTypeEnum;
1462
+ (function (ExportCellTypeEnum) {
1463
+ ExportCellTypeEnum[ExportCellTypeEnum["STRING"] = 0] = "STRING";
1464
+ ExportCellTypeEnum[ExportCellTypeEnum["CURRENCY"] = 1] = "CURRENCY";
1465
+ ExportCellTypeEnum[ExportCellTypeEnum["DATE"] = 2] = "DATE";
1466
+ })(ExportCellTypeEnum || (ExportCellTypeEnum = {}));
1467
+
1468
+ class LoanPaymentCollection extends ExportableCollection {
1469
+ getExportHeader() {
1470
+ return [
1471
+ 'Pmt No.',
1472
+ 'Date',
1473
+ 'Payment Due',
1474
+ 'Interest Accrued',
1475
+ 'Principal Paid',
1476
+ 'Principal Balance',
1477
+ 'Payout'
1478
+ ];
1479
+ }
1480
+ getExportBody() {
1481
+ return this.items.map((payment) => {
1482
+ return [
1483
+ plainToClass(ExportCell, { value: payment.number, type: ExportCellTypeEnum.STRING }),
1484
+ plainToClass(ExportCell, { value: payment.date, type: ExportCellTypeEnum.DATE }),
1485
+ plainToClass(ExportCell, { value: payment.paymentDue, type: ExportCellTypeEnum.CURRENCY }),
1486
+ plainToClass(ExportCell, { value: payment.interestAccrued, type: ExportCellTypeEnum.CURRENCY }),
1487
+ plainToClass(ExportCell, { value: payment.principalPaid, type: ExportCellTypeEnum.CURRENCY }),
1488
+ plainToClass(ExportCell, { value: payment.principalBalance, type: ExportCellTypeEnum.CURRENCY }),
1489
+ plainToClass(ExportCell, { value: payment.payout, type: ExportCellTypeEnum.CURRENCY }),
1490
+ ];
1491
+ });
1492
+ }
1493
+ get paymentDue() {
1494
+ return this.sumBy('paymentDue');
1495
+ }
1496
+ getByFinYear(finYear = new FinancialYear()) {
1497
+ return this.filter((payment) => {
1498
+ return new Date(payment.date) >= finYear.startDate &&
1499
+ new Date(payment.date) <= finYear.endDate;
1500
+ });
1501
+ }
1502
+ getForCurrentYear() {
1503
+ return this.getByFinYear(new FinancialYear());
1504
+ }
1505
+ }
1506
+
1507
+ class Loan extends Loan$1 {
1508
+ /**
1509
+ * Check if loan type is related to LoanVehicleTypeEnum
1510
+ */
1511
+ isVehicle() {
1512
+ return !this.bankAccount && this.type in LoanVehicleTypeEnum;
1513
+ }
1514
+ /**
1515
+ * Get the last payment for passed financial year
1516
+ * @param year financial year for filter
1517
+ */
1518
+ getLastPaymentByYear(year) {
1519
+ const finYear = new FinancialYear(new Date(year.toString()));
1520
+ return last(this.payments.filter((payment) => payment.date > finYear.startDate && payment.date < finYear.endDate));
1521
+ }
1522
+ /**
1523
+ * The size of loan interest
1524
+ * https://taxtank.atlassian.net/wiki/spaces/TAXTANK/pages/212369955/Loans+vehicle+loans
1525
+ * @TODO Vik/Nicole: need to update documentation. Derek gave the right formulas to Mikhail
1526
+ */
1527
+ getInterest() {
1528
+ return new LoanPaymentCollection(this.payments).paymentDue - this.amount;
1529
+ }
1530
+ /**
1531
+ * The last payment size
1532
+ * https://taxtank.atlassian.net/wiki/spaces/TAXTANK/pages/212369955/Loans+vehicle+loans
1533
+ * @TODO Vik/Nicole: need to update documentation. Derek gave the right formulas to Mikhail
1534
+ */
1535
+ getBalloonPayment() {
1536
+ const lastPaymentDueAmount = new LoanPaymentCollection(this.payments).last.paymentDue;
1537
+ return (lastPaymentDueAmount - this.repaymentAmount) > 0 ? lastPaymentDueAmount - this.repaymentAmount : 0;
1538
+ }
1539
+ /**
1540
+ * Percent of ballon payment from all payments
1541
+ * https://taxtank.atlassian.net/wiki/spaces/TAXTANK/pages/212369955/Loans+vehicle+loans
1542
+ * @TODO Vik/Nicole: need to update documentation. Derek gave the right formulas to Mikhail
1543
+ */
1544
+ getBalloonPaymentPercentage() {
1545
+ return this.getBalloonPayment() / new LoanPaymentCollection(this.payments).paymentDue * 100;
1546
+ }
1547
+ }
1548
+ /**
1549
+ * 30 years is default mortgage term
1550
+ */
1551
+ Loan.mortgageDefaultTerm = 360;
1552
+ /**
1553
+ * 5 years is default bank loan term
1554
+ */
1555
+ Loan.loanDefaultTerm = 60;
1556
+ __decorate([
1557
+ Type(() => LoanPayment)
1558
+ ], Loan.prototype, "payments", void 0);
1559
+ __decorate([
1560
+ Type(() => Date)
1561
+ ], Loan.prototype, "commencementDate", void 0);
1562
+ __decorate([
1563
+ Type(() => LoanPayout)
1564
+ ], Loan.prototype, "payout", void 0);
1565
+
1566
+ var TankTypeEnum;
1567
+ (function (TankTypeEnum) {
1568
+ TankTypeEnum[TankTypeEnum["PROPERTY"] = 1] = "PROPERTY";
1569
+ TankTypeEnum[TankTypeEnum["WORK"] = 2] = "WORK";
1570
+ TankTypeEnum[TankTypeEnum["OTHER"] = 3] = "OTHER";
1571
+ TankTypeEnum[TankTypeEnum["SOLE"] = 4] = "SOLE";
1572
+ })(TankTypeEnum || (TankTypeEnum = {}));
1573
+
1574
+ class BankAccountBalance extends AbstractModel {
1575
+ }
1576
+
1577
+ class BankAccountProperty$1 extends AbstractModel {
1578
+ }
1579
+
1580
+ class Property$1 extends AbstractModel {
1581
+ }
1582
+
1583
+ class PropertySubscription$1 extends AbstractModel {
1584
+ }
1585
+
1586
+ class User$1 extends AbstractModel {
1587
+ }
1588
+
1589
+ var UserStatusEnum;
1590
+ (function (UserStatusEnum) {
1591
+ UserStatusEnum[UserStatusEnum["INACTIVE"] = 0] = "INACTIVE";
1592
+ UserStatusEnum[UserStatusEnum["ON_BOARDING"] = 1] = "ON_BOARDING";
1593
+ UserStatusEnum[UserStatusEnum["ACTIVE"] = 2] = "ACTIVE";
1594
+ })(UserStatusEnum || (UserStatusEnum = {}));
1595
+
1596
+ var UserRolesEnum;
1597
+ (function (UserRolesEnum) {
1598
+ UserRolesEnum["FIRM_OWNER"] = "ROLE_FIRM_OWNER";
1599
+ UserRolesEnum["FIRM_MANAGER"] = "ROLE_FIRM_MANAGER";
1600
+ UserRolesEnum["CLIENT"] = "ROLE_CLIENT";
1601
+ UserRolesEnum["EMPLOYEE"] = "ROLE_EMPLOYEE";
1602
+ UserRolesEnum["ACCOUNTANT"] = "ROLE_ACCOUNTANT";
1603
+ UserRolesEnum["ADVISOR"] = "ROLE_ADVISOR";
1604
+ UserRolesEnum["USER"] = "ROLE_USER";
1605
+ UserRolesEnum["SUBSCRIPTION"] = "ROLE_USER_SUBSCRIPTION";
1606
+ UserRolesEnum["WORK_TANK"] = "ROLE_USER_WORK";
1607
+ UserRolesEnum["PROPERTY_TANK"] = "ROLE_USER_PROPERTY";
1608
+ UserRolesEnum["SOLE_TANK"] = "ROLE_USER_SOLE";
1609
+ UserRolesEnum["SWITCH_USER"] = "ROLE_PREVIOUS_ADMIN";
1610
+ })(UserRolesEnum || (UserRolesEnum = {}));
1611
+
1612
+ class Address$1 extends AbstractModel {
1613
+ }
1614
+
1615
+ class Country$1 extends AbstractModel {
1616
+ }
1617
+
1618
+ class Country extends Country$1 {
1619
+ /**
1620
+ * Return country name with phone code
1621
+ */
1622
+ get countryWithCode() {
1623
+ return `${this.name} (+${this.callingCode})`;
1624
+ }
1625
+ /**
1626
+ * Check if country calling code is Australian or not
1627
+ */
1628
+ isAustralianCode() {
1629
+ return this.callingCode === '61';
1630
+ }
1631
+ }
1632
+
1633
+ var AddressTypeEnum;
1634
+ (function (AddressTypeEnum) {
1635
+ AddressTypeEnum[AddressTypeEnum["STREET"] = 1] = "STREET";
1636
+ AddressTypeEnum[AddressTypeEnum["POSTAL"] = 2] = "POSTAL";
1637
+ })(AddressTypeEnum || (AddressTypeEnum = {}));
1638
+
1639
+ class Address extends Address$1 {
1640
+ constructor() {
1641
+ super(...arguments);
1642
+ this.type = AddressTypeEnum.STREET;
1643
+ }
1644
+ toString() {
1645
+ return [this.unitNumber, this.address, this.city, this.state, this.postcode].filter(Boolean).join(', ');
1646
+ }
1647
+ get name() {
1648
+ return `${this.unitNumber ? this.unitNumber + '/' : ''}${this.address}`;
1649
+ }
1650
+ get nameLong() {
1651
+ return `${this.name}, ${this.city}, ${this.state}`;
1652
+ }
1653
+ }
1654
+ __decorate([
1655
+ Type((() => Country))
1656
+ ], Address.prototype, "country", void 0);
1657
+
1658
+ const USER_WORK_POSITION = {
1659
+ [UserRolesEnum.EMPLOYEE]: 'Employee',
1660
+ [UserRolesEnum.FIRM_MANAGER]: 'Manager',
1661
+ [UserRolesEnum.FIRM_OWNER]: 'Firm Owner'
1662
+ };
1663
+
1664
+ class ClientDetails$1 extends AbstractModel {
1665
+ }
1666
+
1667
+ class ClientDetails extends ClientDetails$1 {
1668
+ }
1669
+
1670
+ class EmployeeDetails$1 extends AbstractModel {
1671
+ }
1672
+
1673
+ class Firm$1 extends AbstractModel {
1674
+ }
1675
+
1676
+ class Phone$1 extends AbstractModel {
1677
+ }
1678
+
1679
+ var PhoneTypeEnum;
1680
+ (function (PhoneTypeEnum) {
1681
+ PhoneTypeEnum[PhoneTypeEnum["MOBILE"] = 1] = "MOBILE";
1682
+ PhoneTypeEnum[PhoneTypeEnum["OFFICE"] = 2] = "OFFICE";
1683
+ })(PhoneTypeEnum || (PhoneTypeEnum = {}));
1684
+
1685
+ class Phone extends Phone$1 {
1686
+ constructor() {
1687
+ super(...arguments);
1688
+ this.type = PhoneTypeEnum.MOBILE;
1689
+ }
1690
+ toString() {
1691
+ return `+${this.country.callingCode} ${this.number}`;
1692
+ }
1693
+ }
1694
+
1695
+ class Firm extends Firm$1 {
1696
+ /**
1697
+ * get firm photo link
1698
+ */
1699
+ getPhoto() {
1700
+ return this.photo;
1701
+ }
1702
+ /**
1703
+ * get firm initials
1704
+ */
1705
+ getPhotoPlaceholder() {
1706
+ return `${this.name[0].toUpperCase()}${this.name[1]}`;
1707
+ }
1708
+ }
1709
+ __decorate([
1710
+ Type(() => User)
1711
+ ], Firm.prototype, "owner", void 0);
1712
+ __decorate([
1713
+ Type(() => Address)
1714
+ ], Firm.prototype, "address", void 0);
1715
+ __decorate([
1716
+ Type(() => Phone)
1717
+ ], Firm.prototype, "phone", void 0);
1718
+
1719
+ class EmployeeDetails extends EmployeeDetails$1 {
1720
+ }
1721
+ __decorate([
1722
+ Type(() => Firm)
1723
+ ], EmployeeDetails.prototype, "firm", void 0);
1724
+
1725
+ class ServiceSubscription$1 extends AbstractModel {
1726
+ }
1727
+
1728
+ class ServiceSubscriptionItem$1 extends AbstractModel {
1729
+ }
1730
+
1731
+ class ServicePrice$1 extends AbstractModel {
1732
+ }
1733
+
1734
+ class ServiceProduct$1 extends AbstractModel {
1735
+ }
1736
+
1737
+ var ServiceProductStatusEnum;
1738
+ (function (ServiceProductStatusEnum) {
1739
+ ServiceProductStatusEnum[ServiceProductStatusEnum["ARCHIVED"] = 0] = "ARCHIVED";
1740
+ ServiceProductStatusEnum[ServiceProductStatusEnum["ACTIVE"] = 1] = "ACTIVE";
1424
1741
  })(ServiceProductStatusEnum || (ServiceProductStatusEnum = {}));
1425
1742
 
1426
1743
  var ServiceProductIdEnum;
@@ -2095,6 +2412,9 @@ class SoleInvoiceTemplate$1 extends AbstractModel {
2095
2412
  }
2096
2413
 
2097
2414
  class SoleInvoiceTemplate extends SoleInvoiceTemplate$1 {
2415
+ static create(businessId) {
2416
+ return plainToClass(SoleInvoiceTemplate, { business: { id: businessId }, isTaxIncluded: false });
2417
+ }
2098
2418
  }
2099
2419
  __decorate([
2100
2420
  Type(() => SoleBusiness)
@@ -2130,25 +2450,105 @@ __decorate([
2130
2450
  class VehicleClaim$1 extends AbstractModel {
2131
2451
  }
2132
2452
 
2133
- var VehicleClaimMethodEnum;
2134
- (function (VehicleClaimMethodEnum) {
2135
- VehicleClaimMethodEnum[VehicleClaimMethodEnum["KMS"] = 1] = "KMS";
2136
- VehicleClaimMethodEnum[VehicleClaimMethodEnum["LOGBOOK"] = 2] = "LOGBOOK";
2137
- })(VehicleClaimMethodEnum || (VehicleClaimMethodEnum = {}));
2453
+ class VehicleClaimDetails$1 extends AbstractModel {
2454
+ }
2138
2455
 
2139
- var TransactionSourceEnum;
2140
- (function (TransactionSourceEnum) {
2141
- TransactionSourceEnum[TransactionSourceEnum["CASH"] = 1] = "CASH";
2142
- TransactionSourceEnum[TransactionSourceEnum["BANK_TRANSACTION"] = 2] = "BANK_TRANSACTION";
2143
- })(TransactionSourceEnum || (TransactionSourceEnum = {}));
2456
+ var VehicleClaimDetailsMethodEnum;
2457
+ (function (VehicleClaimDetailsMethodEnum) {
2458
+ VehicleClaimDetailsMethodEnum[VehicleClaimDetailsMethodEnum["KMS"] = 1] = "KMS";
2459
+ VehicleClaimDetailsMethodEnum[VehicleClaimDetailsMethodEnum["LOGBOOK"] = 2] = "LOGBOOK";
2460
+ })(VehicleClaimDetailsMethodEnum || (VehicleClaimDetailsMethodEnum = {}));
2144
2461
 
2145
- var TransactionTypeEnum;
2146
- (function (TransactionTypeEnum) {
2147
- TransactionTypeEnum[TransactionTypeEnum["DEBIT"] = 1] = "DEBIT";
2148
- TransactionTypeEnum[TransactionTypeEnum["CREDIT"] = 2] = "CREDIT";
2149
- })(TransactionTypeEnum || (TransactionTypeEnum = {}));
2462
+ class VehicleClaimDetails extends VehicleClaimDetails$1 {
2463
+ isLogbookMethod() {
2464
+ return this.method === VehicleClaimDetailsMethodEnum.LOGBOOK;
2465
+ }
2466
+ isKlmsMethod() {
2467
+ return this.method === VehicleClaimDetailsMethodEnum.KMS;
2468
+ }
2469
+ // @TODO Alex: discuss with Vik and think about abstract method in AbstractModel
2470
+ static create() {
2471
+ return plainToClass(VehicleClaimDetails, {
2472
+ isManual: true,
2473
+ method: VehicleClaimDetailsMethodEnum.KMS,
2474
+ financialYear: new FinancialYear().year
2475
+ });
2476
+ }
2477
+ }
2478
+ __decorate([
2479
+ Type(() => User)
2480
+ ], VehicleClaimDetails.prototype, "user", void 0);
2481
+
2482
+ class VehicleClaim extends VehicleClaim$1 {
2483
+ isWorkTank() {
2484
+ return !this.business;
2485
+ }
2486
+ isSoleTank() {
2487
+ return !!this.business;
2488
+ }
2489
+ get tankType() {
2490
+ return this.isSoleTank() ? TankTypeEnum.SOLE : TankTypeEnum.WORK;
2491
+ }
2492
+ /**
2493
+ * Claim amount for KLMs method. Exists only for KLMs method.
2494
+ */
2495
+ getKLMsClaimAmount(vehicleClaimRate) {
2496
+ return +(this.kilometers * vehicleClaimRate).toFixed(2);
2497
+ }
2498
+ /**
2499
+ * Get logbook claim amount. Exists only for logbook method.
2500
+ * ClaimAmount = WorkUsage * transaction/depreciation amount
2501
+ */
2502
+ getLogbookClaimAmount(transactions) {
2503
+ const transactionsAmount = transactions
2504
+ .getByVehicleClaim(this)
2505
+ .getLogbookTransactions()
2506
+ .sumBy('amount');
2507
+ // Math.abs because amount will be negative (because we sum expenses), but we don't want negative percent value
2508
+ return Math.abs(transactionsAmount) * this.workUsage / 100;
2509
+ }
2510
+ getKlmsChartAccountsIdByTankType(tankType = this.tankType) {
2511
+ return tankType === TankTypeEnum.WORK
2512
+ ? ChartAccountsListEnum.KLMS_TRAVELLED_FOR_WORK
2513
+ : ChartAccountsListEnum.KLMS_TRAVELLED;
2514
+ }
2515
+ static create(details, business) {
2516
+ return plainToClass(VehicleClaim, {
2517
+ kilometers: 0,
2518
+ workUsage: 0,
2519
+ details,
2520
+ business
2521
+ });
2522
+ }
2523
+ }
2524
+ /**
2525
+ * limit for kms claim method
2526
+ */
2527
+ VehicleClaim.totalKmsLimit = 5000;
2528
+ /**
2529
+ * limit for work usage claim method
2530
+ */
2531
+ VehicleClaim.totalWorkUsagePercent = 100;
2532
+ __decorate([
2533
+ Type(() => VehicleClaimDetails)
2534
+ ], VehicleClaim.prototype, "details", void 0);
2535
+ __decorate([
2536
+ Type(() => SoleBusiness)
2537
+ ], VehicleClaim.prototype, "business", void 0);
2150
2538
 
2151
2539
  class TransactionBase extends AbstractModel {
2540
+ get tankType() {
2541
+ switch (true) {
2542
+ case this.isPropertyTank():
2543
+ return TankTypeEnum.PROPERTY;
2544
+ case this.isWorkTank():
2545
+ return TankTypeEnum.WORK;
2546
+ case this.isSoleTank():
2547
+ return TankTypeEnum.SOLE;
2548
+ default:
2549
+ return TankTypeEnum.OTHER;
2550
+ }
2551
+ }
2152
2552
  /**
2153
2553
  * Check if current tank is Property
2154
2554
  */
@@ -2190,16 +2590,9 @@ __decorate([
2190
2590
  })
2191
2591
  ], TransactionBase.prototype, "file", void 0);
2192
2592
 
2193
- class Transaction$1 extends TransactionBase {
2593
+ class Depreciation$1 extends TransactionBase {
2194
2594
  }
2195
2595
 
2196
- var TransactionOperationEnum;
2197
- (function (TransactionOperationEnum) {
2198
- TransactionOperationEnum[TransactionOperationEnum["ALLOCATE"] = 1] = "ALLOCATE";
2199
- TransactionOperationEnum[TransactionOperationEnum["FIND_AND_MATCH"] = 2] = "FIND_AND_MATCH";
2200
- TransactionOperationEnum[TransactionOperationEnum["TRANSFER"] = 3] = "TRANSFER";
2201
- })(TransactionOperationEnum || (TransactionOperationEnum = {}));
2202
-
2203
2596
  var DepreciationTypeEnum;
2204
2597
  (function (DepreciationTypeEnum) {
2205
2598
  DepreciationTypeEnum[DepreciationTypeEnum["PLANT_EQUIPMENT"] = 1] = "PLANT_EQUIPMENT";
@@ -2217,6 +2610,80 @@ var DepreciationCalculationEnum;
2217
2610
  DepreciationCalculationEnum[DepreciationCalculationEnum["AMORTISATION"] = 5] = "AMORTISATION";
2218
2611
  })(DepreciationCalculationEnum || (DepreciationCalculationEnum = {}));
2219
2612
 
2613
+ class DepreciationCapitalProject$1 extends AbstractModel {
2614
+ }
2615
+
2616
+ class DepreciationCapitalProject extends DepreciationCapitalProject$1 {
2617
+ }
2618
+ __decorate([
2619
+ Type(() => Date)
2620
+ ], DepreciationCapitalProject.prototype, "effectiveDate", void 0);
2621
+
2622
+ class DepreciationForecast$1 extends AbstractModel {
2623
+ }
2624
+
2625
+ class DepreciationForecast extends DepreciationForecast$1 {
2626
+ get dailyClaimAmount() {
2627
+ return this.claimAmount / this.daysApplied;
2628
+ }
2629
+ get daysApplied() {
2630
+ return moment(this.toDate).diff(moment(this.fromDate), 'days');
2631
+ }
2632
+ getDaysByMonth(month) {
2633
+ // @TODO find a better place
2634
+ const year = this.financialYear - (month > 5 ? 1 : 0);
2635
+ // forecast date intersect by month
2636
+ const range = new DateRange(this.fromDate, this.toDate).intersect(new DateRange(new Date(year, month, 1), new Date(year, month + 1, 0)));
2637
+ return range ? range.duration('days') + 1 : 0;
2638
+ }
2639
+ get claimOpenBalance() {
2640
+ return this.openBalance * this.claimRate;
2641
+ }
2642
+ get claimCloseBalance() {
2643
+ return this.closeBalance * this.claimRate;
2644
+ }
2645
+ get claimAmount() {
2646
+ return this.amount * this.claimRate;
2647
+ }
2648
+ get claimRate() {
2649
+ return this.claimPercent / 100;
2650
+ }
2651
+ getClaimAmountByMonth(month) {
2652
+ return this.getDaysByMonth(month) * this.dailyClaimAmount;
2653
+ }
2654
+ }
2655
+
2656
+ class BankTransaction$1 extends AbstractModel {
2657
+ }
2658
+
2659
+ var BankTransactionTypeEnum;
2660
+ (function (BankTransactionTypeEnum) {
2661
+ BankTransactionTypeEnum[BankTransactionTypeEnum["DEBIT"] = 1] = "DEBIT";
2662
+ BankTransactionTypeEnum[BankTransactionTypeEnum["CREDIT"] = 2] = "CREDIT";
2663
+ })(BankTransactionTypeEnum || (BankTransactionTypeEnum = {}));
2664
+
2665
+ var TransactionSourceEnum;
2666
+ (function (TransactionSourceEnum) {
2667
+ TransactionSourceEnum[TransactionSourceEnum["CASH"] = 1] = "CASH";
2668
+ TransactionSourceEnum[TransactionSourceEnum["BANK_TRANSACTION"] = 2] = "BANK_TRANSACTION";
2669
+ })(TransactionSourceEnum || (TransactionSourceEnum = {}));
2670
+
2671
+ class Transaction$1 extends TransactionBase {
2672
+ }
2673
+
2674
+ var TransactionTypeEnum;
2675
+ (function (TransactionTypeEnum) {
2676
+ TransactionTypeEnum[TransactionTypeEnum["DEBIT"] = 1] = "DEBIT";
2677
+ TransactionTypeEnum[TransactionTypeEnum["CREDIT"] = 2] = "CREDIT";
2678
+ })(TransactionTypeEnum || (TransactionTypeEnum = {}));
2679
+
2680
+ var TransactionOperationEnum;
2681
+ (function (TransactionOperationEnum) {
2682
+ TransactionOperationEnum[TransactionOperationEnum["ALLOCATE"] = 1] = "ALLOCATE";
2683
+ TransactionOperationEnum[TransactionOperationEnum["FIND_AND_MATCH"] = 2] = "FIND_AND_MATCH";
2684
+ TransactionOperationEnum[TransactionOperationEnum["TRANSFER"] = 3] = "TRANSFER";
2685
+ })(TransactionOperationEnum || (TransactionOperationEnum = {}));
2686
+
2220
2687
  class TransactionReceipt$1 extends AbstractModel {
2221
2688
  }
2222
2689
 
@@ -2264,474 +2731,206 @@ var IncomeSourceTypeEnum;
2264
2731
  class SalaryForecast$1 extends AbstractModel {
2265
2732
  }
2266
2733
 
2267
- class SalaryForecast extends SalaryForecast$1 {
2268
- }
2269
- __decorate([
2270
- Transform(({ obj }) => obj.netPay + obj.tax),
2271
- Expose()
2272
- ], SalaryForecast.prototype, "grossAmount", void 0);
2273
- __decorate([
2274
- Type(() => IncomeSource)
2275
- ], SalaryForecast.prototype, "incomeSource", void 0);
2276
-
2277
- class SoleForecast$1 extends AbstractModel {
2278
- }
2279
-
2280
- class SoleForecast extends SoleForecast$1 {
2281
- get netPay() {
2282
- return this.amount;
2283
- }
2284
- ;
2285
- }
2286
- __decorate([
2287
- Type(() => IncomeSource)
2288
- ], SoleForecast.prototype, "incomeSource", void 0);
2289
-
2290
- class IncomeSourceForecast$1 extends AbstractModel {
2291
- }
2292
-
2293
- var SalaryForecastFrequencyEnum;
2294
- (function (SalaryForecastFrequencyEnum) {
2295
- SalaryForecastFrequencyEnum[SalaryForecastFrequencyEnum["ANNUAL"] = 1] = "ANNUAL";
2296
- SalaryForecastFrequencyEnum[SalaryForecastFrequencyEnum["MONTHLY"] = 12] = "MONTHLY";
2297
- SalaryForecastFrequencyEnum[SalaryForecastFrequencyEnum["FORTNIGHTLY"] = 26] = "FORTNIGHTLY";
2298
- SalaryForecastFrequencyEnum[SalaryForecastFrequencyEnum["WEEKLY"] = 52] = "WEEKLY";
2299
- })(SalaryForecastFrequencyEnum || (SalaryForecastFrequencyEnum = {}));
2300
-
2301
- class IncomeSourceType$1 extends AbstractModel {
2302
- }
2303
-
2304
- var IncomeSourceTypeListWorkEnum;
2305
- (function (IncomeSourceTypeListWorkEnum) {
2306
- IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["BONUSES"] = 1] = "BONUSES";
2307
- IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["DIRECTOR_FEES"] = 2] = "DIRECTOR_FEES";
2308
- IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["DIVIDENDS"] = 3] = "DIVIDENDS";
2309
- IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["INTEREST"] = 4] = "INTEREST";
2310
- IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["PENSIONS_AND_ALLOWANCES"] = 5] = "PENSIONS_AND_ALLOWANCES";
2311
- IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["SUPERANNUATION"] = 8] = "SUPERANNUATION";
2312
- IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["ATTRIBUTED_P_S_I"] = 11] = "ATTRIBUTED_P_S_I";
2313
- })(IncomeSourceTypeListWorkEnum || (IncomeSourceTypeListWorkEnum = {}));
2314
-
2315
- var IncomeSourceTypeListOtherEnum;
2316
- (function (IncomeSourceTypeListOtherEnum) {
2317
- IncomeSourceTypeListOtherEnum[IncomeSourceTypeListOtherEnum["PSI"] = 6] = "PSI";
2318
- IncomeSourceTypeListOtherEnum[IncomeSourceTypeListOtherEnum["SOLE_TRADER"] = 7] = "SOLE_TRADER";
2319
- IncomeSourceTypeListOtherEnum[IncomeSourceTypeListOtherEnum["TRUSTS"] = 9] = "TRUSTS";
2320
- IncomeSourceTypeListOtherEnum[IncomeSourceTypeListOtherEnum["OTHER_INCOME"] = 10] = "OTHER_INCOME";
2321
- IncomeSourceTypeListOtherEnum[IncomeSourceTypeListOtherEnum["PARTNERSHIPS"] = 12] = "PARTNERSHIPS";
2322
- })(IncomeSourceTypeListOtherEnum || (IncomeSourceTypeListOtherEnum = {}));
2323
-
2324
- var IncomeSourceTypeListSoleEnum;
2325
- (function (IncomeSourceTypeListSoleEnum) {
2326
- IncomeSourceTypeListSoleEnum[IncomeSourceTypeListSoleEnum["SOLE_TRADER"] = 7] = "SOLE_TRADER";
2327
- })(IncomeSourceTypeListSoleEnum || (IncomeSourceTypeListSoleEnum = {}));
2328
-
2329
- class IncomeSourceType extends IncomeSourceType$1 {
2330
- isBonuses() {
2331
- return this.id === IncomeSourceTypeListWorkEnum.BONUSES;
2332
- }
2333
- isWork() {
2334
- return !!IncomeSourceTypeListWorkEnum[this.id];
2335
- }
2336
- isOther() {
2337
- return !!IncomeSourceTypeListOtherEnum[this.id];
2338
- }
2339
- isSole() {
2340
- return !!IncomeSourceTypeListSoleEnum[this.id];
2341
- }
2342
- get type() {
2343
- switch (true) {
2344
- case this.isWork():
2345
- return IncomeSourceTypeEnum.WORK;
2346
- case this.isSole():
2347
- return IncomeSourceTypeEnum.SOLE;
2348
- default:
2349
- return IncomeSourceTypeEnum.OTHER;
2350
- }
2351
- }
2352
- }
2353
-
2354
- class IncomeSourceForecast extends IncomeSourceForecast$1 {
2355
- constructor() {
2356
- super(...arguments);
2357
- this.paygIncome = 0;
2358
- this.frequency = SalaryForecastFrequencyEnum.ANNUAL;
2359
- this.isTaxFree = false;
2360
- }
2361
- /**
2362
- * Sometimes Income source has Salary & Income source forecasts,
2363
- * and we need these fields to work with Income source forecasts like with Salary Forecasts
2364
- */
2365
- get netPay() {
2366
- return this.amount;
2367
- }
2368
- get grossAmount() {
2369
- return this.amount + this.tax + this.taxInstalments + this.frankingCredits;
2370
- }
2371
- }
2372
- __decorate([
2373
- Type(() => IncomeSourceType)
2374
- ], IncomeSourceForecast.prototype, "incomeSourceType", void 0);
2375
- __decorate([
2376
- Type(() => IncomeSource)
2377
- ], IncomeSourceForecast.prototype, "incomeSource", void 0);
2378
-
2379
- class IncomeSource extends IncomeSource$1 {
2380
- isSalaryIncome() {
2381
- return !!this.salaryForecasts.length;
2382
- // @TODO Vik: old code
2383
- // return this.type === IncomeSourceTypeEnum.SALARY;
2384
- }
2385
- isSoleIncome() {
2386
- return this.type === IncomeSourceTypeEnum.SOLE;
2387
- }
2388
- isWorkIncome() {
2389
- return this.type === IncomeSourceTypeEnum.WORK;
2390
- }
2391
- isOtherIncome() {
2392
- return this.type === IncomeSourceTypeEnum.OTHER;
2393
- }
2394
- /**
2395
- * Get salary and other income forecasts
2396
- */
2397
- get forecasts() {
2398
- return [...this.salaryForecasts, ...this.incomeSourceForecasts, ...this.soleForecasts];
2399
- }
2400
- /**
2401
- * Get actual (1st from the list) forecast
2402
- */
2403
- get actualForecast() {
2404
- return this.forecasts[0];
2405
- }
2406
- /**
2407
- * Check if user was working in month taken by the index
2408
- * @param monthIndex by which month should be taken
2409
- */
2410
- isWorkedInMonth(monthIndex) {
2411
- const monthDate = new FinancialYear().getMonthDate(monthIndex);
2412
- return (!this.dateFrom || monthDate >= this.dateFrom) && (!this.dateTo || monthDate < this.dateTo);
2413
- }
2414
- }
2415
- __decorate([
2416
- Type(() => SalaryForecast)
2417
- ], IncomeSource.prototype, "salaryForecasts", void 0);
2418
- __decorate([
2419
- Type(() => SoleForecast)
2420
- ], IncomeSource.prototype, "soleForecasts", void 0);
2421
- __decorate([
2422
- Type(() => IncomeSourceForecast)
2423
- ], IncomeSource.prototype, "incomeSourceForecasts", void 0);
2424
- __decorate([
2425
- Type(() => Date)
2426
- ], IncomeSource.prototype, "dateFrom", void 0);
2427
- __decorate([
2428
- Type(() => Date)
2429
- ], IncomeSource.prototype, "dateTo", void 0);
2430
-
2431
- class TransactionMetadata$1 extends AbstractModel {
2432
- }
2433
-
2434
- class TransactionMetadata extends TransactionMetadata$1 {
2435
- }
2436
- __decorate([
2437
- Type(() => ChartAccountsMetadata)
2438
- ], TransactionMetadata.prototype, "metadata", void 0);
2439
-
2440
- class TransactionAllocation$1 extends AbstractModel {
2441
- }
2442
-
2443
- class BankTransaction$1 extends AbstractModel {
2444
- }
2445
-
2446
- var BankTransactionTypeEnum;
2447
- (function (BankTransactionTypeEnum) {
2448
- BankTransactionTypeEnum[BankTransactionTypeEnum["DEBIT"] = 1] = "DEBIT";
2449
- BankTransactionTypeEnum[BankTransactionTypeEnum["CREDIT"] = 2] = "CREDIT";
2450
- })(BankTransactionTypeEnum || (BankTransactionTypeEnum = {}));
2451
-
2452
- class BankTransaction extends BankTransaction$1 {
2453
- constructor() {
2454
- super(...arguments);
2455
- // allocated money amount for bank transaction
2456
- this.allocatedAmount = 0;
2457
- this.unallocatedAmount = 0;
2458
- }
2459
- /**
2460
- * get allocated amount value but with +/- sign
2461
- */
2462
- get balanceAmount() {
2463
- return this.isCredit() ? this.allocatedAmount : -this.allocatedAmount;
2464
- }
2465
- /**
2466
- * check if bank transaction is debit
2467
- */
2468
- isDebit() {
2469
- return this.type === BankTransactionTypeEnum.DEBIT;
2470
- }
2471
- /**
2472
- * check if bank transaction is credit
2473
- */
2474
- isCredit() {
2475
- return this.type === BankTransactionTypeEnum.CREDIT;
2476
- }
2477
- /**
2478
- * Create Transaction instance based on Bank Transaction
2479
- */
2480
- toTransaction() {
2481
- return plainToClass(Transaction, {
2482
- amount: +this.amount.toFixed(2),
2483
- description: this.description,
2484
- date: this.date,
2485
- source: TransactionSourceEnum.BANK_TRANSACTION,
2486
- operation: this.operation,
2487
- type: this.type,
2488
- });
2489
- }
2490
- /**
2491
- * Check if bank transaction is completely allocated
2492
- */
2493
- isAllocated(allocations) {
2494
- return this.amount === this.getAllocatedAmount(allocations);
2495
- }
2496
- /**
2497
- * Get bank transaction allocated amount
2498
- */
2499
- getAllocatedAmount(allocations) {
2500
- return allocations.getByBankTransactionsIds([this.id]).amount;
2501
- }
2502
- /**
2503
- * Get bank transaction unallocated amount
2504
- */
2505
- getUnallocatedAmount(allocations) {
2506
- return this.amount - this.getAllocatedAmount(allocations);
2507
- }
2508
- }
2509
- __decorate([
2510
- Type(() => Date)
2511
- ], BankTransaction.prototype, "date", void 0);
2512
-
2513
- class TransactionAllocation extends TransactionAllocation$1 {
2514
- /**
2515
- * Create a new instance of transaction allocation
2516
- * transaction could be empty since we can POST allocation inside a new transaction
2517
- */
2518
- static create(amount, bankTransaction, transaction) {
2519
- return plainToClass(TransactionAllocation, { amount, transaction, bankTransaction });
2520
- }
2734
+ class SalaryForecast extends SalaryForecast$1 {
2521
2735
  }
2522
2736
  __decorate([
2523
- Type(() => BankTransaction)
2524
- ], TransactionAllocation.prototype, "bankTransaction", void 0);
2737
+ Transform(({ obj }) => obj.netPay + obj.tax),
2738
+ Expose()
2739
+ ], SalaryForecast.prototype, "grossAmount", void 0);
2525
2740
  __decorate([
2526
- Type(() => Transaction)
2527
- ], TransactionAllocation.prototype, "transaction", void 0);
2528
-
2529
- /**
2530
- * Enum with income amount types (Net or Gross)
2531
- */
2532
- var IncomeAmountTypeEnum;
2533
- (function (IncomeAmountTypeEnum) {
2534
- IncomeAmountTypeEnum[IncomeAmountTypeEnum["NET"] = 0] = "NET";
2535
- IncomeAmountTypeEnum[IncomeAmountTypeEnum["GROSS"] = 1] = "GROSS";
2536
- })(IncomeAmountTypeEnum || (IncomeAmountTypeEnum = {}));
2741
+ Type(() => IncomeSource)
2742
+ ], SalaryForecast.prototype, "incomeSource", void 0);
2537
2743
 
2538
- class Depreciation$1 extends TransactionBase {
2744
+ class SoleForecast$1 extends AbstractModel {
2539
2745
  }
2540
2746
 
2541
- class DepreciationCapitalProject$1 extends AbstractModel {
2747
+ class SoleForecast extends SoleForecast$1 {
2748
+ get netPay() {
2749
+ return this.amount;
2750
+ }
2751
+ ;
2542
2752
  }
2753
+ __decorate([
2754
+ Type(() => IncomeSource)
2755
+ ], SoleForecast.prototype, "incomeSource", void 0);
2543
2756
 
2544
- class DepreciationCapitalProject extends DepreciationCapitalProject$1 {
2757
+ class IncomeSourceForecast$1 extends AbstractModel {
2545
2758
  }
2546
- __decorate([
2547
- Type(() => Date)
2548
- ], DepreciationCapitalProject.prototype, "effectiveDate", void 0);
2549
2759
 
2550
- class DepreciationForecast$1 extends AbstractModel {
2760
+ var SalaryForecastFrequencyEnum;
2761
+ (function (SalaryForecastFrequencyEnum) {
2762
+ SalaryForecastFrequencyEnum[SalaryForecastFrequencyEnum["ANNUAL"] = 1] = "ANNUAL";
2763
+ SalaryForecastFrequencyEnum[SalaryForecastFrequencyEnum["MONTHLY"] = 12] = "MONTHLY";
2764
+ SalaryForecastFrequencyEnum[SalaryForecastFrequencyEnum["FORTNIGHTLY"] = 26] = "FORTNIGHTLY";
2765
+ SalaryForecastFrequencyEnum[SalaryForecastFrequencyEnum["WEEKLY"] = 52] = "WEEKLY";
2766
+ })(SalaryForecastFrequencyEnum || (SalaryForecastFrequencyEnum = {}));
2767
+
2768
+ class IncomeSourceType$1 extends AbstractModel {
2551
2769
  }
2552
2770
 
2553
- class DepreciationForecast extends DepreciationForecast$1 {
2554
- get dailyClaimAmount() {
2555
- return this.claimAmount / this.daysApplied;
2556
- }
2557
- get daysApplied() {
2558
- return moment(this.toDate).diff(moment(this.fromDate), 'days');
2559
- }
2560
- getDaysByMonth(month) {
2561
- // @TODO find a better place
2562
- const year = this.financialYear - (month > 5 ? 1 : 0);
2563
- // forecast date intersect by month
2564
- const range = new DateRange(this.fromDate, this.toDate).intersect(new DateRange(new Date(year, month, 1), new Date(year, month + 1, 0)));
2565
- return range ? range.duration('days') + 1 : 0;
2566
- }
2567
- get claimOpenBalance() {
2568
- return this.openBalance * this.claimRate;
2771
+ var IncomeSourceTypeListWorkEnum;
2772
+ (function (IncomeSourceTypeListWorkEnum) {
2773
+ IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["BONUSES"] = 1] = "BONUSES";
2774
+ IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["DIRECTOR_FEES"] = 2] = "DIRECTOR_FEES";
2775
+ IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["DIVIDENDS"] = 3] = "DIVIDENDS";
2776
+ IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["INTEREST"] = 4] = "INTEREST";
2777
+ IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["PENSIONS_AND_ALLOWANCES"] = 5] = "PENSIONS_AND_ALLOWANCES";
2778
+ IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["SUPERANNUATION"] = 8] = "SUPERANNUATION";
2779
+ IncomeSourceTypeListWorkEnum[IncomeSourceTypeListWorkEnum["ATTRIBUTED_P_S_I"] = 11] = "ATTRIBUTED_P_S_I";
2780
+ })(IncomeSourceTypeListWorkEnum || (IncomeSourceTypeListWorkEnum = {}));
2781
+
2782
+ var IncomeSourceTypeListOtherEnum;
2783
+ (function (IncomeSourceTypeListOtherEnum) {
2784
+ IncomeSourceTypeListOtherEnum[IncomeSourceTypeListOtherEnum["PSI"] = 6] = "PSI";
2785
+ IncomeSourceTypeListOtherEnum[IncomeSourceTypeListOtherEnum["SOLE_TRADER"] = 7] = "SOLE_TRADER";
2786
+ IncomeSourceTypeListOtherEnum[IncomeSourceTypeListOtherEnum["TRUSTS"] = 9] = "TRUSTS";
2787
+ IncomeSourceTypeListOtherEnum[IncomeSourceTypeListOtherEnum["OTHER_INCOME"] = 10] = "OTHER_INCOME";
2788
+ IncomeSourceTypeListOtherEnum[IncomeSourceTypeListOtherEnum["PARTNERSHIPS"] = 12] = "PARTNERSHIPS";
2789
+ })(IncomeSourceTypeListOtherEnum || (IncomeSourceTypeListOtherEnum = {}));
2790
+
2791
+ var IncomeSourceTypeListSoleEnum;
2792
+ (function (IncomeSourceTypeListSoleEnum) {
2793
+ IncomeSourceTypeListSoleEnum[IncomeSourceTypeListSoleEnum["SOLE_TRADER"] = 7] = "SOLE_TRADER";
2794
+ })(IncomeSourceTypeListSoleEnum || (IncomeSourceTypeListSoleEnum = {}));
2795
+
2796
+ class IncomeSourceType extends IncomeSourceType$1 {
2797
+ isBonuses() {
2798
+ return this.id === IncomeSourceTypeListWorkEnum.BONUSES;
2569
2799
  }
2570
- get claimCloseBalance() {
2571
- return this.closeBalance * this.claimRate;
2800
+ isWork() {
2801
+ return !!IncomeSourceTypeListWorkEnum[this.id];
2572
2802
  }
2573
- get claimAmount() {
2574
- return this.amount * this.claimRate;
2803
+ isOther() {
2804
+ return !!IncomeSourceTypeListOtherEnum[this.id];
2575
2805
  }
2576
- get claimRate() {
2577
- return this.claimPercent / 100;
2806
+ isSole() {
2807
+ return !!IncomeSourceTypeListSoleEnum[this.id];
2578
2808
  }
2579
- getClaimAmountByMonth(month) {
2580
- return this.getDaysByMonth(month) * this.dailyClaimAmount;
2809
+ get type() {
2810
+ switch (true) {
2811
+ case this.isWork():
2812
+ return IncomeSourceTypeEnum.WORK;
2813
+ case this.isSole():
2814
+ return IncomeSourceTypeEnum.SOLE;
2815
+ default:
2816
+ return IncomeSourceTypeEnum.OTHER;
2817
+ }
2581
2818
  }
2582
2819
  }
2583
2820
 
2584
- class Depreciation extends Depreciation$1 {
2821
+ class IncomeSourceForecast extends IncomeSourceForecast$1 {
2585
2822
  constructor() {
2586
2823
  super(...arguments);
2587
- this.forecasts = [];
2588
- this.type = DepreciationTypeEnum.PLANT_EQUIPMENT;
2589
- /**
2590
- * @TODO remove after ? signs removed from db models
2591
- */
2592
- this.amount = 0;
2593
- }
2594
- isCapital() {
2595
- return this.type === DepreciationTypeEnum.CAPITAL_WORKS;
2596
- }
2597
- isBorrowingExpense() {
2598
- return this.type === DepreciationTypeEnum.BORROWING_EXPENSES;
2599
- }
2600
- isAsset() {
2601
- return this.type === DepreciationTypeEnum.PLANT_EQUIPMENT;
2602
- }
2603
- /**
2604
- * check if depreciation should be displayed in written off category
2605
- * details in project documentation
2606
- * @TODO new FinancialYear(this.writeOffDate) === new FinancialYear()
2607
- */
2608
- isWrittenOff() {
2609
- return this.isAsset && this.writeOffDate && new FinancialYear(this.writeOffDate).year === this.financialYear;
2824
+ this.paygIncome = 0;
2825
+ this.frequency = SalaryForecastFrequencyEnum.ANNUAL;
2826
+ this.isTaxFree = false;
2610
2827
  }
2611
2828
  /**
2612
- * Check if depreciation is Plant & Equipment
2829
+ * Sometimes Income source has Salary & Income source forecasts,
2830
+ * and we need these fields to work with Income source forecasts like with Salary Forecasts
2613
2831
  */
2614
- isPlantEquipment() {
2615
- return this.isAsset() && !this.isWrittenOff() && !this.isLowValuePool();
2832
+ get netPay() {
2833
+ return this.amount;
2616
2834
  }
2617
- /**
2618
- * check if depreciation should be displayed in low value pool
2619
- * details in project documentation
2620
- * @TODO new FinancialYear(this.writeOffDate) === new FinancialYear()
2621
- */
2622
- isLowValuePool() {
2623
- return this.isAsset &&
2624
- this.calculation === DepreciationCalculationEnum.DIMINISHING &&
2625
- this.amount > Depreciation.WRITTEN_OFF_THRESHOLD &&
2626
- this.amount <= Depreciation.LOW_VALUE_POOL_THRESHOLD;
2835
+ get grossAmount() {
2836
+ return this.amount + this.tax + this.taxInstalments + this.frankingCredits;
2627
2837
  }
2628
- isPrimeCost() {
2629
- return this.calculation === DepreciationCalculationEnum.PRIME_COST;
2838
+ }
2839
+ __decorate([
2840
+ Type(() => IncomeSourceType)
2841
+ ], IncomeSourceForecast.prototype, "incomeSourceType", void 0);
2842
+ __decorate([
2843
+ Type(() => IncomeSource)
2844
+ ], IncomeSourceForecast.prototype, "incomeSource", void 0);
2845
+
2846
+ class IncomeSource extends IncomeSource$1 {
2847
+ isSalaryIncome() {
2848
+ return !!this.salaryForecasts.length;
2849
+ // @TODO Vik: old code
2850
+ // return this.type === IncomeSourceTypeEnum.SALARY;
2630
2851
  }
2631
- isDiminishing() {
2632
- return this.calculation === DepreciationCalculationEnum.DIMINISHING;
2852
+ isSoleIncome() {
2853
+ return this.type === IncomeSourceTypeEnum.SOLE;
2633
2854
  }
2634
- /**
2635
- * Check if depreciation chart accounts heading related to vehicles category
2636
- */
2637
- isVehicleDepreciation() {
2638
- var _a;
2639
- return ((_a = this.chartAccounts.heading) === null || _a === void 0 ? void 0 : _a.id) === ChartAccountsHeadingVehicleListEnum.DEPRECIATION_VEHICLES;
2855
+ isWorkIncome() {
2856
+ return this.type === IncomeSourceTypeEnum.WORK;
2640
2857
  }
2641
- /**
2642
- * Get depreciation purchase date
2643
- */
2644
- getDate() {
2645
- return this.date;
2858
+ isOtherIncome() {
2859
+ return this.type === IncomeSourceTypeEnum.OTHER;
2646
2860
  }
2647
2861
  /**
2648
- * @TODO Vik: Research a problem with depreciations without current year forecast
2862
+ * Get salary and other income forecasts
2649
2863
  */
2650
- get currentYearForecast() {
2651
- return this.forecasts.find((forecast) => {
2652
- return forecast.financialYear === new FinancialYear().year;
2653
- }) || plainToClass(DepreciationForecast, {
2654
- financialYear: new FinancialYear().year,
2655
- openBalance: 0,
2656
- closeBalance: 0,
2657
- amount: 0,
2658
- claimPercent: 0
2659
- });
2660
- }
2661
- getForecastByYear(year) {
2662
- return this.forecasts.find((forecast) => {
2663
- return forecast.financialYear === year;
2664
- });
2665
- }
2666
- getClaimAmountByYear(year) {
2667
- var _a;
2668
- return ((_a = this.getForecastByYear(year)) === null || _a === void 0 ? void 0 : _a.claimAmount) || 0;
2669
- }
2670
- getCloseBalanceByYear(year) {
2671
- var _a;
2672
- return ((_a = this.getForecastByYear(year)) === null || _a === void 0 ? void 0 : _a.closeBalance) || 0;
2673
- }
2674
- isBuildingAtCost() {
2675
- return this.chartAccounts.id === ChartAccountsListEnum.BUILDING_AT_COST;
2864
+ get forecasts() {
2865
+ return [...this.salaryForecasts, ...this.incomeSourceForecasts, ...this.soleForecasts];
2676
2866
  }
2677
2867
  /**
2678
- * Create a new transaction from current depreciation
2868
+ * Get actual (1st from the list) forecast
2679
2869
  */
2680
- toTransaction(params = {}) {
2681
- return plainToClass(Transaction, Object.assign(params, this, { amount: this.currentYearForecast.amount }));
2870
+ get actualForecast() {
2871
+ return this.forecasts[0];
2682
2872
  }
2683
2873
  /**
2684
- * @TODO Michael: remove and check everywhere in reports
2874
+ * Check if user was working in month taken by the index
2875
+ * @param monthIndex by which month should be taken
2685
2876
  */
2686
- get claimAmount() {
2687
- var _a;
2688
- return ((_a = this.currentYearForecast) === null || _a === void 0 ? void 0 : _a.claimAmount) || 0;
2877
+ isWorkedInMonth(monthIndex) {
2878
+ const monthDate = new FinancialYear().getMonthDate(monthIndex);
2879
+ return (!this.dateFrom || monthDate >= this.dateFrom) && (!this.dateTo || monthDate < this.dateTo);
2689
2880
  }
2690
2881
  }
2691
- Depreciation.WRITTEN_OFF_THRESHOLD = 300;
2692
- Depreciation.LOW_VALUE_POOL_THRESHOLD = 1000;
2693
2882
  __decorate([
2694
- Type(() => Date)
2695
- ], Depreciation.prototype, "purchaseDate", void 0);
2883
+ Type(() => SalaryForecast)
2884
+ ], IncomeSource.prototype, "salaryForecasts", void 0);
2696
2885
  __decorate([
2697
- Type(() => Date)
2698
- ], Depreciation.prototype, "date", void 0);
2886
+ Type(() => SoleForecast)
2887
+ ], IncomeSource.prototype, "soleForecasts", void 0);
2699
2888
  __decorate([
2700
- Type(() => Date)
2701
- ], Depreciation.prototype, "lowValuePoolDate", void 0);
2889
+ Type(() => IncomeSourceForecast)
2890
+ ], IncomeSource.prototype, "incomeSourceForecasts", void 0);
2702
2891
  __decorate([
2703
2892
  Type(() => Date)
2704
- ], Depreciation.prototype, "writeOffManualDate", void 0);
2893
+ ], IncomeSource.prototype, "dateFrom", void 0);
2705
2894
  __decorate([
2706
2895
  Type(() => Date)
2707
- ], Depreciation.prototype, "writeOffDate", void 0);
2708
- __decorate([
2709
- Type(() => DepreciationCapitalProject)
2710
- ], Depreciation.prototype, "depreciationCapitalProject", void 0);
2711
- __decorate([
2712
- Type(() => DepreciationForecast),
2713
- Transform(({ value, obj }) => {
2714
- // value = array of DepreciationForecast
2715
- // obj = plain (whole Depreciation object)
2716
- // Set isLVP flag for each DepreciationForecast
2717
- // @TODO refactor
2718
- value.forEach((forecast) => {
2719
- forecast.isLVP =
2720
- forecast.closeBalance < 1000 &&
2721
- obj.calculation === DepreciationCalculationEnum.DIMINISHING &&
2722
- obj.type === DepreciationTypeEnum.PLANT_EQUIPMENT &&
2723
- !(obj.amount > Depreciation.WRITTEN_OFF_THRESHOLD && obj.amount < Depreciation.LOW_VALUE_POOL_THRESHOLD) &&
2724
- !(obj.writeOffDate && new FinancialYear(new Date(obj.writeOffDate)).year === obj.financialYear);
2725
- });
2726
- return value;
2727
- })
2728
- ], Depreciation.prototype, "forecasts", void 0);
2896
+ ], IncomeSource.prototype, "dateTo", void 0);
2897
+
2898
+ class TransactionMetadata$1 extends AbstractModel {
2899
+ }
2900
+
2901
+ class TransactionMetadata extends TransactionMetadata$1 {
2902
+ }
2729
2903
  __decorate([
2730
- Type(() => ChartAccounts)
2731
- ], Depreciation.prototype, "chartAccounts", void 0);
2904
+ Type(() => ChartAccountsMetadata)
2905
+ ], TransactionMetadata.prototype, "metadata", void 0);
2906
+
2907
+ class TransactionAllocation$1 extends AbstractModel {
2908
+ }
2909
+
2910
+ class TransactionAllocation extends TransactionAllocation$1 {
2911
+ /**
2912
+ * Create a new instance of transaction allocation
2913
+ * transaction could be empty since we can POST allocation inside a new transaction
2914
+ */
2915
+ static create(amount, bankTransaction, transaction) {
2916
+ return plainToClass(TransactionAllocation, { amount, transaction, bankTransaction });
2917
+ }
2918
+ }
2732
2919
  __decorate([
2733
2920
  Type(() => BankTransaction)
2734
- ], Depreciation.prototype, "bankTransaction", void 0);
2921
+ ], TransactionAllocation.prototype, "bankTransaction", void 0);
2922
+ __decorate([
2923
+ Type(() => Transaction)
2924
+ ], TransactionAllocation.prototype, "transaction", void 0);
2925
+
2926
+ /**
2927
+ * Enum with income amount types (Net or Gross)
2928
+ */
2929
+ var IncomeAmountTypeEnum;
2930
+ (function (IncomeAmountTypeEnum) {
2931
+ IncomeAmountTypeEnum[IncomeAmountTypeEnum["NET"] = 0] = "NET";
2932
+ IncomeAmountTypeEnum[IncomeAmountTypeEnum["GROSS"] = 1] = "GROSS";
2933
+ })(IncomeAmountTypeEnum || (IncomeAmountTypeEnum = {}));
2735
2934
 
2736
2935
  // @TODO refactor with baseModel in constructor
2737
2936
  class Transaction extends Transaction$1 {
@@ -2939,613 +3138,543 @@ __decorate([
2939
3138
  Type(() => TransactionAllocation)
2940
3139
  ], Transaction.prototype, "allocations", void 0);
2941
3140
 
2942
- const WEEKS_IN_YEAR = 52;
2943
- class VehicleClaim extends VehicleClaim$1 {
3141
+ class BankTransaction extends BankTransaction$1 {
2944
3142
  constructor() {
2945
3143
  super(...arguments);
2946
- // limit for kms claim method
2947
- this.kmsLimit = 5000;
2948
- this.financialYear = new FinancialYear().year;
2949
- this.method = VehicleClaimMethodEnum.KMS;
2950
- this.kilometers = 0;
2951
- this.workUsage = 0;
2952
- this.isManual = true;
3144
+ // allocated money amount for bank transaction
3145
+ this.allocatedAmount = 0;
3146
+ this.unallocatedAmount = 0;
2953
3147
  }
2954
3148
  /**
2955
- * get amount of kilometres per week
3149
+ * get allocated amount value but with +/- sign
2956
3150
  */
2957
- get averageWeeklyTraveledKms() {
2958
- return this.kilometers / WEEKS_IN_YEAR;
2959
- }
2960
- isLogbookMethod() {
2961
- return this.method === VehicleClaimMethodEnum.LOGBOOK;
2962
- }
2963
- isKLMsMethod() {
2964
- return this.method === VehicleClaimMethodEnum.KMS;
2965
- }
2966
- isWorkTank() {
2967
- return !this.business;
2968
- }
2969
- isSoleTank() {
2970
- return !!this.business;
2971
- }
2972
- get tankType() {
2973
- return this.isSoleTank() ? TankTypeEnum.SOLE : TankTypeEnum.WORK;
3151
+ get balanceAmount() {
3152
+ return this.isCredit() ? this.allocatedAmount : -this.allocatedAmount;
2974
3153
  }
2975
3154
  /**
2976
- * Claim amount for KLMs method. Exists only for KLMs method.
3155
+ * check if bank transaction is debit
2977
3156
  */
2978
- getKLMsClaimAmount(vehicleClaimRate) {
2979
- if (!this.isKLMsMethod()) {
2980
- return 0;
2981
- }
2982
- return +(this.kilometers * vehicleClaimRate).toFixed(2);
3157
+ isDebit() {
3158
+ return this.type === BankTransactionTypeEnum.DEBIT;
2983
3159
  }
2984
3160
  /**
2985
- * Get logbook claim amount. Exists only for logbook method.
2986
- * ClaimAmount = WorkUsage * transaction/depreciation amount
3161
+ * check if bank transaction is credit
2987
3162
  */
2988
- getLogbookClaimAmount(transactions) {
2989
- if (!this.isLogbookMethod()) {
2990
- return 0;
2991
- }
2992
- const transactionsAmount = transactions
2993
- .getByTankType(this.tankType)
2994
- .getVehicleTransactions()
2995
- // except klms transactions because they needed only for klms method
2996
- .filter((transaction) => !transaction.chartAccounts.isKLMsByTankType(this.tankType))
2997
- .sumBy('amount');
2998
- // Math.abs because amount will be negative (because we sum expenses), but we don't want negative percent value
2999
- return Math.abs(transactionsAmount) * this.workUsage / 100;
3163
+ isCredit() {
3164
+ return this.type === BankTransactionTypeEnum.CREDIT;
3000
3165
  }
3001
3166
  /**
3002
- * Create KLMs transaction based on vehicle claim and vehicle claim rate
3003
- * @TODO handle on backend: Create klms transaction when vhicle claim created
3167
+ * Create Transaction instance based on Bank Transaction
3004
3168
  */
3005
- toTransaction(vehicleClaimRate) {
3169
+ toTransaction() {
3006
3170
  return plainToClass(Transaction, {
3007
- amount: this.kilometers * vehicleClaimRate,
3008
- source: TransactionSourceEnum.CASH,
3009
- type: TransactionTypeEnum.DEBIT,
3010
- taxWithheld: 0,
3011
- description: 'Klm’s method',
3012
- date: new Date(`${new FinancialYear().year}-06-30`),
3013
- claimPercent: 100,
3014
- chartAccounts: {
3015
- id: this.getKlmsChartAccountsIdByTankType(this.tankType)
3016
- }
3171
+ amount: +this.amount.toFixed(2),
3172
+ description: this.description,
3173
+ date: this.date,
3174
+ source: TransactionSourceEnum.BANK_TRANSACTION,
3175
+ operation: this.operation,
3176
+ type: this.type,
3017
3177
  });
3018
3178
  }
3019
- getKlmsChartAccountsIdByTankType(tankType = this.tankType) {
3020
- if (tankType === TankTypeEnum.WORK) {
3021
- return ChartAccountsListEnum.KLMS_TRAVELLED_FOR_WORK;
3022
- }
3023
- return ChartAccountsListEnum.KLMS_TRAVELLED;
3179
+ /**
3180
+ * Check if bank transaction is completely allocated
3181
+ */
3182
+ isAllocated(allocations) {
3183
+ return this.amount === this.getAllocatedAmount(allocations);
3024
3184
  }
3025
- }
3026
-
3027
- class SoleBusiness extends SoleBusiness$1 {
3028
- getPhotoPlaceholder() {
3029
- return `${this.name[0]}${this.name[1]}`;
3185
+ /**
3186
+ * Get bank transaction allocated amount
3187
+ */
3188
+ getAllocatedAmount(allocations) {
3189
+ return allocations.getByBankTransactionsIds([this.id]).amount;
3030
3190
  }
3031
- getPhoto() {
3032
- return this.logo;
3191
+ /**
3192
+ * Get bank transaction unallocated amount
3193
+ */
3194
+ getUnallocatedAmount(allocations) {
3195
+ return this.amount - this.getAllocatedAmount(allocations);
3033
3196
  }
3034
3197
  }
3035
3198
  __decorate([
3036
- Type(() => User)
3037
- ], SoleBusiness.prototype, "user", void 0);
3038
- __decorate([
3039
- Type(() => SoleBusinessAllocation)
3040
- ], SoleBusiness.prototype, "allocations", void 0);
3041
- __decorate([
3042
- Type(() => SoleBusinessLoss)
3043
- ], SoleBusiness.prototype, "losses", void 0);
3044
- __decorate([
3045
- Type(() => SoleInvoice)
3046
- ], SoleBusiness.prototype, "invoices", void 0);
3047
- __decorate([
3048
- Type(() => SoleInvoiceTemplate)
3049
- ], SoleBusiness.prototype, "invoiceTemplates", void 0);
3050
- __decorate([
3051
- Type(() => VehicleClaim)
3052
- ], SoleBusiness.prototype, "vehicleClaims", void 0);
3053
- __decorate([
3054
- Type(() => Transaction)
3055
- ], SoleBusiness.prototype, "transactions", void 0);
3056
- __decorate([
3057
- Type(() => Depreciation)
3058
- ], SoleBusiness.prototype, "depreciations", void 0);
3059
-
3060
- class SoleDetails$1 extends AbstractModel {
3061
- }
3062
-
3063
- class SoleDetails extends SoleDetails$1 {
3064
- }
3065
- __decorate([
3066
- Type(() => User)
3067
- ], SoleDetails.prototype, "user", void 0);
3199
+ Type(() => Date)
3200
+ ], BankTransaction.prototype, "date", void 0);
3068
3201
 
3069
- class User extends User$1 {
3070
- get fullName() {
3071
- return `${this.firstName} ${this.lastName}`;
3202
+ class Depreciation extends Depreciation$1 {
3203
+ constructor() {
3204
+ super(...arguments);
3205
+ this.forecasts = [];
3206
+ this.type = DepreciationTypeEnum.PLANT_EQUIPMENT;
3207
+ /**
3208
+ * @TODO remove after ? signs removed from db models
3209
+ */
3210
+ this.amount = 0;
3072
3211
  }
3073
- get activeSubscription() {
3074
- return this.subscriptions.find((ss) => ss.isActive);
3212
+ isCapital() {
3213
+ return this.type === DepreciationTypeEnum.CAPITAL_WORKS;
3075
3214
  }
3076
- get lastSubscription() {
3077
- return this.subscriptions[this.subscriptions.length - 1];
3215
+ isBorrowingExpense() {
3216
+ return this.type === DepreciationTypeEnum.BORROWING_EXPENSES;
3217
+ }
3218
+ isAsset() {
3219
+ return this.type === DepreciationTypeEnum.PLANT_EQUIPMENT;
3078
3220
  }
3079
3221
  /**
3080
- * @TODO refactor
3081
- *
3222
+ * check if depreciation should be displayed in written off category
3223
+ * details in project documentation
3224
+ * @TODO new FinancialYear(this.writeOffDate) === new FinancialYear()
3082
3225
  */
3083
- get position() {
3084
- switch (true) {
3085
- case this.isFirmOwner():
3086
- return USER_WORK_POSITION[UserRolesEnum.FIRM_OWNER];
3087
- case this.isManager():
3088
- return USER_WORK_POSITION[UserRolesEnum.FIRM_MANAGER];
3089
- case this.isEmployee():
3090
- return USER_WORK_POSITION[UserRolesEnum.EMPLOYEE];
3091
- default:
3092
- return '';
3093
- }
3094
- }
3095
- hasRole(role) {
3096
- return this.roles.includes(role);
3097
- }
3098
- isOnboarding() {
3099
- return this.status === UserStatusEnum.ON_BOARDING;
3100
- }
3101
- hasSubscription() {
3102
- return this.roles.includes(UserRolesEnum.SUBSCRIPTION);
3103
- }
3104
- isLoggedIn() {
3105
- return this.id === +localStorage.getItem('userId');
3106
- }
3107
- isClient() {
3108
- return this.roles.includes(UserRolesEnum.CLIENT);
3109
- }
3110
- isEmployee() {
3111
- return this.isAccountant() || this.isAdvisor();
3226
+ isWrittenOff() {
3227
+ return this.isAsset && this.writeOffDate && new FinancialYear(this.writeOffDate).year === this.financialYear;
3112
3228
  }
3113
- isAccountant() {
3114
- return this.roles.includes(UserRolesEnum.ACCOUNTANT);
3229
+ /**
3230
+ * Check if depreciation is Plant & Equipment
3231
+ */
3232
+ isPlantEquipment() {
3233
+ return this.isAsset() && !this.isWrittenOff() && !this.isLowValuePool();
3115
3234
  }
3116
- isAdvisor() {
3117
- return this.roles.includes(UserRolesEnum.ADVISOR);
3235
+ /**
3236
+ * check if depreciation should be displayed in low value pool
3237
+ * details in project documentation
3238
+ * @TODO new FinancialYear(this.writeOffDate) === new FinancialYear()
3239
+ */
3240
+ isLowValuePool() {
3241
+ return this.isAsset &&
3242
+ this.calculation === DepreciationCalculationEnum.DIMINISHING &&
3243
+ this.amount > Depreciation.WRITTEN_OFF_THRESHOLD &&
3244
+ this.amount <= Depreciation.LOW_VALUE_POOL_THRESHOLD;
3118
3245
  }
3119
- isImpersonator() {
3120
- return this.roles.includes(UserRolesEnum.SWITCH_USER);
3246
+ isPrimeCost() {
3247
+ return this.calculation === DepreciationCalculationEnum.PRIME_COST;
3121
3248
  }
3122
- /**
3123
- * Check if current user is firm owner
3124
- */
3125
- isFirmOwner() {
3126
- return this.roles.includes(UserRolesEnum.FIRM_OWNER);
3249
+ isDiminishing() {
3250
+ return this.calculation === DepreciationCalculationEnum.DIMINISHING;
3127
3251
  }
3128
3252
  /**
3129
- * Check if current user is firm manager
3253
+ * Check if depreciation chart accounts heading related to vehicles category
3130
3254
  */
3131
- isManager() {
3132
- return this.roles.includes(UserRolesEnum.FIRM_MANAGER) || this.roles.includes(UserRolesEnum.FIRM_OWNER);
3255
+ isVehicleDepreciation() {
3256
+ var _a;
3257
+ return ((_a = this.chartAccounts.heading) === null || _a === void 0 ? void 0 : _a.id) === ChartAccountsHeadingVehicleListEnum.DEPRECIATION_VEHICLES;
3133
3258
  }
3134
3259
  /**
3135
- * check if user has property tank access
3260
+ * Get depreciation purchase date
3136
3261
  */
3137
- hasPropertyTank() {
3138
- return this.roles ?
3139
- this.roles.includes(UserRolesEnum.PROPERTY_TANK) :
3140
- !!this.getSubscriptionRole(UserRolesEnum.PROPERTY_TANK);
3262
+ getDate() {
3263
+ return this.date;
3141
3264
  }
3142
3265
  /**
3143
- * check if user has property tank access
3266
+ * @TODO Vik: Research a problem with depreciations without current year forecast
3144
3267
  */
3145
- hasWorkTank() {
3146
- return this.roles ?
3147
- this.roles.includes(UserRolesEnum.WORK_TANK) :
3148
- !!this.getSubscriptionRole(UserRolesEnum.WORK_TANK);
3268
+ get currentYearForecast() {
3269
+ return this.forecasts.find((forecast) => {
3270
+ return forecast.financialYear === new FinancialYear().year;
3271
+ }) || plainToClass(DepreciationForecast, {
3272
+ financialYear: new FinancialYear().year,
3273
+ openBalance: 0,
3274
+ closeBalance: 0,
3275
+ amount: 0,
3276
+ claimPercent: 0
3277
+ });
3149
3278
  }
3150
- /**
3151
- * Get user subscription role by provided role type
3152
- * @param roleType by which role should be returned
3153
- */
3154
- getSubscriptionRole(roleType) {
3279
+ getForecastByYear(year) {
3280
+ return this.forecasts.find((forecast) => {
3281
+ return forecast.financialYear === year;
3282
+ });
3283
+ }
3284
+ getClaimAmountByYear(year) {
3155
3285
  var _a;
3156
- /**
3157
- * Add @TODO for Alex to check if we should use getLastSubscription here
3158
- */
3159
- return (_a = this.activeSubscription) === null || _a === void 0 ? void 0 : _a.items.find((subscriptionItem) => subscriptionItem.price.product.role.includes(roleType));
3286
+ return ((_a = this.getForecastByYear(year)) === null || _a === void 0 ? void 0 : _a.claimAmount) || 0;
3287
+ }
3288
+ getCloseBalanceByYear(year) {
3289
+ var _a;
3290
+ return ((_a = this.getForecastByYear(year)) === null || _a === void 0 ? void 0 : _a.closeBalance) || 0;
3291
+ }
3292
+ isBuildingAtCost() {
3293
+ return this.chartAccounts.id === ChartAccountsListEnum.BUILDING_AT_COST;
3160
3294
  }
3161
3295
  /**
3162
- * Get user's photo link
3296
+ * Create a new transaction from current depreciation
3163
3297
  */
3164
- getPhoto() {
3165
- return this.photo;
3298
+ toTransaction(params = {}) {
3299
+ return plainToClass(Transaction, Object.assign(params, this, { amount: this.currentYearForecast.amount }));
3166
3300
  }
3167
3301
  /**
3168
- * get user's initials
3302
+ * @TODO Michael: remove and check everywhere in reports
3169
3303
  */
3170
- getPhotoPlaceholder() {
3171
- return `${this.firstName[0].toUpperCase()}${this.lastName[0].toUpperCase()}`;
3304
+ get claimAmount() {
3305
+ var _a;
3306
+ return ((_a = this.currentYearForecast) === null || _a === void 0 ? void 0 : _a.claimAmount) || 0;
3172
3307
  }
3173
3308
  }
3309
+ Depreciation.WRITTEN_OFF_THRESHOLD = 300;
3310
+ Depreciation.LOW_VALUE_POOL_THRESHOLD = 1000;
3174
3311
  __decorate([
3175
- Type(() => ServiceSubscription)
3176
- ], User.prototype, "subscriptions", void 0);
3177
- __decorate([
3178
- Type(() => ClientDetails)
3179
- ], User.prototype, "clientDetails", void 0);
3180
- __decorate([
3181
- Type(() => EmployeeDetails)
3182
- ], User.prototype, "employeeDetails", void 0);
3183
- __decorate([
3184
- Type(() => SoleDetails)
3185
- ], User.prototype, "soleDetails", void 0);
3186
- __decorate([
3187
- Type(() => Address)
3188
- ], User.prototype, "address", void 0);
3312
+ Type(() => Date)
3313
+ ], Depreciation.prototype, "purchaseDate", void 0);
3189
3314
  __decorate([
3190
- Type(() => Phone)
3191
- ], User.prototype, "phone", void 0);
3315
+ Type(() => Date)
3316
+ ], Depreciation.prototype, "date", void 0);
3192
3317
  __decorate([
3193
3318
  Type(() => Date)
3194
- ], User.prototype, "createdAt", void 0);
3319
+ ], Depreciation.prototype, "lowValuePoolDate", void 0);
3195
3320
  __decorate([
3196
- Type(() => User)
3197
- ], User.prototype, "clients", void 0);
3198
-
3199
- class PropertySubscription extends PropertySubscription$1 {
3200
- }
3321
+ Type(() => Date)
3322
+ ], Depreciation.prototype, "writeOffManualDate", void 0);
3201
3323
  __decorate([
3202
3324
  Type(() => Date)
3203
- ], PropertySubscription.prototype, "createdAt", void 0);
3325
+ ], Depreciation.prototype, "writeOffDate", void 0);
3204
3326
  __decorate([
3205
- Type(() => User)
3206
- ], PropertySubscription.prototype, "user", void 0);
3207
-
3208
- class PropertyCategory$1 extends AbstractModel {
3209
- }
3210
-
3211
- class PropertyCategory extends PropertyCategory$1 {
3212
- // @Todo check if category is Owner Occupied. If will be needed to check more categories - move the checking to the backend
3213
- isOwnerOccupied() {
3214
- return this.name === 'Owner Occupied';
3215
- }
3216
- isVacantLand() {
3217
- return this.name === 'Vacant Land';
3218
- }
3219
- }
3220
-
3221
- class PropertyValuation$1 extends AbstractModel {
3222
- }
3223
-
3224
- class PropertyDocument$1 extends AbstractModel {
3225
- getApiUrlPrefix() {
3226
- return '';
3227
- }
3228
- getEntity() {
3229
- return undefined;
3230
- }
3231
- }
3232
-
3233
- class PropertyDocument extends PropertyDocument$1 {
3234
- constructor() {
3235
- super(...arguments);
3236
- this.type = AssetTypeEnum.DOCUMENTS;
3237
- this.entityType = AssetEntityTypeEnum.PROPERTIES;
3238
- }
3239
- getApiUrlPrefix() {
3240
- return '';
3241
- }
3242
- getEntity() {
3243
- return this.property;
3244
- }
3245
- }
3246
-
3247
- class PropertyValuation extends PropertyValuation$1 {
3248
- get financialYear() {
3249
- return new FinancialYear(this.date).year;
3250
- }
3251
- isCurrentYear() {
3252
- return this.financialYear === new FinancialYear(new Date()).year;
3253
- }
3254
- }
3327
+ Type(() => DepreciationCapitalProject)
3328
+ ], Depreciation.prototype, "depreciationCapitalProject", void 0);
3255
3329
  __decorate([
3256
- Type(() => Date)
3257
- ], PropertyValuation.prototype, "date", void 0);
3330
+ Type(() => DepreciationForecast),
3331
+ Transform(({ value, obj }) => {
3332
+ // value = array of DepreciationForecast
3333
+ // obj = plain (whole Depreciation object)
3334
+ // Set isLVP flag for each DepreciationForecast
3335
+ // @TODO refactor
3336
+ value.forEach((forecast) => {
3337
+ forecast.isLVP =
3338
+ forecast.closeBalance < 1000 &&
3339
+ obj.calculation === DepreciationCalculationEnum.DIMINISHING &&
3340
+ obj.type === DepreciationTypeEnum.PLANT_EQUIPMENT &&
3341
+ !(obj.amount > Depreciation.WRITTEN_OFF_THRESHOLD && obj.amount < Depreciation.LOW_VALUE_POOL_THRESHOLD) &&
3342
+ !(obj.writeOffDate && new FinancialYear(new Date(obj.writeOffDate)).year === obj.financialYear);
3343
+ });
3344
+ return value;
3345
+ })
3346
+ ], Depreciation.prototype, "forecasts", void 0);
3258
3347
  __decorate([
3259
- Type(() => PropertyDocument)
3260
- ], PropertyValuation.prototype, "document", void 0);
3348
+ Type(() => ChartAccounts)
3349
+ ], Depreciation.prototype, "chartAccounts", void 0);
3261
3350
  __decorate([
3262
- Exclude()
3263
- ], PropertyValuation.prototype, "documentFile", void 0);
3264
-
3265
- class PropertyForecast$1 extends AbstractModel {
3266
- }
3351
+ Type(() => BankTransaction)
3352
+ ], Depreciation.prototype, "bankTransaction", void 0);
3267
3353
 
3268
- class PropertyForecast extends PropertyForecast$1 {
3269
- /**
3270
- * Get cash position
3271
- * Cash Position = Income - Expense - Interest
3272
- */
3273
- get cashPosition() {
3274
- return this.income + this.expense + this.interest;
3275
- }
3276
- /**
3277
- * Get tax position
3278
- * Tax Position = Income - Expense - Interest - Depreciation
3279
- */
3280
- get taxPosition() {
3281
- return this.cashPosition + this.depreciation;
3282
- }
3283
- /**
3284
- * Get rental return percent
3285
- * Rental Return = Income / Market Value
3286
- */
3287
- get rentalReturn() {
3288
- return this.income / this.marketValue;
3354
+ class SoleBusiness extends SoleBusiness$1 {
3355
+ getPhotoPlaceholder() {
3356
+ return `${this.name[0]}${this.name[1]}`;
3289
3357
  }
3290
- /**
3291
- * Check if forecast is for real current fin year (not selected in the sidebar)
3292
- */
3293
- isCurrentYear() {
3294
- return this.financialYear === new FinancialYear(new Date()).year;
3358
+ getPhoto() {
3359
+ return this.logo;
3295
3360
  }
3296
3361
  }
3297
3362
  __decorate([
3298
- Transform(({ value }) => +value)
3299
- ], PropertyForecast.prototype, "income", void 0);
3300
- __decorate([
3301
- Transform(({ value }) => -Math.abs(+value))
3302
- ], PropertyForecast.prototype, "expense", void 0);
3303
- __decorate([
3304
- Transform(({ value }) => -Math.abs(+value))
3305
- ], PropertyForecast.prototype, "interest", void 0);
3363
+ Type(() => User)
3364
+ ], SoleBusiness.prototype, "user", void 0);
3306
3365
  __decorate([
3307
- Transform(({ value }) => -Math.abs(+value))
3308
- ], PropertyForecast.prototype, "depreciation", void 0);
3366
+ Type(() => SoleBusinessAllocation)
3367
+ ], SoleBusiness.prototype, "allocations", void 0);
3309
3368
  __decorate([
3310
- Transform(({ value }) => +value)
3311
- ], PropertyForecast.prototype, "loanBalance", void 0);
3369
+ Type(() => SoleBusinessLoss)
3370
+ ], SoleBusiness.prototype, "losses", void 0);
3312
3371
  __decorate([
3313
- Transform(({ value }) => +value)
3314
- ], PropertyForecast.prototype, "marketValue", void 0);
3315
-
3316
- class PropertyCategoryMovement$1 extends AbstractModel {
3317
- }
3318
-
3319
- class PropertyCategoryMovement extends PropertyCategoryMovement$1 {
3320
- }
3372
+ Type(() => SoleInvoice)
3373
+ ], SoleBusiness.prototype, "invoices", void 0);
3321
3374
  __decorate([
3322
- Type(() => PropertyValuation)
3323
- ], PropertyCategoryMovement.prototype, "valuation", void 0);
3375
+ Type(() => SoleInvoiceTemplate)
3376
+ ], SoleBusiness.prototype, "invoiceTemplates", void 0);
3324
3377
  __decorate([
3325
- Type(() => PropertyCategory)
3326
- ], PropertyCategoryMovement.prototype, "propertyCategory", void 0);
3378
+ Type(() => VehicleClaim)
3379
+ ], SoleBusiness.prototype, "vehicleClaims", void 0);
3327
3380
  __decorate([
3328
- Type(() => Date)
3329
- ], PropertyCategoryMovement.prototype, "fromDate", void 0);
3381
+ Type(() => Transaction)
3382
+ ], SoleBusiness.prototype, "transactions", void 0);
3330
3383
  __decorate([
3331
- Type(() => Date)
3332
- ], PropertyCategoryMovement.prototype, "toDate", void 0);
3384
+ Type(() => Depreciation)
3385
+ ], SoleBusiness.prototype, "depreciations", void 0);
3333
3386
 
3334
- var TaxExemptionEnum;
3335
- (function (TaxExemptionEnum) {
3336
- TaxExemptionEnum[TaxExemptionEnum["ONE_YEAR_RULE"] = 1] = "ONE_YEAR_RULE";
3337
- // principle place of residence
3338
- TaxExemptionEnum[TaxExemptionEnum["PPR"] = 2] = "PPR";
3339
- TaxExemptionEnum[TaxExemptionEnum["SIX_YEARS_RULE"] = 3] = "SIX_YEARS_RULE";
3340
- TaxExemptionEnum[TaxExemptionEnum["INVESTMENT_TO_PPR"] = 4] = "INVESTMENT_TO_PPR";
3341
- TaxExemptionEnum[TaxExemptionEnum["PPR_TO_INVESTMENT"] = 5] = "PPR_TO_INVESTMENT";
3342
- TaxExemptionEnum[TaxExemptionEnum["TRANSFER"] = 6] = "TRANSFER";
3343
- TaxExemptionEnum[TaxExemptionEnum["OTHER"] = 7] = "OTHER";
3344
- })(TaxExemptionEnum || (TaxExemptionEnum = {}));
3387
+ class SoleDetails$1 extends AbstractModel {
3388
+ }
3345
3389
 
3346
- var PropertyCategoryListEnum;
3347
- (function (PropertyCategoryListEnum) {
3348
- PropertyCategoryListEnum[PropertyCategoryListEnum["OWNER_OCCUPIED"] = 3] = "OWNER_OCCUPIED";
3349
- PropertyCategoryListEnum[PropertyCategoryListEnum["VACANT_LAND"] = 5] = "VACANT_LAND";
3350
- })(PropertyCategoryListEnum || (PropertyCategoryListEnum = {}));
3390
+ class SoleDetails extends SoleDetails$1 {
3391
+ }
3392
+ __decorate([
3393
+ Type(() => User)
3394
+ ], SoleDetails.prototype, "user", void 0);
3351
3395
 
3352
- /**
3353
- * List of collections grouped by passed property
3354
- */
3355
- class CollectionDictionary {
3396
+ class User extends User$1 {
3397
+ get fullName() {
3398
+ return `${this.firstName} ${this.lastName}`;
3399
+ }
3400
+ get activeSubscription() {
3401
+ return this.subscriptions.find((ss) => ss.isActive);
3402
+ }
3403
+ get lastSubscription() {
3404
+ return this.subscriptions[this.subscriptions.length - 1];
3405
+ }
3356
3406
  /**
3357
- * @param collection The Collection instance to be grouped
3358
- * @param path Path to the property to be grouped (Examples: 'transaction', 'property.category')
3359
- * @param prop Optional: Field to group by (Default 'id', Examples: 'id', 'amount', 'date')
3407
+ * @TODO refactor
3408
+ *
3360
3409
  */
3361
- constructor(collection, path = 'id') {
3362
- /**
3363
- * List of grouped collections
3364
- */
3365
- this.items = {};
3366
- this.collectionConstructor = collection.constructor;
3367
- // Nothing to group when collection is empty
3368
- if (!collection.length) {
3369
- return;
3370
- }
3371
- // Do nothing if provided path was not found in the 1st collection's item
3372
- if (!hasIn(collection.items[0], path.split('.')[0])) {
3373
- return;
3410
+ get position() {
3411
+ switch (true) {
3412
+ case this.isFirmOwner():
3413
+ return USER_WORK_POSITION[UserRolesEnum.FIRM_OWNER];
3414
+ case this.isManager():
3415
+ return USER_WORK_POSITION[UserRolesEnum.FIRM_MANAGER];
3416
+ case this.isEmployee():
3417
+ return USER_WORK_POSITION[UserRolesEnum.EMPLOYEE];
3418
+ default:
3419
+ return '';
3374
3420
  }
3375
- this.groupItems(collection, path);
3376
3421
  }
3377
- /**
3378
- * List of collections keys
3379
- */
3380
- get keys() {
3381
- return Object.keys(this.items);
3422
+ hasRole(role) {
3423
+ return this.roles.includes(role);
3382
3424
  }
3383
- /**
3384
- * Get collection by key or return empty collection if key does not exist
3385
- */
3386
- get(key) {
3387
- return this.items[key] ? this.items[key] : this.createCollection([]);
3425
+ isOnboarding() {
3426
+ return this.status === UserStatusEnum.ON_BOARDING;
3427
+ }
3428
+ hasSubscription() {
3429
+ return this.roles.includes(UserRolesEnum.SUBSCRIPTION);
3430
+ }
3431
+ isLoggedIn() {
3432
+ return this.id === +localStorage.getItem('userId');
3433
+ }
3434
+ isClient() {
3435
+ return this.roles.includes(UserRolesEnum.CLIENT);
3436
+ }
3437
+ isEmployee() {
3438
+ return this.isAccountant() || this.isAdvisor();
3439
+ }
3440
+ isAccountant() {
3441
+ return this.roles.includes(UserRolesEnum.ACCOUNTANT);
3442
+ }
3443
+ isAdvisor() {
3444
+ return this.roles.includes(UserRolesEnum.ADVISOR);
3445
+ }
3446
+ isImpersonator() {
3447
+ return this.roles.includes(UserRolesEnum.SWITCH_USER);
3388
3448
  }
3389
3449
  /**
3390
- * Add new item by key
3450
+ * Check if current user is firm owner
3391
3451
  */
3392
- add(key, value) {
3393
- this.items[key] = value;
3452
+ isFirmOwner() {
3453
+ return this.roles.includes(UserRolesEnum.FIRM_OWNER);
3394
3454
  }
3395
3455
  /**
3396
- * Join several collections by ids
3456
+ * Check if current user is firm manager
3397
3457
  */
3398
- merge(keys) {
3399
- return this.createCollection(flatten(keys.map((id) => this.get(id.toString()).items)));
3458
+ isManager() {
3459
+ return this.roles.includes(UserRolesEnum.FIRM_MANAGER) || this.roles.includes(UserRolesEnum.FIRM_OWNER);
3400
3460
  }
3401
3461
  /**
3402
- * Create instance of collection
3462
+ * check if user has property tank access
3403
3463
  */
3404
- createCollection(items = []) {
3405
- return new this.collectionConstructor(items);
3406
- }
3407
- get length() {
3408
- return this.keys.length;
3464
+ hasPropertyTank() {
3465
+ return this.roles ?
3466
+ this.roles.includes(UserRolesEnum.PROPERTY_TANK) :
3467
+ !!this.getSubscriptionRole(UserRolesEnum.PROPERTY_TANK);
3409
3468
  }
3410
3469
  /**
3411
- * @Todo find a better solution to get list of the sorted keys
3412
- * Get array of the "keys" by provided order
3470
+ * check if user has property tank access
3413
3471
  */
3414
- getSortedKeys(isDesc = false) {
3415
- return this.keys.sort((a, b) => {
3416
- if (a > b) {
3417
- return !isDesc ? 1 : -1;
3418
- }
3419
- if (a < b) {
3420
- return !isDesc ? -1 : 1;
3421
- }
3422
- return 0;
3423
- });
3472
+ hasWorkTank() {
3473
+ return this.roles ?
3474
+ this.roles.includes(UserRolesEnum.WORK_TANK) :
3475
+ !!this.getSubscriptionRole(UserRolesEnum.WORK_TANK);
3424
3476
  }
3425
3477
  /**
3426
- * Group collection items by passed path into items object
3478
+ * Get user subscription role by provided role type
3479
+ * @param roleType by which role should be returned
3427
3480
  */
3428
- groupItems(collection, path) {
3429
- // Create empty initial object for groups
3430
- const obj = {};
3431
- // Group collection items
3432
- collection.items.forEach((item) => {
3433
- let key = get(item, path);
3434
- // if object does not have property for grouping it will be grouped as 'other'
3435
- if (key === undefined) {
3436
- key = 'other';
3437
- }
3438
- if (!obj[key]) {
3439
- obj[key] = [];
3440
- }
3441
- obj[key].push(item);
3442
- });
3443
- // Create collections from groups
3444
- Object.keys(obj).forEach((key) => {
3445
- this.items[key] = this.createCollection(obj[key]);
3446
- });
3447
- }
3448
- }
3449
-
3450
- const DEFAULT_INDEX = 'other';
3451
- /**
3452
- * Base collection class. Contains common properties and methods for all collections
3453
- */
3454
- class Collection {
3455
- constructor(items = []) {
3456
- this.items = items;
3481
+ getSubscriptionRole(roleType) {
3482
+ var _a;
3483
+ /**
3484
+ * Add @TODO for Alex to check if we should use getLastSubscription here
3485
+ */
3486
+ return (_a = this.activeSubscription) === null || _a === void 0 ? void 0 : _a.items.find((subscriptionItem) => subscriptionItem.price.product.role.includes(roleType));
3457
3487
  }
3458
3488
  /**
3459
- * Iterator that allow to iterate collection items
3489
+ * Get user's photo link
3460
3490
  */
3461
- [Symbol.iterator]() {
3462
- return this.items.values();
3463
- }
3464
- create(items = []) {
3465
- return new this.constructor(items);
3466
- }
3467
- get length() {
3468
- return this.items.length;
3469
- }
3470
- toArray() {
3471
- return [...this.items];
3472
- }
3473
- get first() {
3474
- return first(this.items);
3475
- }
3476
- get last() {
3477
- return last(this.items);
3478
- }
3479
- getIds() {
3480
- return this.items.map((item) => item['id']);
3481
- }
3482
- mapBy(path) {
3483
- return this.items.map((item) => get(item, path));
3484
- }
3485
- sortBy(field = 'id', isDesc = true) {
3486
- sort(this.items, field, isDesc);
3487
- return this;
3491
+ getPhoto() {
3492
+ return this.photo;
3488
3493
  }
3489
3494
  /**
3490
- * Get total sum of items by field
3495
+ * get user's initials
3491
3496
  */
3492
- sumBy(path) {
3493
- return +this.items.reduce((sum, item) => sum + Number(get(item, path)), 0).toFixed(2);
3494
- }
3495
- groupBy(path = '') {
3496
- return new CollectionDictionary(this, path);
3497
+ getPhotoPlaceholder() {
3498
+ return `${this.firstName[0].toUpperCase()}${this.lastName[0].toUpperCase()}`;
3497
3499
  }
3498
- indexBy(path) {
3499
- // Create empty initial object for groups
3500
- const result = {};
3501
- this.toArray().forEach((model) => {
3502
- result[get(model, path, DEFAULT_INDEX)] = model;
3503
- });
3504
- return result;
3500
+ }
3501
+ __decorate([
3502
+ Type(() => ServiceSubscription)
3503
+ ], User.prototype, "subscriptions", void 0);
3504
+ __decorate([
3505
+ Type(() => ClientDetails)
3506
+ ], User.prototype, "clientDetails", void 0);
3507
+ __decorate([
3508
+ Type(() => EmployeeDetails)
3509
+ ], User.prototype, "employeeDetails", void 0);
3510
+ __decorate([
3511
+ Type(() => SoleDetails)
3512
+ ], User.prototype, "soleDetails", void 0);
3513
+ __decorate([
3514
+ Type(() => Address)
3515
+ ], User.prototype, "address", void 0);
3516
+ __decorate([
3517
+ Type(() => Phone)
3518
+ ], User.prototype, "phone", void 0);
3519
+ __decorate([
3520
+ Type(() => Date)
3521
+ ], User.prototype, "createdAt", void 0);
3522
+ __decorate([
3523
+ Type(() => User)
3524
+ ], User.prototype, "clients", void 0);
3525
+
3526
+ class PropertySubscription extends PropertySubscription$1 {
3527
+ }
3528
+ __decorate([
3529
+ Type(() => Date)
3530
+ ], PropertySubscription.prototype, "createdAt", void 0);
3531
+ __decorate([
3532
+ Type(() => User)
3533
+ ], PropertySubscription.prototype, "user", void 0);
3534
+
3535
+ class PropertyCategory$1 extends AbstractModel {
3536
+ }
3537
+
3538
+ class PropertyCategory extends PropertyCategory$1 {
3539
+ // @Todo check if category is Owner Occupied. If will be needed to check more categories - move the checking to the backend
3540
+ isOwnerOccupied() {
3541
+ return this.name === 'Owner Occupied';
3505
3542
  }
3506
- filter(callback) {
3507
- return this.create(this.items.filter(callback));
3543
+ isVacantLand() {
3544
+ return this.name === 'Vacant Land';
3508
3545
  }
3509
- filterBy(path, values) {
3510
- return this.filter((item) => (Array.isArray(values) ? values : [values]).includes(get(item, path)));
3546
+ }
3547
+
3548
+ class PropertyValuation$1 extends AbstractModel {
3549
+ }
3550
+
3551
+ class PropertyDocument$1 extends AbstractModel {
3552
+ getApiUrlPrefix() {
3553
+ return '';
3511
3554
  }
3512
- filterByRange(path, from, to) {
3513
- return this.filter((item) => get(item, path) >= from && get(item, path) <= to);
3555
+ getEntity() {
3556
+ return undefined;
3514
3557
  }
3515
- find(callback) {
3516
- return this.items.find(callback);
3558
+ }
3559
+
3560
+ class PropertyDocument extends PropertyDocument$1 {
3561
+ constructor() {
3562
+ super(...arguments);
3563
+ this.type = AssetTypeEnum.DOCUMENTS;
3564
+ this.entityType = AssetEntityTypeEnum.PROPERTIES;
3517
3565
  }
3518
- findBy(path, value) {
3519
- return this.items.find((model) => value === get(model, path));
3566
+ getApiUrlPrefix() {
3567
+ return '';
3520
3568
  }
3521
- findIndexBy(path, value) {
3522
- var _a;
3523
- return (_a = this.items.findIndex((item) => get(item, path) === value)) !== null && _a !== void 0 ? _a : null;
3569
+ getEntity() {
3570
+ return this.property;
3524
3571
  }
3525
- push(...items) {
3526
- this.items.push(...items);
3527
- return this.create(this.items);
3572
+ }
3573
+
3574
+ class PropertyValuation extends PropertyValuation$1 {
3575
+ get financialYear() {
3576
+ return new FinancialYear(this.date).year;
3528
3577
  }
3529
- replaceBy(path, value, item) {
3530
- const index = this.findIndexBy(path, value);
3531
- if (index >= 0) {
3532
- this.items.splice(index, 1, item);
3533
- }
3534
- return this;
3578
+ isCurrentYear() {
3579
+ return this.financialYear === new FinancialYear(new Date()).year;
3535
3580
  }
3536
- remove(items) {
3537
- return this.filter((model) => !items.map((item) => item.id).includes(model.id));
3581
+ }
3582
+ __decorate([
3583
+ Type(() => Date)
3584
+ ], PropertyValuation.prototype, "date", void 0);
3585
+ __decorate([
3586
+ Type(() => PropertyDocument)
3587
+ ], PropertyValuation.prototype, "document", void 0);
3588
+ __decorate([
3589
+ Exclude()
3590
+ ], PropertyValuation.prototype, "documentFile", void 0);
3591
+
3592
+ class PropertyForecast$1 extends AbstractModel {
3593
+ }
3594
+
3595
+ class PropertyForecast extends PropertyForecast$1 {
3596
+ /**
3597
+ * Get cash position
3598
+ * Cash Position = Income - Expense - Interest
3599
+ */
3600
+ get cashPosition() {
3601
+ return this.income + this.expense + this.interest;
3538
3602
  }
3539
- removeBy(path, values) {
3540
- return this.filter((item) => !(Array.isArray(values) ? values : [values]).includes(get(item, path)));
3603
+ /**
3604
+ * Get tax position
3605
+ * Tax Position = Income - Expense - Interest - Depreciation
3606
+ */
3607
+ get taxPosition() {
3608
+ return this.cashPosition + this.depreciation;
3541
3609
  }
3542
- minBy(path) {
3543
- return this.items.reduce((prev, current) => (get(prev, path) < get(current, path) ? prev : current));
3610
+ /**
3611
+ * Get rental return percent
3612
+ * Rental Return = Income / Market Value
3613
+ */
3614
+ get rentalReturn() {
3615
+ return this.income / this.marketValue;
3544
3616
  }
3545
- maxBy(path) {
3546
- return this.items.reduce((prev, current) => (get(prev, path) > get(current, path) ? prev : current));
3617
+ /**
3618
+ * Check if forecast is for real current fin year (not selected in the sidebar)
3619
+ */
3620
+ isCurrentYear() {
3621
+ return this.financialYear === new FinancialYear(new Date()).year;
3547
3622
  }
3548
3623
  }
3624
+ __decorate([
3625
+ Transform(({ value }) => +value)
3626
+ ], PropertyForecast.prototype, "income", void 0);
3627
+ __decorate([
3628
+ Transform(({ value }) => -Math.abs(+value))
3629
+ ], PropertyForecast.prototype, "expense", void 0);
3630
+ __decorate([
3631
+ Transform(({ value }) => -Math.abs(+value))
3632
+ ], PropertyForecast.prototype, "interest", void 0);
3633
+ __decorate([
3634
+ Transform(({ value }) => -Math.abs(+value))
3635
+ ], PropertyForecast.prototype, "depreciation", void 0);
3636
+ __decorate([
3637
+ Transform(({ value }) => +value)
3638
+ ], PropertyForecast.prototype, "loanBalance", void 0);
3639
+ __decorate([
3640
+ Transform(({ value }) => +value)
3641
+ ], PropertyForecast.prototype, "marketValue", void 0);
3642
+
3643
+ class PropertyCategoryMovement$1 extends AbstractModel {
3644
+ }
3645
+
3646
+ class PropertyCategoryMovement extends PropertyCategoryMovement$1 {
3647
+ }
3648
+ __decorate([
3649
+ Type(() => PropertyValuation)
3650
+ ], PropertyCategoryMovement.prototype, "valuation", void 0);
3651
+ __decorate([
3652
+ Type(() => PropertyCategory)
3653
+ ], PropertyCategoryMovement.prototype, "propertyCategory", void 0);
3654
+ __decorate([
3655
+ Type(() => Date)
3656
+ ], PropertyCategoryMovement.prototype, "fromDate", void 0);
3657
+ __decorate([
3658
+ Type(() => Date)
3659
+ ], PropertyCategoryMovement.prototype, "toDate", void 0);
3660
+
3661
+ var TaxExemptionEnum;
3662
+ (function (TaxExemptionEnum) {
3663
+ TaxExemptionEnum[TaxExemptionEnum["ONE_YEAR_RULE"] = 1] = "ONE_YEAR_RULE";
3664
+ // principle place of residence
3665
+ TaxExemptionEnum[TaxExemptionEnum["PPR"] = 2] = "PPR";
3666
+ TaxExemptionEnum[TaxExemptionEnum["SIX_YEARS_RULE"] = 3] = "SIX_YEARS_RULE";
3667
+ TaxExemptionEnum[TaxExemptionEnum["INVESTMENT_TO_PPR"] = 4] = "INVESTMENT_TO_PPR";
3668
+ TaxExemptionEnum[TaxExemptionEnum["PPR_TO_INVESTMENT"] = 5] = "PPR_TO_INVESTMENT";
3669
+ TaxExemptionEnum[TaxExemptionEnum["TRANSFER"] = 6] = "TRANSFER";
3670
+ TaxExemptionEnum[TaxExemptionEnum["OTHER"] = 7] = "OTHER";
3671
+ })(TaxExemptionEnum || (TaxExemptionEnum = {}));
3672
+
3673
+ var PropertyCategoryListEnum;
3674
+ (function (PropertyCategoryListEnum) {
3675
+ PropertyCategoryListEnum[PropertyCategoryListEnum["OWNER_OCCUPIED"] = 3] = "OWNER_OCCUPIED";
3676
+ PropertyCategoryListEnum[PropertyCategoryListEnum["VACANT_LAND"] = 5] = "VACANT_LAND";
3677
+ })(PropertyCategoryListEnum || (PropertyCategoryListEnum = {}));
3549
3678
 
3550
3679
  var TaxExemptionMetadataEnum;
3551
3680
  (function (TaxExemptionMetadataEnum) {
@@ -3924,10 +4053,9 @@ class BankAccount extends BankAccount$1 {
3924
4053
  }
3925
4054
  /**
3926
4055
  * check if bank account type is Loan
3927
- * @TODO nicole check
3928
4056
  */
3929
4057
  isLoan() {
3930
- return [BankAccountTypeEnum.MORTGAGE, BankAccountTypeEnum.LOAN].includes(this.type);
4058
+ return this.type === BankAccountTypeEnum.LOAN;
3931
4059
  }
3932
4060
  /**
3933
4061
  * check if bank account type is Credit card
@@ -4013,10 +4141,12 @@ class BankAccount extends BankAccount$1 {
4013
4141
  return this.bankConnection.user.id === userId;
4014
4142
  }
4015
4143
  }
4016
- BankAccount.loanTypes = [BankAccountTypeEnum.LOAN, BankAccountTypeEnum.MORTGAGE];
4017
4144
  __decorate([
4018
4145
  Type(() => BankAccountProperty)
4019
4146
  ], BankAccount.prototype, "bankAccountProperties", void 0);
4147
+ __decorate([
4148
+ Type(() => SoleBusinessAllocation)
4149
+ ], BankAccount.prototype, "businessAllocations", void 0);
4020
4150
  __decorate([
4021
4151
  Type(() => BankAccountBalance)
4022
4152
  ], BankAccount.prototype, "balances", void 0);
@@ -4026,9 +4156,11 @@ __decorate([
4026
4156
  __decorate([
4027
4157
  Type(() => BankConnection)
4028
4158
  ], BankAccount.prototype, "bankConnection", void 0);
4159
+ __decorate([
4160
+ Transform(({ value }) => value === 4 ? BankAccountTypeEnum.LOAN : value)
4161
+ ], BankAccount.prototype, "type", void 0);
4029
4162
 
4030
4163
  const TYPE_LOAN = [
4031
- BankAccountTypeEnum.MORTGAGE,
4032
4164
  BankAccountTypeEnum.CREDIT_CARD,
4033
4165
  BankAccountTypeEnum.LOAN
4034
4166
  ];
@@ -4488,37 +4620,224 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
4488
4620
  }]
4489
4621
  }] });
4490
4622
 
4491
- class TtCoreModule {
4492
- static forRoot(environment) {
4493
- localStorage.setItem('api_uri', environment['api_uri']);
4494
- return {
4495
- ngModule: TtCoreModule,
4496
- providers: [
4497
- {
4498
- provide: 'environment',
4499
- useValue: environment
4623
+ class TtCoreModule {
4624
+ static forRoot(environment) {
4625
+ localStorage.setItem('api_uri', environment['api_uri']);
4626
+ return {
4627
+ ngModule: TtCoreModule,
4628
+ providers: [
4629
+ {
4630
+ provide: 'environment',
4631
+ useValue: environment
4632
+ }
4633
+ ]
4634
+ };
4635
+ }
4636
+ }
4637
+ TtCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TtCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4638
+ TtCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TtCoreModule, imports: [CommonModule,
4639
+ InterceptorsModule] });
4640
+ TtCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TtCoreModule, imports: [[
4641
+ CommonModule,
4642
+ InterceptorsModule
4643
+ ]] });
4644
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TtCoreModule, decorators: [{
4645
+ type: NgModule,
4646
+ args: [{
4647
+ declarations: [],
4648
+ imports: [
4649
+ CommonModule,
4650
+ InterceptorsModule
4651
+ ]
4652
+ }]
4653
+ }] });
4654
+
4655
+ /**
4656
+ * Class contains traveled kilometers and work usage percent in 12 weeks date range
4657
+ * @TODO Vik: Best period: move this and related logic to backend
4658
+ */
4659
+ class LogbookPeriod {
4660
+ isEndOfYear() {
4661
+ return this.to === new FinancialYear().endDate;
4662
+ }
4663
+ getWorkUsageByClaim(claim) {
4664
+ const claimKilometers = this.logbooks.getByVehicleClaim(claim).getClaimableLogbooks().kilometers;
4665
+ return Math.round(this.workUsage * (claimKilometers / this.kilometers));
4666
+ }
4667
+ }
4668
+ __decorate([
4669
+ Type(() => Date)
4670
+ ], LogbookPeriod.prototype, "from", void 0);
4671
+ __decorate([
4672
+ Type(() => Date)
4673
+ ], LogbookPeriod.prototype, "to", void 0);
4674
+
4675
+ class Vehicle$1 extends AbstractModel {
4676
+ }
4677
+
4678
+ class VehicleLogbook$1 extends AbstractModel {
4679
+ }
4680
+
4681
+ class VehicleLogbook extends VehicleLogbook$1 {
4682
+ get kilometers() {
4683
+ return this.odometerEnd - this.odometerStart;
4684
+ }
4685
+ get tankType() {
4686
+ return this.isSoleTank() ? TankTypeEnum.SOLE : TankTypeEnum.WORK;
4687
+ }
4688
+ isWorkTank() {
4689
+ return !this.business;
4690
+ }
4691
+ isSoleTank() {
4692
+ return !!this.business;
4693
+ }
4694
+ }
4695
+ /**
4696
+ * 12 weeks in milliseconds
4697
+ * "To work out your business-use percentage, you need to keep a logbook and the odometer readings for the logbook period.
4698
+ * The logbook period is a minimum continuous period of 12 weeks." © Nicole Kelly
4699
+ */
4700
+ VehicleLogbook.periodDuration = 7257600000;
4701
+ __decorate([
4702
+ Type(() => Date)
4703
+ ], VehicleLogbook.prototype, "date", void 0);
4704
+ __decorate([
4705
+ Type(() => SoleBusiness)
4706
+ ], VehicleLogbook.prototype, "business", void 0);
4707
+
4708
+ class Vehicle extends Vehicle$1 {
4709
+ }
4710
+ __decorate([
4711
+ Type(() => VehicleLogbook)
4712
+ ], Vehicle.prototype, "logbook", void 0);
4713
+
4714
+ class VehicleClaimCollection extends Collection {
4715
+ /**
4716
+ * Get remaining kilometers limit. Total limit ({@link VehicleClaim.totalKmsLimit}) - claimed kilometers from other vehicle claims
4717
+ * @param claim may not exist when user come to vehicle claim page 1st time and not created claim yet
4718
+ */
4719
+ getKlmsLimitForClaim(claim) {
4720
+ let collection = this;
4721
+ if (claim) {
4722
+ collection = collection.removeBy('id', claim.id);
4723
+ }
4724
+ return VehicleClaim.totalKmsLimit - collection.sumBy('kilometers');
4725
+ }
4726
+ /**
4727
+ * Get remaining work usage limit. Total limit ({@link VehicleClaim.totalWorkUsagePercent}) - claimed percent from other vehicle claims
4728
+ * @param claim may not exist when user come to vehicle claim page 1st time and not created claim yet
4729
+ */
4730
+ getWorkUsageLimitForClaim(claim) {
4731
+ let collection = this;
4732
+ if (claim) {
4733
+ collection = collection.removeBy('id', claim.id);
4734
+ }
4735
+ return VehicleClaim.totalWorkUsagePercent - collection.sumBy('workUsage');
4736
+ }
4737
+ }
4738
+
4739
+ class VehicleLogbookCollection extends Collection {
4740
+ /**
4741
+ * Best period may be calculated only when user has logbooks minimum for {@link VehicleLogbook.periodDuration}
4742
+ * @TODO Vik: Best period: move this and related logic to backend
4743
+ */
4744
+ isBestPeriodExist() {
4745
+ if (this.items.length < 2) {
4746
+ return false;
4747
+ }
4748
+ return VehicleLogbook.periodDuration < (this.last.date.getTime() - this.first.date.getTime());
4749
+ }
4750
+ /**
4751
+ * Get collection of non-personal logbooks (work-related, sole-related).
4752
+ * @TODO Vik: Best period: move this and related logic to backend
4753
+ */
4754
+ getClaimableLogbooks() {
4755
+ return this.filterBy('isPersonal', false);
4756
+ }
4757
+ /**
4758
+ * Logbook Period is the best when it has the biggest work usage percent
4759
+ * Best period duration is defined as {@link VehicleLogbook.periodDuration} by the ATO
4760
+ * @TODO Vik: Best period: move this and related logic to backend
4761
+ */
4762
+ getBestPeriod() {
4763
+ if (!this.isBestPeriodExist()) {
4764
+ return null;
4765
+ }
4766
+ // declare best period variable
4767
+ let bestPeriod;
4768
+ // get list of all logbooks available for best period calculation
4769
+ const claimableLogbooks = this.getClaimableLogbooks().toArray();
4770
+ for (let i = 0; i < claimableLogbooks.length; i++) {
4771
+ // no sense to check next logbooks because we already get the end of the year
4772
+ if (bestPeriod && bestPeriod.isEndOfYear()) {
4773
+ break;
4774
+ }
4775
+ // get date range started from current handling logbook date
4776
+ const dateRange = this.getPeriodRange(claimableLogbooks[i].date);
4777
+ // get all logbooks included in current logbook period
4778
+ const logbooksInRange = this.filterByRange('date', dateRange.from, dateRange.to);
4779
+ const currentPeriod = plainToClass(LogbookPeriod, {
4780
+ from: dateRange.from,
4781
+ to: dateRange.to,
4782
+ kilometers: logbooksInRange.getClaimableLogbooks().kilometers,
4783
+ workUsage: logbooksInRange.getWorkUsage(),
4784
+ logbooks: logbooksInRange
4785
+ });
4786
+ // compare with previous best period and overwrite if needs
4787
+ if (!bestPeriod || currentPeriod.workUsage > bestPeriod.workUsage) {
4788
+ bestPeriod = currentPeriod;
4789
+ }
4790
+ else if (currentPeriod.workUsage === bestPeriod.workUsage) {
4791
+ // if work usage is the same then get period with the biggest work usage for work tank
4792
+ const oldWorkUsage = bestPeriod.logbooks.filterBy('tankType', TankTypeEnum.WORK).getWorkUsage();
4793
+ const currentWorkUsage = currentPeriod.logbooks.filterBy('tankType', TankTypeEnum.WORK).getWorkUsage();
4794
+ if (oldWorkUsage < currentWorkUsage) {
4795
+ bestPeriod = currentPeriod;
4500
4796
  }
4501
- ]
4502
- };
4797
+ }
4798
+ }
4799
+ return bestPeriod;
4800
+ }
4801
+ /**
4802
+ * Calculate total kilometers traveled
4803
+ */
4804
+ get kilometers() {
4805
+ return this.sumBy('kilometers');
4806
+ }
4807
+ /**
4808
+ * Calculate work usage (percent of business-related kilometers from total kilometers)
4809
+ * @TODO Alex: TT-2089 replace with getter
4810
+ */
4811
+ getWorkUsage() {
4812
+ const workKilometers = this.getClaimableLogbooks().kilometers;
4813
+ return Math.round(workKilometers / this.kilometers * 100);
4814
+ }
4815
+ /**
4816
+ * Get LOGBOOK_PERIOD_DURATION date range from passed start date
4817
+ * @TODO Vik: Best period: move this and related logic to backend
4818
+ */
4819
+ getPeriodRange(from) {
4820
+ // set end date as VehicleLogbook.periodDuration after start date
4821
+ let to = new Date(from.getTime() + VehicleLogbook.periodDuration);
4822
+ const financialYear = new FinancialYear();
4823
+ // set as period last VehicleLogbook.periodDuration of current year if period end date after end of current year
4824
+ if (to > financialYear.endDate) {
4825
+ to = financialYear.endDate;
4826
+ from = new Date(to.getTime() - VehicleLogbook.periodDuration);
4827
+ }
4828
+ return { from, to };
4829
+ }
4830
+ /**
4831
+ * Get list of logbooks related to passed vehicle claim
4832
+ */
4833
+ getByVehicleClaim(claim) {
4834
+ return claim.isWorkTank()
4835
+ ? this.filterBy('tankType', TankTypeEnum.WORK)
4836
+ : this.filterBy('business.id', claim.business.id);
4503
4837
  }
4504
4838
  }
4505
- TtCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TtCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4506
- TtCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TtCoreModule, imports: [CommonModule,
4507
- InterceptorsModule] });
4508
- TtCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TtCoreModule, imports: [[
4509
- CommonModule,
4510
- InterceptorsModule
4511
- ]] });
4512
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TtCoreModule, decorators: [{
4513
- type: NgModule,
4514
- args: [{
4515
- declarations: [],
4516
- imports: [
4517
- CommonModule,
4518
- InterceptorsModule
4519
- ]
4520
- }]
4521
- }] });
4839
+
4840
+ // @TODO Alex move here all collections
4522
4841
 
4523
4842
  class AccountSetupItemCollection extends Collection {
4524
4843
  constructor(items) {
@@ -4741,39 +5060,6 @@ class ClientPortfolioReportCollection extends Collection {
4741
5060
  }
4742
5061
  }
4743
5062
 
4744
- class ExportDataTable {
4745
- }
4746
-
4747
- class ExportableCollection extends Collection {
4748
- getExportFooter(type) {
4749
- return [];
4750
- }
4751
- ;
4752
- export(type) {
4753
- return plainToClass(ExportDataTable, {
4754
- header: this.getExportHeader(type),
4755
- body: this.getExportBody(type),
4756
- footer: [this.getExportFooter(type)]
4757
- });
4758
- }
4759
- }
4760
-
4761
- /**
4762
- * export table column
4763
- */
4764
- class ExportCell {
4765
- }
4766
-
4767
- /**
4768
- * type of export table column value
4769
- */
4770
- var ExportCellTypeEnum;
4771
- (function (ExportCellTypeEnum) {
4772
- ExportCellTypeEnum[ExportCellTypeEnum["STRING"] = 0] = "STRING";
4773
- ExportCellTypeEnum[ExportCellTypeEnum["CURRENCY"] = 1] = "CURRENCY";
4774
- ExportCellTypeEnum[ExportCellTypeEnum["DATE"] = 2] = "DATE";
4775
- })(ExportCellTypeEnum || (ExportCellTypeEnum = {}));
4776
-
4777
5063
  /**
4778
5064
  * Collection of transactions
4779
5065
  */
@@ -4937,6 +5223,24 @@ class TransactionCollection extends ExportableCollection {
4937
5223
  ];
4938
5224
  });
4939
5225
  }
5226
+ /**
5227
+ * Get list of vehicle transactions filtered by vehicle claim
5228
+ */
5229
+ getByVehicleClaim(vehicleClaim) {
5230
+ return vehicleClaim.isSoleTank()
5231
+ // sole tank may have multiple vehicle claims, so we need to filter by business.id
5232
+ ? this.getVehicleTransactions().filterBy('business.id', vehicleClaim.business.id)
5233
+ // work tank may have only one vehicle claim, so we need to filter by tank type
5234
+ : this.getVehicleTransactions().filterBy('tankType', TankTypeEnum.WORK);
5235
+ }
5236
+ /**
5237
+ * Get list of vehicle transactions except KLMS transactions
5238
+ */
5239
+ getLogbookTransactions() {
5240
+ return this
5241
+ .getVehicleTransactions()
5242
+ .removeBy('chartAccounts.id', [ChartAccountsListEnum.KLMS_TRAVELLED_FOR_WORK, ChartAccountsListEnum.KLMS_TRAVELLED]);
5243
+ }
4940
5244
  }
4941
5245
 
4942
5246
  class DepreciationCollection extends Collection {
@@ -5041,6 +5345,16 @@ class DepreciationCollection extends Collection {
5041
5345
  toTransactions() {
5042
5346
  return new TransactionCollection(this.items.map((item) => item.toTransaction()));
5043
5347
  }
5348
+ /**
5349
+ * Get depreciations by vehicle claim. Only vehicle depreciations may be related to vehicle claim
5350
+ */
5351
+ getByVehicleClaim(vehicleClaim) {
5352
+ return vehicleClaim.isSoleTank()
5353
+ // sole tank may have multiple vehicle claims, so we need to filter by business.id
5354
+ ? this.getVehicleDepreciations().filterBy('business.id', vehicleClaim.business.id)
5355
+ // work tank may have only one vehicle claim, so we need to filter by tank type
5356
+ : this.getVehicleDepreciations().filterBy('tankType', TankTypeEnum.WORK);
5357
+ }
5044
5358
  }
5045
5359
 
5046
5360
  /**
@@ -5108,32 +5422,13 @@ class LoanCollection extends Collection {
5108
5422
  getByBankAccountId(id) {
5109
5423
  return this.items.find((loan) => { var _a; return ((_a = loan.bankAccount) === null || _a === void 0 ? void 0 : _a.id) === id; });
5110
5424
  }
5111
- }
5112
-
5113
- class LoanPaymentCollection extends ExportableCollection {
5114
- getExportHeader() {
5115
- return [
5116
- 'Pmt No.',
5117
- 'Date',
5118
- 'Payment Due',
5119
- 'Interest Accrued',
5120
- 'Principal Paid',
5121
- 'Principal Balance',
5122
- 'Payout'
5123
- ];
5124
- }
5125
- getExportBody() {
5126
- return this.items.map((payment) => {
5127
- return [
5128
- plainToClass(ExportCell, { value: payment.number, type: ExportCellTypeEnum.STRING }),
5129
- plainToClass(ExportCell, { value: payment.date, type: ExportCellTypeEnum.DATE }),
5130
- plainToClass(ExportCell, { value: payment.paymentDue, type: ExportCellTypeEnum.CURRENCY }),
5131
- plainToClass(ExportCell, { value: payment.interestAccrued, type: ExportCellTypeEnum.CURRENCY }),
5132
- plainToClass(ExportCell, { value: payment.principalPaid, type: ExportCellTypeEnum.CURRENCY }),
5133
- plainToClass(ExportCell, { value: payment.principalBalance, type: ExportCellTypeEnum.CURRENCY }),
5134
- plainToClass(ExportCell, { value: payment.payout, type: ExportCellTypeEnum.CURRENCY }),
5135
- ];
5136
- });
5425
+ /**
5426
+ * Get list of current fin year payments grouped by loan id
5427
+ */
5428
+ groupCurrentYearPaymentsByLoans() {
5429
+ const dictionary = new CollectionDictionary(new LoanPaymentCollection([]));
5430
+ this.items.forEach((loan) => dictionary.add(loan.id, new LoanPaymentCollection(loan.payments).getForCurrentYear()));
5431
+ return dictionary;
5137
5432
  }
5138
5433
  }
5139
5434
 
@@ -5753,157 +6048,49 @@ class TransactionAllocationCollection extends Collection {
5753
6048
  get amount() {
5754
6049
  return this.sumBy('amount');
5755
6050
  }
5756
- getByTransactionsIds(ids) {
5757
- return new TransactionAllocationCollection(this.items.filter((allocation) => ids.includes(allocation.transaction.id)));
5758
- }
5759
- getByBankTransactionsIds(ids) {
5760
- return new TransactionAllocationCollection(this.items.filter((allocation) => ids.includes(allocation.bankTransaction.id)));
5761
- }
5762
- /**
5763
- * Group allocations by bank account via bank transactions collection
5764
- */
5765
- groupByBankAccount(bankTransactions) {
5766
- // Group bank transactions by bank account id
5767
- const bankTransactionsByBankAccount = new CollectionDictionary(bankTransactions, 'bankAccount.id');
5768
- // Create empty dictionary of transaction allocations
5769
- const allocationsByBankAccount = new CollectionDictionary(new TransactionAllocationCollection([]));
5770
- // Fill allocations dictionary with bank transactions dictionary keys and allocations related with each bank transaction collection
5771
- bankTransactionsByBankAccount.keys.forEach((key) => {
5772
- allocationsByBankAccount.add(key, this.getByBankTransactionsIds(bankTransactionsByBankAccount.get(key).getIds()));
5773
- });
5774
- return allocationsByBankAccount;
5775
- }
5776
- /**
5777
- * check if collection includes allocation of passed transaction
5778
- */
5779
- hasTransaction(transaction) {
5780
- return !!this.items.find((allocation) => allocation.transaction.id === transaction.id);
5781
- }
5782
- /**
5783
- * Check if bank transaction is related with current allocations
5784
- */
5785
- hasBankTransaction(bankTransaction) {
5786
- return !!this.items.find((allocation) => allocation.bankTransaction.id === bankTransaction.id);
5787
- }
5788
- }
5789
-
5790
- /**
5791
- * Collection of user event settings
5792
- */
5793
- class UserEventSettingCollection extends Collection {
5794
- getConfigurableBy(field) {
5795
- return new UserEventSettingCollection(this.items.filter((setting) => setting[field] !== null));
5796
- }
5797
- }
5798
-
5799
- /**
5800
- * Class contains traveled kilometers and work usage percent in 12 weeks date range
5801
- */
5802
- class LogbookPeriod {
5803
- isEndOfYear() {
5804
- return this.to === new FinancialYear().endDate;
5805
- }
5806
- }
5807
- __decorate([
5808
- Type(() => Date)
5809
- ], LogbookPeriod.prototype, "from", void 0);
5810
- __decorate([
5811
- Type(() => Date)
5812
- ], LogbookPeriod.prototype, "to", void 0);
5813
-
5814
- /**
5815
- * 12 weeks in milliseconds
5816
- * "To work out your business-use percentage, you need to keep a logbook and the odometer readings for the logbook period.
5817
- * The logbook period is a minimum continuous period of 12 weeks." © Nicole Kelly
5818
- */
5819
- const LOGBOOK_PERIOD_DURATION = 12 * 7 * 24 * 3600 * 1000;
5820
- class VehicleLogbookCollection extends Collection {
5821
- /**
5822
- * Check if we can calculate the best period
5823
- */
5824
- isBestPeriodExist() {
5825
- if (this.items.length < 2) {
5826
- return false;
5827
- }
5828
- return LOGBOOK_PERIOD_DURATION < (this.last.date.getTime() - this.first.date.getTime());
5829
- }
5830
- /**
5831
- * Get collection of non-personal logbooks (work-related, sole-related).
5832
- */
5833
- getBusinessLogbooks() {
5834
- return this.create(this.items.filter((logbook) => logbook.isBusiness()));
5835
- }
5836
- /**
5837
- * Logbook Period is the best when it has the biggest amount of work kilometers
5838
- * Best period duration is defined as LOGBOOK_PERIOD_DURATION (12 weeks) by the ATO
5839
- */
5840
- getBestPeriod() {
5841
- if (!this.isBestPeriodExist()) {
5842
- return null;
5843
- }
5844
- let bestPeriod;
5845
- const businessLogbooks = this.getBusinessLogbooks().toArray();
5846
- for (let i = 0; i < businessLogbooks.length; i++) {
5847
- const logbook = businessLogbooks[i];
5848
- // no sense to check next logbooks because we already get the end of the year
5849
- if (bestPeriod && bestPeriod.isEndOfYear()) {
5850
- break;
5851
- }
5852
- const dateRange = this.getPeriodRange(logbook.date);
5853
- // get logbooks included in current logbook period
5854
- const logbooksInRange = this.filterByRange('date', logbook.date, new Date(logbook.date.getTime() + LOGBOOK_PERIOD_DURATION));
5855
- const workUsage = logbooksInRange.getWorkUsage();
5856
- // compare with previous best period and overwrite if needs
5857
- if (!bestPeriod || workUsage > bestPeriod.workUsage) {
5858
- bestPeriod = plainToClass(LogbookPeriod, {
5859
- from: dateRange.from,
5860
- to: dateRange.to,
5861
- kilometers: logbooksInRange.getBusinessLogbooks().getKlms(),
5862
- workUsage: workUsage
5863
- });
5864
- }
5865
- }
5866
- return bestPeriod;
5867
- }
6051
+ getByTransactionsIds(ids) {
6052
+ return new TransactionAllocationCollection(this.items.filter((allocation) => ids.includes(allocation.transaction.id)));
6053
+ }
6054
+ getByBankTransactionsIds(ids) {
6055
+ return new TransactionAllocationCollection(this.items.filter((allocation) => ids.includes(allocation.bankTransaction.id)));
6056
+ }
5868
6057
  /**
5869
- * Calculate total kilometers traveled
6058
+ * Group allocations by bank account via bank transactions collection
5870
6059
  */
5871
- getKlms() {
5872
- return this.items.reduce((sum, logbook) => sum + logbook.getKlms(), 0);
6060
+ groupByBankAccount(bankTransactions) {
6061
+ // Group bank transactions by bank account id
6062
+ const bankTransactionsByBankAccount = new CollectionDictionary(bankTransactions, 'bankAccount.id');
6063
+ // Create empty dictionary of transaction allocations
6064
+ const allocationsByBankAccount = new CollectionDictionary(new TransactionAllocationCollection([]));
6065
+ // Fill allocations dictionary with bank transactions dictionary keys and allocations related with each bank transaction collection
6066
+ bankTransactionsByBankAccount.keys.forEach((key) => {
6067
+ allocationsByBankAccount.add(key, this.getByBankTransactionsIds(bankTransactionsByBankAccount.get(key).getIds()));
6068
+ });
6069
+ return allocationsByBankAccount;
5873
6070
  }
5874
6071
  /**
5875
- * Calculate work usage (percent of business-related kilometers from total kilometers)
6072
+ * check if collection includes allocation of passed transaction
5876
6073
  */
5877
- getWorkUsage() {
5878
- const totalKilometers = this.getKlms();
5879
- const workKilometers = this.getBusinessLogbooks().getKlms();
5880
- return Math.round(workKilometers / totalKilometers * 100);
6074
+ hasTransaction(transaction) {
6075
+ return !!this.items.find((allocation) => allocation.transaction.id === transaction.id);
5881
6076
  }
5882
6077
  /**
5883
- * Get LOGBOOK_PERIOD_DURATION date range from passed start date
6078
+ * Check if bank transaction is related with current allocations
5884
6079
  */
5885
- getPeriodRange(from) {
5886
- // set end date after LOGBOOK_PERIOD_DURATION after start date
5887
- let to = new Date(from.getTime() + LOGBOOK_PERIOD_DURATION);
5888
- const financialYear = new FinancialYear();
5889
- // set as period last LOGBOOK_PERIOD_DURATION of current year if period end date after end of current year
5890
- if (to > financialYear.endDate) {
5891
- to = financialYear.endDate;
5892
- from = new Date(to.getTime() - LOGBOOK_PERIOD_DURATION);
5893
- }
5894
- return { from, to };
6080
+ hasBankTransaction(bankTransaction) {
6081
+ return !!this.items.find((allocation) => allocation.bankTransaction.id === bankTransaction.id);
5895
6082
  }
5896
6083
  }
5897
6084
 
5898
- class VehicleCollection extends Collection {
5899
- getLogbooks() {
5900
- return new VehicleLogbookCollection(flatten(this.items.map((vehicle) => vehicle.logbook)));
6085
+ /**
6086
+ * Collection of user event settings
6087
+ */
6088
+ class UserEventSettingCollection extends Collection {
6089
+ getConfigurableBy(field) {
6090
+ return new UserEventSettingCollection(this.items.filter((setting) => setting[field] !== null));
5901
6091
  }
5902
6092
  }
5903
6093
 
5904
- /**
5905
- * Collection of tax review
5906
- */
5907
6094
  class ClientInviteCollection extends Collection {
5908
6095
  getPending() {
5909
6096
  return this.filter((invite) => invite.isPending());
@@ -6467,7 +6654,6 @@ const BANK_ACCOUNT_TYPES = [
6467
6654
  { key: BankAccountTypeEnum.TERM_DEPOSIT, value: 'Deposit Accounts' },
6468
6655
  { key: BankAccountTypeEnum.INVESTMENT, value: 'Investment Accounts' },
6469
6656
  { key: BankAccountTypeEnum.LOAN, value: 'Loan Accounts' },
6470
- { key: BankAccountTypeEnum.MORTGAGE, value: 'Mortgage Accounts' },
6471
6657
  { key: BankAccountTypeEnum.OFFSET, value: 'Offset' },
6472
6658
  { key: BankAccountTypeEnum.SAVINGS, value: 'Savings Accounts' },
6473
6659
  { key: BankAccountTypeEnum.TRANSACTION, value: 'Transaction Accounts' },
@@ -7245,62 +7431,6 @@ var LoanMaxNumberOfPaymentsEnum;
7245
7431
  LoanMaxNumberOfPaymentsEnum[LoanMaxNumberOfPaymentsEnum["MONTHLY"] = 60] = "MONTHLY";
7246
7432
  })(LoanMaxNumberOfPaymentsEnum || (LoanMaxNumberOfPaymentsEnum = {}));
7247
7433
 
7248
- /**
7249
- * Default vehicle transaction object,
7250
- * which could be used to create transaction with 'Klms travelled for work' chart accounts category
7251
- */
7252
- const DEFAULT_VEHICLE_EXPENSE = {
7253
- source: TransactionSourceEnum.CASH,
7254
- tankType: TankTypeEnum.WORK,
7255
- type: TransactionTypeEnum.DEBIT,
7256
- taxWithheld: 0,
7257
- description: 'Klm’s method',
7258
- date: new Date(`${new FinancialYear().year}-06-30`),
7259
- chartAccounts: { id: ChartAccountsListEnum.KLMS_TRAVELLED_FOR_WORK },
7260
- claimPercent: 100
7261
- };
7262
-
7263
- const WORK_TANK_LOGBOOK_PURPOSE_OPTIONS = [
7264
- { label: 'Business', value: VehicleLogbookPurposeEnum.BUSINESS },
7265
- { label: 'Personal', value: VehicleLogbookPurposeEnum.PERSONAL }
7266
- ];
7267
-
7268
- class Vehicle$1 extends AbstractModel {
7269
- }
7270
-
7271
- class VehicleLogbook$1 extends AbstractModel {
7272
- }
7273
-
7274
- class VehicleLogbook extends VehicleLogbook$1 {
7275
- /**
7276
- * Get amount of kilometers in this logbook
7277
- */
7278
- getKlms() {
7279
- return this.odometerEnd - this.odometerStart;
7280
- }
7281
- /**
7282
- * Check if logbook is business-related
7283
- */
7284
- isBusiness() {
7285
- return this.purpose === VehicleLogbookPurposeEnum.BUSINESS;
7286
- }
7287
- }
7288
- __decorate([
7289
- Type(() => Date)
7290
- ], VehicleLogbook.prototype, "date", void 0);
7291
-
7292
- class Vehicle extends Vehicle$1 {
7293
- /**
7294
- * Get vehicle's logbooks as collection
7295
- */
7296
- getLogbooks() {
7297
- return new VehicleLogbookCollection(this.logbook);
7298
- }
7299
- }
7300
- __decorate([
7301
- Type(() => VehicleLogbook)
7302
- ], Vehicle.prototype, "logbook", void 0);
7303
-
7304
7434
  class ServiceNotification extends AbstractModel {
7305
7435
  }
7306
7436
 
@@ -7859,10 +7989,11 @@ var DeductionSelfEducationTypeEnum;
7859
7989
  })(DeductionSelfEducationTypeEnum || (DeductionSelfEducationTypeEnum = {}));
7860
7990
 
7861
7991
  class MyTaxDeductions {
7862
- constructor(transactions, depreciations, vehicleClaim, vehicleClaimRate) {
7992
+ constructor(transactions, depreciations, vehicleClaim, vehicleClaimDetails, vehicleClaimRate) {
7863
7993
  this.transactions = transactions;
7864
7994
  this.depreciations = depreciations;
7865
7995
  this.vehicleClaim = vehicleClaim;
7996
+ this.vehicleClaimDetails = vehicleClaimDetails;
7866
7997
  this.vehicleClaimRate = vehicleClaimRate;
7867
7998
  // user can have no selected vehicle claim
7868
7999
  if (this.vehicleClaim) {
@@ -7913,9 +8044,8 @@ class MyTaxDeductions {
7913
8044
  .sumBy('claimAmount');
7914
8045
  }
7915
8046
  getVehicleExpensesTotalAmount() {
7916
- var _a;
7917
- if (this.vehicleClaim) {
7918
- return ((_a = this.vehicleClaim) === null || _a === void 0 ? void 0 : _a.isLogbookMethod()) ? this.totalExpensesAmount : this.klmsMethodClaimAmount;
8047
+ if (this.vehicleClaimDetails) {
8048
+ return this.vehicleClaimDetails.isLogbookMethod() ? this.totalExpensesAmount : this.klmsMethodClaimAmount;
7919
8049
  }
7920
8050
  return 0;
7921
8051
  }
@@ -8619,26 +8749,288 @@ class SoleBusinessService extends RestService {
8619
8749
  this.isHydra = true;
8620
8750
  }
8621
8751
  }
8622
- SoleBusinessService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleBusinessService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
8623
- SoleBusinessService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleBusinessService, providedIn: 'root' });
8624
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleBusinessService, decorators: [{
8752
+ SoleBusinessService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleBusinessService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
8753
+ SoleBusinessService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleBusinessService, providedIn: 'root' });
8754
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleBusinessService, decorators: [{
8755
+ type: Injectable,
8756
+ args: [{
8757
+ providedIn: 'root'
8758
+ }]
8759
+ }] });
8760
+
8761
+ class SoleContactService extends RestService {
8762
+ constructor() {
8763
+ super(...arguments);
8764
+ this.modelClass = SoleContact;
8765
+ this.url = 'sole-contacts';
8766
+ this.isHydra = true;
8767
+ }
8768
+ }
8769
+ SoleContactService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleContactService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
8770
+ SoleContactService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleContactService, providedIn: 'root' });
8771
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleContactService, decorators: [{
8772
+ type: Injectable,
8773
+ args: [{
8774
+ providedIn: 'root'
8775
+ }]
8776
+ }] });
8777
+
8778
+ /**
8779
+ * @TODO TT-1777 Alex: extend from rest service when it refactored
8780
+ */
8781
+ class SoleDetailsService {
8782
+ constructor(http, environment) {
8783
+ this.http = http;
8784
+ this.environment = environment;
8785
+ this.cacheSubject = new ReplaySubject(1);
8786
+ }
8787
+ get() {
8788
+ if (!this.cache) {
8789
+ this.http.get(`${this.environment.apiV2}/sole-details`)
8790
+ .pipe(map((response) => plainToClass(SoleDetails, response['hydra:member'][0])))
8791
+ .subscribe((soleDetails) => {
8792
+ // undefined when user not created sole details
8793
+ if (!soleDetails) {
8794
+ soleDetails = plainToClass(SoleDetails, {});
8795
+ }
8796
+ this.cache = soleDetails;
8797
+ this.cacheSubject.next(this.cache);
8798
+ return soleDetails;
8799
+ });
8800
+ }
8801
+ return this.cacheSubject.asObservable();
8802
+ }
8803
+ add(soleDetails) {
8804
+ return this.http.post(`${this.environment.apiV2}/sole-details`, soleDetails).pipe(map((soleDetailsBase) => {
8805
+ this.cache = plainToClass(SoleDetails, soleDetailsBase);
8806
+ this.cacheSubject.next(this.cache);
8807
+ return this.cache;
8808
+ }));
8809
+ }
8810
+ update(soleDetails) {
8811
+ return this.http.put(`${this.environment.apiV2}/sole-details/${soleDetails.id}`, soleDetails).pipe(map((soleDetailsBase) => {
8812
+ this.cache = plainToClass(SoleDetails, soleDetailsBase);
8813
+ this.cacheSubject.next(this.cache);
8814
+ return this.cache;
8815
+ }));
8816
+ }
8817
+ }
8818
+ SoleDetailsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleDetailsService, deps: [{ token: i1.HttpClient }, { token: 'environment' }], target: i0.ɵɵFactoryTarget.Injectable });
8819
+ SoleDetailsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleDetailsService, providedIn: 'root' });
8820
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleDetailsService, decorators: [{
8821
+ type: Injectable,
8822
+ args: [{
8823
+ providedIn: 'root'
8824
+ }]
8825
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: undefined, decorators: [{
8826
+ type: Inject,
8827
+ args: ['environment']
8828
+ }] }]; } });
8829
+
8830
+ class SoleInvoiceTemplateService extends RestService {
8831
+ constructor() {
8832
+ super(...arguments);
8833
+ this.modelClass = SoleInvoiceTemplate;
8834
+ this.url = 'sole-invoice-templates';
8835
+ this.isHydra = true;
8836
+ }
8837
+ }
8838
+ SoleInvoiceTemplateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleInvoiceTemplateService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
8839
+ SoleInvoiceTemplateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleInvoiceTemplateService, providedIn: 'root' });
8840
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleInvoiceTemplateService, decorators: [{
8841
+ type: Injectable,
8842
+ args: [{
8843
+ providedIn: 'root'
8844
+ }]
8845
+ }] });
8846
+
8847
+ /**
8848
+ * Service that allows to work with WorkTank operations
8849
+ */
8850
+ class VehicleService extends RestService {
8851
+ constructor() {
8852
+ super(...arguments);
8853
+ this.url = 'vehicles';
8854
+ this.modelClass = Vehicle;
8855
+ }
8856
+ }
8857
+ VehicleService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
8858
+ VehicleService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleService, providedIn: 'root' });
8859
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleService, decorators: [{
8860
+ type: Injectable,
8861
+ args: [{
8862
+ providedIn: 'root'
8863
+ }]
8864
+ }] });
8865
+
8866
+ class VehicleClaimService extends RestService {
8867
+ constructor() {
8868
+ super(...arguments);
8869
+ this.modelClass = VehicleClaim;
8870
+ this.url = 'vehicle-claims';
8871
+ }
8872
+ listenEvents() {
8873
+ this.listenVehicleClaimDetailsChanges();
8874
+ this.listenBestPeriodChanges();
8875
+ }
8876
+ add(model) {
8877
+ return super.add(model).pipe(map((vehicleClaim) => {
8878
+ this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.VEHICLE_CLAIM_CREATED, vehicleClaim));
8879
+ return vehicleClaim;
8880
+ }));
8881
+ }
8882
+ update(model, queryParams = {}) {
8883
+ return super.update(model, queryParams).pipe(map((vehicleClaim) => {
8884
+ this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.VEHICLE_CLAIM_UPDATED, vehicleClaim));
8885
+ return vehicleClaim;
8886
+ }));
8887
+ }
8888
+ /**
8889
+ * Details changes may affect vehicle claims:
8890
+ * when details method changed, all claims current values become 0
8891
+ */
8892
+ listenVehicleClaimDetailsChanges() {
8893
+ this.eventDispatcherService.on([
8894
+ AppEventTypeEnum.VEHICLE_CLAIM_DETAILS_CREATED,
8895
+ AppEventTypeEnum.VEHICLE_CLAIM_DETAILS_UPDATED
8896
+ ])
8897
+ .subscribe(() => {
8898
+ this.resetCache();
8899
+ });
8900
+ }
8901
+ /**
8902
+ * Best period changes affect to claims workUsage
8903
+ * @TODO Vik: Best period move this and related logic to backend
8904
+ */
8905
+ listenBestPeriodChanges() {
8906
+ this.eventDispatcherService.on(AppEventTypeEnum.VEHICLE_LOGBOOK_BEST_PERIOD_UPDATED)
8907
+ .subscribe((bestPeriod) => {
8908
+ // no need to update claims when best period become null
8909
+ // (case when logbook removed and user don't have enough logbooks for claim period)
8910
+ if (!bestPeriod) {
8911
+ return;
8912
+ }
8913
+ this.updateWorkUsage(bestPeriod);
8914
+ });
8915
+ }
8916
+ /**
8917
+ * Update workUsage for all vehicle claims if logbook best period changed
8918
+ * @TODO Vik: Best period move this and related logic to backend
8919
+ */
8920
+ updateWorkUsage(bestPeriod) {
8921
+ // We are sure this.cache exist here because logbook best period calculation is based on vehicle claims,
8922
+ // so before we can get logbook best period changes, we must get vehicle claims
8923
+ const batch$ = this.cache.map((claim) => {
8924
+ const claimToUpdate = plainToClass(VehicleClaim, Object.assign({}, claim, { workUsage: bestPeriod === null || bestPeriod === void 0 ? void 0 : bestPeriod.getWorkUsageByClaim(claim) }));
8925
+ return this.update(claimToUpdate);
8926
+ });
8927
+ // take(1) is using to avoid unnecessary callback calling whe user updated details directly
8928
+ combineLatest(batch$).pipe(take(1)).subscribe();
8929
+ }
8930
+ }
8931
+ VehicleClaimService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleClaimService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
8932
+ VehicleClaimService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleClaimService, providedIn: 'root' });
8933
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleClaimService, decorators: [{
8934
+ type: Injectable,
8935
+ args: [{
8936
+ providedIn: 'root'
8937
+ }]
8938
+ }] });
8939
+
8940
+ /**
8941
+ * @TODO TT-1777 Alex: extend from rest service when it refactored
8942
+ */
8943
+ class VehicleClaimDetailsService {
8944
+ constructor(environment, http, eventDispatcherService) {
8945
+ this.environment = environment;
8946
+ this.http = http;
8947
+ this.eventDispatcherService = eventDispatcherService;
8948
+ this.cacheSubject = new ReplaySubject(1);
8949
+ this.url = 'vehicle-claim-details';
8950
+ this.listenEvents();
8951
+ }
8952
+ listenEvents() {
8953
+ this.listenBestPeriodChanges();
8954
+ }
8955
+ get() {
8956
+ if (!this.cache) {
8957
+ this.http.get(`${this.environment.apiV2}/${this.url}`)
8958
+ .pipe(map((response) => plainToClass(VehicleClaimDetails, response['hydra:member'][0], { excludePrefixes: ['@'] })))
8959
+ .subscribe((vehicleClaimDetails) => {
8960
+ this.cache = vehicleClaimDetails;
8961
+ this.cacheSubject.next(this.cache);
8962
+ });
8963
+ }
8964
+ return this.cacheSubject.asObservable();
8965
+ }
8966
+ add(details) {
8967
+ return this.http.post(`${this.environment.apiV2}/${this.url}`, details).pipe(map((newDetails) => {
8968
+ const details = plainToClass(VehicleClaimDetails, newDetails);
8969
+ this.cache = details;
8970
+ this.cacheSubject.next(details);
8971
+ this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.VEHICLE_CLAIM_DETAILS_CREATED, details));
8972
+ return details;
8973
+ }));
8974
+ }
8975
+ update(details) {
8976
+ return this.http.put(`${this.environment.apiV2}/${this.url}/${details.id}`, details).pipe(map((updatedDetails) => {
8977
+ const details = plainToClass(VehicleClaimDetails, updatedDetails, { excludePrefixes: ['@'] });
8978
+ this.cache = details;
8979
+ this.cacheSubject.next(details);
8980
+ this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.VEHICLE_CLAIM_DETAILS_UPDATED, details));
8981
+ return details;
8982
+ }));
8983
+ }
8984
+ /**
8985
+ * Listen logbook best period updates
8986
+ * @TODO Vik: Best period move this and related logic to backend
8987
+ */
8988
+ listenBestPeriodChanges() {
8989
+ this.eventDispatcherService.on(AppEventTypeEnum.VEHICLE_LOGBOOK_BEST_PERIOD_UPDATED)
8990
+ .subscribe((bestPeriod) => {
8991
+ // Set details as manual if best period stop exist (removed logbook case)
8992
+ if (!bestPeriod) {
8993
+ this.updateToManual();
8994
+ }
8995
+ });
8996
+ }
8997
+ /**
8998
+ * Set vehicle claim details as manual
8999
+ * @TODO Vik: Best period move this and related logic to backend
9000
+ */
9001
+ updateToManual() {
9002
+ // We are sure this.cache exist here because logbook best period calculation is based on vehicle claim details,
9003
+ // so before we can get logbook best period changes, we must get vehicle claim details
9004
+ const vehicleClaimDetails = plainToClass(VehicleClaimDetails, Object.assign({}, this.cache, { isManual: true }));
9005
+ // take(1) is using to avoid unnecessary callback calling whe user updated details directly
9006
+ this.update(vehicleClaimDetails).pipe(take(1)).subscribe();
9007
+ }
9008
+ }
9009
+ VehicleClaimDetailsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleClaimDetailsService, deps: [{ token: 'environment' }, { token: i1.HttpClient }, { token: EventDispatcherService }], target: i0.ɵɵFactoryTarget.Injectable });
9010
+ VehicleClaimDetailsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleClaimDetailsService, providedIn: 'root' });
9011
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleClaimDetailsService, decorators: [{
8625
9012
  type: Injectable,
8626
9013
  args: [{
8627
9014
  providedIn: 'root'
8628
9015
  }]
8629
- }] });
9016
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
9017
+ type: Inject,
9018
+ args: ['environment']
9019
+ }] }, { type: i1.HttpClient }, { type: EventDispatcherService }]; } });
8630
9020
 
8631
- class SoleContactService extends RestService {
9021
+ /**
9022
+ * Vehicle logbook service. Allows user to add, update or delete vehicle trips
9023
+ */
9024
+ class VehicleLogbookService extends RestService {
8632
9025
  constructor() {
8633
9026
  super(...arguments);
8634
- this.modelClass = SoleContact;
8635
- this.url = 'sole-contacts';
8636
- this.isHydra = true;
9027
+ this.url = 'vehicles/logbooks';
9028
+ this.modelClass = VehicleLogbook;
8637
9029
  }
8638
9030
  }
8639
- SoleContactService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleContactService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
8640
- SoleContactService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleContactService, providedIn: 'root' });
8641
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleContactService, decorators: [{
9031
+ VehicleLogbookService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleLogbookService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
9032
+ VehicleLogbookService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleLogbookService, providedIn: 'root' });
9033
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleLogbookService, decorators: [{
8642
9034
  type: Injectable,
8643
9035
  args: [{
8644
9036
  providedIn: 'root'
@@ -8646,56 +9038,66 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
8646
9038
  }] });
8647
9039
 
8648
9040
  /**
8649
- * @TODO TT-1777 Alex: extend from rest service when it refactored
9041
+ * Service for logbook best period calculation
9042
+ * @TODO Vik: improve structure for such cases (TT-2043)
9043
+ * @TODO Vik: Best period move this and related logic to backend
8650
9044
  */
8651
- class SoleDetailsService {
8652
- constructor(http, environment) {
8653
- this.http = http;
8654
- this.environment = environment;
8655
- this.cacheSubject = new ReplaySubject(1);
9045
+ class LogbookBestPeriodService {
9046
+ constructor(vehicleClaimDetailsService, vehicleClaimService, vehicleLogbookService, eventDispatcherService) {
9047
+ this.vehicleClaimDetailsService = vehicleClaimDetailsService;
9048
+ this.vehicleClaimService = vehicleClaimService;
9049
+ this.vehicleLogbookService = vehicleLogbookService;
9050
+ this.eventDispatcherService = eventDispatcherService;
9051
+ this.cacheSubject = new ReplaySubject();
9052
+ this.listenEvents();
9053
+ }
9054
+ listenEvents() {
9055
+ this.listenCacheUpdates();
8656
9056
  }
8657
9057
  get() {
8658
9058
  if (!this.cache) {
8659
- this.http.get(`${this.environment.apiV2}/sole-details`)
8660
- .pipe(map((response) => plainToClass(SoleDetails, response['hydra:member'][0])))
8661
- .subscribe((soleDetails) => {
8662
- // undefined when user not created sole details
8663
- if (!soleDetails) {
8664
- soleDetails = plainToClass(SoleDetails, {});
9059
+ combineLatest([
9060
+ this.vehicleClaimDetailsService.get(),
9061
+ this.vehicleLogbookService.get().pipe(map((logbooks) => new VehicleLogbookCollection(logbooks)))
9062
+ ])
9063
+ .subscribe(([details, logbooks]) => {
9064
+ let period;
9065
+ // calculate current initial best period
9066
+ if ((details === null || details === void 0 ? void 0 : details.isManual) || !(details === null || details === void 0 ? void 0 : details.isLogbookMethod()) || !logbooks.isBestPeriodExist()) {
9067
+ period = null;
9068
+ }
9069
+ else {
9070
+ period = logbooks.getBestPeriod();
9071
+ }
9072
+ // update cache only when best period changed
9073
+ if (!isEqual(this.cache, period)) {
9074
+ this.cache = period;
9075
+ this.cacheSubject.next(this.cache);
8665
9076
  }
8666
- this.cache = soleDetails;
8667
- this.cacheSubject.next(this.cache);
8668
- return soleDetails;
8669
9077
  });
8670
9078
  }
8671
9079
  return this.cacheSubject.asObservable();
8672
9080
  }
8673
- add(soleDetails) {
8674
- return this.http.post(`${this.environment.apiV2}/sole-details`, soleDetails).pipe(map((soleDetailsBase) => {
8675
- this.cache = plainToClass(SoleDetails, soleDetailsBase);
8676
- this.cacheSubject.next(this.cache);
8677
- return this.cache;
8678
- }));
8679
- }
8680
- update(soleDetails) {
8681
- return this.http.put(`${this.environment.apiV2}/sole-details/${soleDetails.id}`, soleDetails).pipe(map((soleDetailsBase) => {
8682
- this.cache = plainToClass(SoleDetails, soleDetailsBase);
8683
- this.cacheSubject.next(this.cache);
8684
- return this.cache;
8685
- }));
9081
+ /**
9082
+ * Dispatch event when logbook best period changed
9083
+ */
9084
+ listenCacheUpdates() {
9085
+ // Skip initial calculation and fire event only when subject changed
9086
+ this.cacheSubject
9087
+ .pipe(skip(1))
9088
+ .subscribe((period) => {
9089
+ this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.VEHICLE_LOGBOOK_BEST_PERIOD_UPDATED, period));
9090
+ });
8686
9091
  }
8687
9092
  }
8688
- SoleDetailsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleDetailsService, deps: [{ token: i1.HttpClient }, { token: 'environment' }], target: i0.ɵɵFactoryTarget.Injectable });
8689
- SoleDetailsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleDetailsService, providedIn: 'root' });
8690
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: SoleDetailsService, decorators: [{
9093
+ LogbookBestPeriodService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LogbookBestPeriodService, deps: [{ token: VehicleClaimDetailsService }, { token: VehicleClaimService }, { token: VehicleLogbookService }, { token: EventDispatcherService }], target: i0.ɵɵFactoryTarget.Injectable });
9094
+ LogbookBestPeriodService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LogbookBestPeriodService, providedIn: 'root' });
9095
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: LogbookBestPeriodService, decorators: [{
8691
9096
  type: Injectable,
8692
9097
  args: [{
8693
9098
  providedIn: 'root'
8694
9099
  }]
8695
- }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: undefined, decorators: [{
8696
- type: Inject,
8697
- args: ['environment']
8698
- }] }]; } });
9100
+ }], ctorParameters: function () { return [{ type: VehicleClaimDetailsService }, { type: VehicleClaimService }, { type: VehicleLogbookService }, { type: EventDispatcherService }]; } });
8699
9101
 
8700
9102
  /**
8701
9103
  * Enum list of all possible account setup items. Using with [ACCOUNT_SETUP_ITEMS]{@link ACCOUNT_SETUP_ITEMS}
@@ -9196,38 +9598,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
9196
9598
  }]
9197
9599
  }] });
9198
9600
 
9199
- var MessagesEnum;
9200
- (function (MessagesEnum) {
9201
- MessagesEnum["VEHICLE_CREATED"] = "Vehicle created successfully";
9202
- MessagesEnum["VEHICLE_UPDATED"] = "Vehicle updated successfully";
9203
- MessagesEnum["VEHICLE_DELETED"] = "Vehicle deleted successfully";
9204
- MessagesEnum["VEHICLE_CLAIM_CREATED"] = "Vehicle claim created successfully";
9205
- MessagesEnum["VEHICLE_CLAIM_UPDATED"] = "Vehicle claim updated successfully";
9206
- MessagesEnum["VEHICLE_CLAIM_DELETED"] = "Vehicle claim deleted successfully";
9207
- MessagesEnum["VEHICLE_LOGBOOK_CREATED"] = "Vehicle logbook created successfully";
9208
- MessagesEnum["VEHICLE_LOGBOOK_UPDATED"] = "Vehicle logbook updated successfully";
9209
- MessagesEnum["VEHICLE_LOGBOOK_DELETED"] = "Vehicle logbook deleted successfully";
9210
- })(MessagesEnum || (MessagesEnum = {}));
9211
-
9212
- class VehicleClaimService extends RestService {
9213
- constructor() {
9214
- super(...arguments);
9215
- this.modelClass = VehicleClaim;
9216
- this.url = 'vehicle-claims';
9217
- this.messageCreated = MessagesEnum.VEHICLE_CLAIM_CREATED;
9218
- this.messageUpdated = MessagesEnum.VEHICLE_CLAIM_UPDATED;
9219
- this.messageDeleted = MessagesEnum.VEHICLE_CLAIM_DELETED;
9220
- }
9221
- }
9222
- VehicleClaimService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleClaimService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
9223
- VehicleClaimService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleClaimService, providedIn: 'root' });
9224
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleClaimService, decorators: [{
9225
- type: Injectable,
9226
- args: [{
9227
- providedIn: 'root'
9228
- }]
9229
- }] });
9230
-
9231
9601
  function enumToList(data) {
9232
9602
  const list = [];
9233
9603
  for (const key in data) {
@@ -9327,6 +9697,7 @@ class TransactionService extends RestService {
9327
9697
  this.listenPropertyShareUpdate();
9328
9698
  this.listenReceiptAdded();
9329
9699
  this.listenReceiptDeleted();
9700
+ this.listenVehicleClaimChanges();
9330
9701
  }
9331
9702
  /**
9332
9703
  * get list of all user's TaxTank transactions
@@ -9606,6 +9977,16 @@ class TransactionService extends RestService {
9606
9977
  this.updateCache();
9607
9978
  });
9608
9979
  }
9980
+ listenVehicleClaimChanges() {
9981
+ this.eventDispatcherService.on([
9982
+ AppEventTypeEnum.VEHICLE_CLAIM_CREATED,
9983
+ AppEventTypeEnum.VEHICLE_CLAIM_UPDATED,
9984
+ AppEventTypeEnum.VEHICLE_CLAIM_DETAILS_CREATED,
9985
+ AppEventTypeEnum.VEHICLE_CLAIM_DETAILS_UPDATED
9986
+ ]).subscribe(() => {
9987
+ this.resetCache();
9988
+ });
9989
+ }
9609
9990
  }
9610
9991
  TransactionService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TransactionService, deps: [{ token: i1.HttpClient }, { token: EventDispatcherService }, { token: 'environment' }, { token: ToastService }, { token: TransactionReceiptService }], target: i0.ɵɵFactoryTarget.Injectable });
9611
9992
  TransactionService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TransactionService, providedIn: 'root' });
@@ -10484,6 +10865,9 @@ class ClientInviteService extends RestService {
10484
10865
  this.url = 'clients/invites';
10485
10866
  this.modelClass = ClientInvite;
10486
10867
  }
10868
+ listenEvents() {
10869
+ this.listenNotifications();
10870
+ }
10487
10871
  /**
10488
10872
  * Import employees for firm from CSV file
10489
10873
  * @param file
@@ -10560,6 +10944,16 @@ class ClientInviteService extends RestService {
10560
10944
  return newInvite;
10561
10945
  }));
10562
10946
  }
10947
+ /**
10948
+ * Reset cache on client/firm invite events
10949
+ */
10950
+ listenNotifications() {
10951
+ this.eventDispatcherService.on(AppEventTypeEnum.NOTIFICATION_ADDED).subscribe((notification) => {
10952
+ if (!notification.isRead && (notification.eventType === UserEventTypeClientTypeEnum.FIRM_INVITE_ACCEPTED || notification.eventType === UserEventTypeClientTypeEnum.CLIENT_INVITE)) {
10953
+ this.resetCache();
10954
+ }
10955
+ });
10956
+ }
10563
10957
  }
10564
10958
  ClientInviteService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ClientInviteService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
10565
10959
  ClientInviteService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: ClientInviteService, providedIn: 'root' });
@@ -10577,6 +10971,10 @@ class ClientMovementService extends RestService {
10577
10971
  this.url = 'client-movements';
10578
10972
  this.isHydra = true;
10579
10973
  }
10974
+ listenEvents() {
10975
+ this.listenNotifications();
10976
+ this.listenClientInvites();
10977
+ }
10580
10978
  /**
10581
10979
  * @TODO BaseRestService should return collection
10582
10980
  */
@@ -10621,11 +11019,12 @@ class ClientMovementService extends RestService {
10621
11019
  this.updateCache();
10622
11020
  }));
10623
11021
  }
10624
- /**
10625
- * Listen Event Dispatcher service
10626
- */
10627
- listenEvents() {
10628
- this.listenClientInvites();
11022
+ listenNotifications() {
11023
+ this.eventDispatcherService.on(AppEventTypeEnum.NOTIFICATION_ADDED).subscribe((notification) => {
11024
+ if (!notification.isRead && notification.eventType === UserEventTypeClientTypeEnum.FIRM_INVITE_ACCEPTED) {
11025
+ this.resetCache();
11026
+ }
11027
+ });
10629
11028
  }
10630
11029
  /**
10631
11030
  * Listen to EventDispatcherService event related to clients invitations
@@ -10633,10 +11032,7 @@ class ClientMovementService extends RestService {
10633
11032
  listenClientInvites() {
10634
11033
  this.eventDispatcherService.on(AppEventTypeEnum.CLIENT_INVITE_ACCEPTED)
10635
11034
  .subscribe(() => {
10636
- this.fetch().subscribe((clientMovements) => {
10637
- this.cache = clientMovements;
10638
- this.updateCache();
10639
- });
11035
+ this.resetCache();
10640
11036
  });
10641
11037
  }
10642
11038
  }
@@ -10765,7 +11161,7 @@ class DepreciationService extends RestService {
10765
11161
  */
10766
11162
  listenEvents() {
10767
11163
  this.listenToUpdatedLoan();
10768
- this.listenToVehicleClaim();
11164
+ this.listenVehicleClaimChanges();
10769
11165
  this.listenToUpdatedBankAccount();
10770
11166
  }
10771
11167
  getOpenBalance(depreciation) {
@@ -10812,9 +11208,14 @@ class DepreciationService extends RestService {
10812
11208
  /**
10813
11209
  * Listen to EventDispatcherService event related to updated vehicle claim
10814
11210
  */
10815
- listenToVehicleClaim() {
10816
- this.eventDispatcherService.on([AppEventTypeEnum.VEHICLE_CLAIM_CREATED, AppEventTypeEnum.VEHICLE_CLAIM_UPDATED]).subscribe(() => {
10817
- this.fetch().subscribe();
11211
+ listenVehicleClaimChanges() {
11212
+ this.eventDispatcherService.on([
11213
+ AppEventTypeEnum.VEHICLE_CLAIM_CREATED,
11214
+ AppEventTypeEnum.VEHICLE_CLAIM_UPDATED,
11215
+ AppEventTypeEnum.VEHICLE_CLAIM_DETAILS_CREATED,
11216
+ AppEventTypeEnum.VEHICLE_CLAIM_DETAILS_UPDATED
11217
+ ]).subscribe(() => {
11218
+ this.resetCache();
10818
11219
  });
10819
11220
  }
10820
11221
  }
@@ -12409,6 +12810,7 @@ class TaxReviewService extends RestService {
12409
12810
  listenEvents() {
12410
12811
  this.listenFirmChanges();
12411
12812
  this.listenClientTransfer();
12813
+ this.listenNotifications();
12412
12814
  }
12413
12815
  /**
12414
12816
  * Add new Tax Review (request from client to firm)
@@ -12447,8 +12849,7 @@ class TaxReviewService extends RestService {
12447
12849
  listenFirmChanges() {
12448
12850
  this.eventDispatcherService.on([AppEventTypeEnum.CLIENT_MOVEMENT_CLOSED, AppEventTypeEnum.CLIENT_INVITE_ACCEPTED])
12449
12851
  .subscribe(() => {
12450
- this.cache = [];
12451
- this.updateCache();
12852
+ this.resetCache();
12452
12853
  });
12453
12854
  }
12454
12855
  /**
@@ -12468,6 +12869,13 @@ class TaxReviewService extends RestService {
12468
12869
  this.updateCache();
12469
12870
  });
12470
12871
  }
12872
+ listenNotifications() {
12873
+ this.eventDispatcherService.on(AppEventTypeEnum.NOTIFICATION_ADDED).subscribe((notification) => {
12874
+ if (!notification.isRead && notification.eventType === UserEventTypeClientTypeEnum.FIRM_INVITE_ACCEPTED) {
12875
+ this.resetCache();
12876
+ }
12877
+ });
12878
+ }
12471
12879
  }
12472
12880
  TaxReviewService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TaxReviewService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
12473
12881
  TaxReviewService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TaxReviewService, providedIn: 'root' });
@@ -12862,138 +13270,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
12862
13270
  }]
12863
13271
  }] });
12864
13272
 
12865
- /**
12866
- * Service to work with invitations for unregistered users
12867
- */
12868
- class UsersInviteService extends RestService {
12869
- constructor() {
12870
- super(...arguments);
12871
- this.modelClass = RegistrationInvite;
12872
- this.url = 'users/invite';
12873
- }
12874
- }
12875
- UsersInviteService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: UsersInviteService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
12876
- UsersInviteService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: UsersInviteService, providedIn: 'root' });
12877
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: UsersInviteService, decorators: [{
12878
- type: Injectable,
12879
- args: [{
12880
- providedIn: 'root'
12881
- }]
12882
- }] });
12883
-
12884
- /**
12885
- * Service that allows to work with WorkTank operations
12886
- * @TODO separate vehicles and logbooks to different api
12887
- */
12888
- class VehicleService extends RestService {
12889
- constructor() {
12890
- super(...arguments);
12891
- this.url = 'vehicles';
12892
- this.modelClass = Vehicle;
12893
- this.messageCreated = MessagesEnum.VEHICLE_CREATED;
12894
- this.messageUpdated = MessagesEnum.VEHICLE_UPDATED;
12895
- this.messageDeleted = MessagesEnum.VEHICLE_DELETED;
12896
- }
12897
- listenEvents() {
12898
- this.listenLogbookAdded();
12899
- this.listenLogbookUpdated();
12900
- this.listenLogbookDeleted();
12901
- }
12902
- /**
12903
- * Add a new logbook items to the vehicle when a new one created
12904
- */
12905
- listenLogbookAdded() {
12906
- this.eventDispatcherService.on(AppEventTypeEnum.VEHICLE_LOGBOOK_CREATED)
12907
- .subscribe((result) => {
12908
- const tempCache = cloneDeep$1(this.cache);
12909
- tempCache.find((vehicle) => vehicle.id === result.vehicleId).logbook.push(result.logbook);
12910
- this.cache = tempCache;
12911
- this.updateCache();
12912
- });
12913
- }
12914
- /**
12915
- * Replace vehicle's logbook with updated instance when logbook item updated
12916
- */
12917
- listenLogbookUpdated() {
12918
- this.eventDispatcherService.on(AppEventTypeEnum.VEHICLE_LOGBOOK_UPDATED)
12919
- .subscribe((result) => {
12920
- const tempCache = cloneDeep$1(this.cache);
12921
- replace(tempCache.find((vehicle) => vehicle.id === result.vehicleId).logbook, result.logbook);
12922
- this.cache = tempCache;
12923
- this.updateCache();
12924
- });
12925
- }
12926
- /**
12927
- * Remove logbook item from vehicle when logbook deleted
12928
- */
12929
- listenLogbookDeleted() {
12930
- this.eventDispatcherService.on(AppEventTypeEnum.VEHICLE_LOGBOOK_DELETED)
12931
- .subscribe((result) => {
12932
- const tempCache = cloneDeep$1(this.cache);
12933
- const vehicle = tempCache.find((vehicle) => vehicle.id === result.vehicleId);
12934
- vehicle.logbook = vehicle.logbook.filter((logbook) => logbook.id !== result.logbook.id);
12935
- this.cache = tempCache;
12936
- this.updateCache();
12937
- });
12938
- }
12939
- }
12940
- VehicleService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
12941
- VehicleService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleService, providedIn: 'root' });
12942
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleService, decorators: [{
12943
- type: Injectable,
12944
- args: [{
12945
- providedIn: 'root'
12946
- }]
12947
- }] });
12948
-
12949
- /**
12950
- * Vehicle logbook service. Allows user to add, update or delete vehicle trips
12951
- * @TODO extend rest service after it refactored
12952
- */
12953
- class VehicleLogbookService {
12954
- constructor(http, eventDispatcherService, environment, toastService) {
12955
- this.http = http;
12956
- this.eventDispatcherService = eventDispatcherService;
12957
- this.environment = environment;
12958
- this.toastService = toastService;
12959
- }
12960
- add(logbook, vehicleId) {
12961
- return this.http.post(`${this.environment.apiV2}/vehicles/${vehicleId}/logbooks`, logbook)
12962
- .pipe(map((vehicleLogbookBase) => {
12963
- const newVehicleLogbook = plainToClass(VehicleLogbook, vehicleLogbookBase);
12964
- this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.VEHICLE_LOGBOOK_CREATED, { logbook: newVehicleLogbook, vehicleId }));
12965
- this.toastService.success(MessagesEnum.VEHICLE_LOGBOOK_CREATED);
12966
- return newVehicleLogbook;
12967
- }));
12968
- }
12969
- update(logbook, vehicleId) {
12970
- return this.http.put(`${this.environment.apiV2}/vehicles/${vehicleId}/logbooks/${logbook.id}`, logbook).pipe(map((vehicleLogbookBase) => {
12971
- const updatedVehicleLogbook = plainToClass(VehicleLogbook, vehicleLogbookBase);
12972
- this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.VEHICLE_LOGBOOK_UPDATED, { logbook: updatedVehicleLogbook, vehicleId }));
12973
- this.toastService.success(MessagesEnum.VEHICLE_LOGBOOK_UPDATED);
12974
- return plainToClass(VehicleLogbook, updatedVehicleLogbook);
12975
- }));
12976
- }
12977
- delete(logbook, vehicleId) {
12978
- return this.http.delete(`${this.environment.apiV2}/vehicles/${vehicleId}/logbooks/${logbook.id}`)
12979
- .pipe(map(() => {
12980
- this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.VEHICLE_LOGBOOK_DELETED, { logbook, vehicleId }));
12981
- this.toastService.success(MessagesEnum.VEHICLE_LOGBOOK_DELETED);
12982
- }));
12983
- }
12984
- }
12985
- VehicleLogbookService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleLogbookService, deps: [{ token: i1.HttpClient }, { token: EventDispatcherService }, { token: 'environment' }, { token: ToastService }], target: i0.ɵɵFactoryTarget.Injectable });
12986
- VehicleLogbookService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleLogbookService, providedIn: 'root' });
12987
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: VehicleLogbookService, decorators: [{
12988
- type: Injectable,
12989
- args: [{
12990
- providedIn: 'root'
12991
- }]
12992
- }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: EventDispatcherService }, { type: undefined, decorators: [{
12993
- type: Inject,
12994
- args: ['environment']
12995
- }] }, { type: ToastService }]; } });
12996
-
12997
13273
  /**
12998
13274
  * Service to work with XLSX (generate, download, e.t.c.)
12999
13275
  */
@@ -13247,13 +13523,28 @@ function taxReviewFilterPredicate(data, filter) {
13247
13523
  /**
13248
13524
  * Abstract form class
13249
13525
  * @TODO rename to AbstractFormGroup
13526
+ * @TODO Alex: refactor: check and improve logic
13250
13527
  */
13251
13528
  class AbstractForm extends FormGroup {
13252
13529
  constructor(controls, model, validatorOrOpts, asyncValidator) {
13253
13530
  super(controls, validatorOrOpts, asyncValidator);
13531
+ /**
13532
+ * Flag display if some form values changed
13533
+ */
13534
+ this.unsaved = false;
13254
13535
  this.onSubmit = new EventEmitter();
13255
13536
  this.model = model || this.createModelInstance();
13256
13537
  this.modelClass = this.model.constructor;
13538
+ this.initialValue = this.value;
13539
+ if (model && !model['id']) {
13540
+ this.markAsUnsaved();
13541
+ }
13542
+ this.valueChanges.subscribe(() => {
13543
+ !!model && !!model['id'] && isEqual(this.value, this.initialValue) ? this.markAsSaved() : this.markAsUnsaved();
13544
+ });
13545
+ }
13546
+ get saved() {
13547
+ return !this.unsaved;
13257
13548
  }
13258
13549
  /**
13259
13550
  * Check validation and return a new instance of generic model.
@@ -13270,14 +13561,97 @@ class AbstractForm extends FormGroup {
13270
13561
  this.onSubmit.emit(model);
13271
13562
  return model;
13272
13563
  }
13273
- addControl(name, control, options) {
13274
- super.addControl(name, control, options);
13275
- return this;
13564
+ addControl(name, control, options) {
13565
+ super.addControl(name, control, options);
13566
+ return this;
13567
+ }
13568
+ markAsUnsaved() {
13569
+ this.unsaved = true;
13570
+ }
13571
+ markAsSaved() {
13572
+ this.unsaved = false;
13573
+ }
13574
+ createModelInstance(data = {}) {
13575
+ return plainToClass(this.modelClass, data);
13576
+ }
13577
+ }
13578
+
13579
+ /**
13580
+ * Form with loan details.
13581
+ * Loan could be created from bank account (Bank Loan) or directly from loan page (Vehicle Loan)
13582
+ */
13583
+ class LoanForm extends AbstractForm {
13584
+ constructor(loan = plainToClass(Loan, {})) {
13585
+ super({
13586
+ type: new FormControl(loan.type, Validators.required),
13587
+ amount: new FormControl(loan.amount, Validators.required),
13588
+ interestRate: new FormControl(loan.interestRate, [Validators.required, Validators.min(0), Validators.max(100)]),
13589
+ commencementDate: new FormControl(loan.commencementDate, Validators.required),
13590
+ repaymentAmount: new FormControl(loan.repaymentAmount, Validators.required),
13591
+ repaymentFrequency: new FormControl(loan.repaymentFrequency, Validators.required),
13592
+ term: new FormControl(loan.term, Validators.required),
13593
+ // interestType is predefined for vehicle loans
13594
+ interestType: new FormControl({ value: loan.interestType, disabled: !loan.bankAccount }, Validators.required),
13595
+ // availableRedraw is predefined for vehicle loans
13596
+ availableRedraw: new FormControl({ value: loan.availableRedraw, disabled: !loan.bankAccount }, Validators.required),
13597
+ // repaymentType is predefined for vehicle loans
13598
+ repaymentType: new FormControl({ value: loan.repaymentType, disabled: !loan.bankAccount }, Validators.required),
13599
+ }, loan);
13600
+ this.loan = loan;
13601
+ // Set data which always the same for vehicle loans
13602
+ if (!loan.bankAccount) {
13603
+ Object.assign(this.model, {
13604
+ repaymentType: LoanRepaymentTypeEnum.PRINCIPAL_AND_INTEREST,
13605
+ availableRedraw: 0,
13606
+ interestType: LoanInterestTypeEnum.FIXED_RATE
13607
+ });
13608
+ }
13609
+ this.updateTermValidation();
13610
+ this.listenEvents();
13611
+ }
13612
+ listenEvents() {
13613
+ // We need to set term automatically only for bank loans.
13614
+ // For vehicle loans user should fill it manually with validation depended of frequency
13615
+ if (!!this.loan.bankAccount) {
13616
+ this.listenTypeChanges();
13617
+ }
13618
+ else {
13619
+ this.listenRepaymentFrequencyChanges();
13620
+ }
13621
+ }
13622
+ /**
13623
+ * Set term automatically by loan type changes
13624
+ */
13625
+ listenTypeChanges() {
13626
+ this.get('type').valueChanges.subscribe((type) => {
13627
+ this.get('term').setValue(LoanForm.mortgageLoanTypes.includes(type) ? Loan.mortgageDefaultTerm : Loan.loanDefaultTerm);
13628
+ });
13629
+ }
13630
+ /**
13631
+ * term validation depends on selected repaymentFrequency
13632
+ */
13633
+ listenRepaymentFrequencyChanges() {
13634
+ this.get('repaymentFrequency').valueChanges.subscribe(() => {
13635
+ this.updateTermValidation();
13636
+ });
13276
13637
  }
13277
- createModelInstance(data = {}) {
13278
- return plainToClass(this.modelClass, data);
13638
+ /**
13639
+ * For vehicle loans term has a maximum value depended of repayment frequency
13640
+ */
13641
+ updateTermValidation() {
13642
+ const currentRepaymentFrequency = this.get('repaymentFrequency').value;
13643
+ // term validation depends on selected repayment frequency, so can not validate when frequency is empty
13644
+ // repaymentType is required field, so we don't need to clear validation
13645
+ if (!currentRepaymentFrequency) {
13646
+ return;
13647
+ }
13648
+ const termControl = this.get('term');
13649
+ const maxTermValue = LoanMaxNumberOfPaymentsEnum[LoanRepaymentFrequencyEnum[currentRepaymentFrequency]];
13650
+ termControl.setValidators([Validators.max(maxTermValue)]);
13651
+ termControl.updateValueAndValidity();
13279
13652
  }
13280
13653
  }
13654
+ LoanForm.mortgageLoanTypes = [LoanTypeEnum.MORTGAGE, LoanTypeEnum.HOME_EQUITY_LINE_OF_CREDIT, LoanTypeEnum.HOME_LOAN];
13281
13655
 
13282
13656
  /**
13283
13657
  * Check if at least one form field is true, otherwise form is invalid.
@@ -13362,6 +13736,23 @@ function passwordMatchValidator(newPassControlName, confirmPassControlName) {
13362
13736
  };
13363
13737
  }
13364
13738
 
13739
+ var MessagesEnum;
13740
+ (function (MessagesEnum) {
13741
+ MessagesEnum["INVALID_DATE"] = "The date should not be before $1";
13742
+ })(MessagesEnum || (MessagesEnum = {}));
13743
+
13744
+ /**
13745
+ * Validation function, that checks If date form value is more than provided date
13746
+ */
13747
+ function minDateValidator(date, message = MessagesEnum.INVALID_DATE.replace('$1', new DatePipe('en-US').transform(date))) {
13748
+ return (control) => {
13749
+ if (!control.value || (control.value >= date)) {
13750
+ return null;
13751
+ }
13752
+ return { minDate: message };
13753
+ };
13754
+ }
13755
+
13365
13756
  /**
13366
13757
  * Validator that check if sum amount of provided fields is greater than provided sum
13367
13758
  * @param field to check in each formArray element
@@ -13448,50 +13839,144 @@ class BankAccountPropertiesForm extends FormArray {
13448
13839
  }
13449
13840
  }
13450
13841
 
13842
+ class SoleBusinessForm extends AbstractForm {
13843
+ constructor(business = plainToClass(SoleBusiness, {})) {
13844
+ super({
13845
+ name: new FormControl(business.name, Validators.required),
13846
+ code: new FormControl(business.code, Validators.required),
13847
+ description: new FormControl(business.description),
13848
+ website: new FormControl(business.website)
13849
+ }, business);
13850
+ }
13851
+ }
13852
+
13853
+ /**
13854
+ * Form array with bank account business allocations
13855
+ * @TODO create AbstractFormArray
13856
+ */
13857
+ class SoleBusinessAllocationsForm extends FormArray {
13858
+ constructor(businessAllocations) {
13859
+ super(((businessAllocations === null || businessAllocations === void 0 ? void 0 : businessAllocations.length) ? businessAllocations : [plainToClass(SoleBusinessAllocation, {})])
13860
+ .map((businessAllocation) => {
13861
+ return new FormGroup({
13862
+ business: new FormControl(businessAllocation === null || businessAllocation === void 0 ? void 0 : businessAllocation.business, Validators.required),
13863
+ percent: new FormControl(businessAllocation.percent, Validators.required)
13864
+ });
13865
+ }), [
13866
+ conditionalValidator((control) => control.get('tankType').value === TankTypeEnum.SOLE, Validators.required),
13867
+ fieldsSumValidator('percent', 100)
13868
+ ]);
13869
+ }
13870
+ add() {
13871
+ this.push(new FormGroup({
13872
+ business: new FormControl(null, Validators.required),
13873
+ // @TODO disable for loans
13874
+ percent: new FormControl({ value: this.getRemainingPercent(), disabled: !this.at(0).contains('percent') }, Validators.required),
13875
+ // @TODO enable for loans
13876
+ // amount: new FormControl(
13877
+ // {value: this.bankAccount.currentBalance * businessAllocation.percent / 100},
13878
+ // [Validators.required, Validators.max(Math.abs(this.bankAccount.currentBalance))]
13879
+ // ),
13880
+ }));
13881
+ }
13882
+ // @TODO enable for loans
13883
+ // /**
13884
+ // * Recalculate business allocation percentage for current business form group and round to no more than 3 decimal places
13885
+ // * @param amount: new control value
13886
+ // * @param currentBusinessGroup for which amount will be recalculated
13887
+ // */
13888
+ // recalculateBusinessPercentage(amount: number, currentBusinessGroup: FormGroup): void {
13889
+ // currentBusinessGroup.get('percent').setValue(
13890
+ // roundTo(amount / this.bankAccount.currentBalance, 3)
13891
+ // );
13892
+ // }
13893
+ enablePercent() {
13894
+ this.controls.forEach((businessFormGroup) => {
13895
+ businessFormGroup.get('percent').enable();
13896
+ });
13897
+ }
13898
+ disablePercent() {
13899
+ this.controls.forEach((businessFormGroup) => {
13900
+ businessFormGroup.get('percent').disable();
13901
+ });
13902
+ }
13903
+ /**
13904
+ * Percentage available for adding a new bank account business allocation.
13905
+ * Remaining percent can't be more than 100 and less than 0
13906
+ */
13907
+ getRemainingPercent() {
13908
+ const currentTotalPercent = this.controls.reduce((sum, control) => sum + control.get('percent').value, 0);
13909
+ return currentTotalPercent < 100 ? 100 - currentTotalPercent : 0;
13910
+ }
13911
+ }
13912
+
13913
+ class SoleContactForm extends AbstractForm {
13914
+ constructor(contact = plainToClass(SoleContact, {})) {
13915
+ super({
13916
+ name: new FormControl(contact.name, Validators.required),
13917
+ abn: new FormControl(contact.abn, [Validators.minLength(11), Validators.maxLength(11)]),
13918
+ firstName: new FormControl(contact.firstName, Validators.required),
13919
+ lastName: new FormControl(contact.lastName, Validators.required),
13920
+ email: new FormControl(contact.email, [Validators.required, Validators.email]),
13921
+ // @TODO Alex: create phone form and phone form control
13922
+ phone: new FormControl(contact.phone),
13923
+ // @TODO Alex: create address form and address form control
13924
+ address: new FormControl(contact.address)
13925
+ }, contact);
13926
+ }
13927
+ }
13928
+
13929
+ class SoleDetailsForm extends AbstractForm {
13930
+ constructor(soleDetails) {
13931
+ super({
13932
+ abn: new FormControl(soleDetails.abn, [Validators.required, Validators.minLength(11), Validators.maxLength(11)]),
13933
+ isGST: new FormControl(soleDetails.isGST || false)
13934
+ }, soleDetails);
13935
+ }
13936
+ }
13937
+
13938
+ class SoleInvoiceTemplateForm extends AbstractForm {
13939
+ constructor(invoiceTemplate) {
13940
+ super({
13941
+ name: new FormControl(invoiceTemplate.name, Validators.required),
13942
+ isTaxIncluded: new FormControl(invoiceTemplate.isTaxIncluded),
13943
+ term: new FormControl(invoiceTemplate.term, [Validators.required, Validators.min(0)]),
13944
+ bankAccount: new FormControl(invoiceTemplate.bankAccount)
13945
+ }, invoiceTemplate);
13946
+ }
13947
+ }
13948
+
13451
13949
  class BankAccountAllocationForm extends AbstractForm {
13452
13950
  constructor(bankAccount) {
13453
13951
  super({
13454
- tankType: new FormControl(bankAccount ? bankAccount.tankType : null, Validators.required),
13952
+ tankType: new FormControl(bankAccount ? bankAccount.tankType : null, Validators.required)
13455
13953
  }, plainToClass(BankAccount, bankAccount || {}));
13456
13954
  this.bankAccount = bankAccount;
13457
13955
  if (bankAccount === null || bankAccount === void 0 ? void 0 : bankAccount.isPropertyTank()) {
13458
13956
  this.addControl('bankAccountProperties', new BankAccountPropertiesForm(bankAccount.bankAccountProperties));
13459
13957
  }
13958
+ if (bankAccount === null || bankAccount === void 0 ? void 0 : bankAccount.isSoleTank()) {
13959
+ this.addControl('businessAllocations', new SoleBusinessAllocationsForm(bankAccount.businessAllocations));
13960
+ }
13460
13961
  this.watchTankType();
13461
13962
  }
13462
13963
  watchTankType() {
13463
13964
  this.get('tankType').valueChanges.subscribe((tankType) => {
13464
- var _a;
13465
- // @TODO vik add businessAllocation
13466
- if (tankType === TankTypeEnum.PROPERTY) {
13467
- this.addControl('bankAccountProperties', new BankAccountPropertiesForm((_a = this.bankAccount) === null || _a === void 0 ? void 0 : _a.bankAccountProperties));
13468
- }
13469
- else {
13470
- this.removeControl('bankAccountProperties');
13965
+ var _a, _b;
13966
+ this.removeControl('bankAccountProperties');
13967
+ this.removeControl('businessAllocations');
13968
+ switch (tankType) {
13969
+ case TankTypeEnum.PROPERTY:
13970
+ this.addControl('bankAccountProperties', new BankAccountPropertiesForm((_a = this.bankAccount) === null || _a === void 0 ? void 0 : _a.bankAccountProperties));
13971
+ break;
13972
+ case TankTypeEnum.SOLE:
13973
+ this.addControl('businessAllocations', new SoleBusinessAllocationsForm((_b = this.bankAccount) === null || _b === void 0 ? void 0 : _b.businessAllocations));
13974
+ break;
13471
13975
  }
13472
13976
  });
13473
13977
  }
13474
13978
  }
13475
13979
 
13476
- /**
13477
- * Form with bank account loan details
13478
- */
13479
- class BankAccountLoanForm extends AbstractForm {
13480
- constructor(loan = plainToClass(Loan, {})) {
13481
- super({
13482
- type: new FormControl(loan.type, Validators.required),
13483
- amount: new FormControl(loan.amount, Validators.required),
13484
- repaymentType: new FormControl(loan.repaymentType, Validators.required),
13485
- interestRate: new FormControl(loan.interestRate, [Validators.required, Validators.min(0), Validators.max(100)]),
13486
- interestType: new FormControl(loan.interestType, Validators.required),
13487
- availableRedraw: new FormControl(loan.availableRedraw, Validators.required),
13488
- commencementDate: new FormControl(loan.commencementDate, Validators.required),
13489
- repaymentAmount: new FormControl(loan.repaymentAmount, Validators.required),
13490
- repaymentFrequency: new FormControl(loan.repaymentFrequency, Validators.required)
13491
- }, loan);
13492
- }
13493
- }
13494
-
13495
13980
  /**
13496
13981
  * Form is using for import basiq bank accounts.
13497
13982
  * Basiq accounts has all data except tank type, properties and loan partially
@@ -13500,7 +13985,10 @@ class BankAccountImportForm extends BankAccountAllocationForm {
13500
13985
  constructor(bankAccount) {
13501
13986
  super(bankAccount);
13502
13987
  if (bankAccount.isLoan()) {
13503
- this.addControl('loan', new BankAccountLoanForm(bankAccount.loan));
13988
+ // Attach bank account to loan for LoanForm's logic
13989
+ // @TODO Alex/Vik: we should use separated API for bank accounts and loans
13990
+ const loan = plainToClass(Loan, Object.assign(bankAccount.loan, { bankAccount: Object.assign(bankAccount, { loan: null }) }));
13991
+ this.addControl('loan', new LoanForm(loan));
13504
13992
  }
13505
13993
  // basiq account import form should be disabled (unchecked) by default
13506
13994
  this.disable();
@@ -13529,8 +14017,9 @@ class BankAccountAddManualForm extends BankAccountAllocationForm {
13529
14017
  */
13530
14018
  listenTypeChanges() {
13531
14019
  this.get('type').valueChanges.subscribe((type) => {
13532
- if (BankAccount.loanTypes.includes(type)) {
13533
- this.addControl('loan', new BankAccountLoanForm());
14020
+ if (type === BankAccountTypeEnum.LOAN) {
14021
+ // Set prefilled term for bank account loan
14022
+ this.addControl('loan', new LoanForm(plainToClass(Loan, { bankAccount: this.model })));
13534
14023
  }
13535
14024
  else {
13536
14025
  this.removeControl('loan');
@@ -13724,125 +14213,6 @@ class UserInviteForm extends AbstractForm {
13724
14213
  }
13725
14214
  }
13726
14215
 
13727
- class VehicleForm extends AbstractForm {
13728
- constructor(vehicle = plainToClass(Vehicle, {})) {
13729
- super({
13730
- name: new FormControl(vehicle.name, [Validators.required, Validators.maxLength(VehicleForm.maxNameLength)])
13731
- }, vehicle);
13732
- this.vehicle = vehicle;
13733
- }
13734
- }
13735
- VehicleForm.maxNameLength = 60;
13736
-
13737
- class VehicleClaimForm extends AbstractForm {
13738
- constructor(vehicleClaim, logbooks) {
13739
- super({
13740
- method: new FormControl(vehicleClaim.method, Validators.required),
13741
- isManual: new FormControl(vehicleClaim.isManual),
13742
- kilometers: new FormControl({
13743
- value: vehicleClaim.kilometers,
13744
- disabled: !vehicleClaim.isManual
13745
- }),
13746
- workUsage: new FormControl({
13747
- value: vehicleClaim.workUsage,
13748
- disabled: !vehicleClaim.isManual
13749
- })
13750
- }, vehicleClaim);
13751
- this.vehicleClaim = vehicleClaim;
13752
- this.logbooks = logbooks;
13753
- this.setIsManualState();
13754
- this.listenMethodChanges();
13755
- this.listenIsManualChanges();
13756
- }
13757
- /**
13758
- * Check if vehicle claim method changed
13759
- */
13760
- isMethodChanged() {
13761
- return this.vehicleClaim.method !== this.get('method').value;
13762
- }
13763
- /**
13764
- * Check if KLMs method selected
13765
- */
13766
- isKLMsMethod() {
13767
- return this.get('method').value === VehicleClaimMethodEnum.KMS;
13768
- }
13769
- /**
13770
- * Check if Logbook method selected
13771
- */
13772
- isLogbookMethod() {
13773
- return this.get('method').value === VehicleClaimMethodEnum.LOGBOOK;
13774
- }
13775
- /**
13776
- * Check if user selected manual calculation
13777
- */
13778
- isManual() {
13779
- return this.get('isManual').value;
13780
- }
13781
- /**
13782
- * @TODO save model, add generics and handle it in AbstractForm
13783
- */
13784
- submit() {
13785
- return plainToClass(VehicleClaim, Object.assign({}, this.vehicleClaim, this.getRawValue()));
13786
- }
13787
- setIsManualState() {
13788
- if (this.logbooks.isBestPeriodExist()) {
13789
- this.get('isManual').enable();
13790
- }
13791
- else {
13792
- this.get('isManual').disable();
13793
- this.get('isManual').setValue(true);
13794
- }
13795
- }
13796
- /**
13797
- * Handle method field value changes.
13798
- * Set work usage value depended of selected method.
13799
- */
13800
- listenMethodChanges() {
13801
- this.get('method').valueChanges.subscribe((method) => {
13802
- if (method === VehicleClaimMethodEnum.KMS) {
13803
- this.get('workUsage').setValue(0);
13804
- }
13805
- else if (method === VehicleClaimMethodEnum.LOGBOOK && !this.isManual()) {
13806
- this.get('workUsage').setValue(this.logbooks.getBestPeriod().workUsage);
13807
- }
13808
- this.setValues();
13809
- });
13810
- }
13811
- /**
13812
- * Handle isManual field value changes.
13813
- * Enable/disable fields depended of isManual value
13814
- */
13815
- listenIsManualChanges() {
13816
- this.get('isManual').valueChanges.subscribe((isManual) => {
13817
- if (isManual) {
13818
- this.get('kilometers').enable();
13819
- this.get('workUsage').enable();
13820
- }
13821
- else {
13822
- this.get('kilometers').disable();
13823
- this.get('workUsage').disable();
13824
- }
13825
- this.setValues();
13826
- });
13827
- }
13828
- /**
13829
- * Set automatic calculated values depended of current method for non-manual vehicle claim
13830
- */
13831
- setValues() {
13832
- if (this.isManual()) {
13833
- return;
13834
- }
13835
- switch (this.get('method').value) {
13836
- case VehicleClaimMethodEnum.LOGBOOK:
13837
- this.get('workUsage').setValue(this.logbooks.getBestPeriod().workUsage);
13838
- break;
13839
- case VehicleClaimMethodEnum.KMS:
13840
- const businessKms = this.logbooks.getBusinessLogbooks().getKlms();
13841
- this.get('kilometers').setValue(businessKms < this.vehicleClaim.kmsLimit ? businessKms : this.vehicleClaim.kmsLimit);
13842
- }
13843
- }
13844
- }
13845
-
13846
14216
  /**
13847
14217
  * @Todo waiting for the Sole tank implementation
13848
14218
  */
@@ -13879,7 +14249,7 @@ class MyTaxDeductionsForm extends AbstractForm {
13879
14249
  var _a;
13880
14250
  super({
13881
14251
  vehicleClaimMethod: new FormControl({
13882
- value: (_a = deductions.vehicleClaim) === null || _a === void 0 ? void 0 : _a.method,
14252
+ value: (_a = deductions.vehicleClaimDetails) === null || _a === void 0 ? void 0 : _a.method,
13883
14253
  disabled: true
13884
14254
  }),
13885
14255
  vehicleExpensesTotalAmount: new FormControl({
@@ -14222,41 +14592,110 @@ class MyTaxRentForm extends AbstractForm {
14222
14592
  }
14223
14593
  }
14224
14594
 
14225
- class SoleBusinessForm extends AbstractForm {
14226
- constructor(business = plainToClass(SoleBusiness, {})) {
14595
+ /**
14596
+ * Add/Edit Vehicle form
14597
+ */
14598
+ class VehicleForm extends AbstractForm {
14599
+ constructor(vehicle = plainToClass(Vehicle, {})) {
14227
14600
  super({
14228
- name: new FormControl(business.name, Validators.required),
14229
- code: new FormControl(business.code, Validators.required),
14230
- description: new FormControl(business.description),
14231
- website: new FormControl(business.website)
14232
- }, business);
14601
+ name: new FormControl(vehicle.name, [Validators.required, Validators.maxLength(VehicleForm.maxNameLength)])
14602
+ }, vehicle);
14603
+ this.vehicle = vehicle;
14233
14604
  }
14234
14605
  }
14606
+ VehicleForm.maxNameLength = 60;
14235
14607
 
14236
- class SoleContactForm extends AbstractForm {
14237
- constructor(contact = plainToClass(SoleContact, {})) {
14608
+ /**
14609
+ * Add/Edit Vehicle Claim form
14610
+ */
14611
+ class VehicleClaimForm extends AbstractForm {
14612
+ /**
14613
+ * @param vehicleClaim required even for the new claim, because claim needs business for sole tank
14614
+ * @param details required for form controls disabled state management
14615
+ */
14616
+ constructor(vehicleClaim, details) {
14238
14617
  super({
14239
- name: new FormControl(contact.name, Validators.required),
14240
- abn: new FormControl(contact.abn, [Validators.minLength(11), Validators.maxLength(11)]),
14241
- firstName: new FormControl(contact.firstName, Validators.required),
14242
- lastName: new FormControl(contact.lastName, Validators.required),
14243
- email: new FormControl(contact.email, [Validators.required, Validators.email]),
14244
- // @TODO Alex: create phone form and phone form control
14245
- phone: new FormControl(contact.phone),
14246
- // @TODO Alex: create address form and address form control
14247
- address: new FormControl(contact.address)
14248
- }, contact);
14618
+ kilometers: new FormControl({
14619
+ value: vehicleClaim.kilometers,
14620
+ disabled: !details.isManual || details.isLogbookMethod()
14621
+ }),
14622
+ workUsage: new FormControl({
14623
+ value: vehicleClaim.workUsage,
14624
+ disabled: !details.isManual || details.isKlmsMethod()
14625
+ })
14626
+ }, vehicleClaim);
14249
14627
  }
14250
14628
  }
14251
14629
 
14252
- class SoleDetailsForm extends AbstractForm {
14253
- constructor(soleDetails) {
14630
+ /**
14631
+ * Add/Edit vehicle claim details form
14632
+ */
14633
+ class VehicleClaimDetailsForm extends AbstractForm {
14634
+ /**
14635
+ * @param vehicleClaimDetails required because we create a new details with prefilled data (like Financial year)
14636
+ * @param logbooks required for isManual field disabled state management
14637
+ */
14638
+ constructor(vehicleClaimDetails, logbooks) {
14254
14639
  super({
14255
- abn: new FormControl(soleDetails.abn, [Validators.required, Validators.minLength(11), Validators.maxLength(11)]),
14256
- isGST: new FormControl(soleDetails.isGST || false)
14257
- }, soleDetails);
14640
+ method: new FormControl(vehicleClaimDetails.method, Validators.required),
14641
+ isManual: new FormControl({
14642
+ value: vehicleClaimDetails.isManual,
14643
+ disabled: !logbooks.isBestPeriodExist()
14644
+ }),
14645
+ }, vehicleClaimDetails);
14646
+ }
14647
+ }
14648
+
14649
+ /**
14650
+ * Add/Edit vehicle logbook form.
14651
+ * Behavior cases:
14652
+ * 1) Create the first logbook OR Edit the single logbook: all fields enabled
14653
+ * 2) Create the non-first logbook OR Edit the last logbook: odometerStart disabled
14654
+ * 3) Edit the non-last logbook: odometerStart, odometerEnd, date disabled
14655
+ */
14656
+ class VehicleLogbookForm extends AbstractForm {
14657
+ /**
14658
+ * @param logbook required because we need to set vehicle allocation and we can not set in in the form
14659
+ * @param logbooks list of all logbooks related to current logbook's vehicle. Required for form fields validation and disabled state management
14660
+ */
14661
+ constructor(logbook, logbooks) {
14662
+ super({
14663
+ description: new FormControl(logbook.description, [Validators.required, Validators.maxLength(VehicleLogbookForm.maxDescriptionLength)]),
14664
+ isPersonal: new FormControl(logbook.isPersonal),
14665
+ date: new FormControl(logbook.date, Validators.required),
14666
+ odometerStart: new FormControl(logbook.odometerStart, Validators.required),
14667
+ odometerEnd: new FormControl(logbook.odometerEnd, Validators.required),
14668
+ business: new FormControl(logbook.business),
14669
+ // @TODO Alex: remove when backend fixed
14670
+ purpose: new FormControl(VehicleLogbookPurposeEnum.BUSINESS)
14671
+ }, logbook);
14672
+ this.logbook = logbook;
14673
+ this.logbooks = logbooks;
14674
+ switch (true) {
14675
+ // Create the first or edit the single logbook
14676
+ case !logbook.id && !logbooks.length:
14677
+ case !!logbook.id && logbooks.length === 1:
14678
+ this.get('odometerStart').setValidators(Validators.min(0));
14679
+ this.get('date').setValidators(dateRangeValidator(new FinancialYear().startDate, new FinancialYear().endDate));
14680
+ break;
14681
+ // Create the non-first or edit the last logbook
14682
+ case !logbook.id && !!logbooks.length:
14683
+ case !!logbook.id && logbook.id === logbooks.last.id && logbooks.length > 1:
14684
+ this.get('odometerStart').disable();
14685
+ this.get('odometerEnd').setValidators(Validators.min(logbooks.last.odometerEnd));
14686
+ if (!!logbook.id) {
14687
+ }
14688
+ this.get('date').setValidators(dateRangeValidator(logbooks.last.date, new FinancialYear().endDate));
14689
+ break;
14690
+ // Edit the non-last logbook
14691
+ case !!logbook.id && logbook.id !== logbooks.last.id && logbooks.length > 1:
14692
+ this.get('odometerStart').disable();
14693
+ this.get('odometerEnd').disable();
14694
+ this.get('date').disable();
14695
+ }
14258
14696
  }
14259
14697
  }
14698
+ VehicleLogbookForm.maxDescriptionLength = 60;
14260
14699
 
14261
14700
  // @TODO Alex: Create indexes everywhere and break this file to imports from indexes
14262
14701
 
@@ -14264,5 +14703,5 @@ class SoleDetailsForm extends AbstractForm {
14264
14703
  * Generated bundle index. Do not edit.
14265
14704
  */
14266
14705
 
14267
- export { AbstractForm, AbstractModel, AccountSetupItem, AccountSetupItemCollection, AccountSetupService, Address, AddressService, AddressTypeEnum, AlphabetColorsEnum, AppEvent, AppEventTypeEnum, AssetEntityTypeEnum, AssetTypeEnum, AssetsService, AuthService, BANK_ACCOUNT_TYPES, Badge, BadgeColorEnum, Bank, BankAccount, BankAccountAddManualForm, BankAccountAllocationForm, BankAccountCalculationService, BankAccountChartData, BankAccountCollection, BankAccountImportForm, BankAccountLoanForm, BankAccountPropertiesForm, BankAccountProperty, BankAccountService, BankAccountStatusEnum, BankAccountTypeEnum, BankAccountsImportForm, BankConnection, BankConnectionService, BankConnectionStatusEnum, BankLoginData, BankLoginForm, BankService, BankTransaction, BankTransactionCalculationService, BankTransactionChartData, BankTransactionCollection, BankTransactionService, BankTransactionSummaryFieldsEnum, BankTransactionTypeEnum, BasiqConfig, BasiqJob, BasiqService, BasiqToken, BorrowingExpense, BorrowingExpenseLoan, BorrowingExpenseService, CAPITAL_COSTS_ITEMS, CHART_ACCOUNTS_CATEGORIES, CalculationFormItem, CalculationFormTypeEnum, CgtExemptionAndRolloverCodeEnum, ChartAccounts, ChartAccountsCategoryECollection, ChartAccountsCategoryEnum, ChartAccountsCollection, ChartAccountsDepreciation, ChartAccountsDepreciationService, ChartAccountsEtpEnum, ChartAccountsHeading, ChartAccountsHeadingListEnum, ChartAccountsHeadingTaxDeductibleEnum, ChartAccountsHeadingTaxableEnum, ChartAccountsHeadingVehicleListEnum, ChartAccountsListEnum, ChartAccountsMetadata, ChartAccountsMetadataListEnum, ChartAccountsMetadataTypeEnum, ChartAccountsService, ChartAccountsTaxLabelsEnum, ChartAccountsTypeEnum, ChartAccountsValue, ChartData, ChartSerie, Chat, ChatService, ChatStatusEnum, ChatViewTypeEnum, ClientCollection, ClientDetails, ClientDetailsMedicareExemptionEnum, ClientDetailsWorkDepreciationCalculationEnum, ClientDetailsWorkingHolidayMakerEnum, ClientIncomeTypes, ClientIncomeTypesForm, ClientIncomeTypesService, ClientInvite, ClientInviteCollection, ClientInviteService, ClientInviteStatusEnum, ClientInviteTypeEnum, ClientMovement, ClientMovementCollection, ClientMovementService, ClientPortfolioChartData, ClientPortfolioReport, ClientPortfolioReportCollection, ClientPortfolioReportService, Collection, CollectionDictionary, CorelogicService, CorelogicSuggestion, Country, DEDUCTION_CATEGORIES, DEFAULT_VEHICLE_EXPENSE, DEPRECIATION_GROUPS, DOCUMENT_FILE_TYPES, DeductionClothingTypeEnum, DeductionSelfEducationTypeEnum, Depreciation, DepreciationCalculationEnum, DepreciationCalculationPercentEnum, DepreciationCapitalProject, DepreciationCapitalProjectService, DepreciationCollection, DepreciationForecast, DepreciationForecastCollection, DepreciationGroup, DepreciationGroupEnum, DepreciationGroupItem, DepreciationLvpAssetTypeEnum, DepreciationLvpReportItem, DepreciationLvpReportItemCollection, DepreciationReceipt, DepreciationReportItem, DepreciationReportItemCollection, DepreciationService, DepreciationTypeEnum, DepreciationWriteOffAmountEnum, Dictionary, Document, DocumentApiUrlPrefixEnum, DocumentFolder, DocumentFolderService, ENDPOINTS, EmployeeCollection, EmployeeDetails, EmployeeInvite, EmployeeInviteService, EmployeeService, Endpoint, EquityPositionChartService, EventDispatcherService, ExportDataTable, ExportFormatEnum, ExportFormatterService, ExportableCollection, FacebookService, FinancialYear, Firm, FirmService, FirmTypeEnum, HeaderTitleService, IconsFileEnum, IncomeAmountTypeEnum, IncomePosition, IncomeSource, IncomeSourceChartData, IncomeSourceCollection, IncomeSourceForecast, IncomeSourceForecastService, IncomeSourceForecastTrustTypeEnum, IncomeSourceService, IncomeSourceType, IncomeSourceTypeEnum, IncomeSourceTypeListOtherEnum, IncomeSourceTypeListSoleEnum, IncomeSourceTypeListWorkEnum, InterceptorsModule, IntercomService, InviteStatusEnum, JwtService, KompassifyService, Loan, LoanBankTypeEnum, LoanCollection, LoanFrequencyEnum, LoanInterestTypeEnum, LoanMaxNumberOfPaymentsEnum, LoanPayment, LoanPaymentCollection, LoanPayout, LoanPayoutTypeEnum, LoanRepaymentFrequencyEnum, LoanRepaymentTypeEnum, LoanService, LoanTypeEnum, LoanVehicleTypeEnum, LogbookPeriod, LoginForm, MODULE_URL_LIST, MONTHS, Message, MessageCollection, MessageDocument, MessageDocumentCollection, MessageDocumentService, MessageService, MonthNameShortEnum, MonthNumberEnum, MyAccountHistory, MyAccountHistoryInitiatedByEnum, MyAccountHistoryStatusEnum, MyAccountHistoryTypeEnum, MyTaxBusinessOrLosses, MyTaxBusinessOrLossesForm, MyTaxCgt, MyTaxCgtForm, MyTaxDeductions, MyTaxDeductionsForm, MyTaxDividends, MyTaxDividendsForm, MyTaxEmployeeShareSchemes, MyTaxEmployeeShareSchemesForm, MyTaxEstimate, MyTaxIncomeStatements, MyTaxIncomeStatementsForm, MyTaxIncomeTests, MyTaxIncomeTestsForm, MyTaxInterest, MyTaxInterestForm, MyTaxLosses, MyTaxLossesForm, MyTaxMedicareForm, MyTaxOffsets, MyTaxOffsetsForm, MyTaxOtherIncome, MyTaxOtherIncomeForm, MyTaxPartnershipsAndTrusts, MyTaxPartnershipsAndTrustsForm, MyTaxRent, MyTaxRentForm, Notification, Occupation, OccupationService, PASSWORD_REGEXPS, PasswordForm, PdfFromDataTableService, PdfFromDomElementService, PdfFromHtmlTableService, PdfOrientationEnum, PdfSettings, Phone, PhoneTypeEnum, PreloaderService, Property, PropertyCalculationService, PropertyCategory, PropertyCategoryListEnum, PropertyCategoryMovement, PropertyCategoryMovementService, PropertyCategoryService, PropertyCollection, PropertyDepreciationCalculationEnum, PropertyDocument, PropertyDocumentService, PropertyEquityChartData, PropertyEquityChartItem, PropertyForecast, PropertyReportItem, PropertyReportItemCollection, PropertyReportItemDepreciationCollection, PropertyReportItemTransaction, PropertyReportItemTransactionCollection, PropertySale, PropertySaleCollection, PropertySaleService, PropertySaleTaxExemptionMetadata, PropertyService, PropertyShare, PropertyShareAccessEnum, PropertyShareService, PropertyShareStatusEnum, PropertySubscription, PropertyTransactionReportService, PropertyValuation, RegisterClientForm, RegisterFirmForm, RegistrationInvite, RegistrationInviteStatusEnum, ReportItem, ReportItemCollection, ReportItemDetails, ResetPasswordForm, SUBSCRIPTION_DESCRIPTION, SUBSCRIPTION_TITLE, SalaryForecast, SalaryForecastFrequencyEnum, SalaryForecastService, ServiceNotificationService, ServiceNotificationStatusEnum, ServiceNotificationTypeEnum, ServicePayment, ServicePaymentStatusEnum, ServicePrice, ServicePriceRecurringIntervalEnum, ServicePriceService, ServicePriceTypeEnum, ServiceProduct, ServiceProductIdEnum, ServiceProductStatusEnum, ServiceSubscription, ServiceSubscriptionCollection, ServiceSubscriptionItem, ServiceSubscriptionStatusEnum, ShareFilterOptionsEnum, SoleBusiness, SoleBusinessAllocation, SoleBusinessForm, SoleBusinessLoss, SoleBusinessService, SoleContact, SoleContactForm, SoleContactService, SoleDetails, SoleDetailsForm, SoleDetailsService, SoleForecast, SoleForecastService, SoleInvoice, SoleInvoiceItem, SoleInvoiceTemplate, SpareDocumentSpareTypeEnum, SseService, SubscriptionService, SubscriptionTypeEnum, TAX_RETURN_CATEGORIES, TYPE_LOAN, TankTypeEnum, TaxCalculationMedicareExemptionEnum, TaxCalculationTypeEnum, TaxExemption, TaxExemptionEnum, TaxExemptionMetadata, TaxExemptionMetadataEnum, TaxExemptionService, TaxReturnCategoryListEnum, TaxReturnCategorySectionEnum, TaxReview, TaxReviewCollection, TaxReviewHistoryService, TaxReviewService, TaxReviewStatusEnum, TaxSummary, TaxSummaryListEnum, TaxSummarySection, TaxSummarySectionEnum, TaxSummaryService, TaxSummaryTaxSummaryEnum, TaxSummaryTypeEnum, TicketFeedbackEnum, TicketStatusEnum, TicketTypesEnum, Toast, ToastService, ToastTypeEnum, Transaction, TransactionAllocation, TransactionAllocationCollection, TransactionAllocationService, TransactionBase, TransactionCalculationService, TransactionCategoryEnum, TransactionCollection, TransactionMetadata, TransactionOperationEnum, TransactionReceipt, TransactionService, TransactionSourceEnum, TransactionTypeEnum, TtCoreModule, TutorialVideoService, USER_ROLES, USER_WORK_POSITION, User, UserEventSetting, UserEventSettingCollection, UserEventSettingFieldEnum, UserEventSettingService, UserEventStatusEnum, UserEventType, UserEventTypeCategory, UserEventTypeClientTypeEnum, UserEventTypeEmployeeTypeEnum, UserEventTypeFrequencyEnum, UserEventTypeService, UserEventTypeUserTypeEnum, UserInviteForm, UserMedicareExemptionEnum, UserRolesEnum, UserService, UserStatusEnum, UserSwitcherService, UserTitleEnum, UserToRegister, UserWorkDepreciationCalculationEnum, UserWorkingHolidayMakerEnum, UsersInviteService, Vehicle, VehicleClaim, VehicleClaimForm, VehicleClaimMethodEnum, VehicleClaimService, VehicleCollection, VehicleExpense, VehicleExpenseCollection, VehicleForm, VehicleLogbook, VehicleLogbookCollection, VehicleLogbookPurposeEnum, VehicleLogbookService, VehicleService, WORK_TANK_LOGBOOK_PURPOSE_OPTIONS, XlsxService, atLeastOneCheckedValidator, atoLinks, autocompleteValidator, cloneDeep, compare, compareMatOptions, conditionalValidator, createDate, displayMatOptions, enumToList, getDocIcon, passwordMatchValidator, passwordValidator, replace, roundTo, sort, sortDeep, taxReviewFilterPredicate };
14706
+ export { AbstractForm, AbstractModel, AccountSetupItem, AccountSetupItemCollection, AccountSetupService, Address, AddressService, AddressTypeEnum, AlphabetColorsEnum, AppEvent, AppEventTypeEnum, AssetEntityTypeEnum, AssetTypeEnum, AssetsService, AuthService, BANK_ACCOUNT_TYPES, Badge, BadgeColorEnum, Bank, BankAccount, BankAccountAddManualForm, BankAccountAllocationForm, BankAccountCalculationService, BankAccountChartData, BankAccountCollection, BankAccountImportForm, BankAccountPropertiesForm, BankAccountProperty, BankAccountService, BankAccountStatusEnum, BankAccountTypeEnum, BankAccountsImportForm, BankConnection, BankConnectionService, BankConnectionStatusEnum, BankLoginData, BankLoginForm, BankService, BankTransaction, BankTransactionCalculationService, BankTransactionChartData, BankTransactionCollection, BankTransactionService, BankTransactionSummaryFieldsEnum, BankTransactionTypeEnum, BasiqConfig, BasiqJob, BasiqService, BasiqToken, BorrowingExpense, BorrowingExpenseLoan, BorrowingExpenseService, CAPITAL_COSTS_ITEMS, CHART_ACCOUNTS_CATEGORIES, CalculationFormItem, CalculationFormTypeEnum, CgtExemptionAndRolloverCodeEnum, ChartAccounts, ChartAccountsCategoryECollection, ChartAccountsCategoryEnum, ChartAccountsCollection, ChartAccountsDepreciation, ChartAccountsDepreciationService, ChartAccountsEtpEnum, ChartAccountsHeading, ChartAccountsHeadingListEnum, ChartAccountsHeadingTaxDeductibleEnum, ChartAccountsHeadingTaxableEnum, ChartAccountsHeadingVehicleListEnum, ChartAccountsListEnum, ChartAccountsMetadata, ChartAccountsMetadataListEnum, ChartAccountsMetadataTypeEnum, ChartAccountsService, ChartAccountsTaxLabelsEnum, ChartAccountsTypeEnum, ChartAccountsValue, ChartData, ChartSerie, Chat, ChatService, ChatStatusEnum, ChatViewTypeEnum, ClientCollection, ClientDetails, ClientDetailsMedicareExemptionEnum, ClientDetailsWorkDepreciationCalculationEnum, ClientDetailsWorkingHolidayMakerEnum, ClientIncomeTypes, ClientIncomeTypesForm, ClientIncomeTypesService, ClientInvite, ClientInviteCollection, ClientInviteService, ClientInviteStatusEnum, ClientInviteTypeEnum, ClientMovement, ClientMovementCollection, ClientMovementService, ClientPortfolioChartData, ClientPortfolioReport, ClientPortfolioReportCollection, ClientPortfolioReportService, Collection, CollectionDictionary, CorelogicService, CorelogicSuggestion, Country, DEDUCTION_CATEGORIES, DEPRECIATION_GROUPS, DOCUMENT_FILE_TYPES, DeductionClothingTypeEnum, DeductionSelfEducationTypeEnum, Depreciation, DepreciationCalculationEnum, DepreciationCalculationPercentEnum, DepreciationCapitalProject, DepreciationCapitalProjectService, DepreciationCollection, DepreciationForecast, DepreciationForecastCollection, DepreciationGroup, DepreciationGroupEnum, DepreciationGroupItem, DepreciationLvpAssetTypeEnum, DepreciationLvpReportItem, DepreciationLvpReportItemCollection, DepreciationReceipt, DepreciationReportItem, DepreciationReportItemCollection, DepreciationService, DepreciationTypeEnum, DepreciationWriteOffAmountEnum, Dictionary, Document, DocumentApiUrlPrefixEnum, DocumentFolder, DocumentFolderService, ENDPOINTS, EmployeeCollection, EmployeeDetails, EmployeeInvite, EmployeeInviteService, EmployeeService, Endpoint, EquityPositionChartService, EventDispatcherService, ExportDataTable, ExportFormatEnum, ExportFormatterService, ExportableCollection, FacebookService, FinancialYear, Firm, FirmService, FirmTypeEnum, HeaderTitleService, IconsFileEnum, IncomeAmountTypeEnum, IncomePosition, IncomeSource, IncomeSourceChartData, IncomeSourceCollection, IncomeSourceForecast, IncomeSourceForecastService, IncomeSourceForecastTrustTypeEnum, IncomeSourceService, IncomeSourceType, IncomeSourceTypeEnum, IncomeSourceTypeListOtherEnum, IncomeSourceTypeListSoleEnum, IncomeSourceTypeListWorkEnum, InterceptorsModule, IntercomService, InviteStatusEnum, JwtService, KompassifyService, Loan, LoanBankTypeEnum, LoanCollection, LoanForm, LoanFrequencyEnum, LoanInterestTypeEnum, LoanMaxNumberOfPaymentsEnum, LoanPayment, LoanPaymentCollection, LoanPayout, LoanPayoutTypeEnum, LoanRepaymentFrequencyEnum, LoanRepaymentTypeEnum, LoanService, LoanTypeEnum, LoanVehicleTypeEnum, LogbookBestPeriodService, LogbookPeriod, LoginForm, MODULE_URL_LIST, MONTHS, Message, MessageCollection, MessageDocument, MessageDocumentCollection, MessageDocumentService, MessageService, MonthNameShortEnum, MonthNumberEnum, MyAccountHistory, MyAccountHistoryInitiatedByEnum, MyAccountHistoryStatusEnum, MyAccountHistoryTypeEnum, MyTaxBusinessOrLosses, MyTaxBusinessOrLossesForm, MyTaxCgt, MyTaxCgtForm, MyTaxDeductions, MyTaxDeductionsForm, MyTaxDividends, MyTaxDividendsForm, MyTaxEmployeeShareSchemes, MyTaxEmployeeShareSchemesForm, MyTaxEstimate, MyTaxIncomeStatements, MyTaxIncomeStatementsForm, MyTaxIncomeTests, MyTaxIncomeTestsForm, MyTaxInterest, MyTaxInterestForm, MyTaxLosses, MyTaxLossesForm, MyTaxMedicareForm, MyTaxOffsets, MyTaxOffsetsForm, MyTaxOtherIncome, MyTaxOtherIncomeForm, MyTaxPartnershipsAndTrusts, MyTaxPartnershipsAndTrustsForm, MyTaxRent, MyTaxRentForm, Notification, Occupation, OccupationService, PASSWORD_REGEXPS, PasswordForm, PdfFromDataTableService, PdfFromDomElementService, PdfFromHtmlTableService, PdfOrientationEnum, PdfSettings, Phone, PhoneTypeEnum, PreloaderService, Property, PropertyCalculationService, PropertyCategory, PropertyCategoryListEnum, PropertyCategoryMovement, PropertyCategoryMovementService, PropertyCategoryService, PropertyCollection, PropertyDepreciationCalculationEnum, PropertyDocument, PropertyDocumentService, PropertyEquityChartData, PropertyEquityChartItem, PropertyForecast, PropertyReportItem, PropertyReportItemCollection, PropertyReportItemDepreciationCollection, PropertyReportItemTransaction, PropertyReportItemTransactionCollection, PropertySale, PropertySaleCollection, PropertySaleService, PropertySaleTaxExemptionMetadata, PropertyService, PropertyShare, PropertyShareAccessEnum, PropertyShareService, PropertyShareStatusEnum, PropertySubscription, PropertyTransactionReportService, PropertyValuation, RegisterClientForm, RegisterFirmForm, RegistrationInvite, RegistrationInviteStatusEnum, ReportItem, ReportItemCollection, ReportItemDetails, ResetPasswordForm, SUBSCRIPTION_DESCRIPTION, SUBSCRIPTION_TITLE, SalaryForecast, SalaryForecastFrequencyEnum, SalaryForecastService, ServiceNotificationService, ServiceNotificationStatusEnum, ServiceNotificationTypeEnum, ServicePayment, ServicePaymentStatusEnum, ServicePrice, ServicePriceRecurringIntervalEnum, ServicePriceService, ServicePriceTypeEnum, ServiceProduct, ServiceProductIdEnum, ServiceProductStatusEnum, ServiceSubscription, ServiceSubscriptionCollection, ServiceSubscriptionItem, ServiceSubscriptionStatusEnum, ShareFilterOptionsEnum, SoleBusiness, SoleBusinessAllocation, SoleBusinessAllocationsForm, SoleBusinessForm, SoleBusinessLoss, SoleBusinessService, SoleContact, SoleContactForm, SoleContactService, SoleDetails, SoleDetailsForm, SoleDetailsService, SoleForecast, SoleForecastService, SoleInvoice, SoleInvoiceItem, SoleInvoiceTemplate, SoleInvoiceTemplateForm, SoleInvoiceTemplateService, SpareDocumentSpareTypeEnum, SseService, SubscriptionService, SubscriptionTypeEnum, TAX_RETURN_CATEGORIES, TYPE_LOAN, TankTypeEnum, TaxCalculationMedicareExemptionEnum, TaxCalculationTypeEnum, TaxExemption, TaxExemptionEnum, TaxExemptionMetadata, TaxExemptionMetadataEnum, TaxExemptionService, TaxReturnCategoryListEnum, TaxReturnCategorySectionEnum, TaxReview, TaxReviewCollection, TaxReviewHistoryService, TaxReviewService, TaxReviewStatusEnum, TaxSummary, TaxSummaryListEnum, TaxSummarySection, TaxSummarySectionEnum, TaxSummaryService, TaxSummaryTaxSummaryEnum, TaxSummaryTypeEnum, TicketFeedbackEnum, TicketStatusEnum, TicketTypesEnum, Toast, ToastService, ToastTypeEnum, Transaction, TransactionAllocation, TransactionAllocationCollection, TransactionAllocationService, TransactionBase, TransactionCalculationService, TransactionCategoryEnum, TransactionCollection, TransactionMetadata, TransactionOperationEnum, TransactionReceipt, TransactionService, TransactionSourceEnum, TransactionTypeEnum, TtCoreModule, TutorialVideoService, USER_ROLES, USER_WORK_POSITION, User, UserEventSetting, UserEventSettingCollection, UserEventSettingFieldEnum, UserEventSettingService, UserEventStatusEnum, UserEventType, UserEventTypeCategory, UserEventTypeClientTypeEnum, UserEventTypeEmployeeTypeEnum, UserEventTypeFrequencyEnum, UserEventTypeService, UserEventTypeUserTypeEnum, UserInviteForm, UserMedicareExemptionEnum, UserRolesEnum, UserService, UserStatusEnum, UserSwitcherService, UserTitleEnum, UserToRegister, UserWorkDepreciationCalculationEnum, UserWorkingHolidayMakerEnum, Vehicle, VehicleClaim, VehicleClaimCollection, VehicleClaimDetails, VehicleClaimDetailsForm, VehicleClaimDetailsMethodEnum, VehicleClaimDetailsService, VehicleClaimForm, VehicleClaimService, VehicleExpense, VehicleExpenseCollection, VehicleForm, VehicleLogbook, VehicleLogbookCollection, VehicleLogbookForm, VehicleLogbookPurposeEnum, VehicleLogbookService, VehicleService, XlsxService, atLeastOneCheckedValidator, atoLinks, autocompleteValidator, cloneDeep, compare, compareMatOptions, conditionalValidator, createDate, displayMatOptions, enumToList, fieldsSumValidator, getDocIcon, minDateValidator, passwordMatchValidator, passwordValidator, replace, roundTo, sort, sortDeep, taxReviewFilterPredicate };
14268
14707
  //# sourceMappingURL=taxtank-core.js.map