taxtank-core 0.30.0 → 0.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/db/Models/transaction/transaction-base.mjs +5 -1
- package/esm2020/lib/forms/address/address.form.mjs +59 -41
- package/esm2020/lib/forms/phone/phone.form.mjs +3 -2
- package/esm2020/lib/forms/sole/sole-contact.form.mjs +2 -4
- package/esm2020/lib/validators/address-corelogic.validator.mjs +9 -8
- package/fesm2015/taxtank-core.mjs +243 -214
- package/fesm2015/taxtank-core.mjs.map +1 -1
- package/fesm2020/taxtank-core.mjs +242 -214
- package/fesm2020/taxtank-core.mjs.map +1 -1
- package/lib/db/Models/transaction/transaction-base.d.ts +4 -0
- package/lib/forms/address/address.form.d.ts +13 -10
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import * as i1$2 from '@angular/common';
|
|
|
4
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
|
-
import { map, mergeMap, filter, catchError, take, switchMap, finalize, first as first$1, skip,
|
|
7
|
+
import { map, mergeMap, filter, catchError, take, switchMap, finalize, first as first$1, skip, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
8
8
|
import { ReplaySubject, Subject, BehaviorSubject, throwError, Observable, of, combineLatest, forkJoin, from, merge as merge$1 } from 'rxjs';
|
|
9
9
|
import { plainToClass, Type, Exclude, Transform, Expose, classToPlain } from 'class-transformer';
|
|
10
10
|
import { JwtHelperService } from '@auth0/angular-jwt';
|
|
@@ -381,6 +381,10 @@ class TransactionBase extends ObservableModel {
|
|
|
381
381
|
return TankTypeEnum.OTHER;
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* @TODO remove when AllocateForm is refactored and not merging with Transaction class which cause the issue
|
|
386
|
+
*/
|
|
387
|
+
set tankType(tankType) { }
|
|
384
388
|
/**
|
|
385
389
|
* Check if current tank is Property
|
|
386
390
|
*/
|
|
@@ -15761,187 +15765,19 @@ class AbstractForm extends UntypedFormGroup {
|
|
|
15761
15765
|
}
|
|
15762
15766
|
}
|
|
15763
15767
|
|
|
15764
|
-
/**
|
|
15765
|
-
* Check if at least one form field is true, otherwise form is invalid.
|
|
15766
|
-
* Use with groups of boolean form controls (checkbox, toggle, etc.)
|
|
15767
|
-
*/
|
|
15768
|
-
function atLeastOneCheckedValidator() {
|
|
15769
|
-
return (formGroup) => {
|
|
15770
|
-
return Object.values(formGroup.controls)
|
|
15771
|
-
.find((control) => control.value) ? null : { nothingChecked: true };
|
|
15772
|
-
};
|
|
15773
|
-
}
|
|
15774
|
-
|
|
15775
|
-
/**
|
|
15776
|
-
* Validation function for autocomplete fields. Checks that the user should select a value from a list rather than type in input field
|
|
15777
|
-
* @TODO Alex: create class AppValidators with static methods and move there all custom validators (line Angular Validators)
|
|
15778
|
-
*/
|
|
15779
|
-
function autocompleteValidator() {
|
|
15780
|
-
return (control) => {
|
|
15781
|
-
return (!control.value || (typeof control.value === 'object')) ? null : { notFromList: true };
|
|
15782
|
-
};
|
|
15783
|
-
}
|
|
15784
|
-
|
|
15785
|
-
function conditionalValidator(condition, validator) {
|
|
15786
|
-
return function (control) {
|
|
15787
|
-
revalidateOnChanges(control);
|
|
15788
|
-
if (control && control.parent) {
|
|
15789
|
-
if (condition(control.parent)) {
|
|
15790
|
-
return validator(control);
|
|
15791
|
-
}
|
|
15792
|
-
}
|
|
15793
|
-
return null;
|
|
15794
|
-
};
|
|
15795
|
-
}
|
|
15796
|
-
/**
|
|
15797
|
-
* Conditional validator depends on other fields and should be updated on each form value change
|
|
15798
|
-
*/
|
|
15799
|
-
function revalidateOnChanges(control) {
|
|
15800
|
-
if (control && control.parent && !control['_revalidateOnChanges']) {
|
|
15801
|
-
control['_revalidateOnChanges'] = true;
|
|
15802
|
-
control.parent.valueChanges.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)))
|
|
15803
|
-
.subscribe(() => {
|
|
15804
|
-
control.updateValueAndValidity({ emitEvent: false });
|
|
15805
|
-
});
|
|
15806
|
-
}
|
|
15807
|
-
return;
|
|
15808
|
-
}
|
|
15809
|
-
|
|
15810
|
-
/**
|
|
15811
|
-
* Regular expressions that are used to check password strength and valid values
|
|
15812
|
-
*/
|
|
15813
|
-
const PASSWORD_REGEXPS = {
|
|
15814
|
-
medium: /(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})/,
|
|
15815
|
-
strong: /(((?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]))|((?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*]))|((?=.*[A-Z])(?=.*[0-9]))(?=.*[!@#$%^&*]))(?=.{8,})/,
|
|
15816
|
-
format: /^[0-9a-zA-Z!@$!%*?&#]*$/
|
|
15817
|
-
};
|
|
15818
|
-
function passwordValidator() {
|
|
15819
|
-
return (control) => {
|
|
15820
|
-
if (!PASSWORD_REGEXPS.format.test(control.value)) {
|
|
15821
|
-
return { passwordInvalid: true };
|
|
15822
|
-
}
|
|
15823
|
-
if (!PASSWORD_REGEXPS.medium.test(control.value)) {
|
|
15824
|
-
return { passwordWeak: true };
|
|
15825
|
-
}
|
|
15826
|
-
return null;
|
|
15827
|
-
};
|
|
15828
|
-
}
|
|
15829
|
-
|
|
15830
|
-
function passwordMatchValidator(newPassControlName, confirmPassControlName) {
|
|
15831
|
-
return (group) => {
|
|
15832
|
-
const passwordControl = group.get(newPassControlName);
|
|
15833
|
-
const confirmControl = group.get(confirmPassControlName);
|
|
15834
|
-
if (confirmControl.errors && !confirmControl.hasError('passwordMismatch')) {
|
|
15835
|
-
// return if another validator has already found an error on the confirmControl
|
|
15836
|
-
return this;
|
|
15837
|
-
}
|
|
15838
|
-
if (passwordControl.value !== confirmControl.value) {
|
|
15839
|
-
confirmControl.setErrors({ passwordMismatch: true });
|
|
15840
|
-
}
|
|
15841
|
-
else {
|
|
15842
|
-
confirmControl.setErrors(null);
|
|
15843
|
-
}
|
|
15844
|
-
};
|
|
15845
|
-
}
|
|
15846
|
-
|
|
15847
|
-
var MessagesEnum$1;
|
|
15848
|
-
(function (MessagesEnum) {
|
|
15849
|
-
MessagesEnum["INVALID_DATE"] = "The date should not be before $1";
|
|
15850
|
-
})(MessagesEnum$1 || (MessagesEnum$1 = {}));
|
|
15851
|
-
|
|
15852
|
-
/**
|
|
15853
|
-
* Validation function, that checks If date form value is more than provided date
|
|
15854
|
-
*/
|
|
15855
|
-
function minDateValidator(date, message = MessagesEnum$1.INVALID_DATE.replace('$1', new DatePipe('en-US').transform(date))) {
|
|
15856
|
-
return (control) => {
|
|
15857
|
-
if (!control.value) {
|
|
15858
|
-
return null;
|
|
15859
|
-
}
|
|
15860
|
-
// form control value can be as a Moment object - we wrap it in "new Date()" to work with it like with JS Date
|
|
15861
|
-
if (new Date(control.value) >= new Date(date)) {
|
|
15862
|
-
return null;
|
|
15863
|
-
}
|
|
15864
|
-
return { minDate: message };
|
|
15865
|
-
};
|
|
15866
|
-
}
|
|
15867
|
-
|
|
15868
|
-
/**
|
|
15869
|
-
* Validator that check if sum amount of provided fields is greater than provided sum
|
|
15870
|
-
* @param field to check in each formArray element
|
|
15871
|
-
* @param summary to compare with fields sum
|
|
15872
|
-
* @param fieldAlias to show it in error message
|
|
15873
|
-
*/
|
|
15874
|
-
function fieldsSumValidator(field, summary = 100, fieldAlias) {
|
|
15875
|
-
return (formArray) => {
|
|
15876
|
-
// calculate sum of desired fields in formArray control
|
|
15877
|
-
const fieldsSum = formArray['controls']
|
|
15878
|
-
.reduce((acc, group) => acc += group.get(field).value, 0);
|
|
15879
|
-
if (fieldsSum <= summary) {
|
|
15880
|
-
return null;
|
|
15881
|
-
}
|
|
15882
|
-
else {
|
|
15883
|
-
return {
|
|
15884
|
-
fieldsSum: {
|
|
15885
|
-
name: field,
|
|
15886
|
-
alias: fieldAlias,
|
|
15887
|
-
summary
|
|
15888
|
-
}
|
|
15889
|
-
};
|
|
15890
|
-
}
|
|
15891
|
-
};
|
|
15892
|
-
}
|
|
15893
|
-
|
|
15894
|
-
/**
|
|
15895
|
-
* Validation function, that checks If provided date is within a current financial year
|
|
15896
|
-
*/
|
|
15897
|
-
function currentFinYearValidator() {
|
|
15898
|
-
const currentFinYear = new FinancialYear();
|
|
15899
|
-
return (control) => {
|
|
15900
|
-
if (!control.value || control.value >= currentFinYear.startDate && control.value <= currentFinYear.endDate) {
|
|
15901
|
-
return null;
|
|
15902
|
-
}
|
|
15903
|
-
return { notCurrentFinYear: true };
|
|
15904
|
-
};
|
|
15905
|
-
}
|
|
15906
|
-
|
|
15907
|
-
const MAX_SIZE = 4194304;
|
|
15908
|
-
class FileValidator {
|
|
15909
|
-
// File max size check
|
|
15910
|
-
static fileMaxSize(maxSize = MAX_SIZE) {
|
|
15911
|
-
const validatorFn = (file) => {
|
|
15912
|
-
return file.size > maxSize ? { fileMaxSize: { maxSize } } : null;
|
|
15913
|
-
};
|
|
15914
|
-
return FileValidator.fileValidation(validatorFn);
|
|
15915
|
-
}
|
|
15916
|
-
// File extension check
|
|
15917
|
-
static fileExtensions(allowedExtensions = DOCUMENT_FILE_TYPES.all) {
|
|
15918
|
-
const validatorFn = (file) => {
|
|
15919
|
-
return allowedExtensions.includes(file.type) ? null : { fileExtension: { allowedExtensions: allowedExtensions.join() } };
|
|
15920
|
-
};
|
|
15921
|
-
return FileValidator.fileValidation(validatorFn);
|
|
15922
|
-
}
|
|
15923
|
-
static fileValidation(validatorFn) {
|
|
15924
|
-
return (formControl) => {
|
|
15925
|
-
if (!formControl.value) {
|
|
15926
|
-
return null;
|
|
15927
|
-
}
|
|
15928
|
-
return validatorFn(formControl.value);
|
|
15929
|
-
};
|
|
15930
|
-
}
|
|
15931
|
-
}
|
|
15932
|
-
|
|
15933
15768
|
/**
|
|
15934
15769
|
* Validator for address, check if corelogic suggestion selected correctly
|
|
15935
15770
|
*/
|
|
15936
15771
|
function addressCorelogicValidator() {
|
|
15937
15772
|
return (form) => {
|
|
15938
|
-
|
|
15939
|
-
|
|
15940
|
-
|
|
15941
|
-
|
|
15942
|
-
|
|
15943
|
-
|
|
15944
|
-
|
|
15773
|
+
// we are interested in corelogic ids only for Australian addresses
|
|
15774
|
+
if (!form.isAustraliaSelected()) {
|
|
15775
|
+
return null;
|
|
15776
|
+
}
|
|
15777
|
+
// we need at least corelogic locality id to get growth percent
|
|
15778
|
+
const locIdControl = form.get('corelogicLocId');
|
|
15779
|
+
if (locIdControl.enabled && locIdControl.hasError('required')) {
|
|
15780
|
+
return { address: 'City, state or postal code not specified' };
|
|
15945
15781
|
}
|
|
15946
15782
|
return null;
|
|
15947
15783
|
};
|
|
@@ -15951,51 +15787,49 @@ function addressCorelogicValidator() {
|
|
|
15951
15787
|
* Address form. Works with corelogic or manual address
|
|
15952
15788
|
*/
|
|
15953
15789
|
class AddressForm extends AbstractForm {
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
|
|
15957
|
-
|
|
15958
|
-
*/
|
|
15959
|
-
constructor(address = plainToClass(Address, {}), isCorelogicRequired = false) {
|
|
15790
|
+
constructor(
|
|
15791
|
+
// no default value because Address form is always a child form. That's mean address value always passed and then default value never work.
|
|
15792
|
+
// even if null passed, default value will not work
|
|
15793
|
+
address) {
|
|
15960
15794
|
super({
|
|
15961
15795
|
// prefill search input with address string for edit case
|
|
15962
|
-
searchQuery: new UntypedFormControl(address
|
|
15963
|
-
type: new UntypedFormControl(address
|
|
15964
|
-
//
|
|
15965
|
-
corelogicLocId: new UntypedFormControl(address.
|
|
15966
|
-
corelogicRefId: new UntypedFormControl(address
|
|
15967
|
-
// manual fields
|
|
15968
|
-
unitNumber: new UntypedFormControl({ value: address
|
|
15969
|
-
address: new UntypedFormControl({ value: address
|
|
15970
|
-
streetNumber: new UntypedFormControl({ value: address
|
|
15971
|
-
street: new UntypedFormControl({ value: address
|
|
15972
|
-
city: new UntypedFormControl({ value: address
|
|
15973
|
-
state: new UntypedFormControl({ value: address
|
|
15974
|
-
postcode: new UntypedFormControl({ value: address
|
|
15975
|
-
country: new UntypedFormControl({ value: address
|
|
15796
|
+
searchQuery: new UntypedFormControl(address?.address ? address.nameLong : null, Validators.required),
|
|
15797
|
+
type: new UntypedFormControl(address?.type || AddressTypeEnum.STREET, Validators.required),
|
|
15798
|
+
// corelogic fields (required for Australia and disabled for other countries)
|
|
15799
|
+
corelogicLocId: new UntypedFormControl({ value: address?.corelogicLocId, disabled: true }, Validators.required),
|
|
15800
|
+
corelogicRefId: new UntypedFormControl({ value: address?.corelogicRefId, disabled: true }),
|
|
15801
|
+
// manual fields (using when address not found in corelogic)
|
|
15802
|
+
unitNumber: new UntypedFormControl({ value: address?.unitNumber, disabled: true }),
|
|
15803
|
+
address: new UntypedFormControl({ value: address?.address, disabled: true }, Validators.required),
|
|
15804
|
+
streetNumber: new UntypedFormControl({ value: address?.streetNumber, disabled: true }, [Validators.required, Validators.pattern(AddressForm.streetNumberPattern)]),
|
|
15805
|
+
street: new UntypedFormControl({ value: address?.street, disabled: true }, Validators.required),
|
|
15806
|
+
city: new UntypedFormControl({ value: address?.city, disabled: true }, Validators.required),
|
|
15807
|
+
state: new UntypedFormControl({ value: address?.state, disabled: true }, Validators.required),
|
|
15808
|
+
postcode: new UntypedFormControl({ value: address?.postcode, disabled: true }, Validators.required),
|
|
15809
|
+
country: new UntypedFormControl({ value: address?.country || Country.australia, disabled: true }, Validators.required)
|
|
15976
15810
|
}, address, addressCorelogicValidator());
|
|
15977
|
-
this.isCorelogicRequired = isCorelogicRequired;
|
|
15978
15811
|
/**
|
|
15979
15812
|
* Emit event to search address in corelogic when user filled enough data for corelogic
|
|
15980
15813
|
*/
|
|
15981
15814
|
this.onSearch = new EventEmitter();
|
|
15815
|
+
if (this.isAustraliaSelected()) {
|
|
15816
|
+
this.enableCorelogicFields();
|
|
15817
|
+
}
|
|
15982
15818
|
this.listenEvents();
|
|
15983
15819
|
}
|
|
15984
15820
|
/**
|
|
15985
15821
|
* Get search query for corelogic location search based on manual fields values
|
|
15986
15822
|
*/
|
|
15987
15823
|
get manualSearchQuery() {
|
|
15988
|
-
|
|
15824
|
+
// nothing to search when manual fields are invalid or when selected country is not Australia because we don't need to use corelogic for other countries
|
|
15825
|
+
if (!this.isManualSearchAvailable() || !this.isAustraliaSelected()) {
|
|
15989
15826
|
return '';
|
|
15990
15827
|
}
|
|
15991
|
-
|
|
15828
|
+
// for manual mode we search corelogic for city (location) and ignore street
|
|
15829
|
+
return `${this.get('city').value} ${this.get('state').value} ${this.get('postcode').value}`;
|
|
15992
15830
|
}
|
|
15993
15831
|
listenEvents() {
|
|
15994
15832
|
this.listenSearchQueryChanges();
|
|
15995
|
-
// no need to search corelogic locality when corelogic is not required
|
|
15996
|
-
if (this.isCorelogicRequired) {
|
|
15997
|
-
this.listenManualFieldsChanges();
|
|
15998
|
-
}
|
|
15999
15833
|
}
|
|
16000
15834
|
/**
|
|
16001
15835
|
* Handle corelogic suggestion select
|
|
@@ -16011,25 +15845,29 @@ class AddressForm extends AbstractForm {
|
|
|
16011
15845
|
corelogicRefId: suggestion.propertyId
|
|
16012
15846
|
});
|
|
16013
15847
|
}
|
|
15848
|
+
/**
|
|
15849
|
+
* Check if Australia is selected in country field
|
|
15850
|
+
*/
|
|
15851
|
+
isAustraliaSelected() {
|
|
15852
|
+
return this.get('country').value?.id === Country.australia.id;
|
|
15853
|
+
}
|
|
16014
15854
|
/**
|
|
16015
15855
|
* Enable manual mode
|
|
16016
15856
|
*/
|
|
16017
15857
|
switchToManual() {
|
|
16018
15858
|
this.isManual = true;
|
|
16019
15859
|
this.get('searchQuery').disable();
|
|
15860
|
+
this.get('unitNumber').enable();
|
|
16020
15861
|
this.get('address').enable();
|
|
16021
15862
|
this.get('streetNumber').enable();
|
|
16022
15863
|
this.get('street').enable();
|
|
16023
|
-
this.get('unitNumber').enable();
|
|
16024
15864
|
this.get('city').enable();
|
|
16025
15865
|
this.get('state').enable();
|
|
16026
15866
|
this.get('postcode').enable();
|
|
16027
|
-
|
|
16028
|
-
|
|
16029
|
-
this.get('corelogicLocId').disable();
|
|
16030
|
-
this.get('corelogicRefId').disable();
|
|
16031
|
-
}
|
|
15867
|
+
this.get('country').enable();
|
|
15868
|
+
this.listenManualFieldsChanges();
|
|
16032
15869
|
this.listenStreetFieldsChanges();
|
|
15870
|
+
this.listenCountryChanges();
|
|
16033
15871
|
}
|
|
16034
15872
|
/**
|
|
16035
15873
|
* Emit event to search address in corelogic when search field changes
|
|
@@ -16061,7 +15899,7 @@ class AddressForm extends AbstractForm {
|
|
|
16061
15899
|
* Check if all fields required for manual corelogic search are filled before request sending
|
|
16062
15900
|
*/
|
|
16063
15901
|
isManualSearchAvailable() {
|
|
16064
|
-
return this.get('
|
|
15902
|
+
return this.get('city').valid && this.get('state').valid && this.get('postcode').valid;
|
|
16065
15903
|
}
|
|
16066
15904
|
/**
|
|
16067
15905
|
* When corelogic is required we have to search address even for manual address
|
|
@@ -16073,7 +15911,7 @@ class AddressForm extends AbstractForm {
|
|
|
16073
15911
|
// delay to avoid search request for each value change
|
|
16074
15912
|
debounceTime(AddressForm.searchDelay),
|
|
16075
15913
|
// do nothing when not all required fields filled
|
|
16076
|
-
filter(() => this.isManualSearchAvailable()), map(() => this.manualSearchQuery),
|
|
15914
|
+
filter(() => this.isManualSearchAvailable() && this.isAustraliaSelected()), map(() => this.manualSearchQuery),
|
|
16077
15915
|
// skip when value not changed
|
|
16078
15916
|
distinctUntilChanged())
|
|
16079
15917
|
.subscribe(() => {
|
|
@@ -16091,6 +15929,26 @@ class AddressForm extends AbstractForm {
|
|
|
16091
15929
|
this.get('address').setValue(`${this.get('streetNumber').value} ${this.get('street').value}`);
|
|
16092
15930
|
});
|
|
16093
15931
|
}
|
|
15932
|
+
enableCorelogicFields() {
|
|
15933
|
+
this.get('corelogicLocId').enable();
|
|
15934
|
+
this.get('corelogicRefId').enable();
|
|
15935
|
+
}
|
|
15936
|
+
disableCorelogicFields() {
|
|
15937
|
+
this.get('corelogicLocId').disable();
|
|
15938
|
+
this.get('corelogicRefId').disable();
|
|
15939
|
+
}
|
|
15940
|
+
/**
|
|
15941
|
+
* Corelogic loc id is required for Australian addresses
|
|
15942
|
+
*/
|
|
15943
|
+
listenCountryChanges() {
|
|
15944
|
+
this.get('country').valueChanges.subscribe(() => {
|
|
15945
|
+
if (this.isAustraliaSelected()) {
|
|
15946
|
+
this.enableCorelogicFields();
|
|
15947
|
+
return;
|
|
15948
|
+
}
|
|
15949
|
+
this.disableCorelogicFields();
|
|
15950
|
+
});
|
|
15951
|
+
}
|
|
16094
15952
|
}
|
|
16095
15953
|
/**
|
|
16096
15954
|
* Min search query required length
|
|
@@ -16186,6 +16044,175 @@ class LoanForm extends AbstractForm {
|
|
|
16186
16044
|
}
|
|
16187
16045
|
LoanForm.mortgageLoanTypes = [LoanTypeEnum.MORTGAGE, LoanTypeEnum.HOME_EQUITY_LINE_OF_CREDIT, LoanTypeEnum.HOME_LOAN];
|
|
16188
16046
|
|
|
16047
|
+
/**
|
|
16048
|
+
* Check if at least one form field is true, otherwise form is invalid.
|
|
16049
|
+
* Use with groups of boolean form controls (checkbox, toggle, etc.)
|
|
16050
|
+
*/
|
|
16051
|
+
function atLeastOneCheckedValidator() {
|
|
16052
|
+
return (formGroup) => {
|
|
16053
|
+
return Object.values(formGroup.controls)
|
|
16054
|
+
.find((control) => control.value) ? null : { nothingChecked: true };
|
|
16055
|
+
};
|
|
16056
|
+
}
|
|
16057
|
+
|
|
16058
|
+
/**
|
|
16059
|
+
* Validation function for autocomplete fields. Checks that the user should select a value from a list rather than type in input field
|
|
16060
|
+
* @TODO Alex: create class AppValidators with static methods and move there all custom validators (line Angular Validators)
|
|
16061
|
+
*/
|
|
16062
|
+
function autocompleteValidator() {
|
|
16063
|
+
return (control) => {
|
|
16064
|
+
return (!control.value || (typeof control.value === 'object')) ? null : { notFromList: true };
|
|
16065
|
+
};
|
|
16066
|
+
}
|
|
16067
|
+
|
|
16068
|
+
function conditionalValidator(condition, validator) {
|
|
16069
|
+
return function (control) {
|
|
16070
|
+
revalidateOnChanges(control);
|
|
16071
|
+
if (control && control.parent) {
|
|
16072
|
+
if (condition(control.parent)) {
|
|
16073
|
+
return validator(control);
|
|
16074
|
+
}
|
|
16075
|
+
}
|
|
16076
|
+
return null;
|
|
16077
|
+
};
|
|
16078
|
+
}
|
|
16079
|
+
/**
|
|
16080
|
+
* Conditional validator depends on other fields and should be updated on each form value change
|
|
16081
|
+
*/
|
|
16082
|
+
function revalidateOnChanges(control) {
|
|
16083
|
+
if (control && control.parent && !control['_revalidateOnChanges']) {
|
|
16084
|
+
control['_revalidateOnChanges'] = true;
|
|
16085
|
+
control.parent.valueChanges.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)))
|
|
16086
|
+
.subscribe(() => {
|
|
16087
|
+
control.updateValueAndValidity({ emitEvent: false });
|
|
16088
|
+
});
|
|
16089
|
+
}
|
|
16090
|
+
return;
|
|
16091
|
+
}
|
|
16092
|
+
|
|
16093
|
+
/**
|
|
16094
|
+
* Regular expressions that are used to check password strength and valid values
|
|
16095
|
+
*/
|
|
16096
|
+
const PASSWORD_REGEXPS = {
|
|
16097
|
+
medium: /(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})/,
|
|
16098
|
+
strong: /(((?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]))|((?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*]))|((?=.*[A-Z])(?=.*[0-9]))(?=.*[!@#$%^&*]))(?=.{8,})/,
|
|
16099
|
+
format: /^[0-9a-zA-Z!@$!%*?&#]*$/
|
|
16100
|
+
};
|
|
16101
|
+
function passwordValidator() {
|
|
16102
|
+
return (control) => {
|
|
16103
|
+
if (!PASSWORD_REGEXPS.format.test(control.value)) {
|
|
16104
|
+
return { passwordInvalid: true };
|
|
16105
|
+
}
|
|
16106
|
+
if (!PASSWORD_REGEXPS.medium.test(control.value)) {
|
|
16107
|
+
return { passwordWeak: true };
|
|
16108
|
+
}
|
|
16109
|
+
return null;
|
|
16110
|
+
};
|
|
16111
|
+
}
|
|
16112
|
+
|
|
16113
|
+
function passwordMatchValidator(newPassControlName, confirmPassControlName) {
|
|
16114
|
+
return (group) => {
|
|
16115
|
+
const passwordControl = group.get(newPassControlName);
|
|
16116
|
+
const confirmControl = group.get(confirmPassControlName);
|
|
16117
|
+
if (confirmControl.errors && !confirmControl.hasError('passwordMismatch')) {
|
|
16118
|
+
// return if another validator has already found an error on the confirmControl
|
|
16119
|
+
return this;
|
|
16120
|
+
}
|
|
16121
|
+
if (passwordControl.value !== confirmControl.value) {
|
|
16122
|
+
confirmControl.setErrors({ passwordMismatch: true });
|
|
16123
|
+
}
|
|
16124
|
+
else {
|
|
16125
|
+
confirmControl.setErrors(null);
|
|
16126
|
+
}
|
|
16127
|
+
};
|
|
16128
|
+
}
|
|
16129
|
+
|
|
16130
|
+
var MessagesEnum$1;
|
|
16131
|
+
(function (MessagesEnum) {
|
|
16132
|
+
MessagesEnum["INVALID_DATE"] = "The date should not be before $1";
|
|
16133
|
+
})(MessagesEnum$1 || (MessagesEnum$1 = {}));
|
|
16134
|
+
|
|
16135
|
+
/**
|
|
16136
|
+
* Validation function, that checks If date form value is more than provided date
|
|
16137
|
+
*/
|
|
16138
|
+
function minDateValidator(date, message = MessagesEnum$1.INVALID_DATE.replace('$1', new DatePipe('en-US').transform(date))) {
|
|
16139
|
+
return (control) => {
|
|
16140
|
+
if (!control.value) {
|
|
16141
|
+
return null;
|
|
16142
|
+
}
|
|
16143
|
+
// form control value can be as a Moment object - we wrap it in "new Date()" to work with it like with JS Date
|
|
16144
|
+
if (new Date(control.value) >= new Date(date)) {
|
|
16145
|
+
return null;
|
|
16146
|
+
}
|
|
16147
|
+
return { minDate: message };
|
|
16148
|
+
};
|
|
16149
|
+
}
|
|
16150
|
+
|
|
16151
|
+
/**
|
|
16152
|
+
* Validator that check if sum amount of provided fields is greater than provided sum
|
|
16153
|
+
* @param field to check in each formArray element
|
|
16154
|
+
* @param summary to compare with fields sum
|
|
16155
|
+
* @param fieldAlias to show it in error message
|
|
16156
|
+
*/
|
|
16157
|
+
function fieldsSumValidator(field, summary = 100, fieldAlias) {
|
|
16158
|
+
return (formArray) => {
|
|
16159
|
+
// calculate sum of desired fields in formArray control
|
|
16160
|
+
const fieldsSum = formArray['controls']
|
|
16161
|
+
.reduce((acc, group) => acc += group.get(field).value, 0);
|
|
16162
|
+
if (fieldsSum <= summary) {
|
|
16163
|
+
return null;
|
|
16164
|
+
}
|
|
16165
|
+
else {
|
|
16166
|
+
return {
|
|
16167
|
+
fieldsSum: {
|
|
16168
|
+
name: field,
|
|
16169
|
+
alias: fieldAlias,
|
|
16170
|
+
summary
|
|
16171
|
+
}
|
|
16172
|
+
};
|
|
16173
|
+
}
|
|
16174
|
+
};
|
|
16175
|
+
}
|
|
16176
|
+
|
|
16177
|
+
/**
|
|
16178
|
+
* Validation function, that checks If provided date is within a current financial year
|
|
16179
|
+
*/
|
|
16180
|
+
function currentFinYearValidator() {
|
|
16181
|
+
const currentFinYear = new FinancialYear();
|
|
16182
|
+
return (control) => {
|
|
16183
|
+
if (!control.value || control.value >= currentFinYear.startDate && control.value <= currentFinYear.endDate) {
|
|
16184
|
+
return null;
|
|
16185
|
+
}
|
|
16186
|
+
return { notCurrentFinYear: true };
|
|
16187
|
+
};
|
|
16188
|
+
}
|
|
16189
|
+
|
|
16190
|
+
const MAX_SIZE = 4194304;
|
|
16191
|
+
class FileValidator {
|
|
16192
|
+
// File max size check
|
|
16193
|
+
static fileMaxSize(maxSize = MAX_SIZE) {
|
|
16194
|
+
const validatorFn = (file) => {
|
|
16195
|
+
return file.size > maxSize ? { fileMaxSize: { maxSize } } : null;
|
|
16196
|
+
};
|
|
16197
|
+
return FileValidator.fileValidation(validatorFn);
|
|
16198
|
+
}
|
|
16199
|
+
// File extension check
|
|
16200
|
+
static fileExtensions(allowedExtensions = DOCUMENT_FILE_TYPES.all) {
|
|
16201
|
+
const validatorFn = (file) => {
|
|
16202
|
+
return allowedExtensions.includes(file.type) ? null : { fileExtension: { allowedExtensions: allowedExtensions.join() } };
|
|
16203
|
+
};
|
|
16204
|
+
return FileValidator.fileValidation(validatorFn);
|
|
16205
|
+
}
|
|
16206
|
+
static fileValidation(validatorFn) {
|
|
16207
|
+
return (formControl) => {
|
|
16208
|
+
if (!formControl.value) {
|
|
16209
|
+
return null;
|
|
16210
|
+
}
|
|
16211
|
+
return validatorFn(formControl.value);
|
|
16212
|
+
};
|
|
16213
|
+
}
|
|
16214
|
+
}
|
|
16215
|
+
|
|
16189
16216
|
/**
|
|
16190
16217
|
* Form array with bank account properties
|
|
16191
16218
|
* @TODO create AbstractFormArray
|
|
@@ -16401,7 +16428,7 @@ class SoleContactForm extends AbstractForm {
|
|
|
16401
16428
|
lastName: new UntypedFormControl(contact.lastName, Validators.required),
|
|
16402
16429
|
email: new UntypedFormControl(contact.email, [Validators.required, Validators.email]),
|
|
16403
16430
|
phone: new UntypedFormControl(contact.phone),
|
|
16404
|
-
address: new
|
|
16431
|
+
address: new UntypedFormControl(contact.address)
|
|
16405
16432
|
}, contact);
|
|
16406
16433
|
}
|
|
16407
16434
|
}
|
|
@@ -16890,7 +16917,8 @@ function phoneNumberValidator() {
|
|
|
16890
16917
|
|
|
16891
16918
|
class PhoneForm extends AbstractForm {
|
|
16892
16919
|
constructor(
|
|
16893
|
-
// no default value because
|
|
16920
|
+
// no default value because Address form is always a child form. That's mean address value always passed and then default value never work.
|
|
16921
|
+
// even if null passed, default value will not work
|
|
16894
16922
|
phone) {
|
|
16895
16923
|
super({
|
|
16896
16924
|
type: new UntypedFormControl(phone?.type || PhoneTypeEnum.MOBILE, Validators.required),
|