fix: Accounting Migrate Opening Balances view

This commit is contained in:
Jose Alberto Hernandez
2024-05-26 19:12:58 -06:00
committed by Jose Alberto Hernandez
parent 3cc27c5206
commit 545a998426
20 changed files with 132 additions and 100 deletions
@@ -8,28 +8,32 @@
<mat-card-content>
<div #searchFormRef fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
<mat-form-field fxFlex="88%">
<mat-label>{{"labels.inputs.Office" | translate}}</mat-label>
<mat-select required formControlName="officeId">
<mat-option *ngFor="let office of officeData" [value]="office.id">
{{ office.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="openingBalancesForm.controls.officeId.hasError('required')">
{{"labels.inputs.Office" | translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
</mat-error>
</mat-form-field>
<div>
<button mat-button type="button" color="primary" fxFlex="8%" (click)="retrieveOpeningBalances()">{{"labels.buttons.Retrieve" | translate}}</button>
<div class="m-r-30" fxFlex="83%">
<mat-form-field fxFlex="96%">
<mat-label>{{"labels.inputs.Office" | translate}}</mat-label>
<mat-select required formControlName="officeId">
<mat-option *ngFor="let office of officeData" [value]="office.id">
{{ office.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="openingBalancesForm.controls.officeId.hasError('required')">
{{"labels.inputs.Office" | translate}} {{"labels.commons.is" | translate}}
<strong>{{"labels.commons.required" | translate}}</strong>
</mat-error>
</mat-form-field>
</div>
<div fxFlex="15%">
<button mat-raised-button color="primary" (click)="retrieveOpeningBalances()">{{"labels.buttons.Retrieve" |
translate}}</button>
</div>
</div>
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column" *ngIf="openingBalancesData">
<label fxFlex="98%" class="content"><span class="header">{{"labels.inputs.Opening Balances Contra Account:" | translate}}</span>&nbsp;&nbsp;{{ openingBalancesData.contraAccount.name + ' (' + openingBalancesData.contraAccount.glCode + ')' }}</label>
<mifosx-gl-account-display fxFlex="100%" [accountTitle]="'Opening Balances Contra Account'"
[glAccount]="openingBalancesData.contraAccount" [withTitle]="'50%'">
</mifosx-gl-account-display>
<mat-form-field fxFlex="48%">
<mat-label>{{"labels.inputs.Currency" | translate}}</mat-label>
@@ -39,17 +43,20 @@
</mat-option>
</mat-select>
<mat-error *ngIf="openingBalancesForm.controls.currencyCode.hasError('required')">
{{"labels.inputs.Currency" | translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
{{"labels.inputs.Currency" | translate}} {{"labels.commons.is" | translate}}
<strong>{{"labels.commons.required" | translate}}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="48%" (click)="openingBalancesDatePicker.open()">
<mat-label>{{"labels.inputs.Opening Balances Date" | translate}}</mat-label>
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="openingBalancesDatePicker" required formControlName="transactionDate">
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="openingBalancesDatePicker" required
formControlName="transactionDate">
<mat-datepicker-toggle matSuffix [for]="openingBalancesDatePicker"></mat-datepicker-toggle>
<mat-datepicker #openingBalancesDatePicker></mat-datepicker>
<mat-error *ngIf="openingBalancesForm.controls.transactionDate.hasError('required')">
{{"labels.inputs.Opening Balances Date" | translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
{{"labels.inputs.Opening Balances Date" | translate}} {{"labels.commons.is" | translate}}
<strong>{{"labels.commons.required" | translate}}</strong>
</mat-error>
</mat-form-field>
@@ -65,15 +72,14 @@
<div class="header" fxFlex="18%">
{{"labels.inputs.Account" | translate}}
</div>
<div class="header" fxFlex="23%">
{{"labels.inputs.Total Debit" | translate}}: {{ debitsSum }}
<div class="header r-amount" fxFlex="23%">
{{"labels.inputs.Total Debit" | translate}}: {{ debitsSum | currency:currencyCode:'symbol-narrow':'1.2-2' }}
</div>
<div class="header" fxFlex="23%">
{{"labels.inputs.Total Credit" | translate}}: {{ creditsSum }}
<div class="header r-amount" fxFlex="23%">
{{"labels.inputs.Total Credit" | translate}}: {{ creditsSum | currency:currencyCode:'symbol-narrow':'1.2-2' }}
</div>
</div>
@@ -83,26 +89,28 @@
<div fxFlexFill fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column" [formGroupName]="i">
<div fxFlex="8%" class="p-t-30">
{{ (openingBalancesData.glAccounts[i].glAccountType.value !== openingBalancesData.glAccounts[i-1]?.glAccountType.value) ? openingBalancesData.glAccounts[i].glAccountType.value : '' }}
<div fxFlex="8%">
{{ (openingBalancesData.glAccounts[i].glAccountType.value !==
openingBalancesData.glAccounts[i-1]?.glAccountType.value) ?
glAccountTypeLabel(openingBalancesData.glAccounts[i].glAccountType.value) : '' }}
</div>
<div fxFlex="18%" class="p-t-30">
<div fxFlex="13%">
{{ openingBalancesData.glAccounts[i].glAccountCode }}
</div>
<div fxFlex="18%" class="p-t-30">
<div fxFlex="29%">
{{ openingBalancesData.glAccounts[i].glAccountName }}
</div>
<div fxFlex="23%">
<div fxFlex="20%">
<mat-form-field>
<mat-label>{{"labels.inputs.Debit" | translate}}</mat-label>
<input matInput type="number" formControlName="debit">
</mat-form-field>
</div>
<div fxFlex="23%">
<div fxFlex="20%">
<mat-form-field>
<mat-label>{{"labels.inputs.Credit" | translate}}</mat-label>
<input matInput type="number" formControlName="credit">
@@ -117,9 +125,11 @@
</mat-card-content>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px" *ngIf="openingBalancesData">
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px"
*ngIf="openingBalancesData">
<button type="button" mat-raised-button [routerLink]="['../']">{{"labels.buttons.Cancel" | translate}}</button>
<button mat-raised-button color="primary" [disabled]="!openingBalancesForm.valid" *mifosxHasPermission="'DEFINEOPENINGBALANCE_JOURNALENTRY'">{{"labels.buttons.Submit | translate}}</button>
<button mat-raised-button color="primary" [disabled]="!openingBalancesForm.valid"
*mifosxHasPermission="'DEFINEOPENINGBALANCE_JOURNALENTRY'">{{"labels.buttons.Submit" | translate}}</button>
</mat-card-actions>
</form>
@@ -130,10 +140,16 @@
<ng-template #templateSearchFormRef let-popover="popover">
<h2>{{"labels.heading.Migrate opening balances (Office-wise)" | translate}}</h2>
<p class="mw300">{{"labels.text.Migrate Opening Balances" | translate}} <a href="https://mifosforge.jira.com/wiki/spaces/docs/pages/90243328/Migrate+opening+balances+Office-wise" target="_blank">{{"labels.inputs.Migrate opening balances (Office-wise)" | translate}}</a></p>
<p class="mw300">{{"labels.text.Migrate Opening Balances" | translate}} <a
href="https://mifosforge.jira.com/wiki/spaces/docs/pages/90243328/Migrate+opening+balances+Office-wise"
target="_blank">{{"labels.inputs.Migrate opening balances (Office-wise)" | translate}}</a></p>
<div fxLayout="row" fxLayoutAlign="end" fxLayoutGap="2%" fxLayout.lt-md="column">
<button mat-raised-button color="warn" (click)="popover.close();configurationWizardService.closeConfigWizard()">{{"labels.buttons.Close" | translate}}</button>
<button mat-raised-button color="primary" (click)="popover.close();popover.close();previousStep();">{{"labels.buttons.Back" | translate}}</button>
<button mat-raised-button color="primary" (click)="popover.close();popover.close();nextStep();">{{"labels.buttons.Next" | translate}}</button>
<button mat-raised-button color="warn"
(click)="popover.close();configurationWizardService.closeConfigWizard()">{{"labels.buttons.Close" |
translate}}</button>
<button mat-raised-button color="primary"
(click)="popover.close();popover.close();previousStep();">{{"labels.buttons.Back" | translate}}</button>
<button mat-raised-button color="primary"
(click)="popover.close();popover.close();nextStep();">{{"labels.buttons.Next" | translate}}</button>
</div>
</ng-template>
</ng-template>
@@ -1,6 +1,6 @@
.content {
padding-top: 20px;
div {
margin: 1rem 0;
word-wrap: break-word;
&.header {
@@ -12,6 +12,7 @@ import { ConfigurationWizardService } from '../../configuration-wizard/configura
/** Custom Validators */
import { onlyOneOfTheFieldsIsRequiredValidator } from './only-one-of-the-fields-is-required.validator';
import { Dates } from 'app/core/utils/dates';
import { TranslateService } from '@ngx-translate/core';
/**
* Migrate opening balances component.
@@ -35,6 +36,7 @@ export class MigrateOpeningBalancesComponent implements OnInit, AfterViewInit {
officeData: any;
/** Currency data. */
currencyData: any;
currencyCode: string;
/** Sum total of debits. */
debitsSum = 0;
/** Sum total of credits. */
@@ -62,7 +64,8 @@ export class MigrateOpeningBalancesComponent implements OnInit, AfterViewInit {
private route: ActivatedRoute,
private router: Router,
private configurationWizardService: ConfigurationWizardService,
private popoverService: PopoverService) {
private popoverService: PopoverService,
private translateService: TranslateService) {
this.route.data.subscribe((data: {
offices: any,
currencies: any
@@ -90,6 +93,10 @@ export class MigrateOpeningBalancesComponent implements OnInit, AfterViewInit {
'transactionDate': ['', Validators.required],
'glAccountEntries': this.formBuilder.array([])
});
this.openingBalancesForm.controls.currencyCode.valueChanges.subscribe((value: string) => {
this.currencyCode = value;
});
}
/**
@@ -149,27 +156,28 @@ export class MigrateOpeningBalancesComponent implements OnInit, AfterViewInit {
* if successful redirects to view created transaction.
*/
submit() {
const openingBalances = this.openingBalancesForm.value;
// TODO: Update once language and date settings are setup
openingBalances.locale = this.settingsService.language.code;
openingBalances.dateFormat = this.settingsService.dateFormat;
if (openingBalances.transactionDate instanceof Date) {
openingBalances.transactionDate = this.dateUtils.formatDate(openingBalances.transactionDate, this.settingsService.dateFormat);
if (this.amountsAreOK()) {
const openingBalances = this.openingBalancesForm.value;
openingBalances.locale = this.settingsService.language.code;
openingBalances.dateFormat = this.settingsService.dateFormat;
if (openingBalances.transactionDate instanceof Date) {
openingBalances.transactionDate = this.dateUtils.formatDate(openingBalances.transactionDate, this.settingsService.dateFormat);
}
openingBalances.debits = [];
openingBalances.credits = [];
this.openingBalancesForm.value.glAccountEntries.forEach((entry: any) => {
if (entry.debit) {
openingBalances.debits.push({ glAccountId: entry.glAccountId, amount: entry.debit });
}
if (entry.credit) {
openingBalances.credits.push({ glAccountId: entry.glAccountId, amount: entry.credit });
}
});
delete openingBalances.glAccountEntries;
this.accountingService.defineOpeningBalances(openingBalances).subscribe((response: any) => {
this.router.navigate(['/accounting/journal-entries/transactions/view', response.transactionId]);
});
}
openingBalances.debits = [];
openingBalances.credits = [];
this.openingBalancesForm.value.glAccountEntries.forEach((entry: any) => {
if (entry.debit) {
openingBalances.debits.push({ glAccountId: entry.glAccountId, amount: entry.debit });
}
if (entry.credit) {
openingBalances.credits.push({ glAccountId: entry.glAccountId, amount: entry.credit });
}
});
delete openingBalances.glAccountEntries;
this.accountingService.defineOpeningBalances(openingBalances).subscribe((response: any) => {
this.router.navigate(['/accounting/journal-entries/transactions/view', response.transactionId]);
});
}
/**
@@ -210,4 +218,22 @@ export class MigrateOpeningBalancesComponent implements OnInit, AfterViewInit {
this.router.navigate(['/accounting']);
}
amountsAreOK(): boolean {
let debitsSum = 0;
let creditsSum = 0;
this.openingBalancesForm.value.glAccountEntries.forEach((entry: any) => {
if (entry.debit) {
debitsSum = debitsSum + entry.debit;
}
if (entry.credit) {
creditsSum = creditsSum + entry.credit;
}
});
return (debitsSum > 0 && debitsSum === creditsSum);
}
glAccountTypeLabel(accountType: string): string {
return this.translateService.instant('labels.inputs.accounting.' + accountType);
}
}
@@ -5,5 +5,10 @@ import { UntypedFormGroup, ValidatorFn, ValidationErrors } from '@angular/forms'
export const onlyOneOfTheFieldsIsRequiredValidator: ValidatorFn = (glAccountEntriesForm: UntypedFormGroup): ValidationErrors | null => {
const debit = glAccountEntriesForm.controls.debit.value;
const credit = glAccountEntriesForm.controls.credit.value;
return ((debit || credit) && !(debit && credit)) ? null : { 'error': true };
if (debit && credit) {
if (debit > 0 && credit > 0) {
return { 'error': true };
}
}
return null;
};
@@ -191,15 +191,10 @@
</div>
</div>
<mat-form-field *ngIf="chargeForm.controls.chargeAppliesTo.value === 3" fxFlex="48%">
<mat-label>{{"labels.inputs.Income from Charge" | translate}} </mat-label>
<mat-select formControlName="incomeAccountId">
<mat-option *ngFor="let incomeOrLiabilityAccount of incomeAndLiabilityAccountData"
[value]="incomeOrLiabilityAccount.id">
{{ incomeOrLiabilityAccount.name }}
</mat-option>
</mat-select>
</mat-form-field>
<mifosx-gl-account-selector fxFlex="48%" *ngIf="chargeForm.controls.chargeAppliesTo.value === 3"
[inputFormControl]="chargeForm.controls.incomeAccountId"
[glAccountList]="incomeAndLiabilityAccountData" [inputLabel]="'Income from Charge'">
</mifosx-gl-account-selector>
<mat-form-field fxFlex="48%">
<mat-label>{{"labels.inputs.Tax Group" | translate}}</mat-label>
@@ -105,18 +105,10 @@
<input matInput autofocus formControlName="maxCap">
</mat-form-field>
<mat-form-field fxFlex="48%" *ngIf="showGLAccount">
<mat-label>{{"labels.inputs.Income from charge" | translate}}</mat-label>
<mat-select required formControlName="incomeAccountId">
<mat-option *ngFor="let income of chargeData.incomeOrLiabilityAccountOptions.incomeAccountOptions"
[value]="income.id">
{{ income.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="chargeForm.controls.incomeAccountId.hasError('required')">
{{"labels.inputs.Income from charge" | translate}} {{"labels.commons.is" | translate}} <strong>{{"labels.commons.required" | translate}}</strong>
</mat-error>
</mat-form-field>
<mifosx-gl-account-selector fxFlex="48%" *ngIf="showGLAccount"
[inputFormControl]="chargeForm.controls.incomeAccountId"
[glAccountList]="chargeData.incomeOrLiabilityAccountOptions.incomeAccountOptions" [required]="true" [inputLabel]="'Income from Charge'">
</mifosx-gl-account-selector>
<mat-form-field fxFlex="48%">
<mat-label>{{"labels.inputs.Tax Group" | translate}}</mat-label>
@@ -122,13 +122,9 @@
{{ chargeData.feeInterval }}
</div>
<div fxFlex="50%" class="mat-body-strong" *ngIf="chargeData.incomeOrLiabilityAccount">
{{"labels.heading.Income" | translate}} {{"labels.inputs.From" | translate}} {{"labels.heading.Charges" | translate}}
</div>
<div fxFlex="50%" *ngIf="chargeData.incomeOrLiabilityAccount">
{{ chargeData.incomeOrLiabilityAccount.name + ' (' + chargeData.incomeOrLiabilityAccount.glCode + ')' }}
</div>
<mifosx-gl-account-display fxFlex="100%" [accountTitle]="'Income From Charges'" *ngIf="chargeData.incomeOrLiabilityAccount"
[glAccount]="chargeData.incomeOrLiabilityAccount" [withTitle]="'50%'">
</mifosx-gl-account-display>
<div fxFlex="50%" class="mat-body-strong" *ngIf="chargeData.taxGroup">
{{"labels.inputs.Tax Group" | translate}}