diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 181ca043b..3af18298b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,9 +4,9 @@ name: build-run on: # Triggers the workflow on push or pull request events for specific branches push: - branches: [main, dev, angular-update-18] + branches: [main, dev, dev-angular-19] pull_request: - branches: [main, dev, angular-update-18] + branches: [main, dev, dev-angular-19] # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: diff --git a/.github/workflows/create-docker-hub-image.yml b/.github/workflows/create-docker-hub-image.yml index 087c79ac5..4b6e793bf 100644 --- a/.github/workflows/create-docker-hub-image.yml +++ b/.github/workflows/create-docker-hub-image.yml @@ -2,7 +2,7 @@ name: Publish Image in Docker Hub on: push: - branches: [main, dev, angular-update] + branches: [main, dev, dev-angular-19] jobs: build: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 96ba37628..b3dbcb084 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,9 +2,9 @@ name: Tests on: push: - branches: [main, dev, angular-update-17-2] + branches: [main, dev, dev-angular-19] pull_request: - branches: [main, dev, angular-update-17-2] + branches: [main, dev, dev-angular-19] jobs: testRigor: diff --git a/src/app/core/shell/sidenav/sidenav.component.html b/src/app/core/shell/sidenav/sidenav.component.html index 55e668422..cc22f276c 100644 --- a/src/app/core/shell/sidenav/sidenav.component.html +++ b/src/app/core/shell/sidenav/sidenav.component.html @@ -99,7 +99,7 @@ diff --git a/src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.html b/src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.html index 938e085b3..dd3577525 100644 --- a/src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.html +++ b/src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.html @@ -60,6 +60,16 @@ > {{ 'labels.buttons.Submit' | translate }} + diff --git a/src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.ts b/src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.ts index d0743ea2b..9d8a6628f 100644 --- a/src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.ts +++ b/src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.ts @@ -1,10 +1,14 @@ import { Component, Input, OnInit, inject } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; +import { MatDialog } from '@angular/material/dialog'; import { LoansService } from 'app/loans/loans.service'; +import { RepaymentSchedule } from 'app/loans/models/loan-account.model'; import { CodeValue } from 'app/shared/models/general.model'; import { OptionData } from 'app/shared/models/option-data.model'; import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; +import { SettingsService } from 'app/settings/settings.service'; +import { ReAmortizePreviewDialogComponent } from './re-amortize-preview-dialog/re-amortize-preview-dialog.component'; @Component({ selector: 'mifosx-loan-reamortize', @@ -19,6 +23,8 @@ export class LoanReamortizeComponent implements OnInit { private route = inject(ActivatedRoute); private router = inject(Router); private loanService = inject(LoansService); + private settingsService = inject(SettingsService); + private dialog = inject(MatDialog); @Input() dataObject: any; /** Loan Id */ @@ -50,8 +56,76 @@ export class LoanReamortizeComponent implements OnInit { }); } - submit(): void { + private prepareReAmortizeData() { const data = this.reamortizeLoanForm.value; + const locale = this.settingsService.language.code; + const dateFormat = this.settingsService.dateFormat; + + return { + ...data, + dateFormat, + locale + }; + } + + private prepareReAmortizePreviewData() { + const reamortizeLoanFormData = { ...this.reamortizeLoanForm.value }; + const locale = this.settingsService.language.code; + const dateFormat = this.settingsService.dateFormat; + + // Prepare reAmortizationInterestHandling for preview API + let reAmortizationInterestHandling = reamortizeLoanFormData.reAmortizationInterestHandling; + if (reAmortizationInterestHandling && typeof reAmortizationInterestHandling === 'object') { + reAmortizationInterestHandling = reAmortizationInterestHandling.id; + } + // If no value selected, use "default" for preview + if (!reAmortizationInterestHandling && reAmortizationInterestHandling !== 0) { + reAmortizationInterestHandling = 'default'; + } + + delete reamortizeLoanFormData.reAmortizationInterestHandling; + + return { + ...reamortizeLoanFormData, + reAmortizationInterestHandling: reAmortizationInterestHandling, + dateFormat, + locale + }; + } + + preview(): void { + if (this.reamortizeLoanForm.invalid) { + return; + } + const data = this.prepareReAmortizePreviewData(); + + this.loanService.getReAmortizePreview(this.loanId, data).subscribe({ + next: (response: RepaymentSchedule) => { + const currencyCode = response.currency?.code; + + if (!currencyCode) { + console.error('Currency code is not available in API response'); + return; + } + + this.dialog.open(ReAmortizePreviewDialogComponent, { + data: { + repaymentSchedule: response, + currencyCode: currencyCode + }, + width: '95%', + maxWidth: '1400px', + height: '90vh' + }); + }, + error: (error) => { + console.error('Error loading re-amortize preview:', error); + } + }); + } + + submit(): void { + const data = this.prepareReAmortizeData(); this.loanService.submitLoanActionButton(this.loanId, data, 'reAmortize').subscribe((response: any) => { this.router.navigate(['../../transactions'], { relativeTo: this.route }); }); diff --git a/src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.html b/src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.html new file mode 100644 index 000000000..e33efb236 --- /dev/null +++ b/src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.html @@ -0,0 +1,16 @@ +

{{ 'labels.heading.Repayment Schedule Preview' | translate }}

+ + + + + + + + + diff --git a/src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.ts b/src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.ts new file mode 100644 index 000000000..f612bc943 --- /dev/null +++ b/src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.ts @@ -0,0 +1,45 @@ +import { Component, inject, Inject } from '@angular/core'; +import { + MAT_DIALOG_DATA, + MatDialogRef, + MatDialogTitle, + MatDialogContent, + MatDialogActions +} from '@angular/material/dialog'; +import { MatButton } from '@angular/material/button'; +import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module'; +import { RepaymentSchedule } from 'app/loans/models/loan-account.model'; +import { RepaymentScheduleTabComponent } from '../../../repayment-schedule-tab/repayment-schedule-tab.component'; + +export interface ReAmortizePreviewDialogData { + repaymentSchedule: RepaymentSchedule; + currencyCode: string; +} + +@Component({ + selector: 'mifosx-re-amortize-preview-dialog', + templateUrl: './re-amortize-preview-dialog.component.html', + standalone: true, + imports: [ + ...STANDALONE_SHARED_IMPORTS, + MatDialogTitle, + MatDialogContent, + MatDialogActions, + MatButton, + RepaymentScheduleTabComponent + ] +}) +export class ReAmortizePreviewDialogComponent { + // inject() replaces constructor injection + private readonly dialogRef = inject>(MatDialogRef); + + private readonly data = inject(MAT_DIALOG_DATA); + + // public fields used in template + readonly repaymentSchedule: RepaymentSchedule = this.data.repaymentSchedule; + readonly currencyCode: string = this.data.currencyCode; + + close(): void { + this.dialogRef.close(); + } +} diff --git a/src/app/loans/loans.service.ts b/src/app/loans/loans.service.ts index 870906317..0e84ca31c 100644 --- a/src/app/loans/loans.service.ts +++ b/src/app/loans/loans.service.ts @@ -258,6 +258,24 @@ export class LoansService { return this.http.get(`/loans/${loanId}/transactions/reage-preview`, { params: httpParams }); } + /** + * Get Re-Amortize preview with repayment schedule + * @param loanId Loan Id + * @param data Re-Amortize data + * @returns Observable with repayment schedule preview + */ + getReAmortizePreview(loanId: string, data: any): Observable { + let httpParams = new HttpParams(); + + Object.keys(data).forEach((key) => { + if (data[key] !== null && data[key] !== undefined && data[key] !== '') { + httpParams = httpParams.set(key, data[key].toString()); + } + }); + + return this.http.get(`/loans/${loanId}/transactions/reamortized-preview`, { params: httpParams }); + } + getLoanScreenReportsData(): Observable { const httpParams = new HttpParams().set('entityId', '1').set('typeId', '0'); return this.http.get(`/templates`, { params: httpParams }); diff --git a/src/assets/translations/cs-CS.json b/src/assets/translations/cs-CS.json index 3cd05107c..cddf12b6c 100644 --- a/src/assets/translations/cs-CS.json +++ b/src/assets/translations/cs-CS.json @@ -2744,6 +2744,7 @@ "All Fixed Deposits": "Všechny pevné vklady", "All Recurring Deposits": "Všechny opakované vklady", "All Savings": "Všechny úspory", + "Savings Account Details": "Podrobnosti spořicího účtu", "Allocate Cash": "Přidělte hotovost", "Allows you to create new fixed deposit product": "Tato možnost vám umožňuje vytvořit nový produkt s pevným vkladem.", "This option allows you to create new users in your organization": "Tato možnost vám umožňuje vytvářet nové uživatele ve vaší organizaci", diff --git a/src/assets/translations/de-DE.json b/src/assets/translations/de-DE.json index 28a55c57d..1d103054c 100644 --- a/src/assets/translations/de-DE.json +++ b/src/assets/translations/de-DE.json @@ -2744,6 +2744,7 @@ "All Fixed Deposits": "Alle Festgelder", "All Recurring Deposits": "Alle wiederkehrenden Einzahlungen", "All Savings": "Alle Einsparungen", + "Savings Account Details": "Sparkonto-Details", "Allocate Cash": "Bargeld zuweisen", "Allows you to create new fixed deposit product": "Mit dieser Option können Sie ein neues Festgeldprodukt erstellen.", "This option allows you to create new users in your organization": "Mit dieser Option können Sie neue Benutzer in Ihrer Organisation erstellen", diff --git a/src/assets/translations/en-US.json b/src/assets/translations/en-US.json index 33ee0a706..97e867c1d 100644 --- a/src/assets/translations/en-US.json +++ b/src/assets/translations/en-US.json @@ -2754,6 +2754,7 @@ "All Fixed Deposits": "All Fixed Deposits", "All Recurring Deposits": "All Recurring Deposits", "All Savings": "All Savings", + "Savings Account Details": "Savings Account Details", "Allocate Cash": "Allocate Cash", "Allows you to create new fixed deposit product": "This option allows you to create a new fixed deposit product.", "This option allows you to create new users in your organization": "This option allows you to create new users in your organization", diff --git a/src/assets/translations/es-CL.json b/src/assets/translations/es-CL.json index 697e99e75..cf8c8bcd1 100644 --- a/src/assets/translations/es-CL.json +++ b/src/assets/translations/es-CL.json @@ -2744,6 +2744,7 @@ "All Fixed Deposits": "Todos los depósitos fijos", "All Recurring Deposits": "Todos los depósitos recurrentes", "All Savings": "Todos los ahorros", + "Savings Account Details": "Detalles de la cuenta de ahorros", "Allocate Cash": "Asignar efectivo", "Allows you to create new fixed deposit product": "Esta opción le permite crear un nuevo producto de Depósito Fijo.", "This option allows you to create new users in your organization": "Esta opción le permite crear nuevos usuarios en su organización.", diff --git a/src/assets/translations/es-MX.json b/src/assets/translations/es-MX.json index 920452187..8a0f0cc50 100644 --- a/src/assets/translations/es-MX.json +++ b/src/assets/translations/es-MX.json @@ -2746,6 +2746,7 @@ "All Fixed Deposits": "Todos los depósitos fijos", "All Recurring Deposits": "Todos los depósitos recurrentes", "All Savings": "Todos los ahorros", + "Savings Account Details": "Detalles de la cuenta de ahorros", "Allocate Cash": "Asignar efectivo", "Allows you to create new fixed deposit product": "Esta opción le permite crear un nuevo producto de Depósito Fijo.", "This option allows you to create new users in your organization": "Esta opción le permite crear nuevos usuarios en su organización.", diff --git a/src/assets/translations/fr-FR.json b/src/assets/translations/fr-FR.json index fb007d5a0..9f80821ff 100644 --- a/src/assets/translations/fr-FR.json +++ b/src/assets/translations/fr-FR.json @@ -2744,6 +2744,7 @@ "All Fixed Deposits": "Tous les dépôts fixes", "All Recurring Deposits": "Tous les dépôts récurrents", "All Savings": "Toutes les économies", + "Savings Account Details": "Détails du compte d'épargne", "Allocate Cash": "Allouer de l'argent", "Allows you to create new fixed deposit product": "Cette option vous permet de créer un nouveau produit de dépôt fixe.", "This option allows you to create new users in your organization": "Cette option vous permet de créer de nouveaux utilisateurs dans votre organisation", diff --git a/src/assets/translations/it-IT.json b/src/assets/translations/it-IT.json index 648cbe8b4..5c01a646d 100644 --- a/src/assets/translations/it-IT.json +++ b/src/assets/translations/it-IT.json @@ -2744,6 +2744,7 @@ "All Fixed Deposits": "Tutti i depositi fissi", "All Recurring Deposits": "Tutti i depositi ricorrenti", "All Savings": "Tutto il risparmio", + "Savings Account Details": "Dettagli del conto di risparmio", "Allocate Cash": "Assegnare contanti", "Allows you to create new fixed deposit product": "Questa opzione ti consente di creare un nuovo prodotto a deposito fisso.", "This option allows you to create new users in your organization": "Questa opzione ti consente di creare nuovi utenti nella tua organizzazione", diff --git a/src/assets/translations/ko-KO.json b/src/assets/translations/ko-KO.json index d6246f7fd..9189a4439 100644 --- a/src/assets/translations/ko-KO.json +++ b/src/assets/translations/ko-KO.json @@ -2744,6 +2744,7 @@ "All Fixed Deposits": "정기예금 전체", "All Recurring Deposits": "모든 정기 예금", "All Savings": "모든 저축", + "Savings Account Details": "저축 계좌 세부 정보", "Allocate Cash": "현금 할당", "Allows you to create new fixed deposit product": "이 옵션을 사용하면 새로운 정기 예금 상품을 생성할 수 있습니다.", "This option allows you to create new users in your organization": "이 옵션을 사용하면 조직에 새 사용자를 만들 수 있습니다.", diff --git a/src/assets/translations/lt-LT.json b/src/assets/translations/lt-LT.json index 78e178252..8be16f7ea 100644 --- a/src/assets/translations/lt-LT.json +++ b/src/assets/translations/lt-LT.json @@ -2744,6 +2744,7 @@ "All Fixed Deposits": "Visi terminuoti indėliai", "All Recurring Deposits": "Visi periodiniai indėliai", "All Savings": "Visos santaupos", + "Savings Account Details": "Taupomosios sąskaitos informacija", "Allocate Cash": "Paskirstykite grynuosius pinigus", "Allows you to create new fixed deposit product": "Ši parinktis leidžia sukurti naują terminuoto indėlio produktą.", "This option allows you to create new users in your organization": "Ši parinktis leidžia sukurti naujų naudotojų jūsų organizacijoje", diff --git a/src/assets/translations/lv-LV.json b/src/assets/translations/lv-LV.json index 5308f5016..c60f5f426 100644 --- a/src/assets/translations/lv-LV.json +++ b/src/assets/translations/lv-LV.json @@ -2744,6 +2744,7 @@ "All Fixed Deposits": "Visi fiksētie noguldījumi", "All Recurring Deposits": "Visi atkārtotie noguldījumi", "All Savings": "Visi ietaupījumi", + "Savings Account Details": "Krājkonta informācija", "Allocate Cash": "Piešķirt skaidru naudu", "Allows you to create new fixed deposit product": "Šī opcija ļauj izveidot jaunu fiksētā depozīta produktu.", "This option allows you to create new users in your organization": "Šī opcija ļauj izveidot jaunus lietotājus jūsu organizācijā", diff --git a/src/assets/translations/ne-NE.json b/src/assets/translations/ne-NE.json index 57cd16b0f..830d3fb60 100644 --- a/src/assets/translations/ne-NE.json +++ b/src/assets/translations/ne-NE.json @@ -2744,6 +2744,7 @@ "All Fixed Deposits": "सबै फिक्स्ड डिपोजिटहरू", "All Recurring Deposits": "सबै आवर्ती निक्षेपहरू", "All Savings": "सबै बचत", + "Savings Account Details": "बचत खाता विवरण", "Allocate Cash": "नगद आवंटित गर्नुहोस्", "Allows you to create new fixed deposit product": "यो विकल्पले तपाईंलाई नयाँ फिक्स्ड डिपोजिट उत्पादन सिर्जना गर्न अनुमति दिन्छ।", "This option allows you to create new users in your organization": "यो विकल्पले तपाईंलाई आफ्नो संगठनमा नयाँ प्रयोगकर्ताहरू सिर्जना गर्न अनुमति दिन्छ", diff --git a/src/assets/translations/pt-PT.json b/src/assets/translations/pt-PT.json index d5b20a0b3..cd8bab911 100644 --- a/src/assets/translations/pt-PT.json +++ b/src/assets/translations/pt-PT.json @@ -2744,6 +2744,7 @@ "All Fixed Deposits": "Todos os depósitos fixos", "All Recurring Deposits": "Todos os depósitos recorrentes", "All Savings": "Todas as economias", + "Savings Account Details": "Detalhes da Conta Poupança", "Allocate Cash": "Alocar dinheiro", "Allows you to create new fixed deposit product": "Esta opção permite criar um novo produto de depósito fixo.", "This option allows you to create new users in your organization": "Esta opção permite criar novos usuários em sua organização", diff --git a/src/assets/translations/sw-SW.json b/src/assets/translations/sw-SW.json index 64682fd1e..42bcbd9d9 100644 --- a/src/assets/translations/sw-SW.json +++ b/src/assets/translations/sw-SW.json @@ -2743,6 +2743,7 @@ "All Fixed Deposits": "Amana Zote Zisizohamishika", "All Recurring Deposits": "Amana Zote Zinazorudiwa", "All Savings": "Akiba Yote", + "Savings Account Details": "Maelezo ya Akaunti ya Akiba", "Allocate Cash": "Tenga Pesa", "Allows you to create new fixed deposit product": "Chaguo hili hukuruhusu kuunda bidhaa mpya ya amana isiyobadilika.", "This option allows you to create new users in your organization": "Chaguo hili hukuruhusu kuunda watumiaji wapya katika shirika lako",