src/app/modules/ach-setup/ach-setup-form/ach-setup-form.component.ts
selector | app-ach-setup-form |
styleUrls | ./ach-setup-form.component.css |
templateUrl | ./ach-setup-form.component.html |
constructor(filenameFormatHelpMatSnackbar: MatSnackBar, _formBuilder: FormBuilder, router: Router, service: AchSetupService, logger: LogService)
|
||||||||||||||||||
Parameters :
|
confirmShowForm | ||||||
confirmShowForm(hideOverrides: boolean)
|
||||||
Parameters :
Returns :
void
|
fetchSetupForDomain | ||||||
fetchSetupForDomain(event: MatAutocompleteSelectedEvent)
|
||||||
Parameters :
Returns :
void
|
getState |
getState()
|
Returns :
void
|
initFormWithoutState |
initFormWithoutState()
|
Returns :
void
|
initFormWithState | ||||||
initFormWithState(state?: AchConfiguration)
|
||||||
Parameters :
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
onAchOverrideSettingChanged | ||||||
onAchOverrideSettingChanged(event: MatCheckboxChange)
|
||||||
Parameters :
Returns :
void
|
onDeliveryMethodChanged | ||||||
onDeliveryMethodChanged(event: MatRadioChange)
|
||||||
Parameters :
Returns :
void
|
onNoSettleBankChanged | ||||||
onNoSettleBankChanged(event: MatCheckboxChange)
|
||||||
Parameters :
Returns :
void
|
openFilenameFormatHelp |
openFilenameFormatHelp()
|
Returns :
void
|
reset |
reset()
|
Returns :
void
|
resetDomainOnClear |
resetDomainOnClear()
|
Returns :
void
|
review |
review()
|
Returns :
void
|
setAchOverrideSettingsControlsValueAndState |
setAchOverrideSettingsControlsValueAndState()
|
Returns :
void
|
setDeliveryMethodRelatedControlsValueAndState | ||||||||
setDeliveryMethodRelatedControlsValueAndState(deliveryMethod: string)
|
||||||||
Parameters :
Returns :
void
|
setFocus |
setFocus()
|
Returns :
void
|
setNoSettleBankRelatedControlsValues | ||||||||
setNoSettleBankRelatedControlsValues(noSettleBank: boolean)
|
||||||||
Parameters :
Returns :
void
|
shouldBeDisabledByNoSettleBank | ||||||
shouldBeDisabledByNoSettleBank(fiSelection: string)
|
||||||
Parameters :
Returns :
boolean
|
accountNumberForP2PValidations |
accountNumberForP2PValidations:
|
Type : Validators
|
Default value : [Validators.required, this.accountNumberValidator]
|
accountNumberValidator |
accountNumberValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.accountNumber)
|
achOverrideFormGroup |
achOverrideFormGroup:
|
Type : FormGroup
|
choosenDeliveryMethod |
choosenDeliveryMethod:
|
Type : string
|
collectionFiIdValidations |
collectionFiIdValidations:
|
Type : Validators
|
Default value : [Validators.required, this.guidValidator]
|
collectionFileFiIdValidations |
collectionFileFiIdValidations:
|
Type : Validators
|
Default value : [Validators.required, this.guidValidator]
|
collectionFileFiValidations |
collectionFileFiValidations:
|
Type : Validators
|
Default value : [Validators.required, this.fiValidator]
|
collectionFis |
collectionFis:
|
Type : string[]
|
Default value : [Fi, Allied, Centier]
|
collectionFiValidations |
collectionFiValidations:
|
Type : Validators
|
Default value : [Validators.required, this.fiValidator]
|
collectionFormGroup |
collectionFormGroup:
|
Type : FormGroup
|
deliveryMethods |
deliveryMethods:
|
Type : string[]
|
Default value : [FiAdmin, AlliedSftp, FiSftp, RppsSftp]
|
deliveryMethodValidations |
deliveryMethodValidations:
|
Type : Validators
|
Default value : [Validators.required, this.deliveryMethodValidator]
|
deliveryMethodValidator |
deliveryMethodValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.deliveryMethod)
|
deliverySettingsFormGroup |
deliverySettingsFormGroup:
|
Type : FormGroup
|
domainControl |
domainControl:
|
Default value : new FormControl()
|
domainSubscription |
domainSubscription:
|
Type : Subscription
|
domainValidations |
domainValidations:
|
Type : Validators
|
Default value : [Validators.required, this.domainValidator]
|
domainValidator |
domainValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.domain)
|
Private elementRef |
elementRef:
|
Type : ElementRef
|
Decorators :
@ViewChild('domainInput')
|
emailValidator |
emailValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.email)
|
error |
error:
|
Type : string
|
feeAccountNumberValidations |
feeAccountNumberValidations:
|
Type : Validators
|
Default value : [Validators.required, this.accountNumberValidator]
|
feeAccountTypes |
feeAccountTypes:
|
Type : string[]
|
Default value : [FeeAccountTypeGl, FeeAccountTypeDda]
|
feeAccountTypeValidations |
feeAccountTypeValidations:
|
Type : Validators
|
Default value : []
|
feeFormGroup |
feeFormGroup:
|
Type : FormGroup
|
feeRoutingNumberValidations |
feeRoutingNumberValidations:
|
Type : Validators
|
Default value : [Validators.required, this.routingNumberValidator]
|
fiFormGroup |
fiFormGroup:
|
Type : FormGroup
|
filenameExtensionValidations |
filenameExtensionValidations:
|
Type : Validators
|
Default value : [this.filenameExtensionValidator]
|
filenameExtensionValidator |
filenameExtensionValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.fileNameExtension)
|
Public filenameFormatHelpMatSnackbar |
filenameFormatHelpMatSnackbar:
|
Type : MatSnackBar
|
filenameFormatValidations |
filenameFormatValidations:
|
Type : Validators
|
Default value : [this.filenameFormatValidator]
|
filenameFormatValidator |
filenameFormatValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.fileNameFormat)
|
filenamePrefixValidations |
filenamePrefixValidations:
|
Type : Validators
|
Default value : [this.filenameValidator]
|
filenameValidator |
filenameValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.fileName)
|
filepathValidator |
filepathValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.filePath)
|
fileTypes |
fileTypes:
|
Type : string[]
|
Default value : [CollectionType, SettlementType]
|
fileTypeValidations |
fileTypeValidations:
|
Type : Validators
|
Default value : [this.fileTypeValidator]
|
fileTypeValidator |
fileTypeValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.fileType)
|
financialInstitutionIdValidations |
financialInstitutionIdValidations:
|
Type : Validators
|
Default value : [Validators.required, this.guidValidator]
|
fis$ |
fis$:
|
Type : Observable<FinancialInstitution[]>
|
fiSendToAddressValidations |
fiSendToAddressValidations:
|
Type : Validators
|
Default value : [this.multipleEmailsValidator]
|
fiSendToNameValidations |
fiSendToNameValidations:
|
Type : Validators
|
Default value : []
|
fisSubscription |
fisSubscription:
|
Type : Subscription
|
fiValidator |
fiValidator:
|
Type : Validators
|
Default value : Validators.pattern(`(${Fi}|${Allied}|${Centier})`)
|
guidValidator |
guidValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.guid)
|
hasState |
hasState:
|
Type : boolean
|
Default value : undefined
|
hideOverrides |
hideOverrides:
|
Default value : false
|
immediateDestinationNameValidations |
immediateDestinationNameValidations:
|
Type : Validators
|
Default value : [
Validators.required,
this.immediateDestinationOriginNamesValidator
]
|
immediateDestinationOriginNamesValidator |
immediateDestinationOriginNamesValidator:
|
Type : Validators
|
Default value : Validators.pattern(
ValidationPattern.immediateDestinationOriginNames
)
|
immediateDestinationRoutingNumberValidations |
immediateDestinationRoutingNumberValidations:
|
Type : Validators
|
Default value : [
Validators.required,
this.routingNumberValidator
]
|
immediateOriginNameValidations |
immediateOriginNameValidations:
|
Type : Validators
|
Default value : [
Validators.required,
this.immediateDestinationOriginNamesValidator
]
|
immediateOriginRoutingNumberValidations |
immediateOriginRoutingNumberValidations:
|
Type : Validators
|
Default value : [Validators.required, this.routingNumberValidator]
|
isLinear |
isLinear:
|
Default value : false
|
isLoading |
isLoading:
|
Default value : false
|
minifiedFinancialInstitutions |
minifiedFinancialInstitutions:
|
Type : FinancialInstitution[]
|
Default value : []
|
multipleEmailsValidator |
multipleEmailsValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.multiEmail)
|
noSettleBankValidations |
noSettleBankValidations:
|
Type : Validators
|
Default value : []
|
oneRecordSettingsFormGroup |
oneRecordSettingsFormGroup:
|
Type : FormGroup
|
portValidator |
portValidator:
|
Type : Validators
|
Default value : Validators.compose([
Validators.pattern(ValidationPattern.port),
Validators.min(1),
Validators.max(65535)
])
|
routingNumberValidator |
routingNumberValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.routingNumber)
|
Public service |
service:
|
Type : AchSetupService
|
settlementFiIdValidations |
settlementFiIdValidations:
|
Type : Validators
|
Default value : [Validators.required, this.guidValidator]
|
settlementFileFiIdValidations |
settlementFileFiIdValidations:
|
Type : Validators
|
Default value : [Validators.required, this.guidValidator]
|
settlementFileFiValidations |
settlementFileFiValidations:
|
Type : Validators
|
Default value : [Validators.required, this.fiValidator]
|
settlementFis |
settlementFis:
|
Type : string[]
|
Default value : [Fi, Allied, Centier]
|
settlementFiValidations |
settlementFiValidations:
|
Type : Validators
|
Default value : [Validators.required, this.fiValidator]
|
settlementFormGroup |
settlementFormGroup:
|
Type : FormGroup
|
sftpPasswordValidations |
sftpPasswordValidations:
|
Type : Validators
|
Default value : [Validators.required]
|
sftpPathValidations |
sftpPathValidations:
|
Type : Validators
|
Default value : [this.filepathValidator]
|
sftpPortValidations |
sftpPortValidations:
|
Type : Validators
|
Default value : [this.portValidator]
|
sftpUrlValidations |
sftpUrlValidations:
|
Type : Validators
|
Default value : [Validators.required, this.urlValidator]
|
sftpUsernameValidations |
sftpUsernameValidations:
|
Type : Validators
|
Default value : [Validators.required]
|
shouldChangeEffectiveDateToCurrentBusinessDateValidations |
shouldChangeEffectiveDateToCurrentBusinessDateValidations:
|
Type : Validators
|
Default value : []
|
shouldRemoveJulianDateValidations |
shouldRemoveJulianDateValidations:
|
Type : Validators
|
Default value : []
|
shouldUseDifferentAccountNumberForP2PValidations |
shouldUseDifferentAccountNumberForP2PValidations:
|
Type : Validators
|
Default value : []
|
showForm |
showForm:
|
Default value : false
|
stateSubscription |
stateSubscription:
|
Type : Subscription
|
stepper |
stepper:
|
Decorators :
@ViewChild('stepper')
|
urlValidator |
urlValidator:
|
Type : Validators
|
Default value : Validators.pattern(ValidationPattern.url)
|
import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import {
MatAutocompleteSelectedEvent,
MatCheckboxChange,
MatRadioChange,
MatSnackBar
} from '@angular/material';
import { Router } from '@angular/router';
import { Observable, Subscription } from 'rxjs';
import { catchError, filter } from 'rxjs/operators';
import { FinancialInstitution } from 'src/app/ach-setup/models/financial-institution';
import { LogService } from '../../../providers/services/log.service';
import { FilenameFormatHelpSnackbar } from '../../filename-format-help-snackbar/filename-format-help-snackbar.component';
import { AchConfiguration, IAchConfiguration } from '../models/ach-configuration';
import { AchOverrideSettings } from '../models/ach-override';
import { DeliverySettings } from '../models/delivery-settings';
import { OneRecordSettings } from '../models/one-record-settings';
import { AchSetupService } from '../providers/ach-setup.service';
import {
Fi,
Allied,
Centier,
FiAdmin,
AlliedSftp,
FiSftp,
RppsSftp,
CollectionType,
SettlementType,
FeeAccountTypeGl,
FeeAccountTypeDda,
DEFAULT,
AlliedSftpUrl,
ValidationPattern
} from '../ach-setup.constants';
@Component({
selector: 'app-ach-setup-form',
templateUrl: './ach-setup-form.component.html',
styleUrls: ['./ach-setup-form.component.css']
})
export class AchSetupFormComponent implements OnInit, OnDestroy {
isLoading = false;
hasState: boolean = undefined;
hideOverrides = false;
error: string;
showForm = false;
stateSubscription: Subscription;
domainSubscription: Subscription;
fisSubscription: Subscription;
isLinear = false;
fiFormGroup: FormGroup;
collectionFormGroup: FormGroup;
settlementFormGroup: FormGroup;
feeFormGroup: FormGroup;
oneRecordSettingsFormGroup: FormGroup;
deliverySettingsFormGroup: FormGroup;
achOverrideFormGroup: FormGroup;
choosenDeliveryMethod: string;
collectionFis: string[] = [Fi, Allied, Centier];
settlementFis: string[] = [Fi, Allied, Centier];
deliveryMethods: string[] = [FiAdmin, AlliedSftp, FiSftp, RppsSftp];
fileTypes: string[] = [CollectionType, SettlementType];
feeAccountTypes: string[] = [FeeAccountTypeGl, FeeAccountTypeDda];
minifiedFinancialInstitutions: FinancialInstitution[] = [];
domainControl = new FormControl();
@ViewChild('stepper') stepper;
@ViewChild('domainInput') private elementRef: ElementRef;
// Custom Validators
// NOTE: Template Literals ` used here for text strings
domainValidator: Validators = Validators.pattern(ValidationPattern.domain);
guidValidator: Validators = Validators.pattern(ValidationPattern.guid);
accountNumberValidator: Validators = Validators.pattern(ValidationPattern.accountNumber);
routingNumberValidator: Validators = Validators.pattern(ValidationPattern.routingNumber);
fileTypeValidator: Validators = Validators.pattern(ValidationPattern.fileType);
immediateDestinationOriginNamesValidator: Validators = Validators.pattern(
ValidationPattern.immediateDestinationOriginNames
);
fiValidator: Validators = Validators.pattern(`(${Fi}|${Allied}|${Centier})`);
deliveryMethodValidator: Validators = Validators.pattern(ValidationPattern.deliveryMethod);
emailValidator: Validators = Validators.pattern(ValidationPattern.email);
multipleEmailsValidator: Validators = Validators.pattern(ValidationPattern.multiEmail);
urlValidator: Validators = Validators.pattern(ValidationPattern.url);
portValidator: Validators = Validators.compose([
Validators.pattern(ValidationPattern.port),
Validators.min(1),
Validators.max(65535)
]);
filepathValidator: Validators = Validators.pattern(ValidationPattern.filePath);
filenameValidator: Validators = Validators.pattern(ValidationPattern.fileName);
filenameFormatValidator: Validators = Validators.pattern(ValidationPattern.fileNameFormat);
filenameExtensionValidator: Validators = Validators.pattern(ValidationPattern.fileNameExtension);
// Field Validations
// Financial Institution Settings Validations
domainValidations: Validators = [Validators.required, this.domainValidator];
noSettleBankValidations: Validators = [];
financialInstitutionIdValidations: Validators = [Validators.required, this.guidValidator];
// Collection Settings Validations
collectionFiIdValidations: Validators = [Validators.required, this.guidValidator];
collectionFileFiIdValidations: Validators = [Validators.required, this.guidValidator];
collectionFiValidations: Validators = [Validators.required, this.fiValidator];
collectionFileFiValidations: Validators = [Validators.required, this.fiValidator];
// Settlement Settings Validations
settlementFiIdValidations: Validators = [Validators.required, this.guidValidator];
settlementFileFiIdValidations: Validators = [Validators.required, this.guidValidator];
settlementFiValidations: Validators = [Validators.required, this.fiValidator];
settlementFileFiValidations: Validators = [Validators.required, this.fiValidator];
// Fee Validations
feeAccountNumberValidations: Validators = [Validators.required, this.accountNumberValidator];
feeAccountTypeValidations: Validators = [];
feeRoutingNumberValidations: Validators = [Validators.required, this.routingNumberValidator];
// One Record Settings Validations
fileTypeValidations: Validators = [this.fileTypeValidator];
immediateDestinationNameValidations: Validators = [
Validators.required,
this.immediateDestinationOriginNamesValidator
];
immediateDestinationRoutingNumberValidations: Validators = [
Validators.required,
this.routingNumberValidator
];
immediateOriginNameValidations: Validators = [
Validators.required,
this.immediateDestinationOriginNamesValidator
];
immediateOriginRoutingNumberValidations: Validators = [Validators.required, this.routingNumberValidator];
// Delivery Settings Validations
deliveryMethodValidations: Validators = [Validators.required, this.deliveryMethodValidator];
fiSendToNameValidations: Validators = [];
fiSendToAddressValidations: Validators = [this.multipleEmailsValidator];
sftpUrlValidations: Validators = [Validators.required, this.urlValidator];
sftpPortValidations: Validators = [this.portValidator];
sftpUsernameValidations: Validators = [Validators.required];
sftpPasswordValidations: Validators = [Validators.required];
sftpPathValidations: Validators = [this.filepathValidator];
filenamePrefixValidations: Validators = [this.filenameValidator];
filenameFormatValidations: Validators = [this.filenameFormatValidator];
filenameExtensionValidations: Validators = [this.filenameExtensionValidator];
// ACH Override Settings Validations
shouldRemoveJulianDateValidations: Validators = [];
shouldChangeEffectiveDateToCurrentBusinessDateValidations: Validators = [];
shouldUseDifferentAccountNumberForP2PValidations: Validators = [];
accountNumberForP2PValidations: Validators = [Validators.required, this.accountNumberValidator];
fis$: Observable<FinancialInstitution[]>;
constructor(
public filenameFormatHelpMatSnackbar: MatSnackBar,
private _formBuilder: FormBuilder,
private router: Router,
public service: AchSetupService,
private logger: LogService
) {}
ngOnInit() {
this.logger.log(`AchSetupFormComponent loaded`);
this.fis$ = this.service.fis$;
this.initFormWithoutState();
this.setFocus();
this.getState();
this.setDeliveryMethodRelatedControlsValueAndState(
this.deliverySettingsFormGroup.controls.deliveryMethodCtrl.value
);
this.setNoSettleBankRelatedControlsValues(this.fiFormGroup.controls.noSettleBankCtrl.value);
this.setAchOverrideSettingsControlsValueAndState();
this.resetDomainOnClear();
}
ngOnDestroy(): void {
if (this.stateSubscription) {
this.stateSubscription.unsubscribe();
}
if (this.domainSubscription) {
this.domainSubscription.unsubscribe();
}
if (this.fisSubscription) {
this.fisSubscription.unsubscribe();
}
}
resetDomainOnClear() {
this.domainControl.valueChanges.subscribe(value => {
if (!value || value.length === 0) {
console.log('clearing domain');
this.fiFormGroup.controls.domainCtrl.setValue(null);
this.showForm = false;
}
});
}
setFocus() {
setTimeout(() => {
this.elementRef.nativeElement.focus();
}, 500);
}
getState() {
this.stateSubscription = this.service.state$
.pipe(filter(state => state !== null && state !== undefined))
.subscribe(state => {
this.initFormWithState(state);
});
}
reset() {
this.error = null;
this.isLoading = false;
this.hasState = undefined;
this.domainControl.setValue(null);
}
fetchSetupForDomain(event: MatAutocompleteSelectedEvent) {
console.log(event);
this.isLoading = true;
this.service
.fetchSetupForDomain(this.domainControl.value)
.pipe(
catchError(error => {
this.error = error as string;
return null;
}),
filter(state => state !== undefined)
)
.subscribe(state => {
this.isLoading = false;
if (state === null) {
this.hasState = false;
this.fiFormGroup.controls.domainCtrl.setValue(this.domainControl.value);
return;
}
this.hasState = true;
this.initFormWithState(state);
});
}
confirmShowForm(hideOverrides: boolean) {
this.showForm = true;
this.hideOverrides = hideOverrides;
}
initFormWithoutState() {
this.logger.log('init form without state');
this.isLinear = true;
this.fiFormGroup = this._formBuilder.group({
domainCtrl: [DEFAULT, this.domainValidations],
noSettleBankCtrl: [false, this.noSettleBankValidations]
});
this.collectionFormGroup = this._formBuilder.group({
collectionFiCtrl: [Fi, this.collectionFiValidations],
collectionFileFiCtrl: [Fi, this.collectionFileFiValidations]
});
this.settlementFormGroup = this._formBuilder.group({
settlementFiCtrl: [Fi, this.settlementFiValidations],
settlementFileFiCtrl: [Fi, this.settlementFileFiValidations]
});
this.feeFormGroup = this._formBuilder.group({
feeAccountCtrl: [DEFAULT, this.feeAccountNumberValidations],
feeAccountTypeCtrl: [FeeAccountTypeGl, this.feeAccountTypeValidations],
feeRoutingNumberCtrl: [DEFAULT, this.feeRoutingNumberValidations]
});
this.oneRecordSettingsFormGroup = this._formBuilder.group({
fileTypeCtrl: [DEFAULT, this.fileTypeValidations],
immediateDestinationNameCtrl: [DEFAULT, this.immediateDestinationNameValidations],
immediateDestinationCtrl: [DEFAULT, this.immediateDestinationRoutingNumberValidations],
immediateOriginNameCtrl: [DEFAULT, this.immediateOriginNameValidations],
immediateOriginCtrl: [DEFAULT, this.immediateOriginRoutingNumberValidations]
});
this.deliverySettingsFormGroup = this._formBuilder.group({
deliveryMethodCtrl: [DEFAULT, this.deliveryMethodValidations],
fiSendToNameCtrl: [DEFAULT, this.fiSendToNameValidations],
fiSendToAddressCtrl: [DEFAULT, this.fiSendToAddressValidations],
sftpUrlCtrl: [DEFAULT, this.sftpUrlValidations],
sftpPortCtrl: [DEFAULT, this.sftpPortValidations],
sftpUsernameCtrl: [DEFAULT, this.sftpUsernameValidations],
sftpPasswordCtrl: [DEFAULT, this.sftpPasswordValidations],
sftpPathCtrl: [DEFAULT, this.sftpPathValidations],
filenamePrefixCtrl: [DEFAULT, this.filenamePrefixValidations],
filenameFormatCtrl: [DEFAULT, this.filenameFormatValidations],
filenameExtensionCtrl: [DEFAULT, this.filenameExtensionValidations]
});
if (
this.deliverySettingsFormGroup.controls.deliveryMethodCtrl.value !== '' &&
this.deliverySettingsFormGroup.controls.deliveryMethodCtrl.value !== undefined
) {
this.deliverySettingsFormGroup.controls.deliveryMethodCtrl.markAsDirty();
}
this.achOverrideFormGroup = this._formBuilder.group({
shouldRemoveJulianDateCtrl: [false, this.shouldRemoveJulianDateValidations],
shouldChangeEffectiveDateToCurrentBusinessDateCtrl: [
false,
this.shouldChangeEffectiveDateToCurrentBusinessDateValidations
],
shouldUseDifferentAccountNumberForP2PCtrl: [
false,
this.shouldUseDifferentAccountNumberForP2PValidations
],
accountNumberForP2PCtrl: [DEFAULT, this.accountNumberForP2PValidations]
});
}
initFormWithState(state?: AchConfiguration) {
this.logger.log('init form with state');
this.isLinear = false;
if (!state) {
this.logger.log('short circuit init: state is missing!');
return;
}
this.fiFormGroup = this._formBuilder.group({
domainCtrl: [state.domain, this.domainValidations],
noSettleBankCtrl: [state.noSettleBank, this.noSettleBankValidations]
});
this.collectionFormGroup = this._formBuilder.group({
collectionFiCtrl: [state.collectionFi, this.collectionFiValidations],
collectionFileFiCtrl: [state.collectionFileFi, this.collectionFileFiValidations]
});
this.settlementFormGroup = this._formBuilder.group({
settlementFiCtrl: [state.settlementFi, this.settlementFiValidations],
settlementFileFiCtrl: [state.settlementFileFi, this.settlementFileFiValidations]
});
this.feeFormGroup = this._formBuilder.group({
feeAccountCtrl: [state.feeAccount, this.feeAccountNumberValidations],
feeAccountTypeCtrl: [state.feeAccountType, this.feeAccountTypeValidations],
feeRoutingNumberCtrl: [state.feeRoutingNumber, this.feeRoutingNumberValidations]
});
if (state.oneRecordSettings) {
this.oneRecordSettingsFormGroup = this._formBuilder.group({
fileTypeCtrl: [state.oneRecordSettings.fileType, this.fileTypeValidations],
immediateDestinationCtrl: [
state.oneRecordSettings.immediateDestinationCode,
this.immediateDestinationRoutingNumberValidations
],
immediateOriginCtrl: [
state.oneRecordSettings.immediateOriginCode,
this.immediateOriginRoutingNumberValidations
],
immediateDestinationNameCtrl: [
state.oneRecordSettings.immediateDestinationName,
this.immediateDestinationNameValidations
],
immediateOriginNameCtrl: [
state.oneRecordSettings.immediateOriginName,
this.immediateOriginNameValidations
]
});
}
this.deliverySettingsFormGroup = this._formBuilder.group({
deliveryMethodCtrl: [state.deliverySettings.method, this.deliveryMethodValidations],
fiSendToNameCtrl: [state.deliverySettings.achNotificationContactName, this.fiSendToNameValidations],
fiSendToAddressCtrl: [
state.deliverySettings.achNotificationEmailAddress,
this.fiSendToAddressValidations
],
sftpUrlCtrl: [state.deliverySettings.sftpUrl, this.sftpUrlValidations],
sftpPortCtrl: [state.deliverySettings.sftpPort, this.sftpPortValidations],
sftpUsernameCtrl: [state.deliverySettings.sftpUsername, this.sftpUsernameValidations],
sftpPasswordCtrl: [state.deliverySettings.sftpPassword, this.sftpPasswordValidations],
sftpPathCtrl: [state.deliverySettings.sftpPath, this.sftpPathValidations],
filenamePrefixCtrl: [state.deliverySettings.filenamePrefix, this.filenamePrefixValidations],
filenameFormatCtrl: [state.deliverySettings.filenameFormat, this.filenameFormatValidations],
filenameExtensionCtrl: [state.deliverySettings.filenameExtension, this.filenameExtensionValidations]
});
if (
this.deliverySettingsFormGroup.controls.deliveryMethodCtrl.value !== '' &&
this.deliverySettingsFormGroup.controls.deliveryMethodCtrl.value !== undefined
) {
this.deliverySettingsFormGroup.controls.deliveryMethodCtrl.markAsDirty();
}
this.achOverrideFormGroup = this._formBuilder.group({
shouldRemoveJulianDateCtrl: [
state.achOverrideSettings.shouldRemoveJulianDateFromAchFile,
this.shouldRemoveJulianDateValidations
],
shouldChangeEffectiveDateToCurrentBusinessDateCtrl: [
state.achOverrideSettings.shouldChangeEffectiveDateToCurrentBusinessDate,
this.shouldChangeEffectiveDateToCurrentBusinessDateValidations
],
shouldUseDifferentAccountNumberForP2PCtrl: [
state.achOverrideSettings.shouldUseDifferentAccountNumberForP2P,
this.shouldUseDifferentAccountNumberForP2PValidations
],
accountNumberForP2PCtrl: [
state.achOverrideSettings.accountNumberForP2P,
this.accountNumberForP2PValidations
]
});
this.stepper.selectedIndex = 0;
this.stepper.completed = true;
this.stepper.selectedIndex = 7;
}
openFilenameFormatHelp() {
this.filenameFormatHelpMatSnackbar.openFromComponent(FilenameFormatHelpSnackbar, {
horizontalPosition: 'right'
});
}
setDeliveryMethodRelatedControlsValueAndState(deliveryMethod: string = '') {
switch (deliveryMethod.toLowerCase()) {
case AlliedSftp.toLowerCase():
this.deliverySettingsFormGroup.controls.sftpUrlCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpPortCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpUsernameCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpPasswordCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpPathCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpUrlCtrl.setValue(AlliedSftpUrl);
break;
case FiSftp.toLowerCase():
this.deliverySettingsFormGroup.controls.sftpUrlCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpPortCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpUsernameCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpPasswordCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpPathCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpUrlCtrl.setValue('');
break;
case RppsSftp.toLowerCase():
this.deliverySettingsFormGroup.controls.sftpUrlCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpPortCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpUsernameCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpPasswordCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpPathCtrl.enable();
this.deliverySettingsFormGroup.controls.sftpUrlCtrl.setValue(
'ftp://Z619370@12.22.155.208:16021/0076887/production/upload/R716/'
);
break;
default:
this.deliverySettingsFormGroup.controls.sftpUrlCtrl.setValue('');
this.deliverySettingsFormGroup.controls.sftpUrlCtrl.disable();
this.deliverySettingsFormGroup.controls.sftpPortCtrl.setValue('');
this.deliverySettingsFormGroup.controls.sftpPortCtrl.disable();
this.deliverySettingsFormGroup.controls.sftpUsernameCtrl.setValue('');
this.deliverySettingsFormGroup.controls.sftpUsernameCtrl.disable();
this.deliverySettingsFormGroup.controls.sftpPasswordCtrl.setValue('');
this.deliverySettingsFormGroup.controls.sftpPasswordCtrl.disable();
this.deliverySettingsFormGroup.controls.sftpPathCtrl.setValue('');
this.deliverySettingsFormGroup.controls.sftpPathCtrl.disable();
}
}
setNoSettleBankRelatedControlsValues(noSettleBank: boolean = false) {
if (noSettleBank === true) {
const collectionFiControl = this.collectionFormGroup.controls.collectionFiCtrl;
const collectionFileFiControl = this.collectionFormGroup.controls.collectionFileFiCtrl;
const settlementFiControl = this.settlementFormGroup.controls.settlementFiCtrl;
const settlementFileFiControl = this.settlementFormGroup.controls.settlementFileFiCtrl;
if (collectionFiControl.value === Fi) {
collectionFiControl.setValue('');
}
if (collectionFileFiControl.value === Fi) {
collectionFileFiControl.setValue('');
}
if (settlementFiControl.value === Fi) {
settlementFiControl.setValue('');
}
if (settlementFileFiControl.value === Fi) {
settlementFileFiControl.setValue('');
}
}
}
setAchOverrideSettingsControlsValueAndState() {
if (this.achOverrideFormGroup.controls.shouldUseDifferentAccountNumberForP2PCtrl.value === true) {
this.achOverrideFormGroup.controls.accountNumberForP2PCtrl.enable();
} else {
this.achOverrideFormGroup.controls.accountNumberForP2PCtrl.setValue('');
this.achOverrideFormGroup.controls.accountNumberForP2PCtrl.disable();
}
}
onDeliveryMethodChanged(event: MatRadioChange) {
this.setDeliveryMethodRelatedControlsValueAndState(event.value);
}
onNoSettleBankChanged(event: MatCheckboxChange) {
this.setNoSettleBankRelatedControlsValues(event.checked);
}
onAchOverrideSettingChanged(event: MatCheckboxChange) {
this.setAchOverrideSettingsControlsValueAndState();
}
shouldBeDisabledByNoSettleBank(fiSelection: string): boolean {
if (fiSelection === Fi && this.fiFormGroup.controls.noSettleBankCtrl.value) {
return true;
}
return false;
}
review() {
const oneRecordSettings = {
fileType: this.oneRecordSettingsFormGroup.controls.fileTypeCtrl.value,
immediateDestinationCode: this.oneRecordSettingsFormGroup.controls.immediateDestinationCtrl.value,
immediateOriginCode: this.oneRecordSettingsFormGroup.controls.immediateOriginCtrl.value,
immediateDestinationName: this.oneRecordSettingsFormGroup.controls.immediateDestinationNameCtrl.value,
immediateOriginName: this.oneRecordSettingsFormGroup.controls.immediateOriginNameCtrl.value
} as OneRecordSettings;
const deliverySettings = {
method: this.deliverySettingsFormGroup.controls.deliveryMethodCtrl.value,
achNotificationContactName: this.deliverySettingsFormGroup.controls.fiSendToNameCtrl.value,
achNotificationEmailAddress: this.deliverySettingsFormGroup.controls.fiSendToAddressCtrl.value,
sftpUrl: this.deliverySettingsFormGroup.controls.sftpUrlCtrl.value,
sftpPort: this.deliverySettingsFormGroup.controls.sftpPortCtrl.value,
sftpUsername: this.deliverySettingsFormGroup.controls.sftpUsernameCtrl.value,
sftpPassword: this.deliverySettingsFormGroup.controls.sftpPasswordCtrl.value,
sftpPath: this.deliverySettingsFormGroup.controls.sftpPathCtrl.value,
filenamePrefix: this.deliverySettingsFormGroup.controls.filenamePrefixCtrl.value,
filenameFormat: this.deliverySettingsFormGroup.controls.filenameFormatCtrl.value,
filenameExtension: this.deliverySettingsFormGroup.controls.filenameExtensionCtrl.value
} as DeliverySettings;
const achOverrideSettings = {
shouldRemoveJulianDateFromAchFile: this.achOverrideFormGroup.controls.shouldRemoveJulianDateCtrl.value,
shouldChangeEffectiveDateToCurrentBusinessDate: this.achOverrideFormGroup.controls
.shouldChangeEffectiveDateToCurrentBusinessDateCtrl.value,
shouldUseDifferentAccountNumberForP2P: this.achOverrideFormGroup.controls
.shouldUseDifferentAccountNumberForP2PCtrl.value,
accountNumberForP2P: this.achOverrideFormGroup.controls.accountNumberForP2PCtrl.value
} as AchOverrideSettings;
const cfg = {
domain: this.fiFormGroup.controls.domainCtrl.value,
noSettleBank: this.fiFormGroup.controls.noSettleBankCtrl.value,
collectionFi: this.collectionFormGroup.controls.collectionFiCtrl.value,
collectionFileFi: this.collectionFormGroup.controls.collectionFileFiCtrl.value,
settlementFi: this.settlementFormGroup.controls.settlementFiCtrl.value,
settlementFileFi: this.settlementFormGroup.controls.settlementFileFiCtrl.value,
oneRecordSettings: oneRecordSettings,
deliverySettings: deliverySettings,
achOverrideSettings: achOverrideSettings,
feeAccount: this.feeFormGroup.controls.feeAccountCtrl.value,
feeAccountType: this.feeFormGroup.controls.feeAccountTypeCtrl.value,
feeRoutingNumber: this.feeFormGroup.controls.feeRoutingNumberCtrl.value
} as IAchConfiguration;
this.service.set(cfg);
this.router.navigate(['/ach/review']);
}
}
<section fxFill fxFlex.lg="50" fxLayout="column" fxLayoutAlign="space-around start">
<div class="component-title-container" fxFill fxLayout="row" fxLayoutAlign="space-between start">
<h3 class="component-title">ACH Setup Form</h3>
<button [disabled]="!domainControl.value" fxFlex="10" mat-button color="accent" (click)="reset()">
Start Over
</button>
</div>
<h4 class="errors" *ngIf="error">{{ error }}</h4>
<div fxFill fxLayout="row" fxLayoutAlign="start center">
<mat-form-field fxFill>
<input
#domainInput
matInput
placeholder="Domain"
aria-label="Domain"
[matAutocomplete]="auto"
[formControl]="domainControl"
/>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="fetchSetupForDomain($event)">
<mat-option
*ngFor="let fi of (fis$ | async | fiAutoCompleteSearch: domainControl.value)"
[value]="fi.domain"
>
<div fxFill fxLayout="row" fxLayoutAlign="space-between center">
<mat-icon fxFlex="15" title="logo">
<img style="max-width: 72px; max-height: 72px;" aria-hidden [src]="fi.logoUrl" />
</mat-icon>
<p [title]="fi.name" class="fi-name" fxFlex="60">{{ fi.name }}</p>
<p [title]="fi.domain" fxFlex="25" class="fi-domain">
<small>{{ fi.domain | lowercase }} </small>
</p>
</div>
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
<div fxFill fxLayout="column" fxLayoutAlign="center center">
<h5 *ngIf="!(fis$ | async) && !error">Loading Financial Institutions</h5>
<h5 *ngIf="isLoading && !error">Locating current setup</h5>
<mat-progress-spinner
*ngIf="(isLoading || !(fis$ | async)) && !error"
color="accent"
mode="indeterminate"
diameter="48"
strokeWidth="4"
></mat-progress-spinner>
</div>
<div
fxFill
fxLayout="column"
fxLayoutAlign="center center"
*ngIf="!error && !isLoading && hasState === false && !showForm"
>
<div fxFill fxLayout="row" fxLayoutAlign="center center">
<mat-icon color="accent">info</mat-icon>
<h5>No setup found</h5>
</div>
<button mat-raised-button color="primary" (click)="confirmShowForm(false)">Lets Create One!</button>
</div>
<div
fxFill
fxLayout="column"
fxLayoutAlign="center center"
*ngIf="!error && !isLoading && hasState && !showForm"
>
<div fxFill fxLayout="row" fxLayoutAlign="center center">
<mat-icon color="accent">info</mat-icon>
<h5>Setup already exists</h5>
</div>
<button mat-raised-button color="primary" (click)="confirmShowForm(true)">Lets Change It!</button>
</div>
<mat-vertical-stepper [linear]="isLinear" #stepper fxFill *ngIf="!error && !isLoading && showForm">
<mat-step [stepControl]="fiFormGroup">
<form [formGroup]="fiFormGroup" fxLayout="column">
<ng-template matStepLabel>Financial Institution</ng-template>
<mat-checkbox
class="check-box"
matInput
placeholder="No Settle Bank"
formControlName="noSettleBankCtrl"
(change)="onNoSettleBankChanged($event)"
>
No Settle Bank
</mat-checkbox>
<div><button class="button action-background-color" mat-button matStepperNext>Continue</button></div>
</form>
</mat-step>
<mat-step [stepControl]="collectionFormGroup">
<form [formGroup]="collectionFormGroup" fxLayout="column">
<ng-template matStepLabel>Collection</ng-template>
<div>Collection Financial Institution</div>
<mat-radio-group
class="radio-button-group"
labelPosition="after"
placeHolder=""
formControlName="collectionFiCtrl"
>
<mat-radio-button
class="radio-button"
*ngFor="let collectionFi of collectionFis"
[value]="collectionFi"
[disabled]="shouldBeDisabledByNoSettleBank(collectionFi)"
>
{{ collectionFi }}
</mat-radio-button>
</mat-radio-group>
<div>Collection File Financial Institution</div>
<mat-radio-group
class="radio-button-group"
labelPosition="after"
placeHolder=""
formControlName="collectionFileFiCtrl"
>
<mat-radio-button
class="radio-button"
*ngFor="let collectionFileFi of collectionFis"
[value]="collectionFileFi"
[disabled]="shouldBeDisabledByNoSettleBank(collectionFileFi)"
>
{{ collectionFileFi }}
</mat-radio-button>
</mat-radio-group>
<div><button class="button action-background-color" mat-button matStepperNext>Continue</button></div>
</form>
</mat-step>
<mat-step [stepControl]="settlementFormGroup">
<form [formGroup]="settlementFormGroup" fxLayout="column">
<ng-template matStepLabel>Settlement</ng-template>
<div>Settlement Financial Institution</div>
<mat-radio-group
class="radio-button-group"
labelPosition="after"
placeHolder=""
formControlName="settlementFiCtrl"
>
<mat-radio-button
class="radio-button"
*ngFor="let settlementFi of settlementFis"
[value]="settlementFi"
[disabled]="shouldBeDisabledByNoSettleBank(settlementFi)"
>
{{ settlementFi }}
</mat-radio-button>
</mat-radio-group>
<div>Settlement File Financial Institution</div>
<mat-radio-group
class="radio-button-group"
labelPosition="after"
placeHolder=""
formControlName="settlementFileFiCtrl"
>
<mat-radio-button
class="radio-button"
*ngFor="let settlementFileFi of settlementFis"
[value]="settlementFileFi"
[disabled]="shouldBeDisabledByNoSettleBank(settlementFileFi)"
>
{{ settlementFileFi }}
</mat-radio-button>
</mat-radio-group>
<div><button class="button action-background-color" mat-button matStepperNext>Continue</button></div>
</form>
</mat-step>
<mat-step [stepControl]="feeFormGroup">
<form [formGroup]="feeFormGroup" fxLayout="column">
<ng-template matStepLabel>Fee Account</ng-template>
<mat-radio-group
class="radio-button-group"
labelPosition="after"
placeHolder="gl"
formControlName="feeAccountTypeCtrl"
>
<mat-radio-button
class="radio-button"
*ngFor="let feeAccountType of feeAccountTypes"
[value]="feeAccountType"
>
{{ feeAccountType }}
</mat-radio-button>
</mat-radio-group>
<mat-form-field>
<input matInput placeholder="Fee Account Number" formControlName="feeAccountCtrl" />
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Fee Routing Number" formControlName="feeRoutingNumberCtrl" />
</mat-form-field>
<div><button class="button action-background-color" mat-button matStepperNext>Continue</button></div>
</form>
</mat-step>
<mat-step [stepControl]="oneRecordSettingsFormGroup">
<form [formGroup]="oneRecordSettingsFormGroup" fxLayout="column">
<ng-template matStepLabel>One Record</ng-template>
<div>File Type</div>
<mat-radio-group
class="radio-button-group"
labelPosition="after"
placeHolder="File Type"
formControlName="fileTypeCtrl"
>
<mat-radio-button class="radio-button" value=""> no type </mat-radio-button>
<mat-radio-button class="radio-button" *ngFor="let fileType of fileTypes" [value]="fileType">
{{ fileType }}
</mat-radio-button>
</mat-radio-group>
<mat-form-field>
<input
matInput
placeholder="Immediate Destination Name"
formControlName="immediateDestinationNameCtrl"
/>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Immediate Destination #" formControlName="immediateDestinationCtrl" />
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Immediate Origin Name" formControlName="immediateOriginNameCtrl" />
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Immediate Origin #" formControlName="immediateOriginCtrl" />
</mat-form-field>
<div><button class="button action-background-color" mat-button matStepperNext>Continue</button></div>
</form>
</mat-step>
<mat-step [stepControl]="deliverySettingsFormGroup">
<form [formGroup]="deliverySettingsFormGroup" fxLayout="column">
<ng-template matStepLabel>File Delivery Method</ng-template>
<div *ngIf="!deliverySettingsFormGroup.get('deliveryMethodCtrl').dirty" class="errors">
* A delivery method must be selected
</div>
<mat-radio-group
class="radio-button-group"
labelPosition="after"
placeHolder="deliveryMethodCtrl"
formControlName="deliveryMethodCtrl"
(change)="onDeliveryMethodChanged($event)"
>
<mat-radio-button
class="radio-button"
*ngFor="let deliveryMethod of deliveryMethods"
[value]="deliveryMethod"
>
{{ deliveryMethod }}
</mat-radio-button>
</mat-radio-group>
<mat-form-field>
<input matInput placeholder="ACH Notification Contact Name" formControlName="fiSendToNameCtrl" />
</mat-form-field>
<mat-form-field>
<input
matInput
placeholder="ACH Notification E-mail Address"
formControlName="fiSendToAddressCtrl"
/>
</mat-form-field>
<mat-form-field>
<input
matInput
placeholder="SFTP URL (e.g. ftp2.alliedpayment.com)"
formControlName="sftpUrlCtrl"
/>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="SFTP Port # (optional)" formControlName="sftpPortCtrl" />
</mat-form-field>
<mat-form-field>
<input matInput placeholder="SFTP Username" formControlName="sftpUsernameCtrl" />
</mat-form-field>
<mat-form-field>
<input matInput placeholder="SFTP Password" formControlName="sftpPasswordCtrl" />
</mat-form-field>
<mat-form-field>
<input matInput placeholder="SFTP Path" formControlName="sftpPathCtrl" />
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Filename Prefix" formControlName="filenamePrefixCtrl" />
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Filename Format" formControlName="filenameFormatCtrl" /><button
mat-button
color="accent"
class="help-button"
(click)="openFilenameFormatHelp()"
>
Formatting Help
</button>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Filename Extension" formControlName="filenameExtensionCtrl" />
</mat-form-field>
<div><button class="button action-background-color" mat-button matStepperNext>Continue</button></div>
</form>
</mat-step>
<mat-step [stepControl]="achOverrideFormGroup" *ngIf="!hideOverrides">
<form [formGroup]="achOverrideFormGroup" fxLayout="column">
<ng-template matStepLabel>Ach Override</ng-template>
<mat-checkbox
class="check-box"
matInput
placeholder="Remove Julian Date"
formControlName="shouldRemoveJulianDateCtrl"
>
Remove Julian Date
</mat-checkbox>
<mat-checkbox
class="check-box"
matInput
placeholder="Change Effective Date To Current Business Date"
formControlName="shouldChangeEffectiveDateToCurrentBusinessDateCtrl"
>
Change Effective Date To Current Business Date
</mat-checkbox>
<mat-checkbox
class="check-box"
matInput
placeholder="Use Different Account Number for P2P"
formControlName="shouldUseDifferentAccountNumberForP2PCtrl"
(change)="onAchOverrideSettingChanged($event)"
>
Use Different Account Number for P2P
</mat-checkbox>
<mat-form-field>
<input matInput placeholder="Account Number for P2P" formControlName="accountNumberForP2PCtrl" />
</mat-form-field>
<div><button class="button action-background-color" mat-button matStepperNext>Continue</button></div>
</form>
</mat-step>
<mat-step>
<ng-template matStepLabel>Continue</ng-template>
Please continue to review configuration
<div><button mat-raised-button color="primary" (click)="review()">Continue To Review</button></div>
</mat-step>
</mat-vertical-stepper>
</section>
./ach-setup-form.component.css
form {
max-width: 500px;
}
.mat-vertical-stepper-header .mat-step-header-ripple .mat-step-icon {
background-color: #be2438 !important;
}
.mat-step .mat-step-header .mat-step-icon .mat-step-icon-content {
font-size: 12px;
}
.mat-vertical-stepper-header .mat-step-header {
background-color: red !Important;
}
.check-box {
margin: 0.35em;
}
.radio-button-group {
margin: 0.35em;
}
.radio-button {
float: left;
clear: both;
margin: 0.5em;
}
.errors {
color: red;
font-weight: bold;
}
.help-button {
float: right;
margin: -2em 0 0 0;
padding: 0;
border: 0;
}
.fi-name {
text-align: left;
word-break: break-all;
white-space: normal;
line-height: normal;
}
.fi-domain {
text-align: right;
}