Remark Loan product attributes that uses default values from global configurations (#1783)
Co-authored-by: Jose Alberto Hernandez <alberto@blue-daemon.local>
This commit is contained in:
co-authored by
Jose Alberto Hernandez
parent
9f2c644877
commit
e1e3429b66
@@ -11,7 +11,6 @@ import { AuthenticationService } from './authentication/authentication.service';
|
||||
import { HttpService } from './http/http.service';
|
||||
import { HttpCacheService } from './http/http-cache.service';
|
||||
import { ProgressBarService } from './progress-bar/progress-bar.service';
|
||||
import { I18nService } from './i18n/i18n.service';
|
||||
|
||||
/** Custom Guards */
|
||||
import { AuthenticationGuard } from './authentication/authentication.guard';
|
||||
@@ -68,7 +67,6 @@ import { ContentComponent } from './shell/content/content.component';
|
||||
useClass: AuthenticationInterceptor,
|
||||
multi: true
|
||||
},
|
||||
I18nService,
|
||||
HttpCacheService,
|
||||
ApiPrefixInterceptor,
|
||||
ErrorHandlerInterceptor,
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
// import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
// import { TranslateService, LangChangeEvent } from '@ngx-translate/core';
|
||||
// import { Subject } from 'rxjs';
|
||||
|
||||
// import { extract, I18nService } from './i18n.service';
|
||||
|
||||
// const defaultLanguage = 'en-US';
|
||||
// const supportedLanguages = ['eo', 'en-US', 'fr-FR'];
|
||||
|
||||
// class MockTranslateService {
|
||||
|
||||
// currentLang: string;
|
||||
// onLangChange = new Subject();
|
||||
|
||||
// use(language: string) {
|
||||
// this.currentLang = language;
|
||||
// this.onLangChange.next({
|
||||
// lang: this.currentLang,
|
||||
// translations: {}
|
||||
// });
|
||||
// }
|
||||
|
||||
// getBrowserCultureLang() {
|
||||
// return 'en-US';
|
||||
// }
|
||||
|
||||
// setTranslation(lang: string, translations: Object, shouldMerge?: boolean) { }
|
||||
|
||||
// }
|
||||
|
||||
// describe('I18nService', () => {
|
||||
// let i18nService: I18nService;
|
||||
// let translateService: TranslateService;
|
||||
// let onLangChangeSpy: jasmine.Spy;
|
||||
|
||||
// beforeEach(() => {
|
||||
// TestBed.configureTestingModule({
|
||||
// providers: [
|
||||
// I18nService,
|
||||
// { provide: TranslateService, useClass: MockTranslateService },
|
||||
// ]
|
||||
// });
|
||||
// });
|
||||
|
||||
// beforeEach(inject([
|
||||
// I18nService,
|
||||
// TranslateService
|
||||
// ], (_i18nService: I18nService,
|
||||
// _translateService: TranslateService) => {
|
||||
|
||||
// i18nService = _i18nService;
|
||||
// translateService = _translateService;
|
||||
|
||||
// // Create spies
|
||||
// onLangChangeSpy = jasmine.createSpy('onLangChangeSpy');
|
||||
// translateService.onLangChange
|
||||
// .subscribe((event: LangChangeEvent) => {
|
||||
// onLangChangeSpy(event.lang);
|
||||
// });
|
||||
// spyOn(translateService, 'use').and.callThrough();
|
||||
// }));
|
||||
|
||||
// afterEach(() => {
|
||||
// // Cleanup
|
||||
// localStorage.removeItem('language');
|
||||
// });
|
||||
|
||||
// describe('extract', () => {
|
||||
// it('should not modify string', () => {
|
||||
// expect(extract('Hello world !')).toEqual('Hello world !');
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe('init', () => {
|
||||
// it('should init with default language', () => {
|
||||
// // Act
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Assert
|
||||
// expect(translateService.use).toHaveBeenCalledWith(defaultLanguage);
|
||||
// expect(onLangChangeSpy).toHaveBeenCalledWith(defaultLanguage);
|
||||
// });
|
||||
|
||||
// it('should init with save language', () => {
|
||||
// // Arrange
|
||||
// const savedLanguage = 'eo';
|
||||
// localStorage.setItem('language', savedLanguage);
|
||||
|
||||
// // Act
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Assert
|
||||
// expect(translateService.use).toHaveBeenCalledWith(savedLanguage);
|
||||
// expect(onLangChangeSpy).toHaveBeenCalledWith(savedLanguage);
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe('set language', () => {
|
||||
// it('should change current language', () => {
|
||||
// // Arrange
|
||||
// const newLanguage = 'eo';
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Act
|
||||
// i18nService.language = newLanguage;
|
||||
|
||||
// // Assert
|
||||
// expect(translateService.use).toHaveBeenCalledWith(newLanguage);
|
||||
// expect(onLangChangeSpy).toHaveBeenCalledWith(newLanguage);
|
||||
// });
|
||||
|
||||
// it('should change current language without a region match', () => {
|
||||
// // Arrange
|
||||
// const newLanguage = 'fr-CA';
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Act
|
||||
// i18nService.language = newLanguage;
|
||||
|
||||
// // Assert
|
||||
// expect(translateService.use).toHaveBeenCalledWith('fr-FR');
|
||||
// expect(onLangChangeSpy).toHaveBeenCalledWith('fr-FR');
|
||||
// });
|
||||
|
||||
// it('should change current language to default if unsupported', () => {
|
||||
// // Arrange
|
||||
// const newLanguage = 'es';
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Act
|
||||
// i18nService.language = newLanguage;
|
||||
|
||||
// // Assert
|
||||
// expect(translateService.use).toHaveBeenCalledWith(defaultLanguage);
|
||||
// expect(onLangChangeSpy).toHaveBeenCalledWith(defaultLanguage);
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe('get language', () => {
|
||||
// it('should return current language', () => {
|
||||
// // Arrange
|
||||
// i18nService.init(defaultLanguage, supportedLanguages);
|
||||
|
||||
// // Act
|
||||
// const currentLanguage = i18nService.language;
|
||||
|
||||
// // Assert
|
||||
// expect(currentLanguage).toEqual(defaultLanguage);
|
||||
// });
|
||||
// });
|
||||
|
||||
// });
|
||||
@@ -1,2 +1,9 @@
|
||||
mifosx-content { min-height: 100%; height: auto !important; height: 100%; margin: 0 auto -30px; }
|
||||
#push { height:30px;}
|
||||
mifosx-content {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
margin: 0 auto -30px;
|
||||
}
|
||||
#push {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
@@ -48,12 +48,16 @@ export class CreateLoanProductComponent implements OnInit {
|
||||
const assetAccountData = this.loanProductsTemplate.accountingMappingOptions.assetAccountOptions || [];
|
||||
const liabilityAccountData = this.loanProductsTemplate.accountingMappingOptions.liabilityAccountOptions || [];
|
||||
this.loanProductsTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions = assetAccountData.concat(liabilityAccountData);
|
||||
const itemsByDefault: string[] = [];
|
||||
data.configurations.globalConfiguration.forEach((config: GlobalConfiguration) => {
|
||||
if (config.name === 'days-before-repayment-is-due') {
|
||||
this.loanProductsTemplate['dueDaysForRepaymentEvent'] = config.value;
|
||||
itemsByDefault.push('dueDaysForRepaymentEvent');
|
||||
} else if (config.name === 'days-after-repayment-is-overdue') {
|
||||
this.loanProductsTemplate['overDueDaysForRepaymentEvent'] = config.value;
|
||||
itemsByDefault.push('overDueDaysForRepaymentEvent');
|
||||
}
|
||||
this.loanProductsTemplate['itemsByDefault'] = itemsByDefault;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -48,16 +48,20 @@ export class EditLoanProductComponent implements OnInit {
|
||||
const assetAccountData = this.loanProductAndTemplate.accountingMappingOptions.assetAccountOptions || [];
|
||||
const liabilityAccountData = this.loanProductAndTemplate.accountingMappingOptions.liabilityAccountOptions || [];
|
||||
this.loanProductAndTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions = assetAccountData.concat(liabilityAccountData);
|
||||
const itemsByDefault: string[] = [];
|
||||
data.configurations.globalConfiguration.forEach((config: GlobalConfiguration) => {
|
||||
if (config.name === 'days-before-repayment-is-due') {
|
||||
if (this.loanProductAndTemplate['dueDaysForRepaymentEvent'] == null) {
|
||||
this.loanProductAndTemplate['dueDaysForRepaymentEvent'] = config.value;
|
||||
itemsByDefault.push('dueDaysForRepaymentEvent');
|
||||
}
|
||||
} else if (config.name === 'days-after-repayment-is-overdue') {
|
||||
if (this.loanProductAndTemplate['overDueDaysForRepaymentEvent'] == null) {
|
||||
this.loanProductAndTemplate['overDueDaysForRepaymentEvent'] = config.value;
|
||||
itemsByDefault.push('overDueDaysForRepaymentEvent');
|
||||
}
|
||||
}
|
||||
this.loanProductAndTemplate['itemsByDefault'] = itemsByDefault;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
+4
-3
@@ -416,16 +416,17 @@
|
||||
|
||||
<mat-divider fxFlex="98%"></mat-divider>
|
||||
|
||||
<h3 fxFlex="23%" class="mat-h3">Event Settings</h3>
|
||||
<h3 fxFlex="23%" class="mat-h3">Event Settings <i class="fas fa-question"
|
||||
matTooltip="Setting for event notifications to be sent before or after repayments. Blue color means default value from global configurations."></i></h3>
|
||||
<div fxFlexFill fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>Due days for repayment event</mat-label>
|
||||
<mat-label [ngClass]="styleByDefault('dueDaysForRepaymentEvent')">Due days for repayment event</mat-label>
|
||||
<input type="number" matInput matTooltip="Specific days before when repayment due notification should be sent." formControlName="dueDaysForRepaymentEvent" [min]="0">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field fxFlex="48%">
|
||||
<mat-label>OverDue days for repayment event</mat-label>
|
||||
<mat-label [ngClass]="styleByDefault('dueDaysForRepaymentEvent')">OverDue days for repayment event</mat-label>
|
||||
<input type="number" matInput matTooltip="Specific days when after the repayment Overdue notification should be sent." formControlName="overDueDaysForRepaymentEvent" [min]="0">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
+6
@@ -1,3 +1,5 @@
|
||||
@import "assets/styles/colours";
|
||||
|
||||
h3, h4 {
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -21,3 +23,7 @@ mat-divider {
|
||||
.margin-t {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.by-default {
|
||||
color: $status-approved;
|
||||
}
|
||||
|
||||
+12
-2
@@ -28,6 +28,8 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
||||
interestRecalculationOnDayTypeData: any;
|
||||
delinquencyBucketData: any;
|
||||
|
||||
itemsByDefault: string[] = [];
|
||||
|
||||
constructor(private formBuilder: FormBuilder) {
|
||||
this.createLoanProductSettingsForm();
|
||||
this.setConditionalControls();
|
||||
@@ -58,6 +60,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
||||
this.interestRecalculationOnDayTypeData = Array.from({ length: 28 }, (_, index) => index + 1);
|
||||
this.delinquencyBucketData = this.loanProductsTemplate.delinquencyBucketOptions;
|
||||
|
||||
this.itemsByDefault = this.loanProductsTemplate.itemsByDefault || [];
|
||||
this.loanProductSettingsForm.patchValue({
|
||||
'amortizationType': this.loanProductsTemplate.amortizationType.id,
|
||||
'interestType': this.loanProductsTemplate.interestType.id,
|
||||
@@ -88,7 +91,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
||||
'outstandingLoanBalance': this.loanProductsTemplate.outstandingLoanBalance,
|
||||
'dueDaysForRepaymentEvent': this.loanProductsTemplate.dueDaysForRepaymentEvent,
|
||||
'overDueDaysForRepaymentEvent': this.loanProductsTemplate.overDueDaysForRepaymentEvent
|
||||
});
|
||||
});
|
||||
|
||||
if (this.loanProductsTemplate.delinquencyBucket) {
|
||||
this.loanProductSettingsForm.patchValue({
|
||||
@@ -195,7 +198,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
||||
this.loanProductSettingsForm.get('interestCalculationPeriodType').valueChanges
|
||||
.subscribe((interestCalculationPeriodType: any) => {
|
||||
if (interestCalculationPeriodType === 0) {
|
||||
this.loanProductSettingsForm.patchValue({'allowPartialPeriodInterestCalcualtion': false});
|
||||
this.loanProductSettingsForm.patchValue({ 'allowPartialPeriodInterestCalcualtion': false });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -358,6 +361,13 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
styleByDefault(input: string): string {
|
||||
if (this.itemsByDefault.includes(input)) {
|
||||
return 'by-default';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
get loanProductSettings() {
|
||||
return this.loanProductSettingsForm.value;
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ export class LanguageSelectorComponent implements OnInit {
|
||||
|
||||
/**
|
||||
* Sets the language of the application in the selector on initial setup.
|
||||
* @param {I18nService} i18nService Internationalization Service.
|
||||
* @param {TranslateService} translateService Translate Service.
|
||||
*/
|
||||
constructor(private translate: TranslateService,
|
||||
constructor(private translateService: TranslateService,
|
||||
private settingsService: SettingsService) {
|
||||
this.languageSelector.setValue(this.currentLanguage);
|
||||
}
|
||||
@@ -39,7 +39,7 @@ export class LanguageSelectorComponent implements OnInit {
|
||||
* @param {string} language New language.
|
||||
*/
|
||||
setLanguage() {
|
||||
this.translate.use(this.languageSelector.value);
|
||||
this.translateService.use(this.languageSelector.value);
|
||||
this.settingsService.setLanguage({ name: '', code: this.languageSelector.value.substring(0, 2) });
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ export class LanguageSelectorComponent implements OnInit {
|
||||
* @returns {string} Current language.
|
||||
*/
|
||||
get currentLanguage(): string {
|
||||
return this.translate.currentLang;
|
||||
return this.translateService.currentLang;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ export class LanguageSelectorComponent implements OnInit {
|
||||
* @return {string[]} Supported languages.
|
||||
*/
|
||||
get languages(): string[] {
|
||||
return this.translate.getLangs();
|
||||
return this.translateService.getLangs();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ export class WebAppComponent implements OnInit {
|
||||
* @param {ActivatedRoute} activatedRoute Activated Route.
|
||||
* @param {Title} titleService Title Service.
|
||||
* @param {TranslateService} translateService Translate Service.
|
||||
* @param {I18nService} i18nService I18n Service.
|
||||
* @param {ThemeStorageService} themeStorageService Theme Storage Service.
|
||||
* @param {MatSnackBar} snackBar Material Snackbar for notifications.
|
||||
* @param {AlertService} alertService Alert Service.
|
||||
|
||||
Reference in New Issue
Block a user