-
Notifications
You must be signed in to change notification settings - Fork 902
WEB-870: Delinquency management configuration for WC #3400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,67 @@ | ||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||
| * Copyright since 2025 Mifos Initiative | ||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||
| * This Source Code Form is subject to the terms of the Mozilla Public | ||||||||||||||||||||||||||||||||
| * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||||||||||||||||||||||||||||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| import { inject } from '@angular/core'; | ||||||||||||||||||||||||||||||||
| import { ActivatedRoute } from '@angular/router'; | ||||||||||||||||||||||||||||||||
| import { BehaviorSubject } from 'rxjs'; | ||||||||||||||||||||||||||||||||
| import { DELINQUENCY_BUCKET_TYPE, DelinquencyBucketType } from './models/delinquency-models'; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| export abstract class DelinquencyBucketBaseComponent { | ||||||||||||||||||||||||||||||||
| protected route = inject(ActivatedRoute); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| delinquencyBucketType = new BehaviorSubject<DelinquencyBucketType>(DELINQUENCY_BUCKET_TYPE.REGULAR); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| constructor() { | ||||||||||||||||||||||||||||||||
| this.initialize(this.route.snapshot.queryParamMap.get('bucketType') || 'regular'); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| initialize(productType: string): void { | ||||||||||||||||||||||||||||||||
| if (productType === 'regular') { | ||||||||||||||||||||||||||||||||
| this.delinquencyBucketType.next(DELINQUENCY_BUCKET_TYPE.REGULAR); | ||||||||||||||||||||||||||||||||
| } else if (productType === 'workingcapital') { | ||||||||||||||||||||||||||||||||
| this.delinquencyBucketType.next(DELINQUENCY_BUCKET_TYPE.WORKING_CAPITAL); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| get isWorkingCapitalBucket(): boolean { | ||||||||||||||||||||||||||||||||
| return DELINQUENCY_BUCKET_TYPE.WORKING_CAPITAL === this.delinquencyBucketType.value; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| get isRegularBucket(): boolean { | ||||||||||||||||||||||||||||||||
| return DELINQUENCY_BUCKET_TYPE.REGULAR === this.delinquencyBucketType.value; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| bucketTypeLabel(bucketType: number): string { | ||||||||||||||||||||||||||||||||
| if (bucketType === 1) { | ||||||||||||||||||||||||||||||||
| return 'Regular'; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| if (bucketType === 2) { | ||||||||||||||||||||||||||||||||
| return 'Working Capital'; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| return ''; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| bucketType(bucketType: number): string { | ||||||||||||||||||||||||||||||||
| if (bucketType === 1) { | ||||||||||||||||||||||||||||||||
| return 'regular'; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| if (bucketType === 2) { | ||||||||||||||||||||||||||||||||
| return 'workingcapital'; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| return ''; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+39
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use
🛠️ Minimal fix- bucketTypeLabel(bucketType: number): string {
- if (bucketType === 1) {
+ bucketTypeLabel(bucketType: DelinquencyBucketType): string {
+ if (bucketType === DELINQUENCY_BUCKET_TYPE.REGULAR) {
return 'Regular';
}
- if (bucketType === 2) {
+ if (bucketType === DELINQUENCY_BUCKET_TYPE.WORKING_CAPITAL) {
return 'Working Capital';
}
return '';
}
- bucketType(bucketType: number): string {
- if (bucketType === 1) {
- return 'regular';
- }
- if (bucketType === 2) {
- return 'workingcapital';
- }
- return '';
+ bucketType(bucketType: DelinquencyBucketType): DelinquencyBucketType {
+ return bucketType;
}🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| getCatalogLabel(inputText: string): string { | ||||||||||||||||||||||||||||||||
| const datas = inputText.split('.'); | ||||||||||||||||||||||||||||||||
| return this.camalize(datas[1]); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| camalize(word: string) { | ||||||||||||||||||||||||||||||||
| return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); | ||||||||||||||||||||||||||||||||
|
Comment on lines
+59
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard This helper unconditionally reads the second token from 🛡️ Minimal fix getCatalogLabel(inputText: string): string {
- const datas = inputText.split('.');
- return this.camalize(datas[1]);
+ const [, catalogValue] = inputText.split('.');
+ return this.camalize(catalogValue ?? inputText);
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,76 @@ | |
| </mat-error> | ||
| } | ||
| </mat-form-field> | ||
| @if (isWorkingCapitalBucket) { | ||
| <h3 class="mat-h3 flex-100">{{ 'labels.inputs.Delinquency Payment Rule' | translate }}</h3> | ||
| <mat-form-field class="flex-100"> | ||
| <mat-label>{{ 'labels.inputs.Frequency' | translate }}</mat-label> | ||
| <input matInput type="number" required formControlName="frequency" min="1" step="1" /> | ||
| @if (bucketForm.controls.frequency.hasError('required')) { | ||
| <mat-error> | ||
| {{ 'labels.inputs.Frequency' | translate }} {{ 'labels.commons.is' | translate }} | ||
| <strong>{{ 'labels.commons.required' | translate }}</strong> | ||
| </mat-error> | ||
| } | ||
| @if (bucketForm.controls.frequency.hasError('pattern')) { | ||
| <mat-error> | ||
| {{ 'labels.inputs.Frequency' | translate }} {{ 'labels.commons.must be' | translate }} | ||
| {{ 'labels.commons.a positive number' | translate }} | ||
| </mat-error> | ||
| } | ||
| </mat-form-field> | ||
|
|
||
| <mat-form-field class="flex-100"> | ||
| <mat-label>{{ 'labels.inputs.Frequency Type' | translate }}</mat-label> | ||
| <mat-select required formControlName="frequencyType"> | ||
| @for (frequencyType of frequencyTypeOptions; track frequencyType) { | ||
| <mat-option [value]="frequencyType.id"> | ||
| {{ getCatalogLabel(frequencyType.name) | translateKey: 'catalogs' }} | ||
| </mat-option> | ||
| } | ||
| </mat-select> | ||
| @if (bucketForm.controls.frequencyType.hasError('required')) { | ||
| <mat-error> | ||
| {{ 'labels.inputs.Frequency Type' | translate }} {{ 'labels.commons.is' | translate }} | ||
| <strong>{{ 'labels.commons.required' | translate }}</strong> | ||
| </mat-error> | ||
| } | ||
| </mat-form-field> | ||
|
|
||
| <mat-form-field class="flex-100"> | ||
| <mat-label>{{ 'labels.inputs.Minimum Payment' | translate }}</mat-label> | ||
| <input matInput type="number" required formControlName="minimumPayment" min="0.01" /> | ||
| @if (bucketForm.controls.minimumPayment.hasError('required')) { | ||
| <mat-error> | ||
| {{ 'labels.inputs.Minimum Payment' | translate }} {{ 'labels.commons.is' | translate }} | ||
| <strong>{{ 'labels.commons.required' | translate }}</strong> | ||
| </mat-error> | ||
| } | ||
| @if (bucketForm.controls.minimumPayment.hasError('pattern')) { | ||
| <mat-error> | ||
| {{ 'labels.inputs.Minimum Payment' | translate }} {{ 'labels.commons.must be' | translate }} | ||
| {{ 'labels.commons.a positive number' | translate }} | ||
| </mat-error> | ||
| } | ||
|
Comment on lines
+69
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The control uses 🤖 Prompt for AI Agents |
||
| </mat-form-field> | ||
|
|
||
| <mat-form-field class="flex-100"> | ||
| <mat-label>{{ 'labels.inputs.Minimum Payment Type' | translate }}</mat-label> | ||
| <mat-select required formControlName="minimumPaymentType"> | ||
| @for (minimumPaymentType of minimumPaymentOptions; track minimumPaymentType) { | ||
| <mat-option [value]="minimumPaymentType.id"> | ||
| {{ getCatalogLabel(minimumPaymentType.name) | translateKey: 'catalogs' }} | ||
| </mat-option> | ||
| } | ||
| </mat-select> | ||
| @if (bucketForm.controls.minimumPaymentType.hasError('required')) { | ||
| <mat-error> | ||
| {{ 'labels.inputs.Minimum Payment Type' | translate }} {{ 'labels.commons.is' | translate }} | ||
| <strong>{{ 'labels.commons.required' | translate }}</strong> | ||
| </mat-error> | ||
| } | ||
| </mat-form-field> | ||
| } | ||
|
|
||
| <h3 class="mat-h3 flex-40">{{ 'labels.heading.Delinquency Ranges' | translate }}</h3> | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Translate these bucket labels instead of hardcoding English.
RegularandWorking Capitalare rendered text, so they bypass the locale catalog and will not be picked up by translation extraction in this form.As per coding guidelines: Use proper i18n variables from
@ngx-translate/corefor all user-facing strings instead of hardcoded text.🤖 Prompt for AI Agents