diff --git a/src/app/account-transfers/make-account-transfers/make-account-transfers.component.html b/src/app/account-transfers/make-account-transfers/make-account-transfers.component.html
index 36856908d..e5462f6c3 100644
--- a/src/app/account-transfers/make-account-transfers/make-account-transfers.component.html
+++ b/src/app/account-transfers/make-account-transfers/make-account-transfers.component.html
@@ -5,6 +5,7 @@
+
@@ -53,7 +54,7 @@
{{ 'labels.inputs.Phone Number' | translate }}
+
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/account-transfers/make-account-transfers/make-account-transfers.component.scss b/src/app/account-transfers/make-account-transfers/make-account-transfers.component.scss
index 4b619b0d9..a3b5aff57 100644
--- a/src/app/account-transfers/make-account-transfers/make-account-transfers.component.scss
+++ b/src/app/account-transfers/make-account-transfers/make-account-transfers.component.scss
@@ -4,11 +4,7 @@
padding: 1rem;
}
-#search-button {
- background-color: #1074b9;
- color: white;
-}
-
+// Card styling
.transfer-card {
border-radius: 8px;
box-shadow: 0 2px 10px rgb(0 0 0 / 8%);
@@ -26,7 +22,8 @@
font-weight: 600;
color: #333;
margin: 0 0 1rem;
- padding-bottom: 0;
+ padding-bottom: 0.5rem;
+ border-bottom: 1px solid rgb(0 0 0 / 12%);
&.transfer-heading {
font-weight: 700;
@@ -49,9 +46,7 @@
align-items: center;
padding: 0.5rem;
background-color: rgb(0 0 0 / 2%);
- box-shadow: 0 0.5px 1px rgb(0 0 0 / 10%);
- border: 1px solid var(--border-color, #ddd);
- border-radius: 8px;
+ border-radius: 4px;
&:hover {
background-color: rgb(0 0 0 / 4%);
@@ -90,29 +85,55 @@ mat-divider {
gap: 1rem;
@media (width >= 768px) {
- grid-template-columns: repeat(2, 50%);
+ grid-template-columns: repeat(2, 1fr); /* stylelint-disable-line unit-allowed-list */
+ gap: 1.5rem;
}
}
+.form-row {
+ display: contents;
+}
+
.form-field {
width: 100%;
+ margin-bottom: 0.5rem;
+
+ &:nth-child(odd) {
+ @media (width >= 768px) {
+ margin-right: 0.5rem;
+ }
+ }
+
+ &:nth-child(even) {
+ @media (width >= 768px) {
+ margin-left: 0.5rem;
+ }
+ }
&.description-field {
grid-column: 1 / -1;
+
+ textarea {
+ min-height: 80px;
+ resize: vertical;
+ }
}
}
+::ng-deep .mat-form-field {
+ width: 100%;
+}
+
// Button styling
.action-buttons {
display: flex;
- justify-content: center;
+ justify-content: flex-end;
gap: 1rem;
padding: 1rem 1.5rem;
- margin-top: 0;
+ margin-top: 1rem;
@media (width <= 576px) {
flex-direction: column;
- align-items: center;
}
button {
@@ -120,7 +141,6 @@ mat-divider {
@media (width <= 576px) {
width: 100%;
- max-width: 300px;
margin-bottom: 0.5rem;
}
}
@@ -186,16 +206,12 @@ mat-divider {
// Dark theme
// Lower specificity selectors first
.dark-theme {
- .info-row {
- color: #fff !important;
- }
-
.info-label {
- color: rgb(255 255 255 / 70%) !important;
+ color: rgb(255 255 255 / 70%);
}
.info-value {
- color: rgb(255 255 255 / 87%) !important;
+ color: rgb(255 255 255 / 87%);
}
.section-title {
@@ -233,18 +249,6 @@ mat-divider {
}
// Higher specificity selectors
-:host-context(.dark-theme) .info-row {
- color: #fff !important;
-}
-
-:host-context(.dark-theme) .info-label {
- color: rgb(255 255 255 / 70%) !important;
-}
-
-:host-context(.dark-theme) .info-value {
- color: rgb(255 255 255 / 87%) !important;
-}
-
:host-context(.dark-theme) .transfer-heading {
color: #fff;
font-weight: 700;
@@ -266,18 +270,6 @@ mat-divider {
// Medium specificity selectors
body.dark-theme {
.container {
- .info-row {
- color: #fff !important;
- }
-
- .info-label {
- color: rgb(255 255 255 / 70%) !important;
- }
-
- .info-value {
- color: rgb(255 255 255 / 87%) !important;
- }
-
.section-title {
color: #fff;
}
@@ -320,3 +312,20 @@ body.dark-theme {
::ng-deep mat-form-field.error-warn.mat-form-field-invalid .mat-error {
color: #0009 !important;
}
+
+::ng-deep .mat-form-field-flex {
+ align-items: center;
+}
+
+.transfer-form .form-field {
+ margin-bottom: 1rem;
+}
+
+.readonly-field {
+ background-color: rgb(0 0 0 / 2%);
+ cursor: not-allowed;
+}
+
+::ng-deep .mat-input-element {
+ font-size: 14px;
+}
diff --git a/src/app/account-transfers/make-account-transfers/make-account-transfers.component.ts b/src/app/account-transfers/make-account-transfers/make-account-transfers.component.ts
index d66a000c6..47411809d 100644
--- a/src/app/account-transfers/make-account-transfers/make-account-transfers.component.ts
+++ b/src/app/account-transfers/make-account-transfers/make-account-transfers.component.ts
@@ -1,14 +1,12 @@
/** Angular Imports */
-import { Component, OnInit, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
-import { ActivatedRoute, Router, RouterLink } from '@angular/router';
+import { Component, OnInit, AfterViewInit } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
import {
AbstractControl,
- FormGroup,
UntypedFormBuilder,
UntypedFormGroup,
ValidationErrors,
Validators,
- ReactiveFormsModule,
FormsModule
} from '@angular/forms';
@@ -21,11 +19,10 @@ import { Dates } from 'app/core/utils/dates';
/** Environment Configuration */
import { environment } from '../../../environments/environment';
import { MatDivider } from '@angular/material/divider';
-import { MatFormField, MatLabel, MatHint, MatSuffix, MatError } from '@angular/material/form-field';
-import { MatOption, MatAutocompleteTrigger, MatAutocomplete } from '@angular/material/autocomplete';
+import { MatFormField, MatLabel, MatHint, MatError } from '@angular/material/form-field';
+import { MatAutocompleteTrigger, MatAutocomplete } from '@angular/material/autocomplete';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
-import { MakeAccountInterbankTransfersComponent } from '../make-account-interbank-transfers/make-account-interbank-transfers.component';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
/**
@@ -43,8 +40,7 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
MatAutocompleteTrigger,
MatAutocomplete,
FaIconComponent,
- CdkTextareaAutosize,
- MakeAccountInterbankTransfersComponent
+ CdkTextareaAutosize
]
})
export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
@@ -56,7 +52,6 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
maxDate = new Date(2100, 0, 1);
/** Edit Standing Instructions form. */
makeAccountTransferForm: UntypedFormGroup;
- //makeAccountInterbankTransferForm: FormGroup;
/** To Office Type Data */
toOfficeTypeData: any;
/** To Client Type Data */
@@ -77,6 +72,7 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
interbank: boolean = false;
/** Reference of phoneAccount search */
phoneAccount = '';
+ /** Interbank transfer form flag */
interbankTransferForm: boolean = false;
balance: number = 0;
isLoading: boolean = false;
@@ -106,6 +102,8 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
this.setOptions();
});
}
+
+ /** Sets the value from the URL */
/** Sets the value from the URL */
setParams() {
this.accountType = this.route.snapshot.queryParams['accountType'];
@@ -119,7 +117,13 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
this.accountTypeId = '2';
this.id = this.route.snapshot.queryParams['savingsId'];
this.interbank = this.route.snapshot.queryParams['interbank'] === 'true';
- this.balance = this.router.getCurrentNavigation().extras.state.balance;
+ const navigationBalance = this.router.getCurrentNavigation()?.extras?.state?.balance;
+ const templateBalance =
+ this.accountTransferTemplateData?.fromAccount?.availableBalance ??
+ this.accountTransferTemplateData?.fromAccount?.summary?.accountBalance ??
+ this.accountTransferTemplateData?.fromAccount?.balance ??
+ 0;
+ this.balance = typeof navigationBalance === 'number' ? navigationBalance : templateBalance;
break;
default:
this.accountTypeId = '0';
@@ -133,9 +137,50 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
this.maxDate = this.settingsService.businessDate;
if (!this.interbank) {
this.createMakeAccountTransferForm();
+ } else {
+ this.createEmptyInterbankForm();
}
}
+ /**
+ * Crea un formulario vacĂo para interbank mientras se carga
+ */
+ createEmptyInterbankForm() {
+ this.makeAccountTransferForm = this.formBuilder.group({
+ toBank: [
+ '',
+ Validators.required
+ ],
+ toClientId: [
+ '',
+ Validators.required
+ ],
+ toAccountType: [
+ '',
+ Validators.required
+ ],
+ toAccountId: [
+ '',
+ Validators.required
+ ],
+ transferAmount: [
+ 0,
+ [
+ Validators.required,
+ Validators.min(0.01),
+ this.amountExceedsBalanceValidator.bind(this)]
+ ],
+ transferDate: [
+ this.settingsService.businessDate,
+ Validators.required
+ ],
+ transferDescription: [
+ '',
+ Validators.required
+ ]
+ });
+ }
+
/**
* Creates the standing instruction form.
*/
@@ -176,25 +221,34 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
}
createMakeAccountInterbankTransferForm(account: any) {
- /* --> */ this.makeAccountTransferForm = this.formBuilder.group({
+ if (!account) {
+ console.error('Account data is undefined');
+ this.isLoading = false;
+ return;
+ }
+
+ const defaultAmount =
+ this.accountTransferTemplateData?.transferAmount > 0 ? this.accountTransferTemplateData.transferAmount : 1;
+
+ this.makeAccountTransferForm = this.formBuilder.group({
toBank: [
- { value: account.sourceFspId, disabled: true },
+ account.destinationFspId || '',
Validators.required
],
toClientId: [
- { value: account.firsName + ' ' + account.lastName, disabled: true },
+ (account.firstName || account.firsName || '') + ' ' + (account.lastName || ''),
Validators.required
],
toAccountType: [
- { value: 'Saving Account', disabled: true },
+ 'Saving Account',
Validators.required
],
toAccountId: [
- { value: account.partyId, disabled: true },
+ account.partyId || '',
Validators.required
],
transferAmount: [
- this.accountTransferTemplateData.transferAmount,
+ defaultAmount,
[
Validators.required,
Validators.min(0.01),
@@ -205,7 +259,7 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
Validators.required
],
transferDescription: [
- '',
+ 'Transferencia interbancaria',
Validators.required
]
});
@@ -243,7 +297,7 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
delete dataObj.transferAmount;
delete dataObj.transferDate;
delete dataObj.transferDescription;
- if (dataObj.toClientId) {
+ if (dataObj.toClientId && typeof dataObj.toClientId === 'object') {
dataObj.toClientId = dataObj.toClientId.id;
}
const propNames = Object.getOwnPropertyNames(dataObj);
@@ -260,9 +314,9 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
* Subscribes to Clients search filter:
*/
ngAfterViewInit() {
- if (!this.interbank) {
- this.makeAccountTransferForm.controls.toClientId.valueChanges.subscribe((value: string) => {
- if (value.length >= 2) {
+ if (!this.interbank && this.makeAccountTransferForm) {
+ this.makeAccountTransferForm.controls.toClientId.valueChanges.subscribe((value: any) => {
+ if (typeof value === 'string' && value.length >= 2) {
this.clientsService.getFilteredClients('displayName', 'ASC', true, value).subscribe((data: any) => {
this.clientsData = data.pageItems;
});
@@ -292,17 +346,26 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
this.isLoading = true;
const dateFormat = this.settingsService.dateFormat;
const locale = this.settingsService.language.code;
+
+ let toClientIdValue: any;
+ if (typeof this.makeAccountTransferForm.controls.toClientId.value === 'object') {
+ toClientIdValue = this.makeAccountTransferForm.controls.toClientId.value.id;
+ } else {
+ toClientIdValue = this.makeAccountTransferForm.controls.toClientId.value;
+ }
+
const makeAccountTransferData = {
...this.makeAccountTransferForm.value,
transferDate: this.dateUtils.formatDate(this.makeAccountTransferForm.value.transferDate, dateFormat),
dateFormat,
locale,
- toClientId: this.makeAccountTransferForm.controls.toClientId.value.id,
+ toClientId: toClientIdValue,
fromAccountId: this.id,
fromAccountType: this.accountTypeId,
fromClientId: this.accountTransferTemplateData.fromClient.id,
fromOfficeId: this.accountTransferTemplateData.fromClient.officeId
};
+
this.accountTransfersService.createAccountTransfer(makeAccountTransferData).subscribe(() => {
this.isLoading = false;
this.router.navigate(['../../transactions'], { relativeTo: this.route });
@@ -311,12 +374,19 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
makeInterbankTransfer() {
this.isLoading = true;
+
+ if (!this.makeAccountTransferForm.valid) {
+ console.error('Interbank form is not valid');
+ this.isLoading = false;
+ return;
+ }
+
const payload = {
homeTransactionId: crypto.randomUUID(),
from: {
fspId: environment.fineractPlatformTenantId,
idType: 'MSISDN',
- idValue: this.accountTransferTemplateData.fromAccount.externalId.trim()
+ idValue: this.accountTransferTemplateData.fromAccount.externalId?.trim() || ''
},
to: {
fspId: this.makeAccountTransferForm.controls.toBank.value,
@@ -336,6 +406,7 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
},
note: this.makeAccountTransferForm.controls.transferDescription.value
};
+
this.accountTransfersService.sendInterbankTransfer(JSON.stringify(payload)).subscribe(
(trnsfr) => {
if (trnsfr.systemMessage) {
@@ -344,12 +415,17 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
}
},
(error) => {
+ console.error('Interbank transfer error:', error);
this.isLoading = false;
}
);
}
searchAccountByNumber() {
+ if (!this.phoneAccount || this.phoneAccount.length !== 10) {
+ return;
+ }
+
this.isLoading = true;
this.accountTransfersService
.getAccountByNumber(this.phoneAccount, this.accountTransferTemplateData.currency.code)
@@ -359,6 +435,7 @@ export class MakeAccountTransfersComponent implements OnInit, AfterViewInit {
this.createMakeAccountInterbankTransferForm(acc);
},
(error) => {
+ console.error('searching account error:', error);
this.isLoading = false;
}
);