taxtank-core 0.19.2 → 0.21.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 (80) hide show
  1. package/bundles/taxtank-core.umd.js +646 -399
  2. package/bundles/taxtank-core.umd.js.map +1 -1
  3. package/esm2015/lib/collections/collection.js +6 -3
  4. package/esm2015/lib/db/Enums/bank-popular.enum.js +14 -0
  5. package/esm2015/lib/forms/abstract.form.js +11 -4
  6. package/esm2015/lib/forms/bank/bank-account/bank-account-add-manual.form.js +75 -0
  7. package/esm2015/lib/forms/bank/bank-account/bank-account-import.form.js +43 -0
  8. package/esm2015/lib/forms/bank/bank-account/bank-account-loan.form.js +23 -0
  9. package/esm2015/lib/forms/bank/bank-account/bank-account-properties.form.js +36 -0
  10. package/esm2015/lib/forms/bank/bank-account/bank-accounts-import.form.js +50 -0
  11. package/esm2015/lib/forms/index.js +6 -7
  12. package/esm2015/lib/forms/register/register-client.form.js +1 -2
  13. package/esm2015/lib/forms/report/my-tax/my-tax-income-statements.form.js +3 -3
  14. package/esm2015/lib/forms/user/password.form.js +3 -2
  15. package/esm2015/lib/forms/user/reset-password.form.js +2 -1
  16. package/esm2015/lib/interceptors/jwt-interceptor.js +6 -1
  17. package/esm2015/lib/interfaces/auth-tokens.interface.js +2 -0
  18. package/esm2015/lib/models/bank/bank.js +7 -2
  19. package/esm2015/lib/models/dictionary/dictionary.js +35 -0
  20. package/esm2015/lib/models/endpoint/endpoints.const.js +4 -2
  21. package/esm2015/lib/services/auth/auth.service.js +2 -2
  22. package/esm2015/lib/services/http/bank/bank-account/bank-account.service.js +7 -1
  23. package/esm2015/lib/services/http/bank/bank-connection/bank-connection.service.js +15 -45
  24. package/esm2015/lib/services/http/bank/bank.service.js +8 -1
  25. package/esm2015/lib/services/http/bank/basiq/basiq.service.js +52 -14
  26. package/esm2015/lib/services/http/facebook/facebook-auth-options.interface.js +2 -0
  27. package/esm2015/lib/services/http/facebook/facebook-auth-response.interface.js +2 -0
  28. package/esm2015/lib/services/http/facebook/facebook-status-response.interface.js +2 -0
  29. package/esm2015/lib/services/http/facebook/facebook.service.js +90 -0
  30. package/esm2015/lib/services/http/user/user.service.js +4 -1
  31. package/esm2015/lib/validators/at-least-one-enabled.validator.js +11 -0
  32. package/esm2015/lib/validators/autocomplete.validator.js +10 -0
  33. package/esm2015/lib/validators/index.js +2 -3
  34. package/esm2015/public-api.js +3 -2
  35. package/fesm2015/taxtank-core.js +537 -308
  36. package/fesm2015/taxtank-core.js.map +1 -1
  37. package/lib/collections/collection.d.ts +2 -1
  38. package/lib/db/Enums/bank-popular.enum.d.ts +12 -0
  39. package/lib/forms/abstract.form.d.ts +5 -3
  40. package/lib/forms/bank/bank-account/bank-account-add-manual.form.d.ts +25 -0
  41. package/lib/forms/bank/bank-account/bank-account-import.form.d.ts +15 -0
  42. package/lib/forms/bank/bank-account/bank-account-loan.form.d.ts +8 -0
  43. package/lib/forms/bank/bank-account/bank-account-properties.form.d.ts +11 -0
  44. package/lib/forms/bank/bank-account/bank-accounts-import.form.d.ts +12 -0
  45. package/lib/forms/index.d.ts +5 -6
  46. package/lib/interfaces/auth-tokens.interface.d.ts +7 -0
  47. package/lib/models/bank/bank.d.ts +1 -0
  48. package/lib/models/dictionary/dictionary.d.ts +12 -0
  49. package/lib/services/auth/auth.service.d.ts +2 -1
  50. package/lib/services/http/bank/bank-account/bank-account.service.d.ts +3 -0
  51. package/lib/services/http/bank/bank-connection/bank-connection.service.d.ts +0 -8
  52. package/lib/services/http/bank/bank.service.d.ts +2 -0
  53. package/lib/services/http/bank/basiq/basiq.service.d.ts +12 -3
  54. package/lib/services/http/facebook/facebook-auth-options.interface.d.ts +11 -0
  55. package/lib/services/http/facebook/facebook-auth-response.interface.d.ts +11 -0
  56. package/lib/services/http/facebook/facebook-status-response.interface.d.ts +9 -0
  57. package/lib/services/http/facebook/facebook.service.d.ts +38 -0
  58. package/lib/services/http/user/user.service.d.ts +1 -0
  59. package/lib/validators/at-least-one-enabled.validator.d.ts +5 -0
  60. package/lib/validators/{require-autocomplete.d.ts → autocomplete.validator.d.ts} +2 -1
  61. package/lib/validators/index.d.ts +1 -2
  62. package/package.json +1 -1
  63. package/public-api.d.ts +2 -1
  64. package/esm2015/lib/collections/bank.collection.js +0 -15
  65. package/esm2015/lib/forms/bank/bank-account-add-manual.form.js +0 -19
  66. package/esm2015/lib/forms/bank/bank-account-loan.form.js +0 -20
  67. package/esm2015/lib/forms/bank/bank-account-migrate.form.js +0 -15
  68. package/esm2015/lib/forms/bank/bank-account-properties.form.js +0 -15
  69. package/esm2015/lib/forms/bank/bank-account-property.form.js +0 -13
  70. package/esm2015/lib/forms/bank/bank-account.form.js +0 -66
  71. package/esm2015/lib/validators/require-autocomplete.js +0 -14
  72. package/esm2015/lib/validators/require-select.validator.js +0 -15
  73. package/lib/collections/bank.collection.d.ts +0 -7
  74. package/lib/forms/bank/bank-account-add-manual.form.d.ts +0 -10
  75. package/lib/forms/bank/bank-account-loan.form.d.ts +0 -5
  76. package/lib/forms/bank/bank-account-migrate.form.d.ts +0 -9
  77. package/lib/forms/bank/bank-account-properties.form.d.ts +0 -8
  78. package/lib/forms/bank/bank-account-property.form.d.ts +0 -5
  79. package/lib/forms/bank/bank-account.form.d.ts +0 -28
  80. package/lib/validators/require-select.validator.d.ts +0 -5
@@ -15,10 +15,11 @@ import * as moment from 'moment';
15
15
  import flatten from 'lodash/flatten';
16
16
  import hasIn from 'lodash/hasIn';
17
17
  import first from 'lodash/first';
18
- import cloneDeep$1 from 'lodash/cloneDeep';
19
- import compact from 'lodash/compact';
20
18
  import uniqBy from 'lodash/uniqBy';
21
19
  import concat from 'lodash/concat';
20
+ import { throwError as throwError$1 } from 'rxjs/internal/observable/throwError';
21
+ import cloneDeep$1 from 'lodash/cloneDeep';
22
+ import compact from 'lodash/compact';
22
23
  import { DateRange } from 'moment-range';
23
24
  import { Validators, FormGroup, FormControl, FormArray } from '@angular/forms';
24
25
  import fromPairs from 'lodash/fromPairs';
@@ -293,7 +294,7 @@ class AuthService {
293
294
  this.isLoggedInSubject.next(true);
294
295
  }
295
296
  login(username, password) {
296
- return this.http.post(`${this.environment.apiV2}/login_check`, { username, password }).pipe(map((response) => {
297
+ return this.http.post(`${this.environment.apiV2}/login`, { username, password }).pipe(map((response) => {
297
298
  this.setAuth(response);
298
299
  return response;
299
300
  }));
@@ -396,6 +397,11 @@ class JwtInterceptor {
396
397
  // });
397
398
  }
398
399
  handle401Error(req, next, err) {
400
+ var _a;
401
+ // skip 401 errors not from JWT (basiq login case or other)
402
+ if (!((_a = err.error.message) === null || _a === void 0 ? void 0 : _a.includes('JWT Token'))) {
403
+ return throwError(err);
404
+ }
399
405
  if (req.url.includes('token/refresh') || req.url.includes('login')) {
400
406
  if (req.url.includes('token/refresh')) {
401
407
  this.authService.logoutFront();
@@ -589,6 +595,7 @@ const ENDPOINTS = {
589
595
  EMPLOYEES_INVITE_POST: new Endpoint('POST', '\\/employees\\/\\invites'),
590
596
  EMPLOYEES_INVITES_REJECT_POST: new Endpoint('POST', '\\/employees\\/\\invites\\/\\d+\\/\\reject'),
591
597
  EMPLOYEES_INVITES_RESEND_POST: new Endpoint('POST', '\\/employees\\/\\invites\\/\\d+\\/\\resend'),
598
+ FACEBOOK_LOGIN_POST: new Endpoint('POST', '\\/users\\/authentication\\/facebook'),
592
599
  FIRM_GET: new Endpoint('GET', '\\/firms'),
593
600
  FIRM_CURRENT_GET: new Endpoint('GET', '\\/firms\\/current'),
594
601
  FIRM_CURRENT_PUT: new Endpoint('PUT', '\\/firms\\/current\.\*'),
@@ -616,7 +623,7 @@ const ENDPOINTS = {
616
623
  LOANS_PAYOUT_PUT: new Endpoint('PUT', '\\/loans\\/\\d+\\/payout\\/\\d+'),
617
624
  LOANS_PAYOUT_DELETE: new Endpoint('DELETE', '\\/loans\\/\\d+\\/payout\\/\\d+'),
618
625
  LOANS_CALCULATION_POST: new Endpoint('POST', '\\/bank-accounts\\/loans\\/calculation'),
619
- LOGIN_CHECK_POST: new Endpoint('POST', '\\/login_check'),
626
+ LOGIN_POST: new Endpoint('POST', '\\/login'),
620
627
  NOTIFICATIONS_GET: new Endpoint('GET', '\\/service-notifications'),
621
628
  OCCUPATIONS_GET: new Endpoint('GET', '\\/occupations'),
622
629
  PROPERTIES_GET: new Endpoint('GET', '\\/properties'),
@@ -670,6 +677,7 @@ const ENDPOINTS = {
670
677
  TRANSACTIONS_ALLOCATIONS_POST: new Endpoint('POST', '\\/transactions-allocations'),
671
678
  TRANSACTIONS_ALLOCATIONS_DELETE: new Endpoint('DELETE', '\\/transactions-allocations\\/\\d+'),
672
679
  USER_CONFIRMATION_POST: new Endpoint('POST', '\\/users\\/confirmation'),
680
+ USER_CONFIRMATION_RESEND_POST: new Endpoint('POST', '\\/users\\/confirmation\\/resend'),
673
681
  USER_CURRENT_GET: new Endpoint('GET', '\\/users\\/current'),
674
682
  USER_CURRENT_PASSWORD_PUT: new Endpoint('PUT', '\\/users\\/current\\/password\.\*'),
675
683
  USER_EVENT_SETTINGS_GET: new Endpoint('GET', '\\/user-event-settings'),
@@ -2039,6 +2047,9 @@ class Collection {
2039
2047
  getIds() {
2040
2048
  return this.items.map((item) => item['id']);
2041
2049
  }
2050
+ mapBy(path) {
2051
+ return this.items.map((item) => get(item, path));
2052
+ }
2042
2053
  sortBy(field = 'id', isDesc = true) {
2043
2054
  sort(this.items, field, isDesc);
2044
2055
  return this;
@@ -2093,8 +2104,8 @@ class Collection {
2093
2104
  remove(items) {
2094
2105
  return this.filter((model) => !items.map((item) => item.id).includes(model.id));
2095
2106
  }
2096
- removeBy(path, value) {
2097
- return this.filter((item) => get(item, path) !== value);
2107
+ removeBy(path, values) {
2108
+ return this.filter((item) => !(Array.isArray(values) ? values : [values]).includes(get(item, path)));
2098
2109
  }
2099
2110
  }
2100
2111
 
@@ -2356,6 +2367,20 @@ class BasiqJob extends BasiqJob$1 {
2356
2367
  class Bank$1 extends AbstractModel {
2357
2368
  }
2358
2369
 
2370
+ var BankPopularEnum;
2371
+ (function (BankPopularEnum) {
2372
+ BankPopularEnum["BANKWEST"] = "Bank of Western Australia trading as BankWest";
2373
+ BankPopularEnum["ANZ"] = "Australia and New Zealand Banking Group Limited";
2374
+ BankPopularEnum["CBA"] = "Commonwealth Bank Australia";
2375
+ BankPopularEnum["WESTPAC"] = "Westpac Banking Corporation";
2376
+ BankPopularEnum["BENDIGO"] = "Bendigo and Adelaide Bank Limited";
2377
+ BankPopularEnum["ING_DIRECT"] = "ING Bank (Australia) Limited (trading as ING Direct)";
2378
+ BankPopularEnum["ST_GEORGE"] = "St. George Bank (a subsidiary of Westpac)";
2379
+ BankPopularEnum["SUNCORP"] = "Suncorp-Metway Limited";
2380
+ BankPopularEnum["CITIBANK"] = "Citibank";
2381
+ BankPopularEnum["BOQ"] = "Bank of Queensland Limited";
2382
+ })(BankPopularEnum || (BankPopularEnum = {}));
2383
+
2359
2384
  class Bank extends Bank$1 {
2360
2385
  getInitials() {
2361
2386
  return this.name[0] + this.name[1];
@@ -2370,6 +2395,10 @@ class Bank extends Bank$1 {
2370
2395
  __decorate([
2371
2396
  Transform(({ value }) => value ? value.replace(' ', '%20') : null)
2372
2397
  ], Bank.prototype, "logo", void 0);
2398
+ __decorate([
2399
+ Transform(({ obj }) => Object.values(BankPopularEnum).includes(obj.name)),
2400
+ Expose()
2401
+ ], Bank.prototype, "isPopular", void 0);
2373
2402
 
2374
2403
  var BankConnectionStatusEnum;
2375
2404
  (function (BankConnectionStatusEnum) {
@@ -2520,13 +2549,139 @@ __decorate([
2520
2549
  Type(() => BankConnection)
2521
2550
  ], BankAccount.prototype, "bankConnection", void 0);
2522
2551
 
2552
+ const TYPE_LOAN = [
2553
+ BankAccountTypeEnum.MORTGAGE,
2554
+ BankAccountTypeEnum.CREDIT_CARD,
2555
+ BankAccountTypeEnum.LOAN
2556
+ ];
2557
+
2523
2558
  /**
2524
- * any event happened in the app, which needs to be handled somehow (distributed to other part of the app)
2559
+ * Collection of bank accounts.
2525
2560
  */
2526
- class AppEvent {
2527
- constructor(type, payload) {
2528
- this.type = type;
2529
- this.payload = payload;
2561
+ class BankAccountCollection extends Collection {
2562
+ /**
2563
+ * get list of bank accounts with passed types
2564
+ */
2565
+ getByType(types, isExclude = false) {
2566
+ // get types always as array (if only one passed)
2567
+ const typesArray = concat(types);
2568
+ return this.items.filter((bankAccount) => {
2569
+ if (isExclude) {
2570
+ return !typesArray.includes(bankAccount.type);
2571
+ }
2572
+ return typesArray.includes(bankAccount.type);
2573
+ });
2574
+ }
2575
+ /**
2576
+ * get amount of initial loans
2577
+ */
2578
+ getInitialLoanAmount() {
2579
+ return this.getByType(TYPE_LOAN)
2580
+ .reduce((sum, bankAccount) => {
2581
+ return sum += bankAccount.balances.length ? bankAccount.getOpeningBalance() : 0;
2582
+ }, 0);
2583
+ }
2584
+ /**
2585
+ * get amount of current loans
2586
+ */
2587
+ getCurrentLoanAmount() {
2588
+ return this.getByType(TYPE_LOAN)
2589
+ .reduce((sum, bankAccount) => {
2590
+ return sum += bankAccount.currentBalance;
2591
+ }, 0);
2592
+ }
2593
+ /**
2594
+ * get collection filtered by property id
2595
+ */
2596
+ getByPropertyId(id) {
2597
+ return new BankAccountCollection(this.items.filter((bankAccount) => {
2598
+ return bankAccount.bankAccountProperties.find((bankAccountProperty) => {
2599
+ return bankAccountProperty.property.id === id;
2600
+ });
2601
+ }));
2602
+ }
2603
+ /**
2604
+ * get collection filtered by properties ids
2605
+ */
2606
+ getByPropertiesIds(ids) {
2607
+ return new BankAccountCollection(this.items.filter((bankAccount) => {
2608
+ return bankAccount.bankAccountProperties.find((bankAccountProperty) => {
2609
+ return ids.includes(bankAccountProperty.property.id);
2610
+ });
2611
+ }));
2612
+ }
2613
+ /**
2614
+ * get collection of active bank accounts
2615
+ */
2616
+ getActiveBankAccounts() {
2617
+ return new BankAccountCollection(this.items.filter((bankAccount) => {
2618
+ return bankAccount.isActive();
2619
+ }));
2620
+ }
2621
+ /**
2622
+ * get reduction of loan (reduction of principle) percentage
2623
+ */
2624
+ getPrincipleReductionPercent() {
2625
+ const initialLoans = this.getInitialLoanAmount();
2626
+ const currentLoans = this.getCurrentLoanAmount();
2627
+ if (!initialLoans) {
2628
+ return 0;
2629
+ }
2630
+ return (initialLoans - currentLoans) / initialLoans * 100;
2631
+ }
2632
+ /**
2633
+ * Get collection of loan bank accounts
2634
+ */
2635
+ getLoanAccounts() {
2636
+ return new BankAccountCollection(this.getByType(TYPE_LOAN));
2637
+ }
2638
+ getSavingsAccounts() {
2639
+ return new BankAccountCollection(this.getByType(TYPE_LOAN, true));
2640
+ }
2641
+ getOpeningBalance() {
2642
+ return this.items.reduce((sum, bankAccount) => sum + bankAccount.getOpeningBalance(), 0);
2643
+ }
2644
+ get currentBalance() {
2645
+ return this.sumBy('currentBalance');
2646
+ }
2647
+ /**
2648
+ * Get Collection of bank accounts with property tank type
2649
+ */
2650
+ getPropertyBankAccounts() {
2651
+ return new BankAccountCollection(this.items.filter((bankAccount) => bankAccount.isPropertyTank()));
2652
+ }
2653
+ /**
2654
+ * Get Collection of bank accounts with work tank type
2655
+ */
2656
+ getWorkBankAccounts() {
2657
+ return new BankAccountCollection(this.items.filter((bankAccount) => bankAccount.isWorkTank()));
2658
+ }
2659
+ /**
2660
+ * Get Collection of bank accounts by tank type
2661
+ */
2662
+ getByTankType(tankType) {
2663
+ return new BankAccountCollection(this.items.filter((bankAccount) => bankAccount.tankType === tankType));
2664
+ }
2665
+ /**
2666
+ * Get list of all bank account properties
2667
+ */
2668
+ getBankAccountPropertiesList() {
2669
+ return flatten(this.items.map((bankAccount) => {
2670
+ return bankAccount.bankAccountProperties;
2671
+ }));
2672
+ }
2673
+ /**
2674
+ * Get lis of unique properties from all bank accounts properties
2675
+ */
2676
+ getProperties() {
2677
+ return uniqBy(this.getBankAccountPropertiesList().map((bankAccountProperty) => {
2678
+ return bankAccountProperty.property;
2679
+ }), 'id');
2680
+ }
2681
+ getPropertyBalanceAmount(propertyId) {
2682
+ return this.items.reduce((sum, bankAccount) => {
2683
+ return sum + bankAccount.getPropertyBalanceAmount(propertyId);
2684
+ }, 0);
2530
2685
  }
2531
2686
  }
2532
2687
 
@@ -2542,15 +2697,25 @@ class BankConnectionService extends RestService {
2542
2697
  }
2543
2698
  listenEvents() {
2544
2699
  this.listenToAddedBankAccounts();
2545
- this.listenBasiqJobCreated();
2546
- this.listenConnectionUpdated();
2547
2700
  this.listenNotifications();
2548
2701
  }
2549
2702
  add(bankConnection) {
2550
2703
  return this.http.post(`${this.environment.apiV2}/${this.url}`, bankConnection)
2551
2704
  .pipe(map((bankConnectionBase) => {
2552
- this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.BANK_CONNECTION_ADDED, null));
2553
- return plainToClass(BankConnection, bankConnectionBase);
2705
+ const connection = plainToClass(BankConnection, bankConnectionBase);
2706
+ // We use this endpoint for create and reconnect bank connections because of basiq logic.
2707
+ // So we try to replace bank connection in cache for reconnection case.
2708
+ if (bankConnection.id) {
2709
+ const tempCache = cloneDeep$1(this.cache);
2710
+ replace(tempCache, connection);
2711
+ this.cache = cloneDeep$1(tempCache);
2712
+ this.cacheSubject.next(tempCache);
2713
+ }
2714
+ else {
2715
+ this.cache.push(connection);
2716
+ this.cacheSubject.next(cloneDeep$1(this.cache));
2717
+ }
2718
+ return plainToClass(BankConnection, connection);
2554
2719
  }));
2555
2720
  }
2556
2721
  listenToAddedBankAccounts() {
@@ -2558,45 +2723,6 @@ class BankConnectionService extends RestService {
2558
2723
  this.resetCache();
2559
2724
  });
2560
2725
  }
2561
- /**
2562
- * When user log in to bank, basiq create a job. We create a bank connection with based on this job
2563
- */
2564
- listenBasiqJobCreated() {
2565
- this.eventDispatcherService.on(AppEventTypeEnum.BASIQ_JOB_CREATED).subscribe((result) => {
2566
- // push connection to cache temporary to show it to user directly with pending status and not wait until backend loaded
2567
- const tempCache = cloneDeep$1(this.cache);
2568
- result.connection.setPending();
2569
- tempCache.push(result.connection);
2570
- this.cache = tempCache;
2571
- this.cacheSubject.next(tempCache);
2572
- this.add(plainToClass(BankConnection, { basiqJob: { externalId: result.jobId } })).subscribe((newConnection) => {
2573
- // replace temporary connection with real saved connection
2574
- // no replace() because connection does not have id yet
2575
- tempCache.splice(-1, 1, newConnection);
2576
- this.cache = cloneDeep$1(tempCache);
2577
- this.cacheSubject.next(tempCache);
2578
- });
2579
- });
2580
- }
2581
- /**
2582
- * When basiq connection disconnected we create a basiq job and update this connection
2583
- */
2584
- listenConnectionUpdated() {
2585
- this.eventDispatcherService.on(AppEventTypeEnum.BASIQ_CONNECTION_UPDATED).subscribe((result) => {
2586
- // replace connection to cache temporary to show pending status until backend loaded
2587
- const tempCache = cloneDeep$1(this.cache);
2588
- result.connection.setPending();
2589
- replace(tempCache, result.connection);
2590
- this.cache = tempCache;
2591
- this.cacheSubject.next(tempCache);
2592
- this.add(plainToClass(BankConnection, { basiqJob: { externalId: result.jobId } })).subscribe((updatedConnection) => {
2593
- // replace temporary connection again with real updated connection
2594
- replace(tempCache, updatedConnection);
2595
- this.cache = cloneDeep$1(tempCache);
2596
- this.cacheSubject.next(tempCache);
2597
- });
2598
- });
2599
- }
2600
2726
  /**
2601
2727
  * Update cache when basiq login failed to get actual connections statuses
2602
2728
  */
@@ -2622,9 +2748,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
2622
2748
  * service is responsible for fetching bank related information
2623
2749
  */
2624
2750
  class BasiqService extends RestService {
2625
- constructor(http, eventDispatcherService, environment, toastService,
2626
- // init BankConnectionService to listen events
2627
- bankConnectionService) {
2751
+ constructor(http, eventDispatcherService, environment, toastService, bankConnectionService) {
2628
2752
  super(http, eventDispatcherService, environment, toastService);
2629
2753
  this.http = http;
2630
2754
  this.eventDispatcherService = eventDispatcherService;
@@ -2641,21 +2765,58 @@ class BasiqService extends RestService {
2641
2765
  this.listenNotifications();
2642
2766
  }
2643
2767
  /**
2644
- * Create Basiq job for the new bank connection creation
2645
- */
2646
- createConnection(data, userId, connection) {
2647
- return this.http.post(`${BasiqService.basiqApiUrl}/users/${userId}/connections`, data).pipe(map((response) => {
2648
- this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.BASIQ_JOB_CREATED, { jobId: response.id, connection }));
2649
- return response.id;
2768
+ * Create a new Bank connection based on Basiq job.
2769
+ * Here we have nested requests because we need to get a job id before we create a bank connection.
2770
+ * There is no way to use event dispatcher because we expect some errors from bank-connections API, but in components
2771
+ * we interact with basiq service.
2772
+ */
2773
+ createConnection(loginData, userId) {
2774
+ // Send login data to basiq API to create a basiq job
2775
+ return this.http.post(`${BasiqService.basiqApiUrl}/users/${userId}/connections`, loginData)
2776
+ .pipe(mergeMap((response) => {
2777
+ // Create bank connection based on basiq job
2778
+ return this.bankConnectionService.add(plainToClass(BankConnection, { basiqJob: { externalId: response.id } }));
2779
+ }), catchError((error) => {
2780
+ // Show error when user provided wrong login data
2781
+ if (error.status === 401) {
2782
+ this.toastService.error('Invalid credentials');
2783
+ }
2784
+ return throwError$1(error);
2650
2785
  }));
2651
2786
  }
2652
2787
  /**
2653
2788
  * Update disconnected bank connection
2789
+ * Here we have nested requests because we need to get a job id before we create a bank connection.
2790
+ * There is no way to use event dispatcher because we expect some errors from bank-connections API, but in components
2791
+ * we interact with basiq service.
2654
2792
  */
2655
2793
  updateConnection(data, userId, connection) {
2656
- return this.http.post(`${BasiqService.basiqApiUrl}/users/${userId}/connections`, Object.assign(data, { id: connection.externalId })).pipe(map((response) => {
2657
- this.eventDispatcherService.dispatch(new AppEvent(AppEventTypeEnum.BASIQ_CONNECTION_UPDATED, { jobId: response.id, connection }));
2658
- return response.id;
2794
+ // Send login data to basiq API to create a basiq job
2795
+ return this.http.post(`${BasiqService.basiqApiUrl}/users/${userId}/connections`, Object.assign(data, { id: connection.externalId }))
2796
+ .pipe(
2797
+ // Create bank connection based on basiq job
2798
+ mergeMap((response) => {
2799
+ return this.bankConnectionService.add(plainToClass(BankConnection, Object.assign({ id: connection.id, basiqJob: { externalId: response.id } })));
2800
+ }), catchError((error) => {
2801
+ // Show error when user provided wrong login data
2802
+ if (error.status === 401) {
2803
+ this.toastService.error('Invalid credentials');
2804
+ }
2805
+ // Show error when user provided another login (not login he used before)
2806
+ if (error.status === 400) {
2807
+ this.toastService.error('Please enter the login you used before');
2808
+ }
2809
+ return throwError$1(error);
2810
+ }));
2811
+ }
2812
+ getByConnection(connection) {
2813
+ return this.get().pipe(map((bankAccounts) => {
2814
+ return new BankAccountCollection(bankAccounts).filterBy('bankConnection.id', connection.id);
2815
+ }));
2816
+ }
2817
+ getNotImportedByConnection(savedAccounts, connection) {
2818
+ return this.getByConnection(connection).pipe(map((bankAccounts) => {
2819
+ return bankAccounts.removeBy('accountId', savedAccounts.mapBy('accountId'));
2659
2820
  }));
2660
2821
  }
2661
2822
  /**
@@ -2879,156 +3040,6 @@ class AccountSetupItemCollection extends Collection {
2879
3040
  }
2880
3041
  }
2881
3042
 
2882
- class BankCollection extends Collection {
2883
- constructor(banks) {
2884
- super(banks);
2885
- this.sortByPopularity();
2886
- }
2887
- sortByPopularity() {
2888
- this.items.sort((bank1, bank2) => {
2889
- // Banks already sorted on backend by name, so we just need to up top-10 banks
2890
- return (BankCollection.tobBanksIds.includes(bank1.id) && !BankCollection.tobBanksIds.includes(bank2.id)) ? -1 : 1;
2891
- });
2892
- }
2893
- }
2894
- BankCollection.tobBanksIds = [124, 13, 134, 172, 126, 142, 135, 137, 138, 128];
2895
-
2896
- const TYPE_LOAN = [
2897
- BankAccountTypeEnum.MORTGAGE,
2898
- BankAccountTypeEnum.CREDIT_CARD,
2899
- BankAccountTypeEnum.LOAN
2900
- ];
2901
-
2902
- /**
2903
- * Collection of bank accounts.
2904
- */
2905
- class BankAccountCollection extends Collection {
2906
- /**
2907
- * get list of bank accounts with passed types
2908
- */
2909
- getByType(types, isExclude = false) {
2910
- // get types always as array (if only one passed)
2911
- const typesArray = concat(types);
2912
- return this.items.filter((bankAccount) => {
2913
- if (isExclude) {
2914
- return !typesArray.includes(bankAccount.type);
2915
- }
2916
- return typesArray.includes(bankAccount.type);
2917
- });
2918
- }
2919
- /**
2920
- * get amount of initial loans
2921
- */
2922
- getInitialLoanAmount() {
2923
- return this.getByType(TYPE_LOAN)
2924
- .reduce((sum, bankAccount) => {
2925
- return sum += bankAccount.balances.length ? bankAccount.getOpeningBalance() : 0;
2926
- }, 0);
2927
- }
2928
- /**
2929
- * get amount of current loans
2930
- */
2931
- getCurrentLoanAmount() {
2932
- return this.getByType(TYPE_LOAN)
2933
- .reduce((sum, bankAccount) => {
2934
- return sum += bankAccount.currentBalance;
2935
- }, 0);
2936
- }
2937
- /**
2938
- * get collection filtered by property id
2939
- */
2940
- getByPropertyId(id) {
2941
- return new BankAccountCollection(this.items.filter((bankAccount) => {
2942
- return bankAccount.bankAccountProperties.find((bankAccountProperty) => {
2943
- return bankAccountProperty.property.id === id;
2944
- });
2945
- }));
2946
- }
2947
- /**
2948
- * get collection filtered by properties ids
2949
- */
2950
- getByPropertiesIds(ids) {
2951
- return new BankAccountCollection(this.items.filter((bankAccount) => {
2952
- return bankAccount.bankAccountProperties.find((bankAccountProperty) => {
2953
- return ids.includes(bankAccountProperty.property.id);
2954
- });
2955
- }));
2956
- }
2957
- /**
2958
- * get collection of active bank accounts
2959
- */
2960
- getActiveBankAccounts() {
2961
- return new BankAccountCollection(this.items.filter((bankAccount) => {
2962
- return bankAccount.isActive();
2963
- }));
2964
- }
2965
- /**
2966
- * get reduction of loan (reduction of principle) percentage
2967
- */
2968
- getPrincipleReductionPercent() {
2969
- const initialLoans = this.getInitialLoanAmount();
2970
- const currentLoans = this.getCurrentLoanAmount();
2971
- if (!initialLoans) {
2972
- return 0;
2973
- }
2974
- return (initialLoans - currentLoans) / initialLoans * 100;
2975
- }
2976
- /**
2977
- * Get collection of loan bank accounts
2978
- */
2979
- getLoanAccounts() {
2980
- return new BankAccountCollection(this.getByType(TYPE_LOAN));
2981
- }
2982
- getSavingsAccounts() {
2983
- return new BankAccountCollection(this.getByType(TYPE_LOAN, true));
2984
- }
2985
- getOpeningBalance() {
2986
- return this.items.reduce((sum, bankAccount) => sum + bankAccount.getOpeningBalance(), 0);
2987
- }
2988
- get currentBalance() {
2989
- return this.sumBy('currentBalance');
2990
- }
2991
- /**
2992
- * Get Collection of bank accounts with property tank type
2993
- */
2994
- getPropertyBankAccounts() {
2995
- return new BankAccountCollection(this.items.filter((bankAccount) => bankAccount.isPropertyTank()));
2996
- }
2997
- /**
2998
- * Get Collection of bank accounts with work tank type
2999
- */
3000
- getWorkBankAccounts() {
3001
- return new BankAccountCollection(this.items.filter((bankAccount) => bankAccount.isWorkTank()));
3002
- }
3003
- /**
3004
- * Get Collection of bank accounts by tank type
3005
- */
3006
- getByTankType(tankType) {
3007
- return new BankAccountCollection(this.items.filter((bankAccount) => bankAccount.tankType === tankType));
3008
- }
3009
- /**
3010
- * Get list of all bank account properties
3011
- */
3012
- getBankAccountPropertiesList() {
3013
- return flatten(this.items.map((bankAccount) => {
3014
- return bankAccount.bankAccountProperties;
3015
- }));
3016
- }
3017
- /**
3018
- * Get lis of unique properties from all bank accounts properties
3019
- */
3020
- getProperties() {
3021
- return uniqBy(this.getBankAccountPropertiesList().map((bankAccountProperty) => {
3022
- return bankAccountProperty.property;
3023
- }), 'id');
3024
- }
3025
- getPropertyBalanceAmount(propertyId) {
3026
- return this.items.reduce((sum, bankAccount) => {
3027
- return sum + bankAccount.getPropertyBalanceAmount(propertyId);
3028
- }, 0);
3029
- }
3030
- }
3031
-
3032
3043
  var TransactionOperationEnum;
3033
3044
  (function (TransactionOperationEnum) {
3034
3045
  TransactionOperationEnum[TransactionOperationEnum["ALLOCATE"] = 1] = "ALLOCATE";
@@ -6564,6 +6575,39 @@ class DepreciationReceipt extends DepreciationReceipt$1 {
6564
6575
  }
6565
6576
  }
6566
6577
 
6578
+ /**
6579
+ * List of objects grouped by passed property
6580
+ */
6581
+ class Dictionary {
6582
+ constructor(items, path = 'id') {
6583
+ this.items = {};
6584
+ if (!items.length) {
6585
+ return;
6586
+ }
6587
+ // Do nothing if provided path was not found in the 1st item
6588
+ if (!hasIn(items[0], path.split('.')[0])) {
6589
+ return;
6590
+ }
6591
+ this.groupItems(items, path);
6592
+ }
6593
+ add(key, value) {
6594
+ this.items[key] = value;
6595
+ }
6596
+ get(key) {
6597
+ return this.items[key] ? this.items[key] : null;
6598
+ }
6599
+ groupItems(items, path) {
6600
+ items.forEach((item) => {
6601
+ let key = get(item, path);
6602
+ // if object does not have property for grouping it will be grouped as 'other'
6603
+ if (key === undefined) {
6604
+ key = 'other';
6605
+ }
6606
+ this.items[key] = item;
6607
+ });
6608
+ }
6609
+ }
6610
+
6567
6611
  class Document$1 extends AbstractModel {
6568
6612
  }
6569
6613
 
@@ -6640,6 +6684,16 @@ __decorate([
6640
6684
  Type(() => User)
6641
6685
  ], EmployeeInvite.prototype, "employee", void 0);
6642
6686
 
6687
+ /**
6688
+ * any event happened in the app, which needs to be handled somehow (distributed to other part of the app)
6689
+ */
6690
+ class AppEvent {
6691
+ constructor(type, payload) {
6692
+ this.type = type;
6693
+ this.payload = payload;
6694
+ }
6695
+ }
6696
+
6643
6697
  var ExportFormatEnum;
6644
6698
  (function (ExportFormatEnum) {
6645
6699
  ExportFormatEnum["PDF"] = "PDF";
@@ -8386,6 +8440,11 @@ class BankAccountService extends RestService {
8386
8440
  return bankAccounts.filter((bankAccount) => bankAccount.isOwner(+localStorage.getItem('userId')));
8387
8441
  }));
8388
8442
  }
8443
+ getByConnection(connection) {
8444
+ return this.get().pipe(map((bankAccounts) => {
8445
+ return new BankAccountCollection(bankAccounts).filterBy('bankConnection.id', connection.id);
8446
+ }));
8447
+ }
8389
8448
  /**
8390
8449
  * Listen to EventDispatcherService events
8391
8450
  */
@@ -9063,6 +9122,12 @@ class BankService extends RestService {
9063
9122
  this.url = 'banks';
9064
9123
  this.isHydra = true;
9065
9124
  }
9125
+ get() {
9126
+ return super.get().pipe(map((banks) => {
9127
+ // exclude basiq banks without login fields (basiq may return broken banks without loginFields)
9128
+ return banks.filter((bank) => !bank.externalId || (bank.externalId && bank.loginFields));
9129
+ }));
9130
+ }
9066
9131
  }
9067
9132
  BankService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: BankService, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
9068
9133
  BankService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: BankService, providedIn: 'root' });
@@ -11848,6 +11913,9 @@ class UserService {
11848
11913
  resetPassword(newPassword, resetToken) {
11849
11914
  return this.http.put(`${this.environment.apiV2}/users/password/reset`, { newPassword, resetToken });
11850
11915
  }
11916
+ resendConfirmationEmail(email) {
11917
+ return this.http.post(`${this.environment.apiV2}/users/confirmation/resend`, { email });
11918
+ }
11851
11919
  /**
11852
11920
  * Confirm registered user
11853
11921
  */
@@ -12147,6 +12215,88 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
12147
12215
  }]
12148
12216
  }] });
12149
12217
 
12218
+ const ERROR_EMAIL_PERMISSION = 'Access to email denied. Please provide access to email in facebook.';
12219
+ class FacebookService {
12220
+ /**
12221
+ * @TODO when google login will be done, it needs to be moved to an abstract class
12222
+ */
12223
+ constructor(http, toastService, jwtService, router, environment) {
12224
+ this.http = http;
12225
+ this.toastService = toastService;
12226
+ this.jwtService = jwtService;
12227
+ this.router = router;
12228
+ this.environment = environment;
12229
+ this.isLoggedInSubject = new BehaviorSubject(!this.jwtService.isTokenExpired());
12230
+ this.isFacebookEnabled = !!environment['facebookAppId'];
12231
+ }
12232
+ login(redirectUrl = '/client') {
12233
+ return __awaiter(this, void 0, void 0, function* () {
12234
+ const accessToken = yield this.getAccessToken();
12235
+ this.http.post(`${this.environment.apiV2}/users/authentication/facebook`, { accessToken })
12236
+ .subscribe((response) => {
12237
+ this.setAuth(response);
12238
+ this.router.navigate([redirectUrl]);
12239
+ }, (error) => {
12240
+ this.toastService.error(error.error.violations[0].message);
12241
+ this.logout();
12242
+ });
12243
+ });
12244
+ }
12245
+ /**
12246
+ * save user's auth tokens
12247
+ * @TODO move to abstract class
12248
+ */
12249
+ setAuth(response) {
12250
+ this.jwtService.saveTokens(response);
12251
+ this.isLoggedInSubject.next(true);
12252
+ }
12253
+ /**
12254
+ * get facebook auth access token
12255
+ */
12256
+ getAccessToken() {
12257
+ return new Promise((resolve) => {
12258
+ FB.login((response) => {
12259
+ // authResponse will be empty if you close the Facebook login window or enter incorrect user data
12260
+ if (!response.authResponse) {
12261
+ return;
12262
+ }
12263
+ if (!response.authResponse.grantedScopes.includes('email')) {
12264
+ this.toastService.error(ERROR_EMAIL_PERMISSION);
12265
+ return;
12266
+ }
12267
+ resolve(response.authResponse.accessToken);
12268
+ }, FacebookService.authOptions);
12269
+ });
12270
+ }
12271
+ /**
12272
+ * logout user from facebook.
12273
+ * Need to logout when user is trying to login with facebook with manually registered email
12274
+ */
12275
+ logout() {
12276
+ return new Promise((resolve, reject) => {
12277
+ FB.logout((response) => {
12278
+ resolve(response);
12279
+ });
12280
+ });
12281
+ }
12282
+ }
12283
+ FacebookService.authOptions = {
12284
+ scope: 'email, public_profile',
12285
+ auth_type: 'rerequest',
12286
+ return_scopes: true
12287
+ };
12288
+ FacebookService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FacebookService, deps: [{ token: i1.HttpClient }, { token: ToastService }, { token: JwtService }, { token: i1$2.Router }, { token: 'environment' }], target: i0.ɵɵFactoryTarget.Injectable });
12289
+ FacebookService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FacebookService, providedIn: 'root' });
12290
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: FacebookService, decorators: [{
12291
+ type: Injectable,
12292
+ args: [{
12293
+ providedIn: 'root'
12294
+ }]
12295
+ }], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: ToastService }, { type: JwtService }, { type: i1$2.Router }, { type: undefined, decorators: [{
12296
+ type: Inject,
12297
+ args: ['environment']
12298
+ }] }]; } });
12299
+
12150
12300
  // deep clone for entity
12151
12301
  function cloneDeep(array) {
12152
12302
  return JSON.parse(JSON.stringify(array));
@@ -12221,9 +12371,10 @@ function taxReviewFilterPredicate(data, filter) {
12221
12371
  * Abstract form class
12222
12372
  */
12223
12373
  class AbstractForm extends FormGroup {
12224
- constructor(controls, model = {}, validatorOrOpts, asyncValidator) {
12374
+ constructor(controls, model, validatorOrOpts, asyncValidator) {
12225
12375
  super(controls, validatorOrOpts, asyncValidator);
12226
- this.model = model;
12376
+ this.onSubmit = new EventEmitter();
12377
+ this.model = model || this.createModelInstance();
12227
12378
  this.modelClass = this.model.constructor;
12228
12379
  }
12229
12380
  /**
@@ -12237,10 +12388,18 @@ class AbstractForm extends FormGroup {
12237
12388
  if (!this.valid) {
12238
12389
  return null;
12239
12390
  }
12240
- return plainToClass(this.modelClass, Object.assign({}, this.model, this.value, data));
12391
+ const model = this.createModelInstance(Object.assign({}, this.model, this.value, data));
12392
+ this.onSubmit.emit(model);
12393
+ return model;
12394
+ }
12395
+ createModelInstance(data = {}) {
12396
+ return plainToClass(this.modelClass, data);
12241
12397
  }
12242
12398
  }
12243
12399
 
12400
+ /**
12401
+ * Form with bank account loan details
12402
+ */
12244
12403
  class BankAccountLoanForm extends AbstractForm {
12245
12404
  constructor(loan = plainToClass(Loan, {})) {
12246
12405
  super({
@@ -12257,89 +12416,79 @@ class BankAccountLoanForm extends AbstractForm {
12257
12416
  }
12258
12417
  }
12259
12418
 
12260
- class BankAccountPropertyForm extends AbstractForm {
12261
- constructor(isLoan, bankAccountProperty = plainToClass(BankAccountProperty, {})) {
12262
- super({
12263
- property: new FormControl(bankAccountProperty.property, Validators.required),
12264
- percent: new FormControl({ value: bankAccountProperty.percent, disabled: !isLoan }, Validators.required)
12265
- }, bankAccountProperty);
12266
- }
12267
- }
12268
-
12419
+ /**
12420
+ * Form array with bank account properties
12421
+ */
12269
12422
  class BankAccountPropertiesForm extends FormArray {
12270
- constructor(isLoan, bankAccountProperties = []) {
12271
- super(bankAccountProperties.length
12272
- ? bankAccountProperties.map((bankAccountProperty) => new BankAccountPropertyForm(isLoan, bankAccountProperty))
12273
- : [new BankAccountPropertyForm(isLoan)]);
12274
- this.isLoan = isLoan;
12275
- this.bankAccountProperties = bankAccountProperties;
12423
+ constructor(bankAccountProperties = [plainToClass(BankAccountProperty, {})]) {
12424
+ super(bankAccountProperties.map((bankAccountProperty) => {
12425
+ return new FormGroup({
12426
+ property: new FormControl(bankAccountProperty.property, Validators.required),
12427
+ percent: new FormControl(bankAccountProperty.percent, Validators.required)
12428
+ });
12429
+ }));
12276
12430
  }
12277
12431
  add() {
12278
- this.push(new BankAccountPropertyForm(this.isLoan));
12432
+ this.push(new FormGroup({
12433
+ property: new FormControl(null, Validators.required),
12434
+ percent: new FormControl({
12435
+ value: 100,
12436
+ disabled: !this.at(0).contains('percent')
12437
+ }, Validators.required)
12438
+ }));
12439
+ }
12440
+ enablePercent() {
12441
+ this.controls.forEach((propertyFormGroup) => {
12442
+ propertyFormGroup.get('percent').enable();
12443
+ });
12444
+ }
12445
+ disablePercent() {
12446
+ this.controls.forEach((propertyFormGroup) => {
12447
+ propertyFormGroup.get('percent').disable();
12448
+ });
12279
12449
  }
12280
12450
  }
12281
12451
 
12282
12452
  /**
12283
- * Form for additional data for bank accounts. Allow user to set tank type, loan and properties for new not-saved bank accounts.
12284
- * Works with manual and basiq bank accounts.
12453
+ * Form is using for import basiq bank accounts.
12454
+ * Basiq accounts has all data except tank type, properties and loan partially
12285
12455
  */
12286
- class BankAccountForm extends AbstractForm {
12287
- constructor(bankAccount = plainToClass(BankAccount, {})) {
12456
+ class BankAccountImportForm extends AbstractForm {
12457
+ constructor(bankAccount) {
12288
12458
  super({
12289
12459
  tankType: new FormControl(bankAccount.tankType, Validators.required),
12290
12460
  }, bankAccount);
12291
- this.bankAccount = bankAccount;
12292
12461
  if (bankAccount.isLoan()) {
12293
12462
  this.addControl('loan', new BankAccountLoanForm(bankAccount.loan));
12294
12463
  }
12464
+ // basiq account import form should be disabled (unchecked) by default
12465
+ this.disable();
12295
12466
  this.listenEvents();
12296
12467
  }
12297
12468
  listenEvents() {
12298
12469
  this.listenTankTypeChanges();
12299
- this.listenValueChanges();
12300
- }
12301
- get properties() {
12302
- return this.get('bankAccountProperties');
12303
- }
12304
- isLoan() {
12305
- return BankAccount.loanTypes.includes(this.bankAccount.type);
12306
- }
12307
- isPropertyTank() {
12308
- return this.get('tankType').value === TankTypeEnum.PROPERTY;
12309
- }
12310
- confirm() {
12311
- this.markAllAsTouched();
12312
- if (this.invalid) {
12313
- return;
12314
- }
12315
- this.isConfirmed = true;
12316
- }
12317
- addPropertiesArray() {
12318
- const control = new BankAccountPropertiesForm(this.isLoan(), this.bankAccount.bankAccountProperties);
12319
- // Default form behaviour is: if we add enabled form control to disabled form group then this form group enable.
12320
- // Disable form control before add to avoid form group enabling.
12321
- if (this.disabled) {
12322
- control.disable();
12323
- }
12324
- this.addControl('bankAccountProperties', control);
12325
12470
  }
12326
12471
  /**
12327
- * Add/Remove properties form array depending on selected tank type
12472
+ * Add/Remove bank account properties form depends on selected tank type
12328
12473
  */
12329
12474
  listenTankTypeChanges() {
12330
- this.get('tankType').valueChanges.subscribe(() => {
12331
- this.isPropertyTank() ? this.addPropertiesArray() : this.removeControl('bankAccountProperties');
12332
- });
12333
- }
12334
- listenValueChanges() {
12335
- this.valueChanges.subscribe(() => {
12336
- this.isConfirmed = false;
12475
+ this.get('tankType').valueChanges.subscribe((tankType) => {
12476
+ if (tankType === TankTypeEnum.PROPERTY) {
12477
+ this.addControl('bankAccountProperties', new BankAccountPropertiesForm());
12478
+ // property percent allowed only for loan bank accounts
12479
+ if (!this.contains('loan')) {
12480
+ this.get('bankAccountProperties').disablePercent();
12481
+ }
12482
+ }
12483
+ else {
12484
+ this.removeControl('bankAccountProperties');
12485
+ }
12337
12486
  });
12338
12487
  }
12339
12488
  }
12340
12489
 
12341
12490
  /**
12342
- * Form is using for manual bank account creation (not Basiq), prepares bank account data for the next saving.
12491
+ * Form is using for single manual bank account creation (not Basiq)
12343
12492
  */
12344
12493
  class BankAccountAddManualForm extends AbstractForm {
12345
12494
  constructor(connection) {
@@ -12348,7 +12497,61 @@ class BankAccountAddManualForm extends AbstractForm {
12348
12497
  accountName: new FormControl(null, Validators.required),
12349
12498
  currentBalance: new FormControl(null, Validators.required),
12350
12499
  accountNumber: new FormControl(null, [Validators.required, Validators.pattern(BankAccountAddManualForm.accountNumberPattern)]),
12351
- }, plainToClass(BankAccount, { bankConnection: connection }));
12500
+ tankType: new FormControl(null, Validators.required),
12501
+ });
12502
+ this.connection = connection;
12503
+ this.listenEvents();
12504
+ }
12505
+ listenEvents() {
12506
+ this.listenTypeChanges();
12507
+ this.listenTankTypeChanges();
12508
+ }
12509
+ /**
12510
+ * Add/Remove loan form depends on selected bank account type
12511
+ */
12512
+ listenTypeChanges() {
12513
+ this.get('type').valueChanges.subscribe((type) => {
12514
+ if (BankAccount.loanTypes.includes(type)) {
12515
+ this.addControl('loan', new BankAccountLoanForm());
12516
+ // property percent allowed only for loan bank accounts
12517
+ if (this.contains('bankAccountProperties')) {
12518
+ this.get('bankAccountProperties').enablePercent();
12519
+ }
12520
+ }
12521
+ else {
12522
+ this.removeControl('loan');
12523
+ // property percent allowed only for loan bank accounts
12524
+ if (this.contains('bankAccountProperties')) {
12525
+ this.get('bankAccountProperties').disablePercent();
12526
+ }
12527
+ }
12528
+ });
12529
+ }
12530
+ /**
12531
+ * Add/Remove bank account properties form depends on selected tank type
12532
+ */
12533
+ listenTankTypeChanges() {
12534
+ this.get('tankType').valueChanges.subscribe((tankType) => {
12535
+ if (tankType === TankTypeEnum.PROPERTY) {
12536
+ this.addControl('bankAccountProperties', new BankAccountPropertiesForm());
12537
+ // property percent allowed only for loan bank accounts
12538
+ if (this.contains('loan')) {
12539
+ this.get('bankAccountProperties').enablePercent();
12540
+ }
12541
+ else {
12542
+ this.get('bankAccountProperties').disablePercent();
12543
+ }
12544
+ }
12545
+ else {
12546
+ this.removeControl('bankAccountProperties');
12547
+ }
12548
+ });
12549
+ }
12550
+ /**
12551
+ * Attach bank connection to manual bank account
12552
+ */
12553
+ submit() {
12554
+ return super.submit({ bankConnection: this.connection });
12352
12555
  }
12353
12556
  }
12354
12557
  BankAccountAddManualForm.accountNumberPattern = '^[0-9]{6}[ ]{1}[0-9]{1,}$';
@@ -12375,16 +12578,60 @@ function dateRangeValidator(dateStart, dateEnd) {
12375
12578
  };
12376
12579
  }
12377
12580
 
12378
- class BankAccountMigrateForm extends AbstractForm {
12379
- constructor() {
12581
+ /**
12582
+ * Validator check if at least one control in formArray is enabled
12583
+ */
12584
+ function atLeastOneEnabledValidator(arrayName) {
12585
+ return (formGroup) => {
12586
+ return !!formGroup.get(arrayName).controls.find((control) => control.enabled)
12587
+ ? null
12588
+ : { arrayControlsDisabled: true };
12589
+ };
12590
+ }
12591
+
12592
+ /**
12593
+ * Form for import multiple basiq bank accounts
12594
+ */
12595
+ class BankAccountsImportForm extends AbstractForm {
12596
+ constructor(bankAccounts) {
12380
12597
  super({
12381
- migrateFrom: new FormControl(BankAccountMigrateForm.minDate, [Validators.required, dateRangeValidator(BankAccountMigrateForm.minDate, BankAccountMigrateForm.maxDate)]),
12382
- migrateTo: new FormControl(BankAccountMigrateForm.maxDate, [Validators.required, dateRangeValidator(BankAccountMigrateForm.minDate, BankAccountMigrateForm.maxDate)])
12598
+ migrateFrom: new FormControl(BankAccountsImportForm.minDate, [Validators.required, dateRangeValidator(BankAccountsImportForm.minDate, BankAccountsImportForm.maxDate)]),
12599
+ migrateTo: new FormControl(BankAccountsImportForm.maxDate, [Validators.required, dateRangeValidator(BankAccountsImportForm.minDate, BankAccountsImportForm.maxDate)]),
12600
+ bankAccounts: new FormArray(bankAccounts.map((bankAccount) => new BankAccountImportForm(bankAccount)))
12601
+ }, [], {
12602
+ validators: [atLeastOneEnabledValidator('bankAccounts')]
12383
12603
  });
12604
+ this.bankAccounts = bankAccounts;
12605
+ }
12606
+ submit() {
12607
+ this.submitted = true;
12608
+ if (this.invalid) {
12609
+ return null;
12610
+ }
12611
+ const bankAccounts = [];
12612
+ // form is valid when all selected bank accounts forms are valid
12613
+ for (let bankAccountImportForm of this.get('bankAccounts').controls) {
12614
+ // skip disabled forms
12615
+ if (bankAccountImportForm.disabled) {
12616
+ continue;
12617
+ }
12618
+ const bankAccount = bankAccountImportForm.submit({
12619
+ migrateFrom: this.value.migrateFrom,
12620
+ migrateTo: this.value.migrateTo
12621
+ });
12622
+ if (!bankAccount) {
12623
+ return null;
12624
+ }
12625
+ bankAccounts.push(bankAccount);
12626
+ }
12627
+ if (!bankAccounts.length) {
12628
+ return null;
12629
+ }
12630
+ return bankAccounts;
12384
12631
  }
12385
12632
  }
12386
- BankAccountMigrateForm.minDate = new FinancialYear().prevFinYear.startDate;
12387
- BankAccountMigrateForm.maxDate = new Date();
12633
+ BankAccountsImportForm.minDate = new FinancialYear().prevFinYear.startDate;
12634
+ BankAccountsImportForm.maxDate = new Date();
12388
12635
 
12389
12636
  /**
12390
12637
  * Form with basiq bank login fields.
@@ -12414,15 +12661,11 @@ function atLeastOneCheckedValidator() {
12414
12661
 
12415
12662
  /**
12416
12663
  * Validation function for autocomplete fields. Checks that the user should select a value from a list rather than type in input field
12664
+ * @TODO Alex: create class AppValidators with static methods and move there all custom validators (line Angular Validators)
12417
12665
  */
12418
- function requireAutocomplete() {
12666
+ function autocompleteValidator() {
12419
12667
  return (control) => {
12420
- if (typeof control.value === 'string' && !!control.value) {
12421
- return { notFromList: true };
12422
- }
12423
- else {
12424
- return null;
12425
- }
12668
+ return (!control.value || (typeof control.value === 'object')) ? null : { notFromList: true };
12426
12669
  };
12427
12670
  }
12428
12671
 
@@ -12463,21 +12706,6 @@ function passwordMatchValidator(newPassControlName, confirmPassControlName) {
12463
12706
  };
12464
12707
  }
12465
12708
 
12466
- /**
12467
- * Validation function, that checks that the user should select a value from a list rather than type in input field
12468
- */
12469
- function requireSelectValidator() {
12470
- return (control) => {
12471
- const selection = control.value;
12472
- if (typeof selection === 'string' && !!selection) {
12473
- return { notFromList: true };
12474
- }
12475
- else {
12476
- return null;
12477
- }
12478
- };
12479
- }
12480
-
12481
12709
  class ClientIncomeTypesForm extends AbstractForm {
12482
12710
  constructor(clientIncomeTypes) {
12483
12711
  super({
@@ -12500,12 +12728,13 @@ class LoginForm extends AbstractForm {
12500
12728
  }
12501
12729
  }
12502
12730
 
12731
+ // @TODO Alex: Create a model and handle request fields via class-transformer
12503
12732
  class PasswordForm extends AbstractForm {
12504
12733
  constructor() {
12505
12734
  super({
12506
12735
  password: new FormControl(null, [Validators.required, passwordValidator()]),
12507
12736
  confirm: new FormControl(null, Validators.required),
12508
- }, {}, passwordMatchValidator('password', 'confirm'));
12737
+ }, { password: null, confirm: null }, passwordMatchValidator('password', 'confirm'));
12509
12738
  }
12510
12739
  }
12511
12740
 
@@ -12517,7 +12746,6 @@ class RegisterClientForm extends AbstractForm {
12517
12746
  lastName: new FormControl('', [Validators.required]),
12518
12747
  email: new FormControl('', [Validators.required, Validators.email]),
12519
12748
  password: new PasswordForm(),
12520
- acceptTerms: new FormControl(false, [Validators.requiredTrue]),
12521
12749
  referenceCode: new FormControl(referenceCode)
12522
12750
  });
12523
12751
  }
@@ -12549,6 +12777,7 @@ class RegisterFirmForm extends AbstractForm {
12549
12777
  }
12550
12778
  }
12551
12779
 
12780
+ // @TODO Alex: Create a model and handle request fields via class-transformer
12552
12781
  class ResetPasswordForm extends AbstractForm {
12553
12782
  constructor() {
12554
12783
  super({
@@ -12794,7 +13023,7 @@ class MyTaxEmployeeShareSchemesForm extends AbstractForm {
12794
13023
  class MyTaxIncomeStatementsForm extends AbstractForm {
12795
13024
  constructor(incomeStatements, user) {
12796
13025
  super({
12797
- occupation: new FormControl(user.clientDetails.occupation, [Validators.required, requireSelectValidator()]),
13026
+ occupation: new FormControl(user.clientDetails.occupation, [Validators.required, autocompleteValidator()]),
12798
13027
  allowanceTotalAmount: new FormControl({
12799
13028
  value: incomeStatements.allowanceTotalAmount,
12800
13029
  disabled: true
@@ -13033,5 +13262,5 @@ class MyTaxRentForm extends AbstractForm {
13033
13262
  * Generated bundle index. Do not edit.
13034
13263
  */
13035
13264
 
13036
- export { AbstractForm, AbstractModel, AccountSetupItem, AccountSetupItemCollection, AccountSetupService, Address, AddressService, AddressTypeEnum, AlphabetColorsEnum, AppEvent, AppEventTypeEnum, AssetEntityTypeEnum, AssetTypeEnum, AssetsService, AuthService, BANK_ACCOUNT_TYPES, Bank, BankAccount, BankAccountAddManualForm, BankAccountCalculationService, BankAccountChartData, BankAccountCollection, BankAccountForm, BankAccountLoanForm, BankAccountMigrateForm, BankAccountPropertiesForm, BankAccountProperty, BankAccountPropertyForm, BankAccountService, BankAccountStatusEnum, BankAccountTypeEnum, BankCollection, 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, ChartAccounts, ChartAccountsCategoryEnum, 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, 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, Document, DocumentApiUrlPrefixEnum, DocumentFolder, DocumentFolderService, ENDPOINTS, EmployeeCollection, EmployeeDetails, EmployeeInvite, EmployeeInviteService, EmployeeService, Endpoint, EquityPositionChartService, EventDispatcherService, ExportDataTable, ExportFormatEnum, ExportFormatterService, ExportableCollection, FinancialYear, Firm, FirmService, FirmTypeEnum, HeaderTitleService, IconsFileEnum, IncomeAmountTypeEnum, IncomePosition, IncomeSource, IncomeSourceChartData, IncomeSourceCollection, IncomeSourceForecast, IncomeSourceForecastService, 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, MyTaxDeductions, MyTaxDeductionsForm, MyTaxDividends, MyTaxDividendsForm, MyTaxEmployeeShareSchemes, MyTaxEmployeeShareSchemesForm, 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, 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, SoleForecast, SoleForecastService, 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, USER_ROLES, USER_WORK_POSITION, User, UserEventSetting, UserEventSettingCollection, UserEventSettingFieldEnum, UserEventSettingService, UserEventStatusEnum, UserEventType, UserEventTypeCategory, UserEventTypeClientTypeEnum, UserEventTypeEmployeeTypeEnum, UserEventTypeFrequencyEnum, UserEventTypeService, UserEventTypeUserTypeEnum, UserMedicareExemptionEnum, UserRolesEnum, UserService, UserStatusEnum, UserSwitcherService, UserTitleEnum, UserToRegister, UserWorkDepreciationCalculationEnum, UserWorkingHolidayMakerEnum, Vehicle, VehicleClaim, VehicleClaimForm, VehicleClaimMethodEnum, VehicleClaimService, VehicleCollection, VehicleExpense, VehicleExpenseCollection, VehicleForm, VehicleLogbook, VehicleLogbookCollection, VehicleLogbookPurposeEnum, VehicleLogbookService, VehicleService, WORK_TANK_LOGBOOK_PURPOSE_OPTIONS, XlsxService, atLeastOneCheckedValidator, atoLinks, cloneDeep, compare, compareMatOptions, createDate, displayMatOptions, enumToList, getDocIcon, passwordMatchValidator, passwordValidator, replace, requireAutocomplete, requireSelectValidator, roundTo, sort, sortDeep, taxReviewFilterPredicate };
13265
+ export { AbstractForm, AbstractModel, AccountSetupItem, AccountSetupItemCollection, AccountSetupService, Address, AddressService, AddressTypeEnum, AlphabetColorsEnum, AppEvent, AppEventTypeEnum, AssetEntityTypeEnum, AssetTypeEnum, AssetsService, AuthService, BANK_ACCOUNT_TYPES, Bank, BankAccount, BankAccountAddManualForm, 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, ChartAccounts, ChartAccountsCategoryEnum, 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, 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, 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, MyTaxDeductions, MyTaxDeductionsForm, MyTaxDividends, MyTaxDividendsForm, MyTaxEmployeeShareSchemes, MyTaxEmployeeShareSchemesForm, 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, 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, SoleForecast, SoleForecastService, 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, USER_ROLES, USER_WORK_POSITION, User, UserEventSetting, UserEventSettingCollection, UserEventSettingFieldEnum, UserEventSettingService, UserEventStatusEnum, UserEventType, UserEventTypeCategory, UserEventTypeClientTypeEnum, UserEventTypeEmployeeTypeEnum, UserEventTypeFrequencyEnum, UserEventTypeService, UserEventTypeUserTypeEnum, UserMedicareExemptionEnum, UserRolesEnum, UserService, UserStatusEnum, UserSwitcherService, UserTitleEnum, UserToRegister, UserWorkDepreciationCalculationEnum, UserWorkingHolidayMakerEnum, 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, createDate, displayMatOptions, enumToList, getDocIcon, passwordMatchValidator, passwordValidator, replace, roundTo, sort, sortDeep, taxReviewFilterPredicate };
13037
13266
  //# sourceMappingURL=taxtank-core.js.map