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';
|
|
@@ -387,6 +387,10 @@ class TransactionBase extends ObservableModel {
|
|
|
387
387
|
return TankTypeEnum.OTHER;
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
|
+
/**
|
|
391
|
+
* @TODO remove when AllocateForm is refactored and not merging with Transaction class which cause the issue
|
|
392
|
+
*/
|
|
393
|
+
set tankType(tankType) { }
|
|
390
394
|
/**
|
|
391
395
|
* Check if current tank is Property
|
|
392
396
|
*/
|
|
@@ -15877,187 +15881,19 @@ class AbstractForm extends UntypedFormGroup {
|
|
|
15877
15881
|
}
|
|
15878
15882
|
}
|
|
15879
15883
|
|
|
15880
|
-
/**
|
|
15881
|
-
* Check if at least one form field is true, otherwise form is invalid.
|
|
15882
|
-
* Use with groups of boolean form controls (checkbox, toggle, etc.)
|
|
15883
|
-
*/
|
|
15884
|
-
function atLeastOneCheckedValidator() {
|
|
15885
|
-
return (formGroup) => {
|
|
15886
|
-
return Object.values(formGroup.controls)
|
|
15887
|
-
.find((control) => control.value) ? null : { nothingChecked: true };
|
|
15888
|
-
};
|
|
15889
|
-
}
|
|
15890
|
-
|
|
15891
|
-
/**
|
|
15892
|
-
* Validation function for autocomplete fields. Checks that the user should select a value from a list rather than type in input field
|
|
15893
|
-
* @TODO Alex: create class AppValidators with static methods and move there all custom validators (line Angular Validators)
|
|
15894
|
-
*/
|
|
15895
|
-
function autocompleteValidator() {
|
|
15896
|
-
return (control) => {
|
|
15897
|
-
return (!control.value || (typeof control.value === 'object')) ? null : { notFromList: true };
|
|
15898
|
-
};
|
|
15899
|
-
}
|
|
15900
|
-
|
|
15901
|
-
function conditionalValidator(condition, validator) {
|
|
15902
|
-
return function (control) {
|
|
15903
|
-
revalidateOnChanges(control);
|
|
15904
|
-
if (control && control.parent) {
|
|
15905
|
-
if (condition(control.parent)) {
|
|
15906
|
-
return validator(control);
|
|
15907
|
-
}
|
|
15908
|
-
}
|
|
15909
|
-
return null;
|
|
15910
|
-
};
|
|
15911
|
-
}
|
|
15912
|
-
/**
|
|
15913
|
-
* Conditional validator depends on other fields and should be updated on each form value change
|
|
15914
|
-
*/
|
|
15915
|
-
function revalidateOnChanges(control) {
|
|
15916
|
-
if (control && control.parent && !control['_revalidateOnChanges']) {
|
|
15917
|
-
control['_revalidateOnChanges'] = true;
|
|
15918
|
-
control.parent.valueChanges.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)))
|
|
15919
|
-
.subscribe(() => {
|
|
15920
|
-
control.updateValueAndValidity({ emitEvent: false });
|
|
15921
|
-
});
|
|
15922
|
-
}
|
|
15923
|
-
return;
|
|
15924
|
-
}
|
|
15925
|
-
|
|
15926
|
-
/**
|
|
15927
|
-
* Regular expressions that are used to check password strength and valid values
|
|
15928
|
-
*/
|
|
15929
|
-
const PASSWORD_REGEXPS = {
|
|
15930
|
-
medium: /(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})/,
|
|
15931
|
-
strong: /(((?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]))|((?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*]))|((?=.*[A-Z])(?=.*[0-9]))(?=.*[!@#$%^&*]))(?=.{8,})/,
|
|
15932
|
-
format: /^[0-9a-zA-Z!@$!%*?&#]*$/
|
|
15933
|
-
};
|
|
15934
|
-
function passwordValidator() {
|
|
15935
|
-
return (control) => {
|
|
15936
|
-
if (!PASSWORD_REGEXPS.format.test(control.value)) {
|
|
15937
|
-
return { passwordInvalid: true };
|
|
15938
|
-
}
|
|
15939
|
-
if (!PASSWORD_REGEXPS.medium.test(control.value)) {
|
|
15940
|
-
return { passwordWeak: true };
|
|
15941
|
-
}
|
|
15942
|
-
return null;
|
|
15943
|
-
};
|
|
15944
|
-
}
|
|
15945
|
-
|
|
15946
|
-
function passwordMatchValidator(newPassControlName, confirmPassControlName) {
|
|
15947
|
-
return (group) => {
|
|
15948
|
-
const passwordControl = group.get(newPassControlName);
|
|
15949
|
-
const confirmControl = group.get(confirmPassControlName);
|
|
15950
|
-
if (confirmControl.errors && !confirmControl.hasError('passwordMismatch')) {
|
|
15951
|
-
// return if another validator has already found an error on the confirmControl
|
|
15952
|
-
return this;
|
|
15953
|
-
}
|
|
15954
|
-
if (passwordControl.value !== confirmControl.value) {
|
|
15955
|
-
confirmControl.setErrors({ passwordMismatch: true });
|
|
15956
|
-
}
|
|
15957
|
-
else {
|
|
15958
|
-
confirmControl.setErrors(null);
|
|
15959
|
-
}
|
|
15960
|
-
};
|
|
15961
|
-
}
|
|
15962
|
-
|
|
15963
|
-
var MessagesEnum$1;
|
|
15964
|
-
(function (MessagesEnum) {
|
|
15965
|
-
MessagesEnum["INVALID_DATE"] = "The date should not be before $1";
|
|
15966
|
-
})(MessagesEnum$1 || (MessagesEnum$1 = {}));
|
|
15967
|
-
|
|
15968
|
-
/**
|
|
15969
|
-
* Validation function, that checks If date form value is more than provided date
|
|
15970
|
-
*/
|
|
15971
|
-
function minDateValidator(date, message = MessagesEnum$1.INVALID_DATE.replace('$1', new DatePipe('en-US').transform(date))) {
|
|
15972
|
-
return (control) => {
|
|
15973
|
-
if (!control.value) {
|
|
15974
|
-
return null;
|
|
15975
|
-
}
|
|
15976
|
-
// form control value can be as a Moment object - we wrap it in "new Date()" to work with it like with JS Date
|
|
15977
|
-
if (new Date(control.value) >= new Date(date)) {
|
|
15978
|
-
return null;
|
|
15979
|
-
}
|
|
15980
|
-
return { minDate: message };
|
|
15981
|
-
};
|
|
15982
|
-
}
|
|
15983
|
-
|
|
15984
|
-
/**
|
|
15985
|
-
* Validator that check if sum amount of provided fields is greater than provided sum
|
|
15986
|
-
* @param field to check in each formArray element
|
|
15987
|
-
* @param summary to compare with fields sum
|
|
15988
|
-
* @param fieldAlias to show it in error message
|
|
15989
|
-
*/
|
|
15990
|
-
function fieldsSumValidator(field, summary = 100, fieldAlias) {
|
|
15991
|
-
return (formArray) => {
|
|
15992
|
-
// calculate sum of desired fields in formArray control
|
|
15993
|
-
const fieldsSum = formArray['controls']
|
|
15994
|
-
.reduce((acc, group) => acc += group.get(field).value, 0);
|
|
15995
|
-
if (fieldsSum <= summary) {
|
|
15996
|
-
return null;
|
|
15997
|
-
}
|
|
15998
|
-
else {
|
|
15999
|
-
return {
|
|
16000
|
-
fieldsSum: {
|
|
16001
|
-
name: field,
|
|
16002
|
-
alias: fieldAlias,
|
|
16003
|
-
summary
|
|
16004
|
-
}
|
|
16005
|
-
};
|
|
16006
|
-
}
|
|
16007
|
-
};
|
|
16008
|
-
}
|
|
16009
|
-
|
|
16010
|
-
/**
|
|
16011
|
-
* Validation function, that checks If provided date is within a current financial year
|
|
16012
|
-
*/
|
|
16013
|
-
function currentFinYearValidator() {
|
|
16014
|
-
const currentFinYear = new FinancialYear();
|
|
16015
|
-
return (control) => {
|
|
16016
|
-
if (!control.value || control.value >= currentFinYear.startDate && control.value <= currentFinYear.endDate) {
|
|
16017
|
-
return null;
|
|
16018
|
-
}
|
|
16019
|
-
return { notCurrentFinYear: true };
|
|
16020
|
-
};
|
|
16021
|
-
}
|
|
16022
|
-
|
|
16023
|
-
const MAX_SIZE = 4194304;
|
|
16024
|
-
class FileValidator {
|
|
16025
|
-
// File max size check
|
|
16026
|
-
static fileMaxSize(maxSize = MAX_SIZE) {
|
|
16027
|
-
const validatorFn = (file) => {
|
|
16028
|
-
return file.size > maxSize ? { fileMaxSize: { maxSize } } : null;
|
|
16029
|
-
};
|
|
16030
|
-
return FileValidator.fileValidation(validatorFn);
|
|
16031
|
-
}
|
|
16032
|
-
// File extension check
|
|
16033
|
-
static fileExtensions(allowedExtensions = DOCUMENT_FILE_TYPES.all) {
|
|
16034
|
-
const validatorFn = (file) => {
|
|
16035
|
-
return allowedExtensions.includes(file.type) ? null : { fileExtension: { allowedExtensions: allowedExtensions.join() } };
|
|
16036
|
-
};
|
|
16037
|
-
return FileValidator.fileValidation(validatorFn);
|
|
16038
|
-
}
|
|
16039
|
-
static fileValidation(validatorFn) {
|
|
16040
|
-
return (formControl) => {
|
|
16041
|
-
if (!formControl.value) {
|
|
16042
|
-
return null;
|
|
16043
|
-
}
|
|
16044
|
-
return validatorFn(formControl.value);
|
|
16045
|
-
};
|
|
16046
|
-
}
|
|
16047
|
-
}
|
|
16048
|
-
|
|
16049
15884
|
/**
|
|
16050
15885
|
* Validator for address, check if corelogic suggestion selected correctly
|
|
16051
15886
|
*/
|
|
16052
15887
|
function addressCorelogicValidator() {
|
|
16053
15888
|
return (form) => {
|
|
16054
|
-
|
|
16055
|
-
|
|
16056
|
-
|
|
16057
|
-
|
|
16058
|
-
|
|
16059
|
-
|
|
16060
|
-
|
|
15889
|
+
// we are interested in corelogic ids only for Australian addresses
|
|
15890
|
+
if (!form.isAustraliaSelected()) {
|
|
15891
|
+
return null;
|
|
15892
|
+
}
|
|
15893
|
+
// we need at least corelogic locality id to get growth percent
|
|
15894
|
+
const locIdControl = form.get('corelogicLocId');
|
|
15895
|
+
if (locIdControl.enabled && locIdControl.hasError('required')) {
|
|
15896
|
+
return { address: 'City, state or postal code not specified' };
|
|
16061
15897
|
}
|
|
16062
15898
|
return null;
|
|
16063
15899
|
};
|
|
@@ -16067,51 +15903,49 @@ function addressCorelogicValidator() {
|
|
|
16067
15903
|
* Address form. Works with corelogic or manual address
|
|
16068
15904
|
*/
|
|
16069
15905
|
class AddressForm extends AbstractForm {
|
|
16070
|
-
|
|
16071
|
-
|
|
16072
|
-
|
|
16073
|
-
|
|
16074
|
-
*/
|
|
16075
|
-
constructor(address = plainToClass(Address, {}), isCorelogicRequired = false) {
|
|
15906
|
+
constructor(
|
|
15907
|
+
// no default value because Address form is always a child form. That's mean address value always passed and then default value never work.
|
|
15908
|
+
// even if null passed, default value will not work
|
|
15909
|
+
address) {
|
|
16076
15910
|
super({
|
|
16077
15911
|
// prefill search input with address string for edit case
|
|
16078
|
-
searchQuery: new UntypedFormControl(address.address ? address.nameLong : null, Validators.required),
|
|
16079
|
-
type: new UntypedFormControl(address.type
|
|
16080
|
-
//
|
|
16081
|
-
corelogicLocId: new UntypedFormControl(address.corelogicLocId),
|
|
16082
|
-
corelogicRefId: new UntypedFormControl(address.corelogicRefId),
|
|
16083
|
-
// manual fields
|
|
16084
|
-
unitNumber: new UntypedFormControl({ value: address.unitNumber, disabled: true }),
|
|
16085
|
-
address: new UntypedFormControl({ value: address.address, disabled: true }, Validators.required),
|
|
16086
|
-
streetNumber: new UntypedFormControl({ value: address.streetNumber, disabled: true }, [Validators.required, Validators.pattern(AddressForm.streetNumberPattern)]),
|
|
16087
|
-
street: new UntypedFormControl({ value: address.street, disabled: true }, Validators.required),
|
|
16088
|
-
city: new UntypedFormControl({ value: address.city, disabled: true }, Validators.required),
|
|
16089
|
-
state: new UntypedFormControl({ value: address.state, disabled: true }, Validators.required),
|
|
16090
|
-
postcode: new UntypedFormControl({ value: address.postcode, disabled: true }, Validators.required),
|
|
16091
|
-
country: new UntypedFormControl({ value: address.country || Country.australia, disabled: true },
|
|
15912
|
+
searchQuery: new UntypedFormControl((address === null || address === void 0 ? void 0 : address.address) ? address.nameLong : null, Validators.required),
|
|
15913
|
+
type: new UntypedFormControl((address === null || address === void 0 ? void 0 : address.type) || AddressTypeEnum.STREET, Validators.required),
|
|
15914
|
+
// corelogic fields (required for Australia and disabled for other countries)
|
|
15915
|
+
corelogicLocId: new UntypedFormControl({ value: address === null || address === void 0 ? void 0 : address.corelogicLocId, disabled: true }, Validators.required),
|
|
15916
|
+
corelogicRefId: new UntypedFormControl({ value: address === null || address === void 0 ? void 0 : address.corelogicRefId, disabled: true }),
|
|
15917
|
+
// manual fields (using when address not found in corelogic)
|
|
15918
|
+
unitNumber: new UntypedFormControl({ value: address === null || address === void 0 ? void 0 : address.unitNumber, disabled: true }),
|
|
15919
|
+
address: new UntypedFormControl({ value: address === null || address === void 0 ? void 0 : address.address, disabled: true }, Validators.required),
|
|
15920
|
+
streetNumber: new UntypedFormControl({ value: address === null || address === void 0 ? void 0 : address.streetNumber, disabled: true }, [Validators.required, Validators.pattern(AddressForm.streetNumberPattern)]),
|
|
15921
|
+
street: new UntypedFormControl({ value: address === null || address === void 0 ? void 0 : address.street, disabled: true }, Validators.required),
|
|
15922
|
+
city: new UntypedFormControl({ value: address === null || address === void 0 ? void 0 : address.city, disabled: true }, Validators.required),
|
|
15923
|
+
state: new UntypedFormControl({ value: address === null || address === void 0 ? void 0 : address.state, disabled: true }, Validators.required),
|
|
15924
|
+
postcode: new UntypedFormControl({ value: address === null || address === void 0 ? void 0 : address.postcode, disabled: true }, Validators.required),
|
|
15925
|
+
country: new UntypedFormControl({ value: (address === null || address === void 0 ? void 0 : address.country) || Country.australia, disabled: true }, Validators.required)
|
|
16092
15926
|
}, address, addressCorelogicValidator());
|
|
16093
|
-
this.isCorelogicRequired = isCorelogicRequired;
|
|
16094
15927
|
/**
|
|
16095
15928
|
* Emit event to search address in corelogic when user filled enough data for corelogic
|
|
16096
15929
|
*/
|
|
16097
15930
|
this.onSearch = new EventEmitter();
|
|
15931
|
+
if (this.isAustraliaSelected()) {
|
|
15932
|
+
this.enableCorelogicFields();
|
|
15933
|
+
}
|
|
16098
15934
|
this.listenEvents();
|
|
16099
15935
|
}
|
|
16100
15936
|
/**
|
|
16101
15937
|
* Get search query for corelogic location search based on manual fields values
|
|
16102
15938
|
*/
|
|
16103
15939
|
get manualSearchQuery() {
|
|
16104
|
-
|
|
15940
|
+
// 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
|
|
15941
|
+
if (!this.isManualSearchAvailable() || !this.isAustraliaSelected()) {
|
|
16105
15942
|
return '';
|
|
16106
15943
|
}
|
|
16107
|
-
|
|
15944
|
+
// for manual mode we search corelogic for city (location) and ignore street
|
|
15945
|
+
return `${this.get('city').value} ${this.get('state').value} ${this.get('postcode').value}`;
|
|
16108
15946
|
}
|
|
16109
15947
|
listenEvents() {
|
|
16110
15948
|
this.listenSearchQueryChanges();
|
|
16111
|
-
// no need to search corelogic locality when corelogic is not required
|
|
16112
|
-
if (this.isCorelogicRequired) {
|
|
16113
|
-
this.listenManualFieldsChanges();
|
|
16114
|
-
}
|
|
16115
15949
|
}
|
|
16116
15950
|
/**
|
|
16117
15951
|
* Handle corelogic suggestion select
|
|
@@ -16127,25 +15961,30 @@ class AddressForm extends AbstractForm {
|
|
|
16127
15961
|
corelogicRefId: suggestion.propertyId
|
|
16128
15962
|
});
|
|
16129
15963
|
}
|
|
15964
|
+
/**
|
|
15965
|
+
* Check if Australia is selected in country field
|
|
15966
|
+
*/
|
|
15967
|
+
isAustraliaSelected() {
|
|
15968
|
+
var _a;
|
|
15969
|
+
return ((_a = this.get('country').value) === null || _a === void 0 ? void 0 : _a.id) === Country.australia.id;
|
|
15970
|
+
}
|
|
16130
15971
|
/**
|
|
16131
15972
|
* Enable manual mode
|
|
16132
15973
|
*/
|
|
16133
15974
|
switchToManual() {
|
|
16134
15975
|
this.isManual = true;
|
|
16135
15976
|
this.get('searchQuery').disable();
|
|
15977
|
+
this.get('unitNumber').enable();
|
|
16136
15978
|
this.get('address').enable();
|
|
16137
15979
|
this.get('streetNumber').enable();
|
|
16138
15980
|
this.get('street').enable();
|
|
16139
|
-
this.get('unitNumber').enable();
|
|
16140
15981
|
this.get('city').enable();
|
|
16141
15982
|
this.get('state').enable();
|
|
16142
15983
|
this.get('postcode').enable();
|
|
16143
|
-
|
|
16144
|
-
|
|
16145
|
-
this.get('corelogicLocId').disable();
|
|
16146
|
-
this.get('corelogicRefId').disable();
|
|
16147
|
-
}
|
|
15984
|
+
this.get('country').enable();
|
|
15985
|
+
this.listenManualFieldsChanges();
|
|
16148
15986
|
this.listenStreetFieldsChanges();
|
|
15987
|
+
this.listenCountryChanges();
|
|
16149
15988
|
}
|
|
16150
15989
|
/**
|
|
16151
15990
|
* Emit event to search address in corelogic when search field changes
|
|
@@ -16177,7 +16016,7 @@ class AddressForm extends AbstractForm {
|
|
|
16177
16016
|
* Check if all fields required for manual corelogic search are filled before request sending
|
|
16178
16017
|
*/
|
|
16179
16018
|
isManualSearchAvailable() {
|
|
16180
|
-
return this.get('
|
|
16019
|
+
return this.get('city').valid && this.get('state').valid && this.get('postcode').valid;
|
|
16181
16020
|
}
|
|
16182
16021
|
/**
|
|
16183
16022
|
* When corelogic is required we have to search address even for manual address
|
|
@@ -16189,7 +16028,7 @@ class AddressForm extends AbstractForm {
|
|
|
16189
16028
|
// delay to avoid search request for each value change
|
|
16190
16029
|
debounceTime(AddressForm.searchDelay),
|
|
16191
16030
|
// do nothing when not all required fields filled
|
|
16192
|
-
filter(() => this.isManualSearchAvailable()), map(() => this.manualSearchQuery),
|
|
16031
|
+
filter(() => this.isManualSearchAvailable() && this.isAustraliaSelected()), map(() => this.manualSearchQuery),
|
|
16193
16032
|
// skip when value not changed
|
|
16194
16033
|
distinctUntilChanged())
|
|
16195
16034
|
.subscribe(() => {
|
|
@@ -16207,6 +16046,26 @@ class AddressForm extends AbstractForm {
|
|
|
16207
16046
|
this.get('address').setValue(`${this.get('streetNumber').value} ${this.get('street').value}`);
|
|
16208
16047
|
});
|
|
16209
16048
|
}
|
|
16049
|
+
enableCorelogicFields() {
|
|
16050
|
+
this.get('corelogicLocId').enable();
|
|
16051
|
+
this.get('corelogicRefId').enable();
|
|
16052
|
+
}
|
|
16053
|
+
disableCorelogicFields() {
|
|
16054
|
+
this.get('corelogicLocId').disable();
|
|
16055
|
+
this.get('corelogicRefId').disable();
|
|
16056
|
+
}
|
|
16057
|
+
/**
|
|
16058
|
+
* Corelogic loc id is required for Australian addresses
|
|
16059
|
+
*/
|
|
16060
|
+
listenCountryChanges() {
|
|
16061
|
+
this.get('country').valueChanges.subscribe(() => {
|
|
16062
|
+
if (this.isAustraliaSelected()) {
|
|
16063
|
+
this.enableCorelogicFields();
|
|
16064
|
+
return;
|
|
16065
|
+
}
|
|
16066
|
+
this.disableCorelogicFields();
|
|
16067
|
+
});
|
|
16068
|
+
}
|
|
16210
16069
|
}
|
|
16211
16070
|
/**
|
|
16212
16071
|
* Min search query required length
|
|
@@ -16302,6 +16161,175 @@ class LoanForm extends AbstractForm {
|
|
|
16302
16161
|
}
|
|
16303
16162
|
LoanForm.mortgageLoanTypes = [LoanTypeEnum.MORTGAGE, LoanTypeEnum.HOME_EQUITY_LINE_OF_CREDIT, LoanTypeEnum.HOME_LOAN];
|
|
16304
16163
|
|
|
16164
|
+
/**
|
|
16165
|
+
* Check if at least one form field is true, otherwise form is invalid.
|
|
16166
|
+
* Use with groups of boolean form controls (checkbox, toggle, etc.)
|
|
16167
|
+
*/
|
|
16168
|
+
function atLeastOneCheckedValidator() {
|
|
16169
|
+
return (formGroup) => {
|
|
16170
|
+
return Object.values(formGroup.controls)
|
|
16171
|
+
.find((control) => control.value) ? null : { nothingChecked: true };
|
|
16172
|
+
};
|
|
16173
|
+
}
|
|
16174
|
+
|
|
16175
|
+
/**
|
|
16176
|
+
* Validation function for autocomplete fields. Checks that the user should select a value from a list rather than type in input field
|
|
16177
|
+
* @TODO Alex: create class AppValidators with static methods and move there all custom validators (line Angular Validators)
|
|
16178
|
+
*/
|
|
16179
|
+
function autocompleteValidator() {
|
|
16180
|
+
return (control) => {
|
|
16181
|
+
return (!control.value || (typeof control.value === 'object')) ? null : { notFromList: true };
|
|
16182
|
+
};
|
|
16183
|
+
}
|
|
16184
|
+
|
|
16185
|
+
function conditionalValidator(condition, validator) {
|
|
16186
|
+
return function (control) {
|
|
16187
|
+
revalidateOnChanges(control);
|
|
16188
|
+
if (control && control.parent) {
|
|
16189
|
+
if (condition(control.parent)) {
|
|
16190
|
+
return validator(control);
|
|
16191
|
+
}
|
|
16192
|
+
}
|
|
16193
|
+
return null;
|
|
16194
|
+
};
|
|
16195
|
+
}
|
|
16196
|
+
/**
|
|
16197
|
+
* Conditional validator depends on other fields and should be updated on each form value change
|
|
16198
|
+
*/
|
|
16199
|
+
function revalidateOnChanges(control) {
|
|
16200
|
+
if (control && control.parent && !control['_revalidateOnChanges']) {
|
|
16201
|
+
control['_revalidateOnChanges'] = true;
|
|
16202
|
+
control.parent.valueChanges.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)))
|
|
16203
|
+
.subscribe(() => {
|
|
16204
|
+
control.updateValueAndValidity({ emitEvent: false });
|
|
16205
|
+
});
|
|
16206
|
+
}
|
|
16207
|
+
return;
|
|
16208
|
+
}
|
|
16209
|
+
|
|
16210
|
+
/**
|
|
16211
|
+
* Regular expressions that are used to check password strength and valid values
|
|
16212
|
+
*/
|
|
16213
|
+
const PASSWORD_REGEXPS = {
|
|
16214
|
+
medium: /(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})/,
|
|
16215
|
+
strong: /(((?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]))|((?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*]))|((?=.*[A-Z])(?=.*[0-9]))(?=.*[!@#$%^&*]))(?=.{8,})/,
|
|
16216
|
+
format: /^[0-9a-zA-Z!@$!%*?&#]*$/
|
|
16217
|
+
};
|
|
16218
|
+
function passwordValidator() {
|
|
16219
|
+
return (control) => {
|
|
16220
|
+
if (!PASSWORD_REGEXPS.format.test(control.value)) {
|
|
16221
|
+
return { passwordInvalid: true };
|
|
16222
|
+
}
|
|
16223
|
+
if (!PASSWORD_REGEXPS.medium.test(control.value)) {
|
|
16224
|
+
return { passwordWeak: true };
|
|
16225
|
+
}
|
|
16226
|
+
return null;
|
|
16227
|
+
};
|
|
16228
|
+
}
|
|
16229
|
+
|
|
16230
|
+
function passwordMatchValidator(newPassControlName, confirmPassControlName) {
|
|
16231
|
+
return (group) => {
|
|
16232
|
+
const passwordControl = group.get(newPassControlName);
|
|
16233
|
+
const confirmControl = group.get(confirmPassControlName);
|
|
16234
|
+
if (confirmControl.errors && !confirmControl.hasError('passwordMismatch')) {
|
|
16235
|
+
// return if another validator has already found an error on the confirmControl
|
|
16236
|
+
return this;
|
|
16237
|
+
}
|
|
16238
|
+
if (passwordControl.value !== confirmControl.value) {
|
|
16239
|
+
confirmControl.setErrors({ passwordMismatch: true });
|
|
16240
|
+
}
|
|
16241
|
+
else {
|
|
16242
|
+
confirmControl.setErrors(null);
|
|
16243
|
+
}
|
|
16244
|
+
};
|
|
16245
|
+
}
|
|
16246
|
+
|
|
16247
|
+
var MessagesEnum$1;
|
|
16248
|
+
(function (MessagesEnum) {
|
|
16249
|
+
MessagesEnum["INVALID_DATE"] = "The date should not be before $1";
|
|
16250
|
+
})(MessagesEnum$1 || (MessagesEnum$1 = {}));
|
|
16251
|
+
|
|
16252
|
+
/**
|
|
16253
|
+
* Validation function, that checks If date form value is more than provided date
|
|
16254
|
+
*/
|
|
16255
|
+
function minDateValidator(date, message = MessagesEnum$1.INVALID_DATE.replace('$1', new DatePipe('en-US').transform(date))) {
|
|
16256
|
+
return (control) => {
|
|
16257
|
+
if (!control.value) {
|
|
16258
|
+
return null;
|
|
16259
|
+
}
|
|
16260
|
+
// form control value can be as a Moment object - we wrap it in "new Date()" to work with it like with JS Date
|
|
16261
|
+
if (new Date(control.value) >= new Date(date)) {
|
|
16262
|
+
return null;
|
|
16263
|
+
}
|
|
16264
|
+
return { minDate: message };
|
|
16265
|
+
};
|
|
16266
|
+
}
|
|
16267
|
+
|
|
16268
|
+
/**
|
|
16269
|
+
* Validator that check if sum amount of provided fields is greater than provided sum
|
|
16270
|
+
* @param field to check in each formArray element
|
|
16271
|
+
* @param summary to compare with fields sum
|
|
16272
|
+
* @param fieldAlias to show it in error message
|
|
16273
|
+
*/
|
|
16274
|
+
function fieldsSumValidator(field, summary = 100, fieldAlias) {
|
|
16275
|
+
return (formArray) => {
|
|
16276
|
+
// calculate sum of desired fields in formArray control
|
|
16277
|
+
const fieldsSum = formArray['controls']
|
|
16278
|
+
.reduce((acc, group) => acc += group.get(field).value, 0);
|
|
16279
|
+
if (fieldsSum <= summary) {
|
|
16280
|
+
return null;
|
|
16281
|
+
}
|
|
16282
|
+
else {
|
|
16283
|
+
return {
|
|
16284
|
+
fieldsSum: {
|
|
16285
|
+
name: field,
|
|
16286
|
+
alias: fieldAlias,
|
|
16287
|
+
summary
|
|
16288
|
+
}
|
|
16289
|
+
};
|
|
16290
|
+
}
|
|
16291
|
+
};
|
|
16292
|
+
}
|
|
16293
|
+
|
|
16294
|
+
/**
|
|
16295
|
+
* Validation function, that checks If provided date is within a current financial year
|
|
16296
|
+
*/
|
|
16297
|
+
function currentFinYearValidator() {
|
|
16298
|
+
const currentFinYear = new FinancialYear();
|
|
16299
|
+
return (control) => {
|
|
16300
|
+
if (!control.value || control.value >= currentFinYear.startDate && control.value <= currentFinYear.endDate) {
|
|
16301
|
+
return null;
|
|
16302
|
+
}
|
|
16303
|
+
return { notCurrentFinYear: true };
|
|
16304
|
+
};
|
|
16305
|
+
}
|
|
16306
|
+
|
|
16307
|
+
const MAX_SIZE = 4194304;
|
|
16308
|
+
class FileValidator {
|
|
16309
|
+
// File max size check
|
|
16310
|
+
static fileMaxSize(maxSize = MAX_SIZE) {
|
|
16311
|
+
const validatorFn = (file) => {
|
|
16312
|
+
return file.size > maxSize ? { fileMaxSize: { maxSize } } : null;
|
|
16313
|
+
};
|
|
16314
|
+
return FileValidator.fileValidation(validatorFn);
|
|
16315
|
+
}
|
|
16316
|
+
// File extension check
|
|
16317
|
+
static fileExtensions(allowedExtensions = DOCUMENT_FILE_TYPES.all) {
|
|
16318
|
+
const validatorFn = (file) => {
|
|
16319
|
+
return allowedExtensions.includes(file.type) ? null : { fileExtension: { allowedExtensions: allowedExtensions.join() } };
|
|
16320
|
+
};
|
|
16321
|
+
return FileValidator.fileValidation(validatorFn);
|
|
16322
|
+
}
|
|
16323
|
+
static fileValidation(validatorFn) {
|
|
16324
|
+
return (formControl) => {
|
|
16325
|
+
if (!formControl.value) {
|
|
16326
|
+
return null;
|
|
16327
|
+
}
|
|
16328
|
+
return validatorFn(formControl.value);
|
|
16329
|
+
};
|
|
16330
|
+
}
|
|
16331
|
+
}
|
|
16332
|
+
|
|
16305
16333
|
/**
|
|
16306
16334
|
* Form array with bank account properties
|
|
16307
16335
|
* @TODO create AbstractFormArray
|
|
@@ -16518,7 +16546,7 @@ class SoleContactForm extends AbstractForm {
|
|
|
16518
16546
|
lastName: new UntypedFormControl(contact.lastName, Validators.required),
|
|
16519
16547
|
email: new UntypedFormControl(contact.email, [Validators.required, Validators.email]),
|
|
16520
16548
|
phone: new UntypedFormControl(contact.phone),
|
|
16521
|
-
address: new
|
|
16549
|
+
address: new UntypedFormControl(contact.address)
|
|
16522
16550
|
}, contact);
|
|
16523
16551
|
}
|
|
16524
16552
|
}
|
|
@@ -17009,7 +17037,8 @@ function phoneNumberValidator() {
|
|
|
17009
17037
|
|
|
17010
17038
|
class PhoneForm extends AbstractForm {
|
|
17011
17039
|
constructor(
|
|
17012
|
-
// no default value because
|
|
17040
|
+
// no default value because Address form is always a child form. That's mean address value always passed and then default value never work.
|
|
17041
|
+
// even if null passed, default value will not work
|
|
17013
17042
|
phone) {
|
|
17014
17043
|
super({
|
|
17015
17044
|
type: new UntypedFormControl((phone === null || phone === void 0 ? void 0 : phone.type) || PhoneTypeEnum.MOBILE, Validators.required),
|