diff --git a/src/app/core/shell/sidenav/sidenav.component.ts b/src/app/core/shell/sidenav/sidenav.component.ts index b7c396793..8abcb16f8 100644 --- a/src/app/core/shell/sidenav/sidenav.component.ts +++ b/src/app/core/shell/sidenav/sidenav.component.ts @@ -29,7 +29,7 @@ export class SidenavComponent implements OnInit, AfterViewInit { /** True if sidenav is in collapsed state. */ @Input() sidenavCollapsed: boolean; /** Tooltip position */ - tooltipPosition: string = 'after'; + tooltipPosition = 'after'; /** Username of authenticated user. */ username: string; /** Array of all user activities */ diff --git a/src/app/core/utils/accounting.ts b/src/app/core/utils/accounting.ts new file mode 100644 index 000000000..ecd3c1eae --- /dev/null +++ b/src/app/core/utils/accounting.ts @@ -0,0 +1,64 @@ +import { Injectable } from '@angular/core'; +import { AccountingMapping, GLAccount } from 'app/shared/models/general.model'; +import { OptionData } from 'app/shared/models/option-data.model'; + + +@Injectable({ + providedIn: 'root' + }) + export class Accounting { + + public getAccountingRulesForSavings(): string[] { + return ['None', 'Cash', 'Accrual (periodic)']; + } + + public isNoneAccounting(accountingRule: OptionData): boolean { + return (accountingRule.id === 1); + } + + public isNoneAccountingRuleId(accountingRuleId: number): boolean { + return (accountingRuleId === 1); + } + + public isCashOrAccrualAccounting(accountingRule: OptionData): boolean { + return ((accountingRule.id === 2) || (accountingRule.id === 3)); + } + + public isCashOrAccrualAccountingRuleId(accountingRuleId: number): boolean { + return ((accountingRuleId === 2) || (accountingRuleId === 3)); + } + + public isAccrualAccounting(accountingRule: OptionData): boolean { + return (accountingRule.id === 3); + } + + public isAccrualAccountingRuleId(accountingRuleId: number): boolean { + return (accountingRuleId === 3); + } + + public getAccountingRuleFrom(accountingRuleId: number): OptionData { + if (accountingRuleId === 1) { + return {code: 'NONE', id: accountingRuleId, value: 'None'}; + } else if (accountingRuleId === 2) { + return {code: 'CASH', id: accountingRuleId, value: 'Cash'}; + } else if (accountingRuleId === 3) { + return {code: 'ACCRUAL_PERIODIC', id: accountingRuleId, value: 'Accural (periodic)'}; + } else if (accountingRuleId === 4) { + return {code: 'ACCRUAL_UPFRONT', id: accountingRuleId, value: 'Accural (upfront)'}; + } + return {code: 'INVALID', id: accountingRuleId, value: 'Invalid'}; + } + + public glAccountLookUp(glAccountId: number, glAccounts: GLAccount[]): AccountingMapping { + let accountMapping: AccountingMapping | null = null; + if (glAccountId) { + glAccounts.some((glAccount: GLAccount) => { + if (glAccount.id === glAccountId) { + accountMapping = { id: glAccount.id, name: glAccount.name, glCode: glAccount.glCode }; + } + }); + } + return accountMapping; + } + +} diff --git a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts index 49d9f326c..0e7af69e6 100644 --- a/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts +++ b/src/app/deposits/recurring-deposits/recurring-deposits-account-view/recurring-deposits-account-view.component.ts @@ -230,7 +230,7 @@ export class RecurringDepositsAccountViewComponent implements OnInit { private postInterest() { const postInterestAccountDialogRef = this.dialog.open(RecurringDepositConfirmationDialogComponent, { data: { heading: this.translateService.instant('labels.heading.Post Interest'), - dialogContext: this.translateService.instant('lables.text.Are you sure you want to post interest') + ' ?' + dialogContext: this.translateService.instant('labels.text.Are you sure you want to post interest') + ' ?' } }); postInterestAccountDialogRef.afterClosed().subscribe((response: any) => { diff --git a/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.ts b/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.ts index 453a69cb3..0d2ce121f 100644 --- a/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.ts +++ b/src/app/products/fixed-deposit-products/create-fixed-deposit-product/create-fixed-deposit-product.component.ts @@ -14,6 +14,7 @@ import { FixedDepositProductAccountingStepComponent } from '../fixed-deposit-pro /** Custom Services */ import { ProductsService } from 'app/products/products.service'; import { SettingsService } from 'app/settings/settings.service'; +import { Accounting } from 'app/core/utils/accounting'; @Component({ selector: 'mifosx-create-fixed-deposit-product', @@ -31,7 +32,7 @@ export class CreateFixedDepositProductComponent implements OnInit { @ViewChild(FixedDepositProductAccountingStepComponent, { static: true }) fixedDepositProductAccountingStep: FixedDepositProductAccountingStepComponent; fixedDepositProductsTemplate: any; - accountingRuleData = ['None', 'Cash']; + accountingRuleData: string[] = []; /** * @param {ActivatedRoute} route Activated Route. @@ -43,10 +44,12 @@ export class CreateFixedDepositProductComponent implements OnInit { constructor(private route: ActivatedRoute, private productsService: ProductsService, private router: Router, - private settingsService: SettingsService) { + private settingsService: SettingsService, + private accounting: Accounting) { this.route.data.subscribe((data: { fixedDepositProductsTemplate: any }) => { this.fixedDepositProductsTemplate = data.fixedDepositProductsTemplate; }); + this.accountingRuleData = this.accounting.getAccountingRulesForSavings(); } ngOnInit() { diff --git a/src/app/products/fixed-deposit-products/edit-fixed-deposit-product/edit-fixed-deposit-product.component.ts b/src/app/products/fixed-deposit-products/edit-fixed-deposit-product/edit-fixed-deposit-product.component.ts index e02704cc9..afb20ce77 100644 --- a/src/app/products/fixed-deposit-products/edit-fixed-deposit-product/edit-fixed-deposit-product.component.ts +++ b/src/app/products/fixed-deposit-products/edit-fixed-deposit-product/edit-fixed-deposit-product.component.ts @@ -14,6 +14,7 @@ import { FixedDepositProductAccountingStepComponent } from '../fixed-deposit-pro /** Custom Services */ import { ProductsService } from 'app/products/products.service'; import { SettingsService } from 'app/settings/settings.service'; +import { Accounting } from 'app/core/utils/accounting'; @Component({ selector: 'mifosx-edit-fixed-deposit-product', @@ -31,7 +32,7 @@ export class EditFixedDepositProductComponent implements OnInit { @ViewChild(FixedDepositProductAccountingStepComponent, { static: true }) fixedDepositProductAccountingStep: FixedDepositProductAccountingStepComponent; fixedDepositProductsTemplate: any; - accountingRuleData = ['None', 'Cash']; + accountingRuleData: string[] = []; /** * @param {ActivatedRoute} route Activated Route. @@ -43,10 +44,12 @@ export class EditFixedDepositProductComponent implements OnInit { constructor(private route: ActivatedRoute, private productsService: ProductsService, private router: Router, - private settingsService: SettingsService) { + private settingsService: SettingsService, + private accounting: Accounting) { this.route.data.subscribe((data: { fixedDepositProductAndTemplate: any }) => { this.fixedDepositProductsTemplate = data.fixedDepositProductAndTemplate; }); + this.accountingRuleData = this.accounting.getAccountingRulesForSavings(); } ngOnInit() { diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.html index 9d30b6534..a7d63ebb0 100644 --- a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.html +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.html @@ -10,93 +10,93 @@ -
+
-

Assets

+

{{'labels.heading.Assets' | translate}}

- - Saving reference - - - ({{ assetAccount.glCode }}) {{ assetAccount.name }} - - - - Saving reference is required - - + + + + + + + + -

Liabilities

+

{{'labels.heading.Liabilities' | translate}}

- - Saving control - - - ({{ liabilityAccount.glCode }}) {{ liabilityAccount.name }} - - - - Saving control is required - - + + - - Savings transfers in suspense - - - ({{ liabilityAccount.glCode }}) {{ liabilityAccount.name }} - - - - Savings transfers in suspense is required - - + + + + + -

Expenses

+

{{'labels.heading.Expenses' | translate}}

- - Interest on savings - - - ({{ expenseAccount.glCode }}) {{ expenseAccount.name }} - - - - Interest on savings is required - - + + -

Income

+

{{'labels.heading.Income' | translate}}

- - Income from fees - - - ({{ incomeAccount.glCode }}) {{ incomeAccount.name }} - - - - Income from fees Repayments is required - - + + - - Income from penalties - - - ({{ incomeAccount.glCode }}) {{ incomeAccount.name }} - - - - Income from penalties is required - - + + diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts index 5bf2c310d..1c0cfe8e3 100644 --- a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-accounting-step/fixed-deposit-product-accounting-step.component.ts @@ -7,6 +7,7 @@ import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.co import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base'; import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base'; +import { Accounting } from 'app/core/utils/accounting'; @Component({ selector: 'mifosx-fixed-deposit-product-accounting-step', @@ -33,7 +34,8 @@ export class FixedDepositProductAccountingStepComponent implements OnInit { feesPenaltyIncomeDisplayedColumns: string[] = ['chargeId', 'incomeAccountId', 'actions']; constructor(private formBuilder: UntypedFormBuilder, - public dialog: MatDialog) { + public dialog: MatDialog, + private accounting: Accounting) { this.createfixedDepositProductAccountingForm(); this.setConditionalControls(); } @@ -52,10 +54,10 @@ export class FixedDepositProductAccountingStepComponent implements OnInit { } assignAccountingStepData() { - if (this.fixedDepositProductsTemplate.accountingRule.id === 2) { - this.fixedDepositProductAccountingForm.patchValue({ - 'accountingRule': this.fixedDepositProductsTemplate.accountingRule.id - }); + this.fixedDepositProductAccountingForm.patchValue({ + 'accountingRule': this.fixedDepositProductsTemplate.accountingRule.id + }); + if (this.isCashOrAccrualAccounting()) { this.fixedDepositProductAccountingForm.patchValue({ 'savingsReferenceAccountId': this.fixedDepositProductsTemplate.accountingMappings.savingsReferenceAccount.id, 'savingsControlAccountId': this.fixedDepositProductsTemplate.accountingMappings.savingsControlAccount.id, @@ -64,6 +66,15 @@ export class FixedDepositProductAccountingStepComponent implements OnInit { 'incomeFromPenaltyAccountId': this.fixedDepositProductsTemplate.accountingMappings.incomeFromPenaltyAccount.id, 'interestOnSavingsAccountId': this.fixedDepositProductsTemplate.accountingMappings.interestOnSavingsAccount.id }); + + if (this.isAccrualAccounting()) { + this.fixedDepositProductAccountingForm.patchValue({ + 'feesReceivableAccountId': this.fixedDepositProductsTemplate.accountingMappings.feeReceivableAccount.id, + 'penaltiesReceivableAccountId': this.fixedDepositProductsTemplate.accountingMappings.penaltyReceivableAccount.id, + 'interestPayableAccountId': this.fixedDepositProductsTemplate.accountingMappings.interestPayableAccount.id + }); + } + if (this.fixedDepositProductsTemplate.paymentChannelToFundSourceMappings || this.fixedDepositProductsTemplate.feeToIncomeAccountMappings || this.fixedDepositProductsTemplate.penaltyToIncomeAccountMappings) { this.fixedDepositProductAccountingForm.patchValue({ 'advancedAccountingRules': true @@ -111,7 +122,7 @@ export class FixedDepositProductAccountingStepComponent implements OnInit { setConditionalControls() { this.fixedDepositProductAccountingForm.get('accountingRule').valueChanges .subscribe((accountingRule: any) => { - if (accountingRule === 2) { + if (accountingRule === 2 || accountingRule === 3) { this.fixedDepositProductAccountingForm.addControl('savingsReferenceAccountId', new UntypedFormControl('', Validators.required)); this.fixedDepositProductAccountingForm.addControl('savingsControlAccountId', new UntypedFormControl('', Validators.required)); this.fixedDepositProductAccountingForm.addControl('transfersInSuspenseAccountId', new UntypedFormControl('', Validators.required)); @@ -120,6 +131,12 @@ export class FixedDepositProductAccountingStepComponent implements OnInit { this.fixedDepositProductAccountingForm.addControl('incomeFromPenaltyAccountId', new UntypedFormControl('', Validators.required)); this.fixedDepositProductAccountingForm.addControl('advancedAccountingRules', new UntypedFormControl(false)); + if (accountingRule === 3) { + this.fixedDepositProductAccountingForm.addControl('feesReceivableAccountId', new UntypedFormControl('', Validators.required)); + this.fixedDepositProductAccountingForm.addControl('penaltiesReceivableAccountId', new UntypedFormControl('', Validators.required)); + this.fixedDepositProductAccountingForm.addControl('interestPayableAccountId', new UntypedFormControl('', Validators.required)); + } + this.fixedDepositProductAccountingForm.get('advancedAccountingRules').valueChanges .subscribe((advancedAccountingRules: boolean) => { if (advancedAccountingRules) { @@ -144,6 +161,9 @@ export class FixedDepositProductAccountingStepComponent implements OnInit { this.fixedDepositProductAccountingForm.removeControl('incomeFromInterestId'); this.fixedDepositProductAccountingForm.removeControl('advancedAccountingRules'); this.fixedDepositProductAccountingForm.removeControl('escheatLiabilityId'); + this.fixedDepositProductAccountingForm.removeControl('feesReceivableAccountId'); + this.fixedDepositProductAccountingForm.removeControl('penaltiesReceivableAccountId'); + this.fixedDepositProductAccountingForm.removeControl('interestPayableAccountId'); } }); } @@ -269,4 +289,12 @@ export class FixedDepositProductAccountingStepComponent implements OnInit { return this.fixedDepositProductAccountingForm.value; } + isCashOrAccrualAccounting(): boolean { + return this.accounting.isCashOrAccrualAccountingRuleId(this.fixedDepositProductAccountingForm.value.accountingRule); + } + + isAccrualAccounting(): boolean { + return this.accounting.isAccrualAccountingRuleId(this.fixedDepositProductAccountingForm.value.accountingRule); + } + } diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts index 0590442f9..7ad9261f1 100644 --- a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-interest-rate-chart-step/fixed-deposit-product-interest-rate-chart-step.component.ts @@ -111,6 +111,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit this.chartsDetail[i].chartSlabs.forEach((chartSlabDetail: any, j: number) => { const chartSlabInfo = this.formBuilder.group({ + id: [chartSlabDetail.id], amountRangeFrom: [chartSlabDetail.amountRangeFrom || ''], amountRangeTo: [chartSlabDetail.amountRangeTo || ''], annualInterestRate: [chartSlabDetail.annualInterestRate, Validators.required], @@ -155,6 +156,9 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit description: chartData.description, chartSlabs: this.getChartSlabsData(chartData) }; + if (chartData.id) { + chart['id'] = chartData.id; + } this.chartsDetail.push(chart); }); this.fixedDepositProductInterestRateChartForm.patchValue({ @@ -183,6 +187,9 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit toPeriod: eachChartSlabData.toPeriod, incentives: this.getIncentivesData(chartSlabData) }; + if (eachChartSlabData.id) { + chartSlab['id'] = eachChartSlabData.id; + } chartSlabs.push(chartSlab); }); return chartSlabs; @@ -225,6 +232,7 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit createChartForm(): UntypedFormGroup { return this.formBuilder.group({ + 'id': [null], 'name': [''], 'description': [''], 'fromDate': ['', Validators.required], @@ -382,6 +390,9 @@ export class FixedDepositProductInterestRateChartStepComponent implements OnInit if (chart.endDate === '') { delete chart.endDate; } + if (chart.id === null) { + delete chart.id; + } } return fixedDepositProductInterestRateChart; } diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.html b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.html index 78e51c6f3..1c979b41e 100644 --- a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.html +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.html @@ -346,148 +346,107 @@ -
- Type: - {{ accountingRuleData[fixedDepositProduct.accountingRule-1] }} -
+ + -
+
-

Assets

+

Advanced Accounting Rules

+ + + +
+ +

Fund Sources for Payment Channels

+ + + + + + + + + + + + + + + + +
Payment Type + {{ paymentFundSource.paymentTypeId | find:fixedDepositProductsTemplate.paymentTypeOptions:'id':'name' }} + Fund Source + {{ paymentFundSource.fundSourceAccountId | + find:fixedDepositProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }} +
-
- Saving reference: - {{ fixedDepositProduct.savingsReferenceAccountId | - find:fixedDepositProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }}
-

Liabilities

+
+ +

Fees to Specific Income Accounts

+ + + + + + + + + + + + + + + + +
Fees + {{ feesIncome.chargeId | find:fixedDepositProductsTemplate.chargeOptions:'id':'name' }} + Income Account + {{ feesIncome.incomeAccountId | + find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} +
-
- Saving control: - {{ fixedDepositProduct.savingsControlAccountId | - find:fixedDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }} - Savings transfers in suspense: - {{ fixedDepositProduct.transfersInSuspenseAccountId | - find:fixedDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }}
-

Expenses

+
-
- Interest on savings: - {{ fixedDepositProduct.interestOnSavingsAccountId | - find:fixedDepositProductsTemplate.accountingMappingOptions.expenseAccountOptions:'id':'name' }} -
+

Penalties to Specific Income Accounts

-

Income

+ -
- Income from fees: - {{ fixedDepositProduct.incomeFromFeeAccountId | - find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} - Income from penalties: - {{ fixedDepositProduct.incomeFromPenaltyAccountId | - find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} -
+ + + + -
+ +
+ + -

Advanced Accounting Rules

+ + - - -
- -

Fund Sources for Payment Channels

- -
Penalty + {{ penaltyIncome.chargeId | find:fixedDepositProductsTemplate.penaltyOptions:'id':'name' }} + Income Account + {{ penaltyIncome.incomeAccountId | + find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} +
- - - - - - - - - - - - - - -
Payment Type - {{ paymentFundSource.paymentTypeId | find:fixedDepositProductsTemplate.paymentTypeOptions:'id':'name' }} - Fund Source - {{ paymentFundSource.fundSourceAccountId | - find:fixedDepositProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }} -
- -
- -
- -

Fees to Specific Income Accounts

- - - - - - - - - - - - - - - - -
Fees - {{ feesIncome.chargeId | find:fixedDepositProductsTemplate.chargeOptions:'id':'name' }} - Income Account - {{ feesIncome.incomeAccountId | - find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} -
- -
- -
- -

Penalties to Specific Income Accounts

- - - - - - - - - - - - - - - - -
Penalty - {{ penaltyIncome.chargeId | find:fixedDepositProductsTemplate.penaltyOptions:'id':'name' }} - Income Account - {{ penaltyIncome.incomeAccountId | - find:fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} -
- -
+
diff --git a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.ts b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.ts index 4699723f8..3b65cded7 100644 --- a/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.ts +++ b/src/app/products/fixed-deposit-products/fixed-deposit-product-stepper/fixed-deposit-product-preview-step/fixed-deposit-product-preview-step.component.ts @@ -1,5 +1,7 @@ -import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, SimpleChanges, OnChanges } from '@angular/core'; import { trigger, state, transition, animate, style } from '@angular/animations'; +import { Accounting } from 'app/core/utils/accounting'; +import { OptionData } from 'app/shared/models/option-data.model'; @Component({ selector: 'mifosx-fixed-deposit-product-preview-step', @@ -13,7 +15,7 @@ import { trigger, state, transition, animate, style } from '@angular/animations' ]) ] }) -export class FixedDepositProductPreviewStepComponent implements OnInit { +export class FixedDepositProductPreviewStepComponent implements OnInit, OnChanges { @Input() fixedDepositProductsTemplate: any; @Input() chartSlabsDisplayedColumns: any[]; @@ -29,9 +31,55 @@ export class FixedDepositProductPreviewStepComponent implements OnInit { expandChartSlabIndex: number[] = []; - constructor() { } + accountingMappings: any = {}; + accountingRule: OptionData; + + constructor(private accounting: Accounting) { } ngOnInit() { + this.setCurrentValues(); + } + + ngOnChanges(changes: SimpleChanges): void { + this.setCurrentValues(); + } + + setCurrentValues(): void { + if (this.isCashOrAccrualAccounting()) { + this.accountingRule = this.accounting.getAccountingRuleFrom(this.fixedDepositProduct.accountingRule); + + const assetAccountData = this.fixedDepositProductsTemplate.accountingMappingOptions.assetAccountOptions || []; + const incomeAccountData = this.fixedDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions || []; + const expenseAccountData = this.fixedDepositProductsTemplate.accountingMappingOptions.expenseAccountOptions || []; + const liabilityAccountData = this.fixedDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions || []; + + this.accountingMappings = { + 'savingsReferenceAccount': this.accounting.glAccountLookUp(this.fixedDepositProduct.savingsReferenceAccountId, assetAccountData), + 'savingsControlAccount': this.accounting.glAccountLookUp(this.fixedDepositProduct.savingsControlAccountId, liabilityAccountData), + 'transfersInSuspenseAccount': this.accounting.glAccountLookUp(this.fixedDepositProduct.transfersInSuspenseAccountId, liabilityAccountData), + 'interestOnSavingsAccount': this.accounting.glAccountLookUp(this.fixedDepositProduct.interestOnSavingsAccountId, expenseAccountData), + 'incomeFromFeeAccount': this.accounting.glAccountLookUp(this.fixedDepositProduct.incomeFromFeeAccountId, incomeAccountData), + 'incomeFromPenaltyAccount': this.accounting.glAccountLookUp(this.fixedDepositProduct.incomeFromPenaltyAccountId, incomeAccountData) + }; + + if (this.isAccrualAccounting()) { + this.accountingMappings['feeReceivableAccount'] = this.accounting.glAccountLookUp(this.fixedDepositProduct.feesReceivableAccountId, assetAccountData); + this.accountingMappings['penaltyReceivableAccount'] = this.accounting.glAccountLookUp(this.fixedDepositProduct.penaltiesReceivableAccountId, assetAccountData); + this.accountingMappings['interestPayableAccount'] = this.accounting.glAccountLookUp(this.fixedDepositProduct.interestPayableAccountId, liabilityAccountData); + } + } + } + + isNoneAccounting(): boolean { + return this.accounting.isNoneAccountingRuleId(this.fixedDepositProduct.accountingRule); + } + + isCashOrAccrualAccounting(): boolean { + return this.accounting.isCashOrAccrualAccountingRuleId(this.fixedDepositProduct.accountingRule); + } + + isAccrualAccounting(): boolean { + return this.accounting.isAccrualAccountingRuleId(this.fixedDepositProduct.accountingRule); } } diff --git a/src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-general-tab/fixed-deposit-general-tab.component.html b/src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-general-tab/fixed-deposit-general-tab.component.html index 6040264c0..d946895bb 100644 --- a/src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-general-tab/fixed-deposit-general-tab.component.html +++ b/src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-general-tab/fixed-deposit-general-tab.component.html @@ -367,141 +367,105 @@ -
- Type: - {{ fixedDepositProductData.accountingRule.value }} -
+ + -
+
-

Assets

+

Advanced Accounting Rules

-
- Saving reference: - {{ fixedDepositProductData.accountingMappings.savingsReferenceAccount.name }} -
+ -

Liabilities

+
-
- Saving control: - {{ fixedDepositProductData.accountingMappings.savingsControlAccount.name }} - Savings transfers in suspense: - {{ fixedDepositProductData.accountingMappings.transfersInSuspenseAccount.name }} -
- -

Expenses

- -
- Interest on savings: - {{ fixedDepositProductData.accountingMappings.interestOnSavingsAccount.name }} -
- -

Income

- -
- Income from fees: - {{ fixedDepositProductData.accountingMappings.incomeFromFeeAccount.name }} - Income from penalties: - {{ fixedDepositProductData.accountingMappings.incomeFromPenaltyAccount.name }} -
- -
+

Configure Fund Sources for Payment Channels

-

Advanced Accounting Rules

+ - + + + + -
+ + + + -
-

Configure Fund Sources for Payment Channels

+
+ -
Payment Type + {{ paymentFundSource.paymentType.name }} + Fund Source + {{ paymentFundSource.fundSourceAccount.name }} +
+
- - Payment Type - - {{ paymentFundSource.paymentType.name }} - - +
- - Fund Source - - {{ paymentFundSource.fundSourceAccount.name }} - - +
- - +

Fees to Specific Income Accounts

- + - + + + + -
+ +
+ + -

Fees to Specific Income Accounts

+ + -
Fees + {{ feesIncome.charge.name }} + Income Account + {{ feesIncome.incomeAccount.name }} +
+
- - Fees - - {{ feesIncome.charge.name }} - - +
- - Income Account - - {{ feesIncome.incomeAccount.name }} - - +
- - +

Penalties to Specific Income Accounts

- + - + + + + -
+ +
+ + -

Penalties to Specific Income Accounts

+ + -
Penalty + {{ penaltyIncome.charge.name }} + Income Account + {{ penaltyIncome.incomeAccount.name }} +
- - - - - - - - - - - - - - -
Penalty - {{ penaltyIncome.charge.name }} - Income Account - {{ penaltyIncome.incomeAccount.name }} -
- -
+
diff --git a/src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-general-tab/fixed-deposit-general-tab.component.scss b/src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-general-tab/fixed-deposit-general-tab.component.scss index ffb197031..15237d40f 100644 --- a/src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-general-tab/fixed-deposit-general-tab.component.scss +++ b/src/app/products/fixed-deposit-products/view-fixed-deposit-product/fixed-deposit-general-tab/fixed-deposit-general-tab.component.scss @@ -1,5 +1,9 @@ @import "assets/styles/helper"; +.container { + width: 100%; +} + .tab-container { padding: 1%; margin: 1%; @@ -11,10 +15,6 @@ color: $status-approved; } -table { - width: 100%; -} - .mat-elevation-z1 { margin: 1em 0 1.5em 0; } diff --git a/src/app/products/recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component.ts b/src/app/products/recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component.ts index 4d70c2d22..5b872284a 100644 --- a/src/app/products/recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component.ts +++ b/src/app/products/recurring-deposit-products/create-recurring-deposit-product/create-recurring-deposit-product.component.ts @@ -14,6 +14,7 @@ import { RecurringDepositProductAccountingStepComponent } from '../recurring-dep /** Custom Services */ import { ProductsService } from 'app/products/products.service'; import { SettingsService } from 'app/settings/settings.service'; +import { Accounting } from 'app/core/utils/accounting'; @Component({ selector: 'mifosx-create-recurring-deposit-product', @@ -31,7 +32,7 @@ export class CreateRecurringDepositProductComponent implements OnInit { @ViewChild(RecurringDepositProductAccountingStepComponent, { static: true }) recurringDepositProductAccountingStep: RecurringDepositProductAccountingStepComponent; recurringDepositProductsTemplate: any; - accountingRuleData = ['None', 'Cash']; + accountingRuleData: string[] = []; /** * @param {ActivatedRoute} route Activated Route. @@ -43,10 +44,12 @@ export class CreateRecurringDepositProductComponent implements OnInit { constructor(private route: ActivatedRoute, private productsService: ProductsService, private router: Router, - private settingsService: SettingsService) { + private settingsService: SettingsService, + private accounting: Accounting) { this.route.data.subscribe((data: { recurringDepositProductsTemplate: any }) => { this.recurringDepositProductsTemplate = data.recurringDepositProductsTemplate; }); + this.accountingRuleData = this.accounting.getAccountingRulesForSavings(); } ngOnInit() { diff --git a/src/app/products/recurring-deposit-products/edit-recurring-deposit-product/edit-recurring-deposit-product.component.ts b/src/app/products/recurring-deposit-products/edit-recurring-deposit-product/edit-recurring-deposit-product.component.ts index 9230ee4d1..46a3f5d6a 100644 --- a/src/app/products/recurring-deposit-products/edit-recurring-deposit-product/edit-recurring-deposit-product.component.ts +++ b/src/app/products/recurring-deposit-products/edit-recurring-deposit-product/edit-recurring-deposit-product.component.ts @@ -14,6 +14,7 @@ import { RecurringDepositProductAccountingStepComponent } from '../recurring-dep /** Custom Services */ import { ProductsService } from 'app/products/products.service'; import { SettingsService } from 'app/settings/settings.service'; +import { Accounting } from 'app/core/utils/accounting'; @Component({ selector: 'mifosx-edit-recurring-deposit-product', @@ -31,7 +32,7 @@ export class EditRecurringDepositProductComponent implements OnInit { @ViewChild(RecurringDepositProductAccountingStepComponent, { static: true }) recurringDepositProductAccountingStep: RecurringDepositProductAccountingStepComponent; recurringDepositProductsTemplate: any; - accountingRuleData = ['None', 'Cash']; + accountingRuleData: string[] = []; /** * @param {ActivatedRoute} route Activated Route. @@ -43,10 +44,12 @@ export class EditRecurringDepositProductComponent implements OnInit { constructor(private route: ActivatedRoute, private productsService: ProductsService, private router: Router, - private settingsService: SettingsService) { + private settingsService: SettingsService, + private accounting: Accounting) { this.route.data.subscribe((data: { recurringDepositProductAndTemplate: any }) => { this.recurringDepositProductsTemplate = data.recurringDepositProductAndTemplate; }); + this.accountingRuleData = this.accounting.getAccountingRulesForSavings(); } ngOnInit() { diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-accounting-step/recurring-deposit-product-accounting-step.component.html b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-accounting-step/recurring-deposit-product-accounting-step.component.html index 21a970b36..e66fc7ee4 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-accounting-step/recurring-deposit-product-accounting-step.component.html +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-accounting-step/recurring-deposit-product-accounting-step.component.html @@ -11,94 +11,93 @@ -
+
-

Assets

+

{{'labels.heading.Assets' | translate}}

- - Saving reference - - - ({{ assetAccount.glCode }}) {{ assetAccount.name }} - - - - Saving reference is required - - + + + + + + + + -

Liabilities

+

{{'labels.heading.Liabilities' | translate}}

- - Saving control - - - ({{ liabilityAccount.glCode }}) {{ liabilityAccount.name }} - - - - Saving control is required - - + + - - Savings transfers in suspense - - - ({{ liabilityAccount.glCode }}) {{ liabilityAccount.name }} - - - - Savings transfers in suspense is required - - + + + + + -

Expenses

+

{{'labels.heading.Expenses' | translate}}

- - Interest on savings - - - ({{ expenseAccount.glCode }}) {{ expenseAccount.name }} - - - - Interest on savings is required - - + + -

Income

+

{{'labels.heading.Income' | translate}}

- - Income from fees - - - ({{ incomeAccount.glCode }}) {{ incomeAccount.name }} - - - - Income from fees Repayments is required - - + + - - Income from penalties - - - ({{ incomeAccount.glCode }}) {{ incomeAccount.name }} - - - - Income from penalties is required - - + + diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-accounting-step/recurring-deposit-product-accounting-step.component.ts b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-accounting-step/recurring-deposit-product-accounting-step.component.ts index 210f10a18..04b6faf1b 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-accounting-step/recurring-deposit-product-accounting-step.component.ts +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-accounting-step/recurring-deposit-product-accounting-step.component.ts @@ -7,6 +7,7 @@ import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.co import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base'; import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base'; +import { Accounting } from 'app/core/utils/accounting'; @Component({ selector: 'mifosx-recurring-deposit-product-accounting-step', @@ -33,7 +34,8 @@ export class RecurringDepositProductAccountingStepComponent implements OnInit { feesPenaltyIncomeDisplayedColumns: string[] = ['chargeId', 'incomeAccountId', 'actions']; constructor(private formBuilder: UntypedFormBuilder, - public dialog: MatDialog) { + public dialog: MatDialog, + private accounting: Accounting) { this.createrecurringDepositProductAccountingForm(); this.setConditionalControls(); } @@ -52,10 +54,11 @@ export class RecurringDepositProductAccountingStepComponent implements OnInit { } assignAccountingStepData() { - if (this.recurringDepositProductsTemplate.accountingRule.id === 2) { - this.recurringDepositProductAccountingForm.patchValue({ - 'accountingRule': this.recurringDepositProductsTemplate.accountingRule.id - }); + this.recurringDepositProductAccountingForm.patchValue({ + 'accountingRule': this.recurringDepositProductsTemplate.accountingRule.id + }); + if (this.isCashOrAccrualAccounting()) { + this.recurringDepositProductAccountingForm.patchValue({ 'savingsReferenceAccountId': this.recurringDepositProductsTemplate.accountingMappings.savingsReferenceAccount.id, 'savingsControlAccountId': this.recurringDepositProductsTemplate.accountingMappings.savingsControlAccount.id, @@ -64,6 +67,15 @@ export class RecurringDepositProductAccountingStepComponent implements OnInit { 'incomeFromPenaltyAccountId': this.recurringDepositProductsTemplate.accountingMappings.incomeFromPenaltyAccount.id, 'interestOnSavingsAccountId': this.recurringDepositProductsTemplate.accountingMappings.interestOnSavingsAccount.id }); + + if (this.isAccrualAccounting()) { + this.recurringDepositProductAccountingForm.patchValue({ + 'feesReceivableAccountId': this.recurringDepositProductsTemplate.accountingMappings.feeReceivableAccount.id, + 'penaltiesReceivableAccountId': this.recurringDepositProductsTemplate.accountingMappings.penaltyReceivableAccount.id, + 'interestPayableAccountId': this.recurringDepositProductsTemplate.accountingMappings.interestPayableAccount.id + }); + } + if (this.recurringDepositProductsTemplate.paymentChannelToFundSourceMappings || this.recurringDepositProductsTemplate.feeToIncomeAccountMappings || this.recurringDepositProductsTemplate.penaltyToIncomeAccountMappings) { this.recurringDepositProductAccountingForm.patchValue({ 'advancedAccountingRules': true @@ -111,7 +123,7 @@ export class RecurringDepositProductAccountingStepComponent implements OnInit { setConditionalControls() { this.recurringDepositProductAccountingForm.get('accountingRule').valueChanges .subscribe((accountingRule: any) => { - if (accountingRule === 2) { + if (accountingRule === 2 || accountingRule === 3) { this.recurringDepositProductAccountingForm.addControl('savingsReferenceAccountId', new UntypedFormControl('', Validators.required)); this.recurringDepositProductAccountingForm.addControl('savingsControlAccountId', new UntypedFormControl('', Validators.required)); this.recurringDepositProductAccountingForm.addControl('transfersInSuspenseAccountId', new UntypedFormControl('', Validators.required)); @@ -120,6 +132,12 @@ export class RecurringDepositProductAccountingStepComponent implements OnInit { this.recurringDepositProductAccountingForm.addControl('incomeFromPenaltyAccountId', new UntypedFormControl('', Validators.required)); this.recurringDepositProductAccountingForm.addControl('advancedAccountingRules', new UntypedFormControl(false)); + if (accountingRule === 3) { + this.recurringDepositProductAccountingForm.addControl('feesReceivableAccountId', new UntypedFormControl('', Validators.required)); + this.recurringDepositProductAccountingForm.addControl('penaltiesReceivableAccountId', new UntypedFormControl('', Validators.required)); + this.recurringDepositProductAccountingForm.addControl('interestPayableAccountId', new UntypedFormControl('', Validators.required)); + } + this.recurringDepositProductAccountingForm.get('advancedAccountingRules').valueChanges .subscribe((advancedAccountingRules: boolean) => { if (advancedAccountingRules) { @@ -144,6 +162,9 @@ export class RecurringDepositProductAccountingStepComponent implements OnInit { this.recurringDepositProductAccountingForm.removeControl('incomeFromInterestId'); this.recurringDepositProductAccountingForm.removeControl('advancedAccountingRules'); this.recurringDepositProductAccountingForm.removeControl('escheatLiabilityId'); + this.recurringDepositProductAccountingForm.removeControl('feesReceivableAccountId'); + this.recurringDepositProductAccountingForm.removeControl('penaltiesReceivableAccountId'); + this.recurringDepositProductAccountingForm.removeControl('interestPayableAccountId'); } }); } @@ -269,4 +290,12 @@ export class RecurringDepositProductAccountingStepComponent implements OnInit { return this.recurringDepositProductAccountingForm.value; } + isCashOrAccrualAccounting(): boolean { + return this.accounting.isCashOrAccrualAccountingRuleId(this.recurringDepositProductAccountingForm.value.accountingRule); + } + + isAccrualAccounting(): boolean { + return this.accounting.isAccrualAccountingRuleId(this.recurringDepositProductAccountingForm.value.accountingRule); + } + } diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.html b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.html index 9fc28825e..6b3ac89b9 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.html +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.html @@ -320,131 +320,96 @@ -
- Type: - {{ accountingRuleData[recurringDepositProduct.accountingRule-1] }} -
+ + -
+
-

Assets

+

Advanced Accounting Rules

+ + + +
+ +

Fund Sources for Payment Channels

+ + + + + + + + + + + + + + + + +
Payment Type + {{ paymentFundSource.paymentTypeId | find:recurringDepositProductsTemplate.paymentTypeOptions:'id':'name' }} + Fund Source + {{ paymentFundSource.fundSourceAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }} +
-
- Saving reference: - {{ recurringDepositProduct.savingsReferenceAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }}
-

Liabilities

+
+ +

Fees to Specific Income Accounts

+ + + + + + + + + + + + + + + + +
Fees + {{ feesIncome.chargeId | find:recurringDepositProductsTemplate.chargeOptions:'id':'name' }} + Income Account + {{ feesIncome.incomeAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} +
-
- Saving control: - {{ recurringDepositProduct.savingsControlAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }} - Savings transfers in suspense: - {{ recurringDepositProduct.transfersInSuspenseAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }}
-

Expenses

+
-
- Interest on savings: - {{ recurringDepositProduct.interestOnSavingsAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.expenseAccountOptions:'id':'name' }} -
+

Penalties to Specific Income Accounts

-

Income

+ -
- Income from fees: - {{ recurringDepositProduct.incomeFromFeeAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} - Income from penalties: - {{ recurringDepositProduct.incomeFromPenaltyAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} -
+ + + + -
+ +
+ + -

Advanced Accounting Rules

+ + - - -
- -

Fund Sources for Payment Channels

- -
Penalty + {{ penaltyIncome.chargeId | find:recurringDepositProductsTemplate.penaltyOptions:'id':'name' }} + Income Account + {{ penaltyIncome.incomeAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} +
- - - - - - - - - - - - - - -
Payment Type - {{ paymentFundSource.paymentTypeId | find:recurringDepositProductsTemplate.paymentTypeOptions:'id':'name' }} - Fund Source - {{ paymentFundSource.fundSourceAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }} -
- -
- -
- -

Fees to Specific Income Accounts

- - - - - - - - - - - - - - - - -
Fees - {{ feesIncome.chargeId | find:recurringDepositProductsTemplate.chargeOptions:'id':'name' }} - Income Account - {{ feesIncome.incomeAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} -
- -
- -
- -

Penalties to Specific Income Accounts

- - - - - - - - - - - - - - - - -
Penalty - {{ penaltyIncome.chargeId | find:recurringDepositProductsTemplate.penaltyOptions:'id':'name' }} - Income Account - {{ penaltyIncome.incomeAccountId | find:recurringDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} -
- -
+
diff --git a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.ts b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.ts index 292a05068..a9752994f 100644 --- a/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.ts +++ b/src/app/products/recurring-deposit-products/recurring-deposit-product-stepper/recurring-deposit-product-preview-step/recurring-deposit-product-preview-step.component.ts @@ -1,5 +1,7 @@ -import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core'; import { trigger, state, transition, animate, style } from '@angular/animations'; +import { OptionData } from 'app/shared/models/option-data.model'; +import { Accounting } from 'app/core/utils/accounting'; @Component({ selector: 'mifosx-recurring-deposit-product-preview-step', @@ -13,7 +15,7 @@ import { trigger, state, transition, animate, style } from '@angular/animations' ]) ] }) -export class RecurringDepositProductPreviewStepComponent implements OnInit { +export class RecurringDepositProductPreviewStepComponent implements OnInit, OnChanges { @Input() recurringDepositProductsTemplate: any; @Input() chartSlabsDisplayedColumns: any[]; @@ -29,9 +31,55 @@ export class RecurringDepositProductPreviewStepComponent implements OnInit { expandChartSlabIndex: number[] = []; - constructor() { } + accountingMappings: any = {}; + accountingRule: OptionData; + + constructor(private accounting: Accounting) { } ngOnInit() { + this.setCurrentValues(); + } + + ngOnChanges(changes: SimpleChanges): void { + this.setCurrentValues(); + } + + setCurrentValues(): void { + if (this.isCashOrAccrualAccounting()) { + this.accountingRule = this.accounting.getAccountingRuleFrom(this.recurringDepositProduct.accountingRule); + + const assetAccountData = this.recurringDepositProductsTemplate.accountingMappingOptions.assetAccountOptions || []; + const incomeAccountData = this.recurringDepositProductsTemplate.accountingMappingOptions.incomeAccountOptions || []; + const expenseAccountData = this.recurringDepositProductsTemplate.accountingMappingOptions.expenseAccountOptions || []; + const liabilityAccountData = this.recurringDepositProductsTemplate.accountingMappingOptions.liabilityAccountOptions || []; + + this.accountingMappings = { + 'savingsReferenceAccount': this.accounting.glAccountLookUp(this.recurringDepositProduct.savingsReferenceAccountId, assetAccountData), + 'savingsControlAccount': this.accounting.glAccountLookUp(this.recurringDepositProduct.savingsControlAccountId, liabilityAccountData), + 'transfersInSuspenseAccount': this.accounting.glAccountLookUp(this.recurringDepositProduct.transfersInSuspenseAccountId, liabilityAccountData), + 'interestOnSavingsAccount': this.accounting.glAccountLookUp(this.recurringDepositProduct.interestOnSavingsAccountId, expenseAccountData), + 'incomeFromFeeAccount': this.accounting.glAccountLookUp(this.recurringDepositProduct.incomeFromFeeAccountId, incomeAccountData), + 'incomeFromPenaltyAccount': this.accounting.glAccountLookUp(this.recurringDepositProduct.incomeFromPenaltyAccountId, incomeAccountData) + }; + + if (this.isAccrualAccounting()) { + this.accountingMappings['feeReceivableAccount'] = this.accounting.glAccountLookUp(this.recurringDepositProduct.feesReceivableAccountId, assetAccountData); + this.accountingMappings['penaltyReceivableAccount'] = this.accounting.glAccountLookUp(this.recurringDepositProduct.penaltiesReceivableAccountId, assetAccountData); + this.accountingMappings['interestPayableAccount'] = this.accounting.glAccountLookUp(this.recurringDepositProduct.interestPayableAccountId, liabilityAccountData); + } + } + } + + isNoneAccounting(): boolean { + return this.accounting.isNoneAccountingRuleId(this.recurringDepositProduct.accountingRule); + } + + isCashOrAccrualAccounting(): boolean { + return this.accounting.isCashOrAccrualAccountingRuleId(this.recurringDepositProduct.accountingRule); + } + + isAccrualAccounting(): boolean { + return this.accounting.isAccrualAccountingRuleId(this.recurringDepositProduct.accountingRule); } } diff --git a/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.html b/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.html index 55e8993a3..fda26f2df 100644 --- a/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.html +++ b/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.html @@ -352,141 +352,102 @@ -
- Type: - {{ recurringDepositProduct.accountingRule.value }} -
+ + -
+
-

Assets

+

Advanced Accounting Rules

-
- Saving reference: - {{ recurringDepositProduct.accountingMappings.savingsReferenceAccount.name }} + + +
+

Configure Fund Sources for Payment Channels

+ + + + + + + + + + + + + + + + +
Payment Type + {{ paymentFundSource.paymentType.name }} + Fund Source + {{ paymentFundSource.fundSourceAccount.name }} +
-

Liabilities

-
- Saving control: - {{ recurringDepositProduct.accountingMappings.savingsControlAccount.name }} - Savings transfers in suspense: - {{ recurringDepositProduct.accountingMappings.transfersInSuspenseAccount.name }} +
+ + +

Fees to Specific Income Accounts

+ + + + + + + + + + + + + + + + +
Fees + {{ feesIncome.charge.name }} + Income Account + {{ feesIncome.incomeAccount.name }} +
+
-

Expenses

+
-
- Interest on savings: - {{ recurringDepositProduct.accountingMappings.interestOnSavingsAccount.name }} - - Write-off: - {{ recurringDepositProduct.accountingMappings.writeOffAccount.name }} - -
+

Penalties to Specific Income Accounts

-

Income

+ -
- Income from fees: - {{ recurringDepositProduct.accountingMappings.incomeFromFeeAccount.name }} - Income from penalties: - {{ recurringDepositProduct.accountingMappings.incomeFromPenaltyAccount.name }} -
+ + + + -
+ +
+ + -

Advanced Accounting Rules

+ + - - -
-

Configure Fund Sources for Payment Channels

- -
Penalty + {{ penaltyIncome.charge.name }} + Income Account + {{ penaltyIncome.incomeAccount.name }} +
- - - - - - - - - - - - - - -
Payment Type - {{ paymentFundSource.paymentType.name }} - Fund Source - {{ paymentFundSource.fundSourceAccount.name }} -
-
- - -
- - -

Fees to Specific Income Accounts

- - - - - - - - - - - - - - - - -
Fees - {{ feesIncome.charge.name }} - Income Account - {{ feesIncome.incomeAccount.name }} -
- -
- -
- -

Penalties to Specific Income Accounts

- - - - - - - - - - - - - - - - -
Penalty - {{ penaltyIncome.charge.name }} - Income Account - {{ penaltyIncome.incomeAccount.name }} -
- -
+
diff --git a/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.scss b/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.scss index 081f8a5f9..20a014539 100644 --- a/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.scss +++ b/src/app/products/recurring-deposit-products/view-recurring-deposit-product/recurring-deposit-general-tab/recurring-deposit-general-tab.component.scss @@ -1,5 +1,9 @@ @import "assets/styles/helper"; +.container { + width: 100%; +} + .tab-container { padding: 1%; margin: 1%; @@ -11,27 +15,10 @@ color: $status-approved; } -table { - width: 100%; -} - .mat-elevation-z1 { margin: 1em 0 1.5em 0; } -h2, h3, h4 { - margin: 0; - font-weight: 500; -} - -span { - margin: 0.5em 0; -} - -.margin-t { - margin-top: 1em; -} - .interestCarts { float:right; } diff --git a/src/app/products/saving-products/create-saving-product/create-saving-product.component.ts b/src/app/products/saving-products/create-saving-product/create-saving-product.component.ts index 62ef18a84..363325e26 100644 --- a/src/app/products/saving-products/create-saving-product/create-saving-product.component.ts +++ b/src/app/products/saving-products/create-saving-product/create-saving-product.component.ts @@ -13,6 +13,7 @@ import { SavingProductAccountingStepComponent } from '../saving-product-stepper/ /** Custom Services */ import { ProductsService } from 'app/products/products.service'; import { SettingsService } from 'app/settings/settings.service'; +import { Accounting } from 'app/core/utils/accounting'; @Component({ selector: 'mifosx-create-saving-product', @@ -29,7 +30,7 @@ export class CreateSavingProductComponent implements OnInit { @ViewChild(SavingProductAccountingStepComponent, { static: true }) savingProductAccountingStep: SavingProductAccountingStepComponent; savingProductsTemplate: any; - accountingRuleData = ['None', 'Cash']; + accountingRuleData: string[] = []; /** * @param {ActivatedRoute} route Activated Route. @@ -41,10 +42,12 @@ export class CreateSavingProductComponent implements OnInit { constructor(private route: ActivatedRoute, private productsService: ProductsService, private router: Router, - private settingsService: SettingsService) { + private settingsService: SettingsService, + private accounting: Accounting) { this.route.data.subscribe((data: { savingProductsTemplate: any }) => { this.savingProductsTemplate = data.savingProductsTemplate; }); + this.accountingRuleData = this.accounting.getAccountingRulesForSavings(); } ngOnInit() { diff --git a/src/app/products/saving-products/edit-saving-product/edit-saving-product.component.ts b/src/app/products/saving-products/edit-saving-product/edit-saving-product.component.ts index 04a77648c..b3f597acf 100644 --- a/src/app/products/saving-products/edit-saving-product/edit-saving-product.component.ts +++ b/src/app/products/saving-products/edit-saving-product/edit-saving-product.component.ts @@ -13,6 +13,7 @@ import { SavingProductAccountingStepComponent } from '../saving-product-stepper/ /** Custom Services */ import { ProductsService } from 'app/products/products.service'; import { SettingsService } from 'app/settings/settings.service'; +import { Accounting } from 'app/core/utils/accounting'; @Component({ @@ -30,7 +31,7 @@ export class EditSavingProductComponent implements OnInit { @ViewChild(SavingProductAccountingStepComponent, { static: true }) savingProductAccountingStep: SavingProductAccountingStepComponent; savingProductAndTemplate: any; - accountingRuleData = ['None', 'Cash']; + accountingRuleData: string[] = []; /** * @param {ActivatedRoute} route Activated Route. @@ -42,10 +43,12 @@ export class EditSavingProductComponent implements OnInit { constructor(private route: ActivatedRoute, private productsService: ProductsService, private router: Router, - private settingsService: SettingsService) { + private settingsService: SettingsService, + private accounting: Accounting) { this.route.data.subscribe((data: { savingProductAndTemplate: any }) => { this.savingProductAndTemplate = data.savingProductAndTemplate; }); + this.accountingRuleData = this.accounting.getAccountingRulesForSavings(); } ngOnInit() { diff --git a/src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.html b/src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.html index 5c11e9db9..aebc4503f 100644 --- a/src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.html +++ b/src/app/products/saving-products/saving-product-stepper/saving-product-accounting-step/saving-product-accounting-step.component.html @@ -10,7 +10,7 @@ -
+

{{'labels.heading.Assets' | translate}}

@@ -30,6 +30,22 @@ > + + + + + +

{{'labels.heading.Liabilities' | translate}}

@@ -50,6 +66,14 @@ > + + + - -

{{'labels.heading.Expenses' | translate}}

+ this.savingProductAccountingForm.setControl('paymentChannelToFundSourceMappings', + this.formBuilder.array((this.savingProductsTemplate.paymentChannelToFundSourceMappings || []).map((paymentFundSource: any) => ({ paymentTypeId: paymentFundSource.paymentType.id, fundSourceAccountId: paymentFundSource.fundSourceAccount.id })))); - this.savingProductAccountingForm.setControl('feeToIncomeAccountMappings', - this.formBuilder.array((this.savingProductsTemplate.feeToIncomeAccountMappings || []).map((feesIncome: any) => + this.savingProductAccountingForm.setControl('feeToIncomeAccountMappings', + this.formBuilder.array((this.savingProductsTemplate.feeToIncomeAccountMappings || []).map((feesIncome: any) => ({ chargeId: feesIncome.charge.id, incomeAccountId: feesIncome.incomeAccount.id })))); - this.savingProductAccountingForm.setControl('penaltyToIncomeAccountMappings', - this.formBuilder.array((this.savingProductsTemplate.penaltyToIncomeAccountMappings || []).map((penaltyIncome: any) => + this.savingProductAccountingForm.setControl('penaltyToIncomeAccountMappings', + this.formBuilder.array((this.savingProductsTemplate.penaltyToIncomeAccountMappings || []).map((penaltyIncome: any) => ({ chargeId: penaltyIncome.charge.id, incomeAccountId: penaltyIncome.incomeAccount.id })))); } } @@ -110,7 +120,7 @@ export class SavingProductAccountingStepComponent implements OnInit { setConditionalControls() { this.savingProductAccountingForm.get('accountingRule').valueChanges .subscribe((accountingRule: any) => { - if (accountingRule === 2) { + if (accountingRule === 2 || accountingRule === 3) { this.savingProductAccountingForm.addControl('savingsReferenceAccountId', new UntypedFormControl('', Validators.required)); this.savingProductAccountingForm.addControl('overdraftPortfolioControlId', new UntypedFormControl('', Validators.required)); this.savingProductAccountingForm.addControl('savingsControlAccountId', new UntypedFormControl('', Validators.required)); @@ -122,6 +132,12 @@ export class SavingProductAccountingStepComponent implements OnInit { this.savingProductAccountingForm.addControl('incomeFromInterestId', new UntypedFormControl('', Validators.required)); this.savingProductAccountingForm.addControl('advancedAccountingRules', new UntypedFormControl(false)); + if (accountingRule === 3) { + this.savingProductAccountingForm.addControl('feesReceivableAccountId', new UntypedFormControl('', Validators.required)); + this.savingProductAccountingForm.addControl('penaltiesReceivableAccountId', new UntypedFormControl('', Validators.required)); + this.savingProductAccountingForm.addControl('interestPayableAccountId', new UntypedFormControl('', Validators.required)); + } + if (this.isDormancyTrackingActive.value) { this.savingProductAccountingForm.addControl('escheatLiabilityId', new UntypedFormControl('', Validators.required)); } @@ -159,6 +175,9 @@ export class SavingProductAccountingStepComponent implements OnInit { this.savingProductAccountingForm.removeControl('incomeFromInterestId'); this.savingProductAccountingForm.removeControl('advancedAccountingRules'); this.savingProductAccountingForm.removeControl('escheatLiabilityId'); + this.savingProductAccountingForm.removeControl('feesReceivableAccountId'); + this.savingProductAccountingForm.removeControl('penaltiesReceivableAccountId'); + this.savingProductAccountingForm.removeControl('interestPayableAccountId'); } }); } @@ -293,4 +312,13 @@ export class SavingProductAccountingStepComponent implements OnInit { return this.savingProductAccountingForm.value; } + isCashOrAccrualAccounting(): boolean { + return ((this.savingProductAccountingForm.value.accountingRule === 2) || + (this.savingProductAccountingForm.value.accountingRule === 3)); + } + + isAccrualAccounting(): boolean { + return (this.savingProductAccountingForm.value.accountingRule === 3); + } + } diff --git a/src/app/products/saving-products/saving-product-stepper/saving-product-currency-step/saving-product-currency-step.component.ts b/src/app/products/saving-products/saving-product-stepper/saving-product-currency-step/saving-product-currency-step.component.ts index 0d91f2d97..cfa0363ab 100644 --- a/src/app/products/saving-products/saving-product-stepper/saving-product-currency-step/saving-product-currency-step.component.ts +++ b/src/app/products/saving-products/saving-product-stepper/saving-product-currency-step/saving-product-currency-step.component.ts @@ -25,7 +25,7 @@ export class SavingProductCurrencyStepComponent implements OnInit { this.savingProductCurrencyForm.patchValue({ 'currencyCode': this.savingProductsTemplate.currency.code || this.currencyData[0].code, 'digitsAfterDecimal': this.savingProductsTemplate.currency.code ? this.savingProductsTemplate.currency.decimalPlaces : 2, - 'inMultiplesOf': this.savingProductsTemplate.currency.inMultiplesOf + 'inMultiplesOf': this.savingProductsTemplate.currency.inMultiplesOf || 1 }); } diff --git a/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.html b/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.html index 160cb7782..6e5bb8d8f 100644 --- a/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.html +++ b/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.html @@ -191,141 +191,96 @@ -
- Type: - {{ accountingRuleData[savingProduct.accountingRule-1] }} -
+ + -
+
-

Assets

+

Advanced Accounting Rules

+ + + +
+ +

Fund Sources for Payment Channels

+ + + + + + + + + + + + + + + + +
Payment Type + {{ paymentFundSource.paymentTypeId | find:savingProductsTemplate.paymentTypeOptions:'id':'name' }} + Fund Source + {{ paymentFundSource.fundSourceAccountId | find:savingProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }} +
-
- Saving reference: - {{ savingProduct.savingsReferenceAccountId | find:savingProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }} - Overdraft portfolio: - {{ savingProduct.overdraftPortfolioControlId | find:savingProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }}
-

Liabilities

+
+ +

Fees to Specific Income Accounts

+ + + + + + + + + + + + + + + + +
Fees + {{ feesIncome.chargeId | find:savingProductsTemplate.chargeOptions:'id':'name' }} + Income Account + {{ feesIncome.incomeAccountId | find:savingProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} +
-
- Saving control: - {{ savingProduct.savingsControlAccountId | find:savingProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }} - Savings transfers in suspense: - {{ savingProduct.transfersInSuspenseAccountId | find:savingProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }} -
- Escheat liability: - {{ savingProduct.escheatLiabilityId | find:savingProductsTemplate.accountingMappingOptions.liabilityAccountOptions:'id':'name' }} -
-

Expenses

+
-
- Interest on savings: - {{ savingProduct.interestOnSavingsAccountId | find:savingProductsTemplate.accountingMappingOptions.expenseAccountOptions:'id':'name' }} - Write-off: - {{ savingProduct.writeOffAccountId | find:savingProductsTemplate.accountingMappingOptions.expenseAccountOptions:'id':'name' }} -
+

Penalties to Specific Income Accounts

-

Income

+ -
- Income from fees: - {{ savingProduct.incomeFromFeeAccountId | find:savingProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} - Income from penalties: - {{ savingProduct.incomeFromPenaltyAccountId | find:savingProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} - Overdraft Interest Income: - {{ savingProduct.incomeFromInterestId | find:savingProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} -
+ + + + -
+ +
+ + -

Advanced Accounting Rules

+ + - - -
- -

Fund Sources for Payment Channels

- -
Penalty + {{ penaltyIncome.chargeId | find:savingProductsTemplate.penaltyOptions:'id':'name' }} + Income Account + {{ penaltyIncome.incomeAccountId | find:savingProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} +
- - - - - - - - - - - - - - -
Payment Type - {{ paymentFundSource.paymentTypeId | find:savingProductsTemplate.paymentTypeOptions:'id':'name' }} - Fund Source - {{ paymentFundSource.fundSourceAccountId | find:savingProductsTemplate.accountingMappingOptions.assetAccountOptions:'id':'name' }} -
- -
- -
- -

Fees to Specific Income Accounts

- - - - - - - - - - - - - - - - -
Fees - {{ feesIncome.chargeId | find:savingProductsTemplate.chargeOptions:'id':'name' }} - Income Account - {{ feesIncome.incomeAccountId | find:savingProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} -
- -
- -
- -

Penalties to Specific Income Accounts

- - - - - - - - - - - - - - - - -
Penalty - {{ penaltyIncome.chargeId | find:savingProductsTemplate.penaltyOptions:'id':'name' }} - Income Account - {{ penaltyIncome.incomeAccountId | find:savingProductsTemplate.accountingMappingOptions.incomeAccountOptions:'id':'name' }} -
- -
+
diff --git a/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.scss b/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.scss index 87258dacb..5426ff16b 100644 --- a/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.scss +++ b/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.scss @@ -1,5 +1,47 @@ +@import "assets/styles/helper"; + +.tab-container { + padding: 1%; + margin: 1%; +} + +.mat-h3 { + margin-top: 10px !important; + font-weight: 300; + color: $status-approved; +} + +.mat-elevation-z1 { + margin: 1em 0 1.5em 0; +} + +.interestCarts { + float:right; +} + table { width: 100%; + + tr.incentives-row { + height: 0; + + > td { + padding: 0; + } + + .incentives { + overflow: hidden; + } + + .mat-card { + border-radius: 0; + + > h4 { + font-weight: 500; + margin: 0.5em 0 0; + } + } + } } .mat-elevation-z1 { diff --git a/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.ts b/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.ts index 4e663f609..e661df60b 100644 --- a/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.ts +++ b/src/app/products/saving-products/saving-product-stepper/saving-product-preview-step/saving-product-preview-step.component.ts @@ -1,11 +1,13 @@ -import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core'; +import { Accounting } from 'app/core/utils/accounting'; +import { OptionData } from 'app/shared/models/option-data.model'; @Component({ selector: 'mifosx-saving-product-preview-step', templateUrl: './saving-product-preview-step.component.html', styleUrls: ['./saving-product-preview-step.component.scss'] }) -export class SavingProductPreviewStepComponent implements OnInit { +export class SavingProductPreviewStepComponent implements OnInit, OnChanges { @Input() savingProductsTemplate: any; @Input() accountingRuleData: any; @@ -17,9 +19,56 @@ export class SavingProductPreviewStepComponent implements OnInit { paymentFundSourceDisplayedColumns: string[] = ['paymentTypeId', 'fundSourceAccountId']; feesPenaltyIncomeDisplayedColumns: string[] = ['chargeId', 'incomeAccountId']; - constructor() { } + accountingMappings: any = {}; + accountingRule: OptionData; + + constructor(private accounting: Accounting) { } ngOnInit() { + this.setCurrentValues(); + } + + ngOnChanges(changes: SimpleChanges): void { + this.setCurrentValues(); + } + + setCurrentValues(): void { + + if (this.isCashOrAccrualAccounting()) { + this.accountingRule = this.accounting.getAccountingRuleFrom(this.savingProduct.accountingRule); + + const assetAccountData = this.savingProductsTemplate.accountingMappingOptions.assetAccountOptions || []; + const incomeAccountData = this.savingProductsTemplate.accountingMappingOptions.incomeAccountOptions || []; + const expenseAccountData = this.savingProductsTemplate.accountingMappingOptions.expenseAccountOptions || []; + const liabilityAccountData = this.savingProductsTemplate.accountingMappingOptions.liabilityAccountOptions || []; + + this.accountingMappings = { + 'savingsReferenceAccount': this.accounting.glAccountLookUp(this.savingProduct.savingsReferenceAccountId, assetAccountData), + 'overdraftPortfolioControl': this.accounting.glAccountLookUp(this.savingProduct.overdraftPortfolioControlId, assetAccountData), + 'savingsControlAccount': this.accounting.glAccountLookUp(this.savingProduct.savingsControlAccountId, liabilityAccountData), + 'transfersInSuspenseAccount': this.accounting.glAccountLookUp(this.savingProduct.transfersInSuspenseAccountId, liabilityAccountData), + 'escheatLiability': this.accounting.glAccountLookUp(this.savingProduct.escheatLiabilityId, liabilityAccountData), + 'interestOnSavingsAccount': this.accounting.glAccountLookUp(this.savingProduct.interestOnSavingsAccountId, expenseAccountData), + 'writeOffAccount': this.accounting.glAccountLookUp(this.savingProduct.writeOffAccountId, expenseAccountData), + 'incomeFromFeeAccount': this.accounting.glAccountLookUp(this.savingProduct.incomeFromFeeAccountId, incomeAccountData), + 'incomeFromPenaltyAccount': this.accounting.glAccountLookUp(this.savingProduct.incomeFromPenaltyAccountId, incomeAccountData), + 'incomeFromInterest': this.accounting.glAccountLookUp(this.savingProduct.incomeFromInterestId, incomeAccountData) + }; + + if (this.isAccrualAccounting()) { + this.accountingMappings['feesReceivableAccount'] = this.accounting.glAccountLookUp(this.savingProduct.feesReceivableAccountId, assetAccountData); + this.accountingMappings['penaltiesReceivableAccount'] = this.accounting.glAccountLookUp(this.savingProduct.penaltiesReceivableAccountId, assetAccountData); + this.accountingMappings['interestPayableAccount'] = this.accounting.glAccountLookUp(this.savingProduct.interestPayableAccountId, liabilityAccountData); + } + } + } + + isCashOrAccrualAccounting(): boolean { + return this.accounting.isAccrualAccountingRuleId(this.savingProduct.accountingRule); + } + + isAccrualAccounting(): boolean { + return this.accounting.isAccrualAccounting(this.savingProduct.accountingRule); } } diff --git a/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.html b/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.html index 1b54379dc..ec8038944 100644 --- a/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.html +++ b/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.html @@ -201,145 +201,103 @@ -
- Type: - {{ savingProduct.accountingRule.value }} -
+ + + +
-
+

Advanced Accounting Rules

-

{{'labels.heading.Assets' | translate}}

- - - - + -

{{'labels.heading.Income' | translate}}

- - - - - - +
-

{{'labels.heading.Expenses' | translate}}

- - - - +

Fund Sources for Payment Channels

-

{{'labels.heading.Liabilities' | translate}}

- - - - - - + -
+ +
+ + -

Advanced Accounting Rules

+ + + + - + + -
+
Payment Type + {{ paymentFundSource.paymentType.name }} + Fund Source + ({{ paymentFundSource.fundSourceAccount.glCode }}) {{ paymentFundSource.fundSourceAccount.name }} +
-

Fund Sources for Payment Channels

+
- +
- -
- - +

Fees to Specific Income Accounts

- - - - +
Payment Type - {{ paymentFundSource.paymentType.name }} - Fund Source - ({{ paymentFundSource.fundSourceAccount.glCode }}) {{ paymentFundSource.fundSourceAccount.name }} -
- - + + + + -
Fees + {{ feesIncome.charge.name }} +
+ + Income Account + + ({{ feesIncome.incomeAccount.glCode }}) {{ feesIncome.incomeAccount.name }} + + -
+ + -
+ -

Fees to Specific Income Accounts

+
- +
- -
- - +

Penalties to Specific Income Accounts

- - - - +
Fees - {{ feesIncome.charge.name }} - Income Account - ({{ feesIncome.incomeAccount.glCode }}) {{ feesIncome.incomeAccount.name }} -
- - + + + + -
Penalty + {{ penaltyIncome.charge.name }} +
+ + Income Account + + ({{ penaltyIncome.incomeAccount.glCode }}) {{ penaltyIncome.incomeAccount.name }} + + -
+ + -
- -

Penalties to Specific Income Accounts

- - - - - - - - - - - - - - - - -
Penalty - {{ penaltyIncome.charge.name }} - Income Account - ({{ penaltyIncome.incomeAccount.glCode }}) {{ penaltyIncome.incomeAccount.name }} -
- -
+
diff --git a/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.scss b/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.scss index e71120a64..27927fffa 100644 --- a/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.scss +++ b/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.scss @@ -3,10 +3,6 @@ .tab-container { padding: 1%; margin: 1%; - - div: { - margin-top: 3px; - } } .mat-h3 { @@ -14,3 +10,53 @@ font-weight: 300; color: $status-approved; } + +.interestCarts { + float:right; +} + +table { + width: 100%; + + tr.incentives-row { + height: 0; + + > td { + padding: 0; + } + + .incentives { + overflow: hidden; + } + + .mat-card { + border-radius: 0; + + > h4 { + font-weight: 500; + margin: 0.5em 0 0; + } + } + } +} + +.mat-elevation-z1 { + margin: 1em 0 1.5em 0; +} + +h2, h3, h4 { + margin: 0; + font-weight: 500; +} + +span { + margin: 0.5em 0; +} + +mat-divider { + margin: 0 0 0.5em 0; +} + +.margin-t { + margin-top: 1em; +} diff --git a/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.ts b/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.ts index 85ea528c3..9adab5d2d 100644 --- a/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.ts +++ b/src/app/products/saving-products/view-saving-product/saving-product-general-tab/saving-product-general-tab.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { Accounting } from 'app/core/utils/accounting'; @Component({ selector: 'mifosx-saving-product-general-tab', @@ -13,7 +14,8 @@ export class SavingProductGeneralTabComponent implements OnInit { paymentFundSourceDisplayedColumns: string[] = ['paymentTypeId', 'fundSourceAccountId']; feesPenaltyIncomeDisplayedColumns: string[] = ['chargeId', 'incomeAccountId']; - constructor(private route: ActivatedRoute) { + constructor(private route: ActivatedRoute, + private accounting: Accounting) { this.route.data.subscribe((data: { savingProduct: any }) => { this.savingProduct = data.savingProduct; }); @@ -21,4 +23,13 @@ export class SavingProductGeneralTabComponent implements OnInit { ngOnInit() { } + + isCashOrAccrualAccounting(): boolean { + return this.accounting.isCashOrAccrualAccounting(this.savingProduct.accountingRule); + } + + isAccrualAccounting(): boolean { + return this.accounting.isAccrualAccounting(this.savingProduct.accountingRule); + } + } diff --git a/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.html b/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.html new file mode 100644 index 000000000..59c8655b2 --- /dev/null +++ b/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.html @@ -0,0 +1,59 @@ +
+ +
+ Type: + {{ accountingRule.value }} +
+ +
+ +

{{'labels.heading.Assets' | translate}}

+ + + + + + + + + +

{{'labels.heading.Liabilities' | translate}}

+ + + + + + + + + +

{{'labels.heading.Income' | translate}}

+ + + + + + + +

{{'labels.heading.Expenses' | translate}}

+ + + + +
+ +
\ No newline at end of file diff --git a/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.scss b/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.scss new file mode 100644 index 000000000..683cea090 --- /dev/null +++ b/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.scss @@ -0,0 +1,59 @@ +@import "assets/styles/colours"; + +.container { + padding: 1%; + margin: 1%; + width: 100%; +} + +table { + width: 100%; + + tr.incentives-row { + height: 0; + + > td { + padding: 0; + } + + .incentives { + overflow: hidden; + } + + .mat-card { + border-radius: 0; + + > h4 { + font-weight: 500; + margin: 0.5em 0 0; + } + } + } +} + +.mat-h4 { + margin-top: 10px !important; + font-weight: 200; + color: $status-approved; +} + +.mat-elevation-z1 { + margin: 1em 0 1.5em 0; +} + +h2, h3, h4 { + margin: 0; + font-weight: 500; +} + +span { + margin: 0.5em 0; +} + +mat-divider { + margin: 0 0 0.5em 0; +} + +.margin-t { + margin-top: 1em; +} diff --git a/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.spec.ts b/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.spec.ts new file mode 100644 index 000000000..8c71cc91f --- /dev/null +++ b/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewSavingsAccountingDetailsComponent } from './view-savings-accounting-details.component'; + +describe('ViewSavingsAccountingDetailsComponent', () => { + let component: ViewSavingsAccountingDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ViewSavingsAccountingDetailsComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ViewSavingsAccountingDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.ts b/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.ts new file mode 100644 index 000000000..4ccbafe94 --- /dev/null +++ b/src/app/shared/accounting/view-savings-accounting-details/view-savings-accounting-details.component.ts @@ -0,0 +1,28 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Accounting } from 'app/core/utils/accounting'; +import { OptionData } from 'app/shared/models/option-data.model'; + +@Component({ + selector: 'mifosx-view-savings-accounting-details', + templateUrl: './view-savings-accounting-details.component.html', + styleUrls: ['./view-savings-accounting-details.component.scss'] +}) +export class ViewSavingsAccountingDetailsComponent implements OnInit { + + @Input() accountingRule: OptionData; + @Input() accountingMappings: any[] = []; + + constructor(private accounting: Accounting) { } + + ngOnInit(): void { + } + + isCashOrAccrualAccounting(): boolean { + return this.accounting.isCashOrAccrualAccounting(this.accountingRule); + } + + isAccrualAccounting(): boolean { + return this.accounting.isAccrualAccounting(this.accountingRule); + } + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 7cb5fdb27..823029010 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -45,6 +45,7 @@ import { TransactionPaymentDetailComponent } from './transaction-payment-detail/ import { StepperButtonsComponent } from './steppers/stepper-buttons/stepper-buttons.component'; import { GlAccountSelectorComponent } from './accounting/gl-account-selector/gl-account-selector.component'; import { GlAccountDisplayComponent } from './accounting/gl-account-display/gl-account-display.component'; +import { ViewSavingsAccountingDetailsComponent } from './accounting/view-savings-accounting-details/view-savings-accounting-details.component'; /** * Shared Module @@ -96,7 +97,8 @@ import { GlAccountDisplayComponent } from './accounting/gl-account-display/gl-ac TransactionPaymentDetailComponent, StepperButtonsComponent, GlAccountSelectorComponent, - GlAccountDisplayComponent + GlAccountDisplayComponent, + ViewSavingsAccountingDetailsComponent ], exports: [ FileUploadComponent, @@ -126,7 +128,8 @@ import { GlAccountDisplayComponent } from './accounting/gl-account-display/gl-ac TransactionPaymentDetailComponent, StepperButtonsComponent, GlAccountSelectorComponent, - GlAccountDisplayComponent + GlAccountDisplayComponent, + ViewSavingsAccountingDetailsComponent, ] }) export class SharedModule { } diff --git a/src/assets/translations/cs-CS.json b/src/assets/translations/cs-CS.json index ab0a13ac2..9370a1bfd 100644 --- a/src/assets/translations/cs-CS.json +++ b/src/assets/translations/cs-CS.json @@ -474,6 +474,7 @@ "Transfer Client": "Převést klienta", "Transfer Clients": "Převod klientů", "Unassign Staff": "Zrušit přidělení personálu", + "Undo": "vrátit", "Undo Rejection": "Zrušit odmítnutí", "Undo Transfer": "Vrátit zpět převod", "Update Default Savings": "Aktualizovat výchozí úspory", @@ -1399,6 +1400,7 @@ "Interest Grace Periods": "Doby odkladu úroků", "Interest Method": "Zájmová metoda", "Interest Outstanding": "Neuvěřitelný zájem", + "Interest Payable": "Zájem päyable", "Interest Posted": "Zájem zveřejněn", "Interest Posting Period": "Období účtování úroků", "Interest Posting period": "Úrokové období zveřejnění", diff --git a/src/assets/translations/de-DE.json b/src/assets/translations/de-DE.json index 33de38b57..2da85d559 100644 --- a/src/assets/translations/de-DE.json +++ b/src/assets/translations/de-DE.json @@ -474,6 +474,7 @@ "Transfer Client": "Client übertragen", "Transfer Clients": "Kunden übertragen", "Unassign Staff": "Personalzuweisung aufheben", + "Undo": "Rückgängig machen", "Undo Rejection": "Ablehnung rückgängig machen", "Undo Transfer": "Übertragung rückgängig machen", "Update Default Savings": "Standardeinsparungen aktualisieren", @@ -1399,6 +1400,7 @@ "Interest Grace Periods": "Zinsschonfristen", "Interest Method": "Zinsmethode", "Interest Outstanding": "Ausstehende Zinsen", + "Interest Payable": "Interesse päylierbar", "Interest Posted": "Interesse gepostet", "Interest Posting Period": "Zinsbuchungszeitraum", "Interest Posting period": "Zinsbuchungszeitraum", diff --git a/src/assets/translations/en-US.json b/src/assets/translations/en-US.json index ded9ae1ab..7ead816a5 100644 --- a/src/assets/translations/en-US.json +++ b/src/assets/translations/en-US.json @@ -474,6 +474,7 @@ "Transfer Client": "Transfer Client", "Transfer Clients": "Transfer Clients", "Unassign Staff": "Unassign Staff", + "Undo": "Undo", "Undo Rejection": "Undo Rejection", "Undo Transfer": "Undo Transfer", "Update Default Savings": "Update Default Savings", @@ -1398,6 +1399,7 @@ "Interest Grace Periods": "Interest Grace Periods", "Interest Method": "Interest Method", "Interest Outstanding": "Interest Outstanding", + "Interest Payable": "Interest Payable", "Interest Posted": "Interest Posted", "Interest Posting Period": "Interest Posting Period", "Interest Posting period": "Interest Posting period", diff --git a/src/assets/translations/es-MX.json b/src/assets/translations/es-MX.json index f6a691cf8..069a31a0b 100644 --- a/src/assets/translations/es-MX.json +++ b/src/assets/translations/es-MX.json @@ -474,6 +474,7 @@ "Transfer Client": "Transferir cliente", "Transfer Clients": "Transferir Clientes", "Unassign Staff": "Desasignar personal", + "Undo": "Deshacer", "Undo Rejection": "Deshacer rechazo", "Undo Transfer": "Deshacer transferencia", "Update Default Savings": "Actualizar ahorros predeterminados", @@ -1399,6 +1400,7 @@ "Interest Grace Periods": "Períodos de gracia de intereses", "Interest Method": "Método de interés", "Interest Outstanding": "Interés pendiente", + "Interest Payable": "Intereses a pagar", "Interest Posted": "Interés publicado", "Interest Posting Period": "Período de contabilización de intereses", "Interest Posting period": "Periodo de contabilización de intereses", diff --git a/src/assets/translations/fr-FR.json b/src/assets/translations/fr-FR.json index ab9847f07..549959bc8 100644 --- a/src/assets/translations/fr-FR.json +++ b/src/assets/translations/fr-FR.json @@ -474,6 +474,7 @@ "Transfer Client": "Client de transfert", "Transfer Clients": "Transférer des clients", "Unassign Staff": "Annuler l'affectation du personnel", + "Undo": "annuler", "Undo Rejection": "Annuler le rejet", "Undo Transfer": "Annuler le transfert", "Update Default Savings": "Mettre à jour les économies par défaut", @@ -1399,6 +1400,7 @@ "Interest Grace Periods": "Délais de grâce des intérêts", "Interest Method": "Méthode d'intérêt", "Interest Outstanding": "Intérêts impayés", + "Interest Payable": "Intérêts payables", "Interest Posted": "Intérêt affiché", "Interest Posting Period": "Période de comptabilisation des intérêts", "Interest Posting period": "Période de comptabilisation des intérêts", diff --git a/src/assets/translations/it-IT.json b/src/assets/translations/it-IT.json index f0585cbcb..cf3c4a401 100644 --- a/src/assets/translations/it-IT.json +++ b/src/assets/translations/it-IT.json @@ -474,6 +474,7 @@ "Transfer Client": "Trasferisci cliente", "Transfer Clients": "Trasferisci clienti", "Unassign Staff": "Annulla assegnazione del personale", + "Undo": "Disfare", "Undo Rejection": "Annulla rifiuto", "Undo Transfer": "Annulla trasferimento", "Update Default Savings": "Aggiorna i risparmi predefiniti", @@ -1399,6 +1400,7 @@ "Interest Grace Periods": "Periodi di grazia degli interessi", "Interest Method": "Metodo degli interessi", "Interest Outstanding": "Interessi in sospeso", + "Interest Payable": "Interesse päyable", "Interest Posted": "Interesse pubblicato", "Interest Posting Period": "Periodo di registrazione degli interessi", "Interest Posting period": "Periodo di registrazione degli interessi", diff --git a/src/assets/translations/ko-KO.json b/src/assets/translations/ko-KO.json index a24fe901d..2552529a4 100644 --- a/src/assets/translations/ko-KO.json +++ b/src/assets/translations/ko-KO.json @@ -474,6 +474,7 @@ "Transfer Client": "클라이언트 이전", "Transfer Clients": "클라이언트 이전", "Unassign Staff": "직원 할당 해제", + "Undo": "실행 취소", "Undo Rejection": "거부 취소", "Undo Transfer": "전송 취소", "Update Default Savings": "기본 절감액 업데이트", @@ -1400,6 +1401,7 @@ "Interest Grace Periods": "이자 유예 기간", "Interest Method": "이자방식", "Interest Outstanding": "미결제 이자", + "Interest Payable": "관심있는 관심", "Interest Posted": "게시된 관심", "Interest Posting Period": "이자 공시 기간", "Interest Posting period": "이자 공시 기간", diff --git a/src/assets/translations/lt-LT.json b/src/assets/translations/lt-LT.json index 214715ada..628f46d36 100644 --- a/src/assets/translations/lt-LT.json +++ b/src/assets/translations/lt-LT.json @@ -474,6 +474,7 @@ "Transfer Client": "Perkelti klientą", "Transfer Clients": "Klientų perkėlimas", "Unassign Staff": "Atšaukti personalo priskyrimą", + "Undo": "Anuliuoti", "Undo Rejection": "Anuliuoti atmetimą", "Undo Transfer": "Anuliuoti perkėlimą", "Update Default Savings": "Atnaujinkite numatytuosius taupymo elementus", @@ -1399,6 +1400,7 @@ "Interest Grace Periods": "Palūkanų lengvatinis laikotarpis", "Interest Method": "Palūkanų metodas", "Interest Outstanding": "Susidomėjimas išskirtinis", + "Interest Payable": "Mokėtinos palūkanos", "Interest Posted": "Paskelbtas susidomėjimas", "Interest Posting Period": "Interesų skelbimo laikotarpis", "Interest Posting period": "Interesų paskelbimo laikotarpis", diff --git a/src/assets/translations/lv-LV.json b/src/assets/translations/lv-LV.json index 381cfdd82..ca22a847e 100644 --- a/src/assets/translations/lv-LV.json +++ b/src/assets/translations/lv-LV.json @@ -474,6 +474,7 @@ "Transfer Client": "Pārsūtīt klientu", "Transfer Clients": "Pārsūtīt klientus", "Unassign Staff": "Atcelt personāla piešķiršanu", + "Undo": "Atsaukt", "Undo Rejection": "Atsaukt noraidījumu", "Undo Transfer": "Atsaukt pārsūtīšanu", "Update Default Savings": "Atjauniniet noklusējuma ietaupījumus", @@ -1399,6 +1400,7 @@ "Interest Grace Periods": "Procentu labvēlības periodi", "Interest Method": "Interešu metode", "Interest Outstanding": "Interese Izcila", + "Interest Payable": "Procenti Päyable", "Interest Posted": "Interese publicēta", "Interest Posting Period": "Interešu publicēšanas periods", "Interest Posting period": "Interešu publicēšanas periods", diff --git a/src/assets/translations/ne-NE.json b/src/assets/translations/ne-NE.json index 645285d13..8bcb58717 100644 --- a/src/assets/translations/ne-NE.json +++ b/src/assets/translations/ne-NE.json @@ -474,6 +474,7 @@ "Transfer Client": "ग्राहक स्थानान्तरण", "Transfer Clients": "ग्राहक हस्तान्तरण", "Unassign Staff": "कर्मचारी नियुक्ति रद्द गर्नुहोस्", + "Undo": "पूर्वकार्य", "Undo Rejection": "अस्वीकार अनडू गर्नुहोस्", "Undo Transfer": "स्थानान्तरण अनडू गर्नुहोस्", "Update Default Savings": "पूर्वनिर्धारित बचत अद्यावधिक गर्नुहोस्", @@ -1399,6 +1400,7 @@ "Interest Grace Periods": "ब्याज अनुग्रह अवधिहरू", "Interest Method": "ब्याज विधि", "Interest Outstanding": "बकाया ब्याज", + "Interest Payable": "ब्याज päyy", "Interest Posted": "चासो पोस्ट गरियो", "Interest Posting Period": "रुचि पोस्टिङ अवधि", "Interest Posting period": "ब्याज पोस्टिङ अवधि", diff --git a/src/assets/translations/pt-PT.json b/src/assets/translations/pt-PT.json index ad24e51bd..a7a0664f9 100644 --- a/src/assets/translations/pt-PT.json +++ b/src/assets/translations/pt-PT.json @@ -474,6 +474,7 @@ "Transfer Client": "Cliente de transferência", "Transfer Clients": "Transferir clientes", "Unassign Staff": "Cancelar atribuição de equipe", + "Undo": "Desfazer", "Undo Rejection": "Desfazer rejeição", "Undo Transfer": "Desfazer transferência", "Update Default Savings": "Atualizar economia padrão", @@ -1399,6 +1400,7 @@ "Interest Grace Periods": "Períodos de carência de juros", "Interest Method": "Método de juros", "Interest Outstanding": "Juros pendentes", + "Interest Payable": "Juros a pagar", "Interest Posted": "Interesse Postado", "Interest Posting Period": "Período de postagem de juros", "Interest Posting period": "Período de postagem de juros", diff --git a/src/assets/translations/sw-SW.json b/src/assets/translations/sw-SW.json index 94b2ff2e1..46cd30000 100644 --- a/src/assets/translations/sw-SW.json +++ b/src/assets/translations/sw-SW.json @@ -475,6 +475,7 @@ "Transfer Clients": "Wateja wa Uhamisho", "Unassign Staff": "Batilisha Wafanyikazi", "Undo Rejection": "Tendua Kukataliwa", + "Undo": "Tengeneza", "Undo Transfer": "Tendua Uhamisho", "Update Default Savings": "Sasisha Akiba Chaguomsingi", "Upload": "Pakia", @@ -1399,6 +1400,7 @@ "Interest Grace Periods": "Vipindi vya Neema vya Riba", "Interest Method": "Mbinu ya Maslahi", "Interest Outstanding": "Maslahi Bora", + "Interest Payable": "Riba inaelezewa", "Interest Posted": "Nia Imetumwa", "Interest Posting Period": "Kipindi cha Kuchapisha Riba", "Interest Posting period": "Kipindi cha Kuchapisha Riba",