Upgrading to Angular 20:

Replaced checked in package-lock.json by regenerated one.
Ran ng update @angular/core@20 @angular/cli@20
Ran npm install @angular-builders/jest@^20.0.0 @fortawesome/angular-fontawesome@^3.0.0 @swimlane/ngx-graph@^11
Ran npm install ngx-mat-select-search@^8.0.2.
Ran ng update @angular/material@20.
Updated all eslint and typescript to the latest versions.
Removed @angular-devkit/schematics.
Updated fontawesome.
Updated rxjs and tslib.
Moved required node version from 16 to 20.
Updated jest-preset-angular.
Set preserveWhitespaces to false.
Corrected two type declarations in two typescript files to make ng serve run without errors.
Removed unused angular-devkit/schematics from view-user.component.ts .
Updated list of supported browsers.
Upgraded prettier.
Ran prettier . --write the first time.
Ran prettier . --write the second time.
Ran ng generate @angular/core:inject with defaults, excepted a handful of files.
Fixed remaining eslint problems.
Added dist directory to ignores in eslint.config.js.
Let prettier fix formatting, almost everything is just line breaks.
Made htmlhint ignore @if and @for Angular constructs.
Updated node version in Github workflow to 22.12.0 (build.yml).
Updated .env.ts.
Updated Angular datetime format strings from YYYY-MM-DD to yyyy-MM-dd.
Merged changes from dev into angular20 branch.
This commit is contained in:
Felix van Hove
2025-12-08 11:01:01 +01:00
parent f1b4ec2cf2
commit 7fd1486c08
1516 changed files with 39367 additions and 36037 deletions
@@ -386,7 +386,6 @@ const routes: Routes = [
]
}
])
];
/**
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
@@ -13,10 +13,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class AccountingRuleResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the accounting rule data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class AccountingRulesTemplateResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the accounting rules template data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, ViewChild } from '@angular/core';
import { Component, OnInit, ViewChild, inject } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, MatSortHeader } from '@angular/material/sort';
import {
@@ -45,6 +45,8 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class AccountingRulesComponent implements OnInit {
private route = inject(ActivatedRoute);
/** Accounting rule data. */
accountingRuleData: any;
/** Columns to be displayed in accounting rules table. */
@@ -68,7 +70,7 @@ export class AccountingRulesComponent implements OnInit {
* Retrieves the accounting rules data from `resolve`.
* @param {ActivatedRoute} route Activated Route.
*/
constructor(private route: ActivatedRoute) {
constructor() {
this.route.data.subscribe((data: { accountingRules: any }) => {
this.accountingRuleData = data.accountingRules;
});
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class AccountingRulesResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the accounting rules data.
@@ -6,23 +6,29 @@
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Accounting Rule Name' | translate }}</mat-label>
<input matInput required formControlName="name" />
<mat-error *ngIf="accountingRuleForm.controls.name.hasError('required')">
{{ 'labels.inputs.Accounting Rule Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (accountingRuleForm.controls.name.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Accounting Rule Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<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>
@for (office of officeData; track office) {
<mat-option [value]="office.id">
{{ office.name }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="accountingRuleForm.controls.officeId.hasError('required')">
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (accountingRuleForm.controls.officeId.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<div class="rule-wrapper flex-48 layout-row responsive-column">
@@ -40,34 +46,38 @@
</mat-radio-group>
</div>
<mat-form-field class="flex-48" *ngIf="accountingRuleForm.controls.debitRuleType.value === 'fixedAccount'">
<mat-label>{{ 'labels.inputs.Account to Debit' | translate }}</mat-label>
<mat-select formControlName="accountToDebit">
<mat-option *ngFor="let glAccount of glAccountData" [value]="glAccount.id">
{{ glAccount.name }}
</mat-option>
</mat-select>
</mat-form-field>
<div
class="flex-48 layout-row gap-2percent responsive-column"
*ngIf="accountingRuleForm.controls.debitRuleType.value === 'listOfAccounts'"
>
<mat-form-field class="flex-50">
<mat-label>{{ 'labels.inputs.Debit Tags' | translate }}</mat-label>
<mat-select formControlName="debitTags" multiple>
<mat-option *ngFor="let debitTag of debitTagData" [value]="debitTag.id">
{{ debitTag.name }}
</mat-option>
@if (accountingRuleForm.controls.debitRuleType.value === 'fixedAccount') {
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Account to Debit' | translate }}</mat-label>
<mat-select formControlName="accountToDebit">
@for (glAccount of glAccountData; track glAccount) {
<mat-option [value]="glAccount.id">
{{ glAccount.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
}
<div class="flex-50" ngClass.gt-md="entries-wrapper">
<mat-checkbox labelPosition="before" formControlName="allowMultipleDebitEntries" class="entries">
{{ 'labels.inputs.Multiple Debit Entries Allowed' | translate }}
</mat-checkbox>
@if (accountingRuleForm.controls.debitRuleType.value === 'listOfAccounts') {
<div class="flex-48 layout-row gap-2percent responsive-column">
<mat-form-field class="flex-50">
<mat-label>{{ 'labels.inputs.Debit Tags' | translate }}</mat-label>
<mat-select formControlName="debitTags" multiple>
@for (debitTag of debitTagData; track debitTag) {
<mat-option [value]="debitTag.id">
{{ debitTag.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
<div class="flex-50" ngClass.gt-md="entries-wrapper">
<mat-checkbox labelPosition="before" formControlName="allowMultipleDebitEntries" class="entries">
{{ 'labels.inputs.Multiple Debit Entries Allowed' | translate }}
</mat-checkbox>
</div>
</div>
</div>
}
<div class="rule-wrapper flex-48 layout-row responsive-column">
<mat-label class="flex-50"
@@ -84,34 +94,38 @@
</mat-radio-group>
</div>
<mat-form-field class="flex-48" *ngIf="accountingRuleForm.controls.creditRuleType.value === 'fixedAccount'">
<mat-label>{{ 'labels.inputs.Account to Credit' | translate }}</mat-label>
<mat-select formControlName="accountToCredit">
<mat-option *ngFor="let glAccount of glAccountData" [value]="glAccount.id">
{{ glAccount.name }}
</mat-option>
</mat-select>
</mat-form-field>
<div
class="flex-48 layout-row gap-2percent responsive-column"
*ngIf="accountingRuleForm.controls.creditRuleType.value === 'listOfAccounts'"
>
<mat-form-field class="flex-50">
<mat-label>{{ 'labels.inputs.Credit Tags' | translate }}</mat-label>
<mat-select formControlName="creditTags" multiple>
<mat-option *ngFor="let creditTag of creditTagData" [value]="creditTag.id">
{{ creditTag.name }}
</mat-option>
@if (accountingRuleForm.controls.creditRuleType.value === 'fixedAccount') {
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Account to Credit' | translate }}</mat-label>
<mat-select formControlName="accountToCredit">
@for (glAccount of glAccountData; track glAccount) {
<mat-option [value]="glAccount.id">
{{ glAccount.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
}
<div class="flex-50" ngClass.gt-md="entries-wrapper">
<mat-checkbox labelPosition="before" formControlName="allowMultipleCreditEntries" class="entries">
{{ 'labels.inputs.Multiple Credit Entries Allowed' | translate }}
</mat-checkbox>
@if (accountingRuleForm.controls.creditRuleType.value === 'listOfAccounts') {
<div class="flex-48 layout-row gap-2percent responsive-column">
<mat-form-field class="flex-50">
<mat-label>{{ 'labels.inputs.Credit Tags' | translate }}</mat-label>
<mat-select formControlName="creditTags" multiple>
@for (creditTag of creditTagData; track creditTag) {
<mat-option [value]="creditTag.id">
{{ creditTag.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
<div class="flex-50" ngClass.gt-md="entries-wrapper">
<mat-checkbox labelPosition="before" formControlName="allowMultipleCreditEntries" class="entries">
{{ 'labels.inputs.Multiple Credit Entries Allowed' | translate }}
</mat-checkbox>
</div>
</div>
</div>
}
<mat-form-field class="flex-98">
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
@@ -29,6 +29,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class CreateRuleComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Accounting rule form. */
accountingRuleForm: UntypedFormGroup;
/** Office data. */
@@ -47,12 +52,7 @@ export class CreateRuleComponent implements OnInit {
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router
) {
constructor() {
this.route.data.subscribe((data: { accountingRulesTemplate: any }) => {
this.officeData = data.accountingRulesTemplate.allowedOffices;
this.glAccountData = data.accountingRulesTemplate.allowedAccounts;
@@ -6,23 +6,29 @@
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Accounting Rule Name' | translate }}</mat-label>
<input matInput required formControlName="name" />
<mat-error *ngIf="accountingRuleForm.controls.name.hasError('required')">
{{ 'labels.inputs.Accounting Rule Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (accountingRuleForm.controls.name.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Accounting Rule Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<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>
@for (office of officeData; track office) {
<mat-option [value]="office.id">
{{ office.name }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="accountingRuleForm.controls.officeId.hasError('required')">
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (accountingRuleForm.controls.officeId.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<div class="rule-wrapper flex-48 layout-row responsive-column">
@@ -40,34 +46,38 @@
</mat-radio-group>
</div>
<mat-form-field class="flex-48" *ngIf="accountingRuleForm.controls.debitRuleType.value === 'fixedAccount'">
<mat-label>{{ 'labels.inputs.Account to Debit' | translate }}</mat-label>
<mat-select formControlName="accountToDebit">
<mat-option *ngFor="let glAccount of glAccountData" [value]="glAccount.id">
{{ glAccount.name }}
</mat-option>
</mat-select>
</mat-form-field>
<div
class="flex-48 layout-row gap-2percent responsive-column"
*ngIf="accountingRuleForm.controls.debitRuleType.value === 'listOfAccounts'"
>
<mat-form-field class="flex-50">
<mat-label>{{ 'labels.inputs.Debit Tags' | translate }}</mat-label>
<mat-select formControlName="debitTags" multiple>
<mat-option *ngFor="let debitTag of debitTagData" [value]="debitTag.id">
{{ debitTag.name }}
</mat-option>
@if (accountingRuleForm.controls.debitRuleType.value === 'fixedAccount') {
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Account to Debit' | translate }}</mat-label>
<mat-select formControlName="accountToDebit">
@for (glAccount of glAccountData; track glAccount) {
<mat-option [value]="glAccount.id">
{{ glAccount.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
}
<div class="flex-50 entries-wrapper">
<mat-checkbox labelPosition="before" formControlName="allowMultipleDebitEntries" class="entries">
{{ 'labels.inputs.Multiple Debit Entries Allowed' | translate }}
</mat-checkbox>
@if (accountingRuleForm.controls.debitRuleType.value === 'listOfAccounts') {
<div class="flex-48 layout-row gap-2percent responsive-column">
<mat-form-field class="flex-50">
<mat-label>{{ 'labels.inputs.Debit Tags' | translate }}</mat-label>
<mat-select formControlName="debitTags" multiple>
@for (debitTag of debitTagData; track debitTag) {
<mat-option [value]="debitTag.id">
{{ debitTag.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
<div class="flex-50 entries-wrapper">
<mat-checkbox labelPosition="before" formControlName="allowMultipleDebitEntries" class="entries">
{{ 'labels.inputs.Multiple Debit Entries Allowed' | translate }}
</mat-checkbox>
</div>
</div>
</div>
}
<div class="rule-wrapper flex-48 layout-row responsive-column">
<mat-label class="flex-50"
@@ -84,34 +94,38 @@
</mat-radio-group>
</div>
<mat-form-field class="flex-48" *ngIf="accountingRuleForm.controls.creditRuleType.value === 'fixedAccount'">
<mat-label>{{ 'labels.inputs.Account to Credit' | translate }}</mat-label>
<mat-select formControlName="accountToCredit">
<mat-option *ngFor="let glAccount of glAccountData" [value]="glAccount.id">
{{ glAccount.name }}
</mat-option>
</mat-select>
</mat-form-field>
<div
class="flex-48 layout-row gap-2percent responsive-column"
*ngIf="accountingRuleForm.controls.creditRuleType.value === 'listOfAccounts'"
>
<mat-form-field class="flex-50">
<mat-label>{{ 'labels.inputs.Credit Tags' | translate }}</mat-label>
<mat-select formControlName="creditTags" multiple>
<mat-option *ngFor="let creditTag of creditTagData" [value]="creditTag.id">
{{ creditTag.name }}
</mat-option>
@if (accountingRuleForm.controls.creditRuleType.value === 'fixedAccount') {
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Account to Credit' | translate }}</mat-label>
<mat-select formControlName="accountToCredit">
@for (glAccount of glAccountData; track glAccount) {
<mat-option [value]="glAccount.id">
{{ glAccount.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
}
<div class="flex-50 entries-wrapper">
<mat-checkbox labelPosition="before" formControlName="allowMultipleCreditEntries" class="entries">
{{ 'labels.inputs.Multiple Credit Entries Allowed' | translate }}
</mat-checkbox>
@if (accountingRuleForm.controls.creditRuleType.value === 'listOfAccounts') {
<div class="flex-48 layout-row gap-2percent responsive-column">
<mat-form-field class="flex-50">
<mat-label>{{ 'labels.inputs.Credit Tags' | translate }}</mat-label>
<mat-select formControlName="creditTags" multiple>
@for (creditTag of creditTagData; track creditTag) {
<mat-option [value]="creditTag.id">
{{ creditTag.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
<div class="flex-50 entries-wrapper">
<mat-checkbox labelPosition="before" formControlName="allowMultipleCreditEntries" class="entries">
{{ 'labels.inputs.Multiple Credit Entries Allowed' | translate }}
</mat-checkbox>
</div>
</div>
</div>
}
<mat-form-field class="flex-98">
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
@@ -29,6 +29,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class EditRuleComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Accounting rule form. */
accountingRuleForm: UntypedFormGroup;
/** Accounting rule. */
@@ -49,12 +54,7 @@ export class EditRuleComponent implements OnInit {
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router
) {
constructor() {
this.route.data.subscribe((data: { accountingRulesTemplate: any; accountingRule: any }) => {
this.officeData = data.accountingRulesTemplate.allowedOffices;
this.glAccountData = data.accountingRulesTemplate.allowedAccounts;
@@ -22,10 +22,12 @@
<div class="value">{{ accountingRule.officeName }}</div>
</div>
<div class="content-row" *ngIf="accountingRule.description">
<div class="label">{{ 'labels.inputs.Description' | translate }}</div>
<div class="value">{{ accountingRule.description }}</div>
</div>
@if (accountingRule.description) {
<div class="content-row">
<div class="label">{{ 'labels.inputs.Description' | translate }}</div>
<div class="value">{{ accountingRule.description }}</div>
</div>
}
<div class="content-row">
<div class="label">{{ 'labels.inputs.Multiple Debit Entries Allowed' | translate }}</div>
@@ -41,37 +43,49 @@
<mat-card>
<mat-card-content class="content-rows">
<div class="content-row" *ngIf="accountingRule.debitTags?.length">
<div class="label">{{ 'labels.inputs.Debit Tags' | translate }}</div>
<div class="value">
<span *ngFor="let debitTag of accountingRule.debitTags">{{ debitTag.tag.name }}</span>
@if (accountingRule.debitTags?.length) {
<div class="content-row">
<div class="label">{{ 'labels.inputs.Debit Tags' | translate }}</div>
<div class="value">
@for (debitTag of accountingRule.debitTags; track debitTag) {
<span>{{ debitTag.tag.name }}</span>
}
</div>
</div>
</div>
}
<div class="content-row" *ngIf="accountingRule.debitAccounts?.length">
<div class="label">{{ 'labels.inputs.Debit Account Name' | translate }}</div>
<div class="value">
<span *ngFor="let debitAccount of accountingRule.debitAccounts">{{
debitAccount.name + ' (' + debitAccount.glCode + ')'
}}</span>
@if (accountingRule.debitAccounts?.length) {
<div class="content-row">
<div class="label">{{ 'labels.inputs.Debit Account Name' | translate }}</div>
<div class="value">
@for (debitAccount of accountingRule.debitAccounts; track debitAccount) {
<span>{{ debitAccount.name + ' (' + debitAccount.glCode + ')' }}</span>
}
</div>
</div>
</div>
}
<div class="content-row" *ngIf="accountingRule.creditTags?.length">
<div class="label">{{ 'labels.inputs.Credit Tags' | translate }}</div>
<div class="value">
<span *ngFor="let creditTag of accountingRule.creditTags">{{ creditTag.tag.name }}</span>
@if (accountingRule.creditTags?.length) {
<div class="content-row">
<div class="label">{{ 'labels.inputs.Credit Tags' | translate }}</div>
<div class="value">
@for (creditTag of accountingRule.creditTags; track creditTag) {
<span>{{ creditTag.tag.name }}</span>
}
</div>
</div>
</div>
}
<div class="content-row" *ngIf="accountingRule.creditAccounts?.length">
<div class="label">{{ 'labels.inputs.Credit Account Name' | translate }}</div>
<div class="value">
<span *ngFor="let creditAccount of accountingRule.creditAccounts">{{
creditAccount.name + ' (' + creditAccount.glCode + ')'
}}</span>
@if (accountingRule.creditAccounts?.length) {
<div class="content-row">
<div class="label">{{ 'labels.inputs.Credit Account Name' | translate }}</div>
<div class="value">
@for (creditAccount of accountingRule.creditAccounts; track creditAccount) {
<span>{{ creditAccount.name + ' (' + creditAccount.glCode + ')' }}</span>
}
</div>
</div>
</div>
}
</mat-card-content>
</mat-card>
</div>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component } from '@angular/core';
import { Component, inject } from '@angular/core';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
@@ -24,6 +24,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class ViewRuleComponent {
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
dialog = inject(MatDialog);
/** Accounting rule. */
accountingRule: any;
@@ -34,12 +39,7 @@ export class ViewRuleComponent {
* @param {Router} router Router for navigation.
* @param {MatDialog} dialog Dialog reference.
*/
constructor(
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router,
public dialog: MatDialog
) {
constructor() {
this.route.data.subscribe((data: { accountingRule: any }) => {
this.accountingRule = data.accountingRule;
});
+110 -145
View File
@@ -11,24 +11,20 @@
</mat-icon>
<div matLine>
{{ 'labels.heading.Frequent Postings' | translate }}
<p
matLine
*ngIf="arrowBooleans[0]"
[routerLink]="['journal-entries/frequent-postings']"
class="menu-explanation"
>
{{ 'labels.text.These are predefined postings' | translate }}
</p>
@if (arrowBooleans[0]) {
<p matLine [routerLink]="['journal-entries/frequent-postings']" class="menu-explanation">
{{ 'labels.text.These are predefined postings' | translate }}
</p>
}
</div>
</div>
<div class="menu-right-section">
<fa-icon
(click)="arrowBooleansToggle(0)"
*ngIf="!arrowBooleans[0]"
icon="arrow-down"
size="md"
></fa-icon>
<fa-icon (click)="arrowBooleansToggle(0)" *ngIf="arrowBooleans[0]" icon="arrow-up" size="md"></fa-icon>
@if (!arrowBooleans[0]) {
<fa-icon (click)="arrowBooleansToggle(0)" icon="arrow-down" size="md"></fa-icon>
}
@if (arrowBooleans[0]) {
<fa-icon (click)="arrowBooleansToggle(0)" icon="arrow-up" size="md"></fa-icon>
}
</div>
</div>
</mat-list-item>
@@ -42,29 +38,20 @@
</mat-icon>
<div matLine>
{{ 'labels.heading.Create Journal Entries' | translate }}
<p
matLine
*ngIf="arrowBooleans[1]"
[routerLink]="['journal-entries/create']"
class="menu-explanation"
>
{{ 'labels.text.Manual journal entry transactions recorded in a journal' | translate }}
</p>
@if (arrowBooleans[1]) {
<p matLine [routerLink]="['journal-entries/create']" class="menu-explanation">
{{ 'labels.text.Manual journal entry transactions recorded in a journal' | translate }}
</p>
}
</div>
</div>
<div class="menu-right-section">
<fa-icon
(click)="arrowBooleansToggle(1)"
*ngIf="!arrowBooleans[1]"
icon="arrow-down"
size="md"
></fa-icon>
<fa-icon
(click)="arrowBooleansToggle(1)"
*ngIf="arrowBooleans[1]"
icon="arrow-up"
size="md"
></fa-icon>
@if (!arrowBooleans[1]) {
<fa-icon (click)="arrowBooleansToggle(1)" icon="arrow-down" size="md"></fa-icon>
}
@if (arrowBooleans[1]) {
<fa-icon (click)="arrowBooleansToggle(1)" icon="arrow-up" size="md"></fa-icon>
}
</div>
</div>
</mat-list-item>
@@ -78,19 +65,20 @@
</mat-icon>
<div matLine>
{{ 'labels.heading.Search Journal Entries' | translate }}
<p matLine *ngIf="arrowBooleans[2]" [routerLink]="['journal-entries']" class="menu-explanation">
{{ 'labels.text.Advanced search option for journal entries' | translate }}
</p>
@if (arrowBooleans[2]) {
<p matLine [routerLink]="['journal-entries']" class="menu-explanation">
{{ 'labels.text.Advanced search option for journal entries' | translate }}
</p>
}
</div>
</div>
<div class="menu-right-section">
<fa-icon
(click)="arrowBooleansToggle(2)"
*ngIf="!arrowBooleans[2]"
icon="arrow-down"
size="md"
></fa-icon>
<fa-icon (click)="arrowBooleansToggle(2)" *ngIf="arrowBooleans[2]" icon="arrow-up" size="md"></fa-icon>
@if (!arrowBooleans[2]) {
<fa-icon (click)="arrowBooleansToggle(2)" icon="arrow-down" size="md"></fa-icon>
}
@if (arrowBooleans[2]) {
<fa-icon (click)="arrowBooleansToggle(2)" icon="arrow-up" size="md"></fa-icon>
}
</div>
</div>
</mat-list-item>
@@ -104,29 +92,20 @@
</mat-icon>
<div matLine>
{{ 'labels.heading.Accounts Linked to Financial Activities' | translate }}
<p
matLine
*ngIf="arrowBooleans[3]"
[routerLink]="['financial-activity-mappings']"
class="menu-explanation"
>
{{ 'labels.text.List of Financial Activities and GL Account Mappings' | translate }}
</p>
@if (arrowBooleans[3]) {
<p matLine [routerLink]="['financial-activity-mappings']" class="menu-explanation">
{{ 'labels.text.List of Financial Activities and GL Account Mappings' | translate }}
</p>
}
</div>
</div>
<div class="menu-right-section">
<fa-icon
(click)="arrowBooleansToggle(3)"
*ngIf="!arrowBooleans[3]"
icon="arrow-down"
size="md"
></fa-icon>
<fa-icon
(click)="arrowBooleansToggle(3)"
*ngIf="arrowBooleans[3]"
icon="arrow-up"
size="md"
></fa-icon>
@if (!arrowBooleans[3]) {
<fa-icon (click)="arrowBooleansToggle(3)" icon="arrow-down" size="md"></fa-icon>
}
@if (arrowBooleans[3]) {
<fa-icon (click)="arrowBooleansToggle(3)" icon="arrow-up" size="md"></fa-icon>
}
</div>
</div>
</mat-list-item>
@@ -141,29 +120,20 @@
</mat-icon>
<div matLine>
{{ 'labels.heading.Migrate Opening Balances (Office-wise)' | translate }}
<p
matLine
*ngIf="arrowBooleans[4]"
[routerLink]="['migrate-opening-balances']"
class="menu-explanation"
>
{{ 'labels.text.Set or update office-level opening balances for GL accounts' | translate }}
</p>
@if (arrowBooleans[4]) {
<p matLine [routerLink]="['migrate-opening-balances']" class="menu-explanation">
{{ 'labels.text.Set or update office-level opening balances for GL accounts' | translate }}
</p>
}
</div>
</div>
<div class="menu-right-section">
<fa-icon
(click)="arrowBooleansToggle(4)"
*ngIf="!arrowBooleans[4]"
icon="arrow-down"
size="md"
></fa-icon>
<fa-icon
(click)="arrowBooleansToggle(4)"
*ngIf="arrowBooleans[4]"
icon="arrow-up"
size="md"
></fa-icon>
@if (!arrowBooleans[4]) {
<fa-icon (click)="arrowBooleansToggle(4)" icon="arrow-down" size="md"></fa-icon>
}
@if (arrowBooleans[4]) {
<fa-icon (click)="arrowBooleansToggle(4)" icon="arrow-up" size="md"></fa-icon>
}
</div>
</div>
</mat-list-item>
@@ -182,24 +152,20 @@
</mat-icon>
<div matLine>
{{ 'labels.heading.Chart of Accounts' | translate }}
<p matLine *ngIf="arrowBooleans[5]" [routerLink]="['chart-of-accounts']" class="menu-explanation">
{{ 'labels.text.List of accounts used by the organization' | translate }}
</p>
@if (arrowBooleans[5]) {
<p matLine [routerLink]="['chart-of-accounts']" class="menu-explanation">
{{ 'labels.text.List of accounts used by the organization' | translate }}
</p>
}
</div>
</div>
<div class="menu-right-section">
<fa-icon
(click)="arrowBooleansToggle(5)"
*ngIf="!arrowBooleans[5]"
icon="arrow-down"
size="md"
></fa-icon>
<fa-icon
(click)="arrowBooleansToggle(5)"
*ngIf="arrowBooleans[5]"
icon="arrow-up"
size="md"
></fa-icon>
@if (!arrowBooleans[5]) {
<fa-icon (click)="arrowBooleansToggle(5)" icon="arrow-down" size="md"></fa-icon>
}
@if (arrowBooleans[5]) {
<fa-icon (click)="arrowBooleansToggle(5)" icon="arrow-up" size="md"></fa-icon>
}
</div>
</div>
</mat-list-item>
@@ -214,24 +180,20 @@
</mat-icon>
<div matLine>
{{ 'labels.heading.Closing Entries' | translate }}
<p matLine *ngIf="arrowBooleans[6]" [routerLink]="['closing-entries']" class="menu-explanation">
{{ 'labels.text.Journal entries made at the end of accounting period' | translate }}
</p>
@if (arrowBooleans[6]) {
<p matLine [routerLink]="['closing-entries']" class="menu-explanation">
{{ 'labels.text.Journal entries made at the end of accounting period' | translate }}
</p>
}
</div>
</div>
<div class="menu-right-section">
<fa-icon
(click)="arrowBooleansToggle(6)"
*ngIf="!arrowBooleans[6]"
icon="arrow-down"
size="md"
></fa-icon>
<fa-icon
(click)="arrowBooleansToggle(6)"
*ngIf="arrowBooleans[6]"
icon="arrow-up"
size="md"
></fa-icon>
@if (!arrowBooleans[6]) {
<fa-icon (click)="arrowBooleansToggle(6)" icon="arrow-down" size="md"></fa-icon>
}
@if (arrowBooleans[6]) {
<fa-icon (click)="arrowBooleansToggle(6)" icon="arrow-up" size="md"></fa-icon>
}
</div>
</div>
</mat-list-item>
@@ -245,19 +207,20 @@
</mat-icon>
<div matLine>
{{ 'labels.heading.Accounting Rules' | translate }}
<p matLine *ngIf="arrowBooleans[7]" [routerLink]="['accounting-rules']" class="menu-explanation">
{{ 'labels.text.List of all accounting rules' | translate }}
</p>
@if (arrowBooleans[7]) {
<p matLine [routerLink]="['accounting-rules']" class="menu-explanation">
{{ 'labels.text.List of all accounting rules' | translate }}
</p>
}
</div>
</div>
<div class="menu-right-section">
<fa-icon
(click)="arrowBooleansToggle(7)"
*ngIf="!arrowBooleans[7]"
icon="arrow-down"
size="md"
></fa-icon>
<fa-icon (click)="arrowBooleansToggle(7)" *ngIf="arrowBooleans[7]" icon="arrow-up" size="md"></fa-icon>
@if (!arrowBooleans[7]) {
<fa-icon (click)="arrowBooleansToggle(7)" icon="arrow-down" size="md"></fa-icon>
}
@if (arrowBooleans[7]) {
<fa-icon (click)="arrowBooleansToggle(7)" icon="arrow-up" size="md"></fa-icon>
}
</div>
</div>
</mat-list-item>
@@ -270,19 +233,20 @@
</mat-icon>
<div matLine>
{{ 'labels.heading.Accruals' | translate }}
<p matLine *ngIf="arrowBooleans[8]" [routerLink]="['periodic-accruals']" class="menu-explanation">
{{ 'labels.text.Accrues income, expenses and liabilities' | translate }}
</p>
@if (arrowBooleans[8]) {
<p matLine [routerLink]="['periodic-accruals']" class="menu-explanation">
{{ 'labels.text.Accrues income, expenses and liabilities' | translate }}
</p>
}
</div>
</div>
<div class="menu-right-section">
<fa-icon
(click)="arrowBooleansToggle(8)"
*ngIf="!arrowBooleans[8]"
icon="arrow-down"
size="md"
></fa-icon>
<fa-icon (click)="arrowBooleansToggle(8)" *ngIf="arrowBooleans[8]" icon="arrow-up" size="md"></fa-icon>
@if (!arrowBooleans[8]) {
<fa-icon (click)="arrowBooleansToggle(8)" icon="arrow-down" size="md"></fa-icon>
}
@if (arrowBooleans[8]) {
<fa-icon (click)="arrowBooleansToggle(8)" icon="arrow-up" size="md"></fa-icon>
}
</div>
</div>
</mat-list-item>
@@ -295,19 +259,20 @@
</mat-icon>
<div matLine>
{{ 'labels.heading.Provisioning Entries' | translate }}
<p matLine *ngIf="arrowBooleans[9]" [routerLink]="['provisioning-entries']" class="menu-explanation">
{{ 'labels.text.Create provisioning entries' | translate }}
</p>
@if (arrowBooleans[9]) {
<p matLine [routerLink]="['provisioning-entries']" class="menu-explanation">
{{ 'labels.text.Create provisioning entries' | translate }}
</p>
}
</div>
</div>
<div class="menu-right-section">
<fa-icon
(click)="arrowBooleansToggle(9)"
*ngIf="!arrowBooleans[9]"
icon="arrow-down"
size="md"
></fa-icon>
<fa-icon (click)="arrowBooleansToggle(9)" *ngIf="arrowBooleans[9]" icon="arrow-up" size="md"></fa-icon>
@if (!arrowBooleans[9]) {
<fa-icon (click)="arrowBooleansToggle(9)" icon="arrow-down" size="md"></fa-icon>
}
@if (arrowBooleans[9]) {
<fa-icon (click)="arrowBooleansToggle(9)" icon="arrow-up" size="md"></fa-icon>
}
</div>
</div>
</mat-list-item>
+5 -12
View File
@@ -1,5 +1,5 @@
/** Angular Imports */
import { AfterViewInit, Component, ElementRef, TemplateRef, ViewChild } from '@angular/core';
import { AfterViewInit, Component, ElementRef, TemplateRef, ViewChild, inject } from '@angular/core';
import { Router, RouterLink } from '@angular/router';
/** Custom Services */
@@ -28,6 +28,10 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class AccountingComponent implements AfterViewInit {
private router = inject(Router);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
/* Reference of Chart of Accounts */
@ViewChild('chartofAccounts') chartofAccounts: ElementRef<any>;
/* Template for popover on Chart of Accounts */
@@ -51,17 +55,6 @@ export class AccountingComponent implements AfterViewInit {
// Initialize an array of 10 boolean values, all set to false
arrowBooleans: boolean[] = new Array(10).fill(false);
/**
* @param {Router} router Router.
* @param {ConfigurationWizardService} configurationWizardService ConfigurationWizard Service.
* @param {PopoverService} popoverService PopoverService.
*/
constructor(
private router: Router,
private configurationWizardService: ConfigurationWizardService,
private popoverService: PopoverService
) {}
/**
* Popover function
* @param template TemplateRef<any>.
+2 -5
View File
@@ -1,7 +1,7 @@
/** TODO: Separate services for feature modules for cleaner accounting service. */
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
/** rxjs Imports */
@@ -14,10 +14,7 @@ import { Observable } from 'rxjs';
providedIn: 'root'
})
export class AccountingService {
/**
* @param {HttpClient} http Http Client to send requests.
*/
constructor(private http: HttpClient) {}
private http = inject(HttpClient);
/**
* @returns {Observable<any>} Offices data ordered by id.
@@ -70,22 +70,24 @@
{{ 'labels.inputs.Manual Entries Allowed' | translate }}
</th>
<td mat-cell *matCellDef="let glAccount">
<fa-icon
*ngIf="glAccount.manualEntriesAllowed"
class="manual-entries-allowed"
matTooltip="{{ 'tooltips.Allowed' | translate }}"
matTooltipPosition="right"
icon="check-circle"
size="lg"
></fa-icon>
<fa-icon
*ngIf="!glAccount.manualEntriesAllowed"
class="manual-entries-not-allowed"
matTooltip="{{ 'tooltips.' | translate }}"
matTooltipPosition="right"
icon="times-circle"
size="lg"
></fa-icon>
@if (glAccount.manualEntriesAllowed) {
<fa-icon
class="manual-entries-allowed"
matTooltip="{{ 'tooltips.Allowed' | translate }}"
matTooltipPosition="right"
icon="check-circle"
size="lg"
></fa-icon>
}
@if (!glAccount.manualEntriesAllowed) {
<fa-icon
class="manual-entries-not-allowed"
matTooltip="{{ 'tooltips.' | translate }}"
matTooltipPosition="right"
icon="times-circle"
size="lg"
></fa-icon>
}
</td>
</ng-container>
@@ -123,7 +125,9 @@
<li class="mat-tree-node">
<button mat-icon-button disabled></button>
<span (click)="viewGLAccountNode(node)">
<span *ngIf="node.glCode" class="m-r-10">{{ '(' + node.glCode + ')' }}</span>
@if (node.glCode) {
<span class="m-r-10">{{ '(' + node.glCode + ')' }}</span>
}
{{ node.name }}
</span>
</li>
@@ -139,7 +143,9 @@
></fa-icon>
</button>
<span (click)="viewGLAccountNode(node)">
<span *ngIf="node.glCode" class="m-r-10">{{ '(' + node.glCode + ')' }}</span>
@if (node.glCode) {
<span class="m-r-10">{{ '(' + node.glCode + ')' }}</span>
}
{{ node.name }}
</span>
</div>
@@ -151,61 +157,52 @@
</mat-tree>
</div>
<div class="flex-48" *ngIf="glAccount">
<mat-card>
<mat-card-content>
<div class="layout-row-wrap">
<div class="flex-50 header">
{{ 'labels.inputs.Account Name' | translate }}
@if (glAccount) {
<div class="flex-48">
<mat-card>
<mat-card-content>
<div class="layout-row-wrap">
<div class="flex-50 header">
{{ 'labels.inputs.Account Name' | translate }}
</div>
<div class="flex-50">
{{ glAccount.name }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.GL Code' | translate }}
</div>
<div class="flex-50">
{{ glAccount.glCode }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Account Type' | translate }}
</div>
<div class="flex-50">
{{ 'labels.inputs.accounting.' + glAccount.type | translate }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Account Usage' | translate }}
</div>
<div class="flex-50">
{{ glAccount.usage }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Manual Entries Allowed' | translate }}
</div>
<div class="flex-50">
{{ glAccount.manualEntriesAllowed }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Description' | translate }}
</div>
<div class="flex-50">
{{ glAccount.description }}
</div>
</div>
<div class="flex-50">
{{ glAccount.name }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.GL Code' | translate }}
</div>
<div class="flex-50">
{{ glAccount.glCode }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Account Type' | translate }}
</div>
<div class="flex-50">
{{ 'labels.inputs.accounting.' + glAccount.type | translate }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Account Usage' | translate }}
</div>
<div class="flex-50">
{{ glAccount.usage }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Manual Entries Allowed' | translate }}
</div>
<div class="flex-50">
{{ glAccount.manualEntriesAllowed }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Description' | translate }}
</div>
<div class="flex-50">
{{ glAccount.description }}
</div>
</div>
</mat-card-content>
</mat-card>
</div>
</mat-card-content>
</mat-card>
</div>
}
</div>
</div>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit, inject } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, MatSortHeader } from '@angular/material/sort';
import {
@@ -81,6 +81,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class ChartOfAccountsComponent implements AfterViewInit, OnInit {
private glAccountTreeService = inject(GlAccountTreeService);
private route = inject(ActivatedRoute);
private router = inject(Router);
private treeControlService = inject(TreeControlService);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
/** Button toggle group form control for type of view. (list/tree) */
viewGroup = new UntypedFormControl('listView');
/** GL Account data. */
@@ -127,14 +134,9 @@ export class ChartOfAccountsComponent implements AfterViewInit, OnInit {
* @param {ConfigurationWizardService} configurationWizardService ConfigurationWizard Service.
* @param {PopoverService} popoverService PopoverService.
*/
constructor(
private glAccountTreeService: GlAccountTreeService,
private route: ActivatedRoute,
private router: Router,
private treeControlService: TreeControlService,
private configurationWizardService: ConfigurationWizardService,
private popoverService: PopoverService
) {
constructor() {
const glAccountTreeService = this.glAccountTreeService;
this.route.data.subscribe((data: { chartOfAccounts: any }) => {
this.glAccountData = data.chartOfAccounts;
glAccountTreeService.initialize(this.glAccountData);
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class ChartOfAccountsResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the chart of accounts data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../../accounting.service';
*/
@Injectable()
export class ChartOfAccountsTemplateResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the chart of accounts template data.
@@ -6,65 +6,69 @@
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Account Type' | translate }}</mat-label>
<mat-select required formControlName="type">
<mat-option *ngFor="let accountType of accountTypeData" [value]="accountType.id">
{{ 'labels.inputs.accounting.' + accountType.value | translate }}
</mat-option>
@for (accountType of accountTypeData; track accountType) {
<mat-option [value]="accountType.id">
{{ 'labels.inputs.accounting.' + accountType.value | translate }}
</mat-option>
}
</mat-select>
<mat-error
*ngIf="
glAccountForm.controls.type.hasError('required') &&
(glAccountForm.controls.type.touched || glAccountForm.controls.type.dirty)
"
>
{{ 'labels.inputs.Account Type' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (
glAccountForm.controls.type.hasError('required') &&
(glAccountForm.controls.type.touched || glAccountForm.controls.type.dirty)
) {
<mat-error>
{{ 'labels.inputs.Account Type' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Account Name' | translate }}</mat-label>
<input matInput required formControlName="name" />
<mat-error
*ngIf="
glAccountForm.controls.name.hasError('required') &&
(glAccountForm.controls.name.touched || glAccountForm.controls.name.dirty)
"
>
{{ 'labels.inputs.Account Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (
glAccountForm.controls.name.hasError('required') &&
(glAccountForm.controls.name.touched || glAccountForm.controls.name.dirty)
) {
<mat-error>
{{ 'labels.inputs.Account Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Account Usage' | translate }}</mat-label>
<mat-select required formControlName="usage">
<mat-option *ngFor="let accountUsage of accountUsageData" [value]="accountUsage.id">
{{ accountUsage.value }}
</mat-option>
@for (accountUsage of accountUsageData; track accountUsage) {
<mat-option [value]="accountUsage.id">
{{ accountUsage.value }}
</mat-option>
}
</mat-select>
<mat-error
*ngIf="
glAccountForm.controls.usage.hasError('required') &&
(glAccountForm.controls.usage.touched || glAccountForm.controls.usage.dirty)
"
>
{{ 'labels.inputs.Account Usage' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (
glAccountForm.controls.usage.hasError('required') &&
(glAccountForm.controls.usage.touched || glAccountForm.controls.usage.dirty)
) {
<mat-error>
{{ 'labels.inputs.Account Usage' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.GL Code' | translate }}</mat-label>
<input matInput required formControlName="glCode" />
<mat-error
*ngIf="
glAccountForm.controls.glCode.hasError('required') &&
(glAccountForm.controls.glCode.touched || glAccountForm.controls.glCode.dirty)
"
>
{{ 'labels.inputs.GL Code' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (
glAccountForm.controls.glCode.hasError('required') &&
(glAccountForm.controls.glCode.touched || glAccountForm.controls.glCode.dirty)
) {
<mat-error>
{{ 'labels.inputs.GL Code' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mifosx-gl-account-selector
@@ -79,9 +83,11 @@
<mat-form-field class="flex-28">
<mat-label>{{ 'labels.inputs.Tag' | translate }}</mat-label>
<mat-select formControlName="tagId">
<mat-option *ngFor="let tag of tagData" [value]="tag.id">
{{ tag.name }}
</mat-option>
@for (tag of tagData; track tag) {
<mat-option [value]="tag.id">
{{ tag.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit, inject } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
@@ -32,6 +32,14 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class CreateGlAccountComponent implements OnInit, AfterViewInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
dialog = inject(MatDialog);
/** GL account form. */
glAccountForm: UntypedFormGroup;
/** Chart of accounts data. */
@@ -66,15 +74,7 @@ export class CreateGlAccountComponent implements OnInit, AfterViewInit {
* @param {PopoverService} popoverService PopoverService.
* @param {Matdialog} dialog Matdialog.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router,
private configurationWizardService: ConfigurationWizardService,
private popoverService: PopoverService,
public dialog: MatDialog
) {
constructor() {
this.route.queryParamMap.subscribe((params) => {
this.accountTypeId = Number(params.get('accountType'));
this.parentId = Number(params.get('parent'));
@@ -6,45 +6,57 @@
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Account Type' | translate }}</mat-label>
<mat-select required formControlName="type">
<mat-option *ngFor="let accountType of accountTypeData" [value]="accountType.id">
{{ accountType.value }}
</mat-option>
@for (accountType of accountTypeData; track accountType) {
<mat-option [value]="accountType.id">
{{ accountType.value }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="glAccountForm.controls.type.hasError('required')">
{{ 'labels.inputs.Account Type' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (glAccountForm.controls.type.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Account Type' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Account Name' | translate }}</mat-label>
<input matInput required formControlName="name" />
<mat-error *ngIf="glAccountForm.controls.name.hasError('required')">
{{ 'labels.inputs.Account Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (glAccountForm.controls.name.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Account Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Account Usage' | translate }}</mat-label>
<mat-select required formControlName="usage">
<mat-option *ngFor="let accountUsage of accountUsageData" [value]="accountUsage.id">
{{ accountUsage.value }}
</mat-option>
@for (accountUsage of accountUsageData; track accountUsage) {
<mat-option [value]="accountUsage.id">
{{ accountUsage.value }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="glAccountForm.controls.usage.hasError('required')">
{{ 'labels.inputs.Account Usage' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (glAccountForm.controls.usage.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Account Usage' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.GL Code' | translate }}</mat-label>
<input matInput required formControlName="glCode" />
<mat-error *ngIf="glAccountForm.controls.glCode.hasError('required')">
{{ 'labels.inputs.GL Code' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (glAccountForm.controls.glCode.hasError('required')) {
<mat-error>
{{ 'labels.inputs.GL Code' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mifosx-gl-account-selector
@@ -59,9 +71,11 @@
<mat-form-field class="flex-28">
<mat-label>{{ 'labels.inputs.Tag' | translate }}</mat-label>
<mat-select formControlName="tagId">
<mat-option *ngFor="let tag of tagData" [value]="tag.id">
{{ tag.name }}
</mat-option>
@for (tag of tagData; track tag) {
<mat-option [value]="tag.id">
{{ tag.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
@@ -25,6 +25,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class EditGlAccountComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** GL account form. */
glAccountForm: UntypedFormGroup;
/** GL account and chart of accounts data. */
@@ -45,12 +50,7 @@ export class EditGlAccountComponent implements OnInit {
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router
) {
constructor() {
this.route.data.subscribe((data: { glAccountAndChartOfAccountsTemplate: any }) => {
this.glAccount = data.glAccountAndChartOfAccountsTemplate;
});
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
@@ -14,10 +14,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class GlAccountAndChartOfAccountsTemplateResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the gl account and chart of accounts template data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { BehaviorSubject } from 'rxjs';
@@ -16,6 +16,8 @@ import { GLAccount } from 'app/shared/models/general.model';
providedIn: 'root'
})
export class GlAccountTreeService {
private translateService = inject(TranslateService);
/** GL Account data. */
glAccountData: any;
/** Chart of accounts tree data behavior subject to represent chart of accounts tree nodes. */
@@ -28,8 +30,6 @@ export class GlAccountTreeService {
return this.treeDataChange.value;
}
constructor(private translateService: TranslateService) {}
/**
* Builds the chart of accounts tree and emits the value.
* @param {any} glAccountData Chart of accounts data.
@@ -1,15 +1,16 @@
<div class="container m-b-20 layout-row layout-lt-md-column align-end gap-2percent">
<span *mifosxHasPermission="'CREATE_GLACCOUNT'">
<button
mat-raised-button
color="primary"
*ngIf="glAccount.usage.value === 'HEADER'"
[routerLink]="['/accounting/chart-of-accounts/gl-accounts/create']"
[queryParams]="{ parent: glAccount.id, accountType: glAccount.type.id }"
>
<fa-icon icon="plus" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Subledger Account' | translate }}
</button>
@if (glAccount.usage.value === 'HEADER') {
<button
mat-raised-button
color="primary"
[routerLink]="['/accounting/chart-of-accounts/gl-accounts/create']"
[queryParams]="{ parent: glAccount.id, accountType: glAccount.type.id }"
>
<fa-icon icon="plus" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Subledger Account' | translate }}
</button>
}
</span>
<span *mifosxHasPermission="'UPDATE_GLACCOUNT'">
@@ -20,17 +21,21 @@
</span>
<span *mifosxHasPermission="'UPDATE_GLACCOUNT'">
<button mat-raised-button color="warn" *ngIf="!glAccount.disabled" (click)="changeGlAccountState()">
<fa-icon icon="lock" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Disable' | translate }}
</button>
@if (!glAccount.disabled) {
<button mat-raised-button color="warn" (click)="changeGlAccountState()">
<fa-icon icon="lock" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Disable' | translate }}
</button>
}
</span>
<span *mifosxHasPermission="'UPDATE_GLACCOUNT'">
<button mat-raised-button color="accent" *ngIf="glAccount.disabled" (click)="changeGlAccountState()">
<fa-icon icon="lock-open" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Enable' | translate }}
</button>
@if (glAccount.disabled) {
<button mat-raised-button color="accent" (click)="changeGlAccountState()">
<fa-icon icon="lock-open" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Enable' | translate }}
</button>
}
</span>
<button mat-raised-button color="warn" (click)="deleteGlAccount()" *mifosxHasPermission="'DELETE_GLACCOUNT'">
@@ -54,22 +59,26 @@
<div class="value">{{ glAccount.glCode }}</div>
</div>
<div class="content-row" *ngIf="glAccount.parent">
<div class="label">{{ 'labels.inputs.Parent Account Name' | translate }}</div>
<div class="value">
<a
class="tab-link"
[routerLink]="['/accounting/chart-of-accounts/gl-accounts/view/' + glAccount.parent.id]"
>
<mifosx-gl-account-display [glAccount]="glAccount.parent"></mifosx-gl-account-display>
</a>
@if (glAccount.parent) {
<div class="content-row">
<div class="label">{{ 'labels.inputs.Parent Account Name' | translate }}</div>
<div class="value">
<a
class="tab-link"
[routerLink]="['/accounting/chart-of-accounts/gl-accounts/view/' + glAccount.parent.id]"
>
<mifosx-gl-account-display [glAccount]="glAccount.parent"></mifosx-gl-account-display>
</a>
</div>
</div>
</div>
}
<div class="content-row" *ngIf="glAccount.tagId.id">
<div class="label">{{ 'labels.inputs.Tag' | translate }}</div>
<div class="value">{{ glAccount.tagId.name }}</div>
</div>
@if (glAccount.tagId.id) {
<div class="content-row">
<div class="label">{{ 'labels.inputs.Tag' | translate }}</div>
<div class="value">{{ glAccount.tagId.name }}</div>
</div>
}
<div class="content-row">
<div class="label">{{ 'labels.inputs.Account Usage' | translate }}</div>
@@ -81,10 +90,12 @@
<div class="value">{{ glAccount.manualEntriesAllowed | yesNo }}</div>
</div>
<div class="content-row" *ngIf="glAccount.description">
<div class="label">{{ 'labels.inputs.Description' | translate }}</div>
<div class="value">{{ glAccount.description }}</div>
</div>
@if (glAccount.description) {
<div class="content-row">
<div class="label">{{ 'labels.inputs.Description' | translate }}</div>
<div class="value">{{ glAccount.description }}</div>
</div>
}
</div>
</mat-card-content>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component } from '@angular/core';
import { Component, inject } from '@angular/core';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
@@ -8,7 +8,7 @@ import { DeleteDialogComponent } from '../../../shared/delete-dialog/delete-dial
/** Custom Services */
import { AccountingService } from '../../accounting.service';
import { Location, NgIf } from '@angular/common';
import { Location } from '@angular/common';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { GlAccountDisplayComponent } from '../../../shared/accounting/gl-account-display/gl-account-display.component';
import { YesnoPipe } from '../../../pipes/yesno.pipe';
@@ -29,6 +29,12 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class ViewGlAccountComponent {
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
private dialog = inject(MatDialog);
private location = inject(Location);
/** GL Account. */
glAccount: any;
@@ -39,13 +45,7 @@ export class ViewGlAccountComponent {
* @param {Router} router Router for navigation.
* @param {MatDialog} dialog Dialog reference.
*/
constructor(
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router,
private dialog: MatDialog,
private location: Location
) {
constructor() {
this.route.data.subscribe((data: { glAccountAndChartOfAccountsTemplate: any }) => {
this.glAccount = data.glAccountAndChartOfAccountsTemplate;
});
@@ -16,9 +16,11 @@
<!-- Autocomplete data -->
<mat-autocomplete autoActiveFirstOption #officeNameAutocomplete="matAutocomplete">
<mat-option *ngFor="let office of filteredOfficeData | async" [value]="office.name">
{{ office.name }}
</mat-option>
@for (office of filteredOfficeData | async; track office) {
<mat-option [value]="office.name">
{{ office.name }}
</mat-option>
}
</mat-autocomplete>
<div class="container">
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit, inject } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, MatSortHeader } from '@angular/material/sort';
import {
@@ -26,7 +26,7 @@ import { PopoverService } from '../../configuration-wizard/popover/popover.servi
import { ConfigurationWizardService } from '../../configuration-wizard/configuration-wizard.service';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatAutocompleteTrigger, MatAutocomplete, MatOption } from '@angular/material/autocomplete';
import { NgFor, AsyncPipe } from '@angular/common';
import { AsyncPipe } from '@angular/common';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
/**
@@ -58,6 +58,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class ClosingEntriesComponent implements OnInit, AfterViewInit {
private route = inject(ActivatedRoute);
private router = inject(Router);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
/** Columns to be displayed in closing entries table. */
displayedColumns: string[] = [
'officeName',
@@ -97,12 +102,7 @@ export class ClosingEntriesComponent implements OnInit, AfterViewInit {
* @param {ConfigurationWizardService} configurationWizardService ConfigurationWizard Service.
* @param {PopoverService} popoverService PopoverService.
*/
constructor(
private route: ActivatedRoute,
private router: Router,
private configurationWizardService: ConfigurationWizardService,
private popoverService: PopoverService
) {
constructor() {
this.route.data.subscribe((data: { offices: any; glAccountClosures: any }) => {
this.officeData = data.offices;
this.glAccountClosureData = data.glAccountClosures;
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class ClosingEntriesResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the gl account closures data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
@@ -13,10 +13,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class ClosingEntryResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the gl account closure data.
@@ -6,14 +6,18 @@
<mat-form-field>
<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>
@for (office of officeData; track office) {
<mat-option [value]="office.id">
{{ office.name }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="accountingClosureForm.controls.officeId.hasError('required')">
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (accountingClosureForm.controls.officeId.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field (click)="closingDatePicker.open()">
@@ -28,10 +32,12 @@
/>
<mat-datepicker-toggle matSuffix [for]="closingDatePicker"></mat-datepicker-toggle>
<mat-datepicker #closingDatePicker></mat-datepicker>
<mat-error *ngIf="accountingClosureForm.controls.closingDate.hasError('required')">
{{ 'labels.inputs.Closing Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (accountingClosureForm.controls.closingDate.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Closing Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
@@ -22,6 +22,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class CreateClosureComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private settingsService = inject(SettingsService);
private dateUtils = inject(Dates);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Minimum closing date allowed. */
minDate = new Date(2000, 0, 1);
/** Maximum closing date allowed. */
@@ -39,14 +46,7 @@ export class CreateClosureComponent implements OnInit {
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private settingsService: SettingsService,
private dateUtils: Dates,
private route: ActivatedRoute,
private router: Router
) {
constructor() {
this.route.data.subscribe((data: { offices: any }) => {
this.officeData = data.offices;
});
@@ -6,9 +6,11 @@
<mat-form-field>
<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>
@for (office of officeData; track office) {
<mat-option [value]="office.id">
{{ office.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
@@ -21,6 +21,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class EditClosureComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Accounting closure form. */
accountingClosureForm: UntypedFormGroup;
/** GL Account closure. */
@@ -35,12 +40,7 @@ export class EditClosureComponent implements OnInit {
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router
) {
constructor() {
this.route.data.subscribe((data: { glAccountClosure: any }) => {
this.glAccountClosure = data.glAccountClosure;
});
@@ -9,66 +9,55 @@
</button>
</div>
<div class="container" *ngIf="glAccountClosure">
<mat-card>
<mat-card-content>
<div class="layout-row-wrap">
<div class="flex-50 header">
{{ 'labels.inputs.Office' | translate }}
@if (glAccountClosure) {
<div class="container">
<mat-card>
<mat-card-content>
<div class="layout-row-wrap">
<div class="flex-50 header">
{{ 'labels.inputs.Office' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.officeName }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Closure Date' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.closingDate }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Closed By' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.createdByUsername }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Updated By' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.lastUpdatedByUsername }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Updated On' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.lastUpdatedDate }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Closure Creation Date' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.createdDate }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Comments' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.comments }}
</div>
</div>
<div class="flex-50">
{{ glAccountClosure.officeName }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Closure Date' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.closingDate }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Closed By' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.createdByUsername }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Updated By' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.lastUpdatedByUsername }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Updated On' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.lastUpdatedDate }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Closure Creation Date' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.createdDate }}
</div>
<div class="flex-50 header">
{{ 'labels.inputs.Comments' | translate }}
</div>
<div class="flex-50">
{{ glAccountClosure.comments }}
</div>
</div>
</mat-card-content>
</mat-card>
</div>
</mat-card-content>
</mat-card>
</div>
}
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component } from '@angular/core';
import { Component, inject } from '@angular/core';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
@@ -24,6 +24,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class ViewClosureComponent {
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
dialog = inject(MatDialog);
/** GL Account closure. */
glAccountClosure: any;
@@ -34,12 +39,7 @@ export class ViewClosureComponent {
* @param {Router} router Router for navigation.
* @param {MatDialog} dialog Dialog reference.
*/
constructor(
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router,
public dialog: MatDialog
) {
constructor() {
this.route.data.subscribe((data: { glAccountClosure: any }) => {
this.glAccountClosure = data.glAccountClosure;
});
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class AccountingRulesAssociationsResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the accounting rules associations data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class CurrenciesResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the currencies data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { SystemService } from 'app/system/system.service';
*/
@Injectable()
export class ExternalAssetConfigurationResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private systemService: SystemService) {}
private systemService = inject(SystemService);
/**
* Returns the offices data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class GlAccountsResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the gl accounts data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
@@ -13,10 +13,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class JournalEntryTransactionResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the transaction data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class LoanProductsResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the loan products data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class OfficesResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the offices data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class PaymentTypesResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the payment types data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class ProvisioningCategoriesResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the Provisioning categories data.
@@ -6,129 +6,131 @@
<mat-form-field class="flex-48">
<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>
@for (office of officeData; track office) {
<mat-option [value]="office.id">
{{ office.name }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="journalEntryForm.controls.officeId.hasError('required')">
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (journalEntryForm.controls.officeId.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-24">
<mat-label>{{ 'labels.inputs.Currency' | translate }}</mat-label>
<mat-select required formControlName="currencyCode">
<mat-option *ngFor="let currency of currencyData" [value]="currency.code">
{{ currency.displayLabel }}
</mat-option>
@for (currency of currencyData; track currency) {
<mat-option [value]="currency.code">
{{ currency.displayLabel }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="journalEntryForm.controls.currencyCode.hasError('required')">
{{ 'labels.inputs.Currency' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (journalEntryForm.controls.currencyCode.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Currency' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-24" *ngIf="assetExternalizationEnabled">
<mat-label>{{ 'labels.inputs.External Asset Owner' | translate }}</mat-label>
<input matInput formControlName="externalAssetOwner" />
</mat-form-field>
@if (assetExternalizationEnabled) {
<mat-form-field class="flex-24">
<mat-label>{{ 'labels.inputs.External Asset Owner' | translate }}</mat-label>
<input matInput formControlName="externalAssetOwner" />
</mat-form-field>
}
<div
class="flex-fill layout-row-wrap responsive-column"
formArrayName="debits"
*ngFor="let debit of debits.controls; let i = index"
>
<div class="flex-fill layout-row-wrap gap-2percent responsive-column" [formGroupName]="i">
<mifosx-gl-account-selector
class="flex-48"
[inputFormControl]="debits.at(i).controls.glAccountId"
[glAccountList]="glAccountData"
[required]="true"
[inputLabel]="'Affected GL Entry (Debit)'"
>
</mifosx-gl-account-selector>
<mat-form-field class="flex-43">
<mat-label>{{ 'labels.inputs.Debit Amount' | translate }}</mat-label>
<input
type="number"
matInput
required
formControlName="amount"
min="1"
(input)="onAmountInput($event)"
/>
<mat-error *ngIf="debits.at(i).controls.amount.hasError('required')">
{{ 'labels.inputs.Debit Amount' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<span class="flex-fill">
<button *ngIf="i !== 0" type="button" mat-icon-button (click)="removeAffectedGLEntry(debits, i)">
<fa-icon icon="minus-circle" size="lg"></fa-icon>
</button>
<button
*ngIf="i === 0"
type="button"
mat-icon-button
color="primary"
(click)="addAffectedGLEntry(debits)"
@for (debit of debits.controls; track debit; let i = $index) {
<div class="flex-fill layout-row-wrap responsive-column" formArrayName="debits">
<div class="flex-fill layout-row-wrap gap-2percent responsive-column" [formGroupName]="i">
<mifosx-gl-account-selector
class="flex-48"
[inputFormControl]="debits.at(i).controls.glAccountId"
[glAccountList]="glAccountData"
[required]="true"
[inputLabel]="'Affected GL Entry (Debit)'"
>
<fa-icon icon="plus-circle" size="lg"></fa-icon>
</button>
</span>
</mifosx-gl-account-selector>
<mat-form-field class="flex-43">
<mat-label>{{ 'labels.inputs.Debit Amount' | translate }}</mat-label>
<input
type="number"
matInput
required
formControlName="amount"
min="1"
(input)="onAmountInput($event)"
/>
@if (debits.at(i).controls.amount.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Debit Amount' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<span class="flex-fill">
@if (i !== 0) {
<button type="button" mat-icon-button (click)="removeAffectedGLEntry(debits, i)">
<fa-icon icon="minus-circle" size="lg"></fa-icon>
</button>
}
@if (i === 0) {
<button type="button" mat-icon-button color="primary" (click)="addAffectedGLEntry(debits)">
<fa-icon icon="plus-circle" size="lg"></fa-icon>
</button>
}
</span>
</div>
</div>
</div>
}
<div
class="flex-fill layout-row-wrap responsive-column"
formArrayName="credits"
*ngFor="let credit of credits.controls; let i = index"
>
<div class="flex-fill layout-row-wrap gap-2percent responsive-column" [formGroupName]="i">
<mifosx-gl-account-selector
class="flex-48"
[inputFormControl]="credits.at(i).controls.glAccountId"
[glAccountList]="glAccountData"
[required]="true"
[inputLabel]="'Affected GL Entry (Credit)'"
>
</mifosx-gl-account-selector>
<mat-form-field class="flex-43">
<mat-label>{{ 'labels.inputs.Credit Amount' | translate }}</mat-label>
<input
type="number"
matInput
required
formControlName="amount"
min="1"
(input)="onAmountInput($event)"
/>
<mat-error *ngIf="credits.at(i).controls.amount.hasError('required')">
{{ 'labels.inputs.Credit Amount' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<span class="flex-fill">
<button *ngIf="i !== 0" type="button" mat-icon-button (click)="removeAffectedGLEntry(credits, i)">
<fa-icon icon="minus-circle" size="lg"></fa-icon>
</button>
<button
*ngIf="i === 0"
type="button"
mat-icon-button
color="primary"
(click)="addAffectedGLEntry(credits)"
@for (credit of credits.controls; track credit; let i = $index) {
<div class="flex-fill layout-row-wrap responsive-column" formArrayName="credits">
<div class="flex-fill layout-row-wrap gap-2percent responsive-column" [formGroupName]="i">
<mifosx-gl-account-selector
class="flex-48"
[inputFormControl]="credits.at(i).controls.glAccountId"
[glAccountList]="glAccountData"
[required]="true"
[inputLabel]="'Affected GL Entry (Credit)'"
>
<fa-icon icon="plus-circle" size="lg"></fa-icon>
</button>
</span>
</mifosx-gl-account-selector>
<mat-form-field class="flex-43">
<mat-label>{{ 'labels.inputs.Credit Amount' | translate }}</mat-label>
<input
type="number"
matInput
required
formControlName="amount"
min="1"
(input)="onAmountInput($event)"
/>
@if (credits.at(i).controls.amount.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Credit Amount' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<span class="flex-fill">
@if (i !== 0) {
<button type="button" mat-icon-button (click)="removeAffectedGLEntry(credits, i)">
<fa-icon icon="minus-circle" size="lg"></fa-icon>
</button>
}
@if (i === 0) {
<button type="button" mat-icon-button color="primary" (click)="addAffectedGLEntry(credits)">
<fa-icon icon="plus-circle" size="lg"></fa-icon>
</button>
}
</span>
</div>
</div>
</div>
}
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Reference Number' | translate }}</mat-label>
@@ -147,18 +149,22 @@
/>
<mat-datepicker-toggle matSuffix [for]="transactionDatePicker"></mat-datepicker-toggle>
<mat-datepicker #transactionDatePicker></mat-datepicker>
<mat-error *ngIf="journalEntryForm.controls.transactionDate.hasError('required')">
{{ 'labels.inputs.Transaction Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (journalEntryForm.controls.transactionDate.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Transaction Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Payment Type' | translate }}</mat-label>
<mat-select formControlName="paymentTypeId">
<mat-option *ngFor="let paymentType of paymentTypeData" [value]="paymentType.id">
{{ paymentType.name }}
</mat-option>
@for (paymentType of paymentTypeData; track paymentType) {
<mat-option [value]="paymentType.id">
{{ paymentType.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit, inject } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormArray, UntypedFormControl } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
@@ -34,6 +34,16 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class CreateJournalEntryComponent implements OnInit, AfterViewInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private settingsService = inject(SettingsService);
private dateUtils = inject(Dates);
private route = inject(ActivatedRoute);
private router = inject(Router);
private dialog = inject(MatDialog);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
onCreditAmountInput(event: any) {
if (event.target.value < 1) {
event.target.value = 1;
@@ -72,17 +82,7 @@ export class CreateJournalEntryComponent implements OnInit, AfterViewInit {
* @param {ConfigurationWizardService} configurationWizardService ConfigurationWizard Service.
* @param {PopoverService} popoverService PopoverService.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private settingsService: SettingsService,
private dateUtils: Dates,
private route: ActivatedRoute,
private router: Router,
private dialog: MatDialog,
private configurationWizardService: ConfigurationWizardService,
private popoverService: PopoverService
) {
constructor() {
this.assetExternalizationEnabled = false;
this.route.data.subscribe(
(data: { offices: any; currencies: any; paymentTypes: any; glAccounts: any; globalConfig: any }) => {
@@ -147,7 +147,8 @@ export class CreateJournalEntryComponent implements OnInit, AfterViewInit {
'',
[
Validators.required,
Validators.min(1)]
Validators.min(1)
]
]
});
}
@@ -6,15 +6,19 @@
<mat-form-field>
<mat-label>{{ 'labels.inputs.Financial Activity' | translate }}</mat-label>
<mat-select required formControlName="financialActivityId">
<mat-option *ngFor="let financialActivity of financialActivityData" [value]="financialActivity.id">
({{ financialActivity.id }})
{{ 'labels.accounting.financialActivity.' + financialActivity.name | translate }}
</mat-option>
@for (financialActivity of financialActivityData; track financialActivity) {
<mat-option [value]="financialActivity.id">
({{ financialActivity.id }})
{{ 'labels.accounting.financialActivity.' + financialActivity.name | translate }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="financialActivityMappingForm.controls.financialActivityId.hasError('required')">
{{ 'labels.inputs.Financial Activity' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (financialActivityMappingForm.controls.financialActivityId.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Financial Activity' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mifosx-gl-account-selector
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
@@ -22,6 +22,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class CreateFinancialActivityMappingComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Financial activity mapping form. */
financialActivityMappingForm: UntypedFormGroup;
/** GL Account options. */
@@ -38,12 +43,7 @@ export class CreateFinancialActivityMappingComponent implements OnInit {
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router
) {
constructor() {
this.route.data.subscribe((data: { financialActivityAccountsTemplate: any }) => {
this.glAccountOptions = data.financialActivityAccountsTemplate.glAccountOptions;
this.financialActivityData = data.financialActivityAccountsTemplate.financialActivityOptions;
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../../accounting.service';
*/
@Injectable()
export class FinancialActivityMappingsTemplateResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the financial activity mappings template data.
@@ -6,10 +6,12 @@
<mat-form-field>
<mat-label>{{ 'labels.inputs.Financial Activity' | translate }}</mat-label>
<mat-select required formControlName="financialActivityId">
<mat-option *ngFor="let financialActivity of financialActivityData" [value]="financialActivity.id">
({{ financialActivity.id }})
{{ 'labels.accounting.financialActivity.' + financialActivity.name | translate }}
</mat-option>
@for (financialActivity of financialActivityData; track financialActivity) {
<mat-option [value]="financialActivity.id">
({{ financialActivity.id }})
{{ 'labels.accounting.financialActivity.' + financialActivity.name | translate }}
</mat-option>
}
</mat-select>
</mat-form-field>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
@@ -22,6 +22,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class EditFinancialActivityMappingComponent implements OnInit {
private formBuider = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Financial activity mapping form. */
financialActivityMappingForm: UntypedFormGroup;
/** GL Account options. */
@@ -44,12 +49,7 @@ export class EditFinancialActivityMappingComponent implements OnInit {
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private formBuider: UntypedFormBuilder,
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router
) {
constructor() {
this.route.data.subscribe((data: { financialActivityAccountAndTemplate: any }) => {
this.financialActivityAccountId = data.financialActivityAccountAndTemplate.id;
this.financialActivityId = data.financialActivityAccountAndTemplate.financialActivityData.id;
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
@@ -13,10 +13,7 @@ import { AccountingService } from '../../accounting.service';
*/
@Injectable()
export class FinancialActivityMappingAndTemplateResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the financial activity mapping and template data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit, inject } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, MatSortHeader } from '@angular/material/sort';
import {
@@ -49,6 +49,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class FinancialActivityMappingsComponent implements OnInit, AfterViewInit {
private route = inject(ActivatedRoute);
private router = inject(Router);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
/** Financial activity account data. */
financialActivityAccountData: any;
/** Columns to be displayed in financial activity mappings table. */
@@ -82,12 +87,7 @@ export class FinancialActivityMappingsComponent implements OnInit, AfterViewInit
* @param {ConfigurationWizardService} configurationWizardService ConfigurationWizard Service.
* @param {PopoverService} popoverService PopoverService.
*/
constructor(
private route: ActivatedRoute,
private router: Router,
private configurationWizardService: ConfigurationWizardService,
private popoverService: PopoverService
) {
constructor() {
this.route.data.subscribe((data: { financialActivityAccounts: any }) => {
this.financialActivityAccountData = data.financialActivityAccounts;
});
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class FinancialActivityMappingsResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the financial activity mappings data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
@@ -13,10 +13,7 @@ import { AccountingService } from '../../accounting.service';
*/
@Injectable()
export class FinancialActivityMappingResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the financial activity mapping data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component } from '@angular/core';
import { Component, inject } from '@angular/core';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
@@ -27,6 +27,12 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class ViewFinancialActivityMappingComponent {
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
private dialog = inject(MatDialog);
private location = inject(Location);
/** Financial activity account ID. */
financialActivityAccountId: any;
/** Financial activity account data. */
@@ -39,13 +45,7 @@ export class ViewFinancialActivityMappingComponent {
* @param {Router} router Router for navigation.
* @param {MatDialog} dialog Dialog reference.
*/
constructor(
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router,
private dialog: MatDialog,
private location: Location
) {
constructor() {
this.route.data.subscribe((data: { financialActivityAccount: any }) => {
this.financialActivityAccount = data.financialActivityAccount;
this.financialActivityAccountId = data.financialActivityAccount.id;
@@ -6,136 +6,145 @@
<mat-form-field class="flex-48">
<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>
@for (office of officeData; track office) {
<mat-option [value]="office.id">
{{ office.name }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="frequentPostingsForm.controls.officeId.hasError('required')">
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (frequentPostingsForm.controls.officeId.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Accounting Rule' | translate }}</mat-label>
<mat-select required formControlName="accountingRule">
<mat-option *ngFor="let accountingRule of accountingRuleData" [value]="accountingRule">
{{ accountingRule.name }}
</mat-option>
@for (accountingRule of accountingRuleData; track accountingRule) {
<mat-option [value]="accountingRule">
{{ accountingRule.name }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="frequentPostingsForm.controls.accountingRule.hasError('required')">
{{ 'labels.inputs.Accounting Rule' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (frequentPostingsForm.controls.accountingRule.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Accounting Rule' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Currency' | translate }}</mat-label>
<mat-select required formControlName="currencyCode">
<mat-option *ngFor="let currency of currencyData" [value]="currency.code">
{{ currency.displayLabel }}
</mat-option>
@for (currency of currencyData; track currency) {
<mat-option [value]="currency.code">
{{ currency.displayLabel }}
</mat-option>
}
</mat-select>
<mat-error *ngIf="frequentPostingsForm.controls.currencyCode.hasError('required')">
{{ 'labels.inputs.Currency' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (frequentPostingsForm.controls.currencyCode.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Currency' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<span class="flex-48 hide-lt-md"></span>
<div
class="flex-fill layout-row-wrap responsive-column"
formArrayName="debits"
*ngFor="let debit of debits.controls; let i = index"
>
<div class="flex-fill layout-row-wrap gap-2percent responsive-column" [formGroupName]="i">
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Affected GL Entry (Debit)' | translate }}</mat-label>
<mat-select required formControlName="glAccountId">
<mat-option *ngFor="let affectedGLEntryDebit of debitAccountData" [value]="affectedGLEntryDebit.id">
{{ affectedGLEntryDebit.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="debits.at(i).controls.glAccountId.hasError('required')">
{{ 'labels.inputs.Affected GL Entry (Debit)' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field class="flex-43">
<mat-label>{{ 'labels.inputs.Debit Amount' | translate }}</mat-label>
<input type="number" matInput required formControlName="amount" />
<mat-error *ngIf="debits.at(i).controls.amount.hasError('required')">
{{ 'labels.inputs.Debit Amount' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<span class="flex-fill">
<button *ngIf="i !== 0" type="button" mat-icon-button (click)="removeAffectedGLEntry(debits, i)">
<fa-icon icon="minus-circle" size="lg"></fa-icon>
</button>
<button
*ngIf="i === 0 && allowMultipleDebitEntries"
type="button"
mat-icon-button
color="primary"
(click)="addAffectedGLEntry(debits)"
>
<fa-icon icon="plus-circle" size="lg"></fa-icon>
</button>
</span>
@for (debit of debits.controls; track debit; let i = $index) {
<div class="flex-fill layout-row-wrap responsive-column" formArrayName="debits">
<div class="flex-fill layout-row-wrap gap-2percent responsive-column" [formGroupName]="i">
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Affected GL Entry (Debit)' | translate }}</mat-label>
<mat-select required formControlName="glAccountId">
@for (affectedGLEntryDebit of debitAccountData; track affectedGLEntryDebit) {
<mat-option [value]="affectedGLEntryDebit.id">
{{ affectedGLEntryDebit.name }}
</mat-option>
}
</mat-select>
@if (debits.at(i).controls.glAccountId.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Affected GL Entry (Debit)' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-43">
<mat-label>{{ 'labels.inputs.Debit Amount' | translate }}</mat-label>
<input type="number" matInput required formControlName="amount" />
@if (debits.at(i).controls.amount.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Debit Amount' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<span class="flex-fill">
@if (i !== 0) {
<button type="button" mat-icon-button (click)="removeAffectedGLEntry(debits, i)">
<fa-icon icon="minus-circle" size="lg"></fa-icon>
</button>
}
@if (i === 0 && allowMultipleDebitEntries) {
<button type="button" mat-icon-button color="primary" (click)="addAffectedGLEntry(debits)">
<fa-icon icon="plus-circle" size="lg"></fa-icon>
</button>
}
</span>
</div>
</div>
</div>
}
<div
class="flex-fill layout-row-wrap responsive-column"
formArrayName="credits"
*ngFor="let credit of credits.controls; let i = index"
>
<div class="flex-fill layout-row-wrap gap-2percent responsive-column" [formGroupName]="i">
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Affected GL Entry (Credit)' | translate }}</mat-label>
<mat-select required formControlName="glAccountId">
<mat-option
*ngFor="let affectedGLEntryCredit of creditAccountData"
[value]="affectedGLEntryCredit.id"
>
{{ affectedGLEntryCredit.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="credits.at(i).controls.glAccountId.hasError('required')">
{{ 'labels.inputs.Affected GL Entry (Credit)' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field class="flex-43">
<mat-label>{{ 'labels.inputs.Credit Amount' | translate }}</mat-label>
<input type="number" matInput required formControlName="amount" />
<mat-error *ngIf="credits.at(i).controls.amount.hasError('required')">
{{ 'labels.inputs.Credit Amount' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<span class="flex-fill">
<button *ngIf="i !== 0" type="button" mat-icon-button (click)="removeAffectedGLEntry(credits, i)">
<fa-icon icon="minus-circle" size="lg"></fa-icon>
</button>
<button
*ngIf="i === 0 && allowMultipleCreditEntries"
type="button"
mat-icon-button
color="primary"
(click)="addAffectedGLEntry(credits)"
>
<fa-icon icon="plus-circle" size="lg"></fa-icon>
</button>
</span>
@for (credit of credits.controls; track credit; let i = $index) {
<div class="flex-fill layout-row-wrap responsive-column" formArrayName="credits">
<div class="flex-fill layout-row-wrap gap-2percent responsive-column" [formGroupName]="i">
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Affected GL Entry (Credit)' | translate }}</mat-label>
<mat-select required formControlName="glAccountId">
@for (affectedGLEntryCredit of creditAccountData; track affectedGLEntryCredit) {
<mat-option [value]="affectedGLEntryCredit.id">
{{ affectedGLEntryCredit.name }}
</mat-option>
}
</mat-select>
@if (credits.at(i).controls.glAccountId.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Affected GL Entry (Credit)' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-43">
<mat-label>{{ 'labels.inputs.Credit Amount' | translate }}</mat-label>
<input type="number" matInput required formControlName="amount" />
@if (credits.at(i).controls.amount.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Credit Amount' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<span class="flex-fill">
@if (i !== 0) {
<button type="button" mat-icon-button (click)="removeAffectedGLEntry(credits, i)">
<fa-icon icon="minus-circle" size="lg"></fa-icon>
</button>
}
@if (i === 0 && allowMultipleCreditEntries) {
<button type="button" mat-icon-button color="primary" (click)="addAffectedGLEntry(credits)">
<fa-icon icon="plus-circle" size="lg"></fa-icon>
</button>
}
</span>
</div>
</div>
</div>
}
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Reference Number' | translate }}</mat-label>
@@ -154,18 +163,22 @@
/>
<mat-datepicker-toggle matSuffix [for]="transactionDatePicker"></mat-datepicker-toggle>
<mat-datepicker #transactionDatePicker></mat-datepicker>
<mat-error *ngIf="frequentPostingsForm.controls.transactionDate.hasError('required')">
{{ 'labels.inputs.Transaction Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (frequentPostingsForm.controls.transactionDate.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Transaction Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Payment Type' | translate }}</mat-label>
<mat-select formControlName="paymentTypeId">
<mat-option *ngFor="let paymentType of paymentTypeData" [value]="paymentType.id">
{{ paymentType.name }}
</mat-option>
@for (paymentType of paymentTypeData; track paymentType) {
<mat-option [value]="paymentType.id">
{{ paymentType.name }}
</mat-option>
}
</mat-select>
</mat-form-field>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import {
UntypedFormGroup,
UntypedFormBuilder,
@@ -32,6 +32,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class FrequentPostingsComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private settingsService = inject(SettingsService);
private dateUtils = inject(Dates);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Minimum transaction date allowed. */
minDate = new Date(2000, 0, 1);
/** Maximum transaction date allowed. */
@@ -63,14 +70,7 @@ export class FrequentPostingsComponent implements OnInit {
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private settingsService: SettingsService,
private dateUtils: Dates,
private route: ActivatedRoute,
private router: Router
) {
constructor() {
this.route.data.subscribe((data: { offices: any; accountingRules: any; currencies: any; paymentTypes: any }) => {
this.officeData = data.offices;
this.accountingRuleData = data.accountingRules;
@@ -8,14 +8,18 @@
<mat-form-field class="flex-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>
@for (office of officeData; track office) {
<mat-option [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>
@if (openingBalancesForm.controls.officeId.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
</div>
@@ -26,125 +30,121 @@
</div>
</div>
<div class="layout-row-wrap gap-2percent responsive-column" *ngIf="openingBalancesData">
<mifosx-gl-account-display
class="flex-100"
[accountTitle]="'Opening Balances Contra Account'"
[glAccount]="openingBalancesData.contraAccount"
[withTitle]="'50%'"
>
</mifosx-gl-account-display>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Currency' | translate }}</mat-label>
<mat-select required formControlName="currencyCode">
<mat-option *ngFor="let currency of currencyData" [value]="currency.code">
{{ currency.displayLabel }}
</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>
</mat-error>
</mat-form-field>
<mat-form-field class="flex-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"
/>
<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>
</mat-error>
</mat-form-field>
<div class="layout-row-wrap gap-2percent responsive-column flex-100 content">
<div class="header flex-8">
{{ 'labels.inputs.Type' | translate }}
</div>
<div class="header flex-18">
{{ 'labels.inputs.GL Code' | translate }}
</div>
<div class="header flex-18">
{{ 'labels.inputs.GL Name' | translate }}
{{ 'labels.inputs.Account' | translate }}
</div>
<div class="header r-amount flex-18">
{{ 'labels.inputs.Total Debit' | translate }}:
{{ debitsSum | currency: currencyCode : 'symbol-narrow' : '1.2-2' }}
</div>
<div class="header r-amount flex-23">
{{ 'labels.inputs.Total Credit' | translate }}:
{{ creditsSum | currency: currencyCode : 'symbol-narrow' : '1.2-2' }}
@if (openingBalancesData) {
<div class="layout-row-wrap gap-2percent responsive-column">
<mifosx-gl-account-display
class="flex-100"
[accountTitle]="'Opening Balances Contra Account'"
[glAccount]="openingBalancesData.contraAccount"
[withTitle]="'50%'"
>
</mifosx-gl-account-display>
<mat-form-field class="flex-48">
<mat-label>{{ 'labels.inputs.Currency' | translate }}</mat-label>
<mat-select required formControlName="currencyCode">
@for (currency of currencyData; track currency) {
<mat-option [value]="currency.code">
{{ currency.displayLabel }}
</mat-option>
}
</mat-select>
@if (openingBalancesForm.controls.currencyCode.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Currency' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<mat-form-field class="flex-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"
/>
<mat-datepicker-toggle matSuffix [for]="openingBalancesDatePicker"></mat-datepicker-toggle>
<mat-datepicker #openingBalancesDatePicker></mat-datepicker>
@if (openingBalancesForm.controls.transactionDate.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Opening Balances Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<div class="layout-row-wrap gap-2percent responsive-column flex-100 content">
<div class="header flex-8">
{{ 'labels.inputs.Type' | translate }}
</div>
<div class="header flex-18">
{{ 'labels.inputs.GL Code' | translate }}
</div>
<div class="header flex-18">
{{ 'labels.inputs.GL Name' | translate }}
{{ 'labels.inputs.Account' | translate }}
</div>
<div class="header r-amount flex-18">
{{ 'labels.inputs.Total Debit' | translate }}:
{{ debitsSum | currency: currencyCode : 'symbol-narrow' : '1.2-2' }}
</div>
<div class="header r-amount flex-23">
{{ 'labels.inputs.Total Credit' | translate }}:
{{ creditsSum | currency: currencyCode : 'symbol-narrow' : '1.2-2' }}
</div>
</div>
@for (credit of glAccountEntries.controls; track credit; let i = $index) {
<div class="flex-fill layout-row-wrap responsive-column content" formArrayName="glAccountEntries">
<div class="flex-fill layout-row-wrap gap-2percent responsive-column" [formGroupName]="i">
<div class="flex-8">
{{
openingBalancesData.glAccounts[i].glAccountType.value !==
openingBalancesData.glAccounts[i - 1]?.glAccountType.value
? glAccountTypeLabel(openingBalancesData.glAccounts[i].glAccountType.value)
: ''
}}
</div>
<div class="flex-13">
{{ openingBalancesData.glAccounts[i].glAccountCode }}
</div>
<div class="flex-29">
{{ openingBalancesData.glAccounts[i].glAccountName }}
</div>
<div class="flex-20">
<mat-form-field>
<mat-label>{{ 'labels.inputs.Debit' | translate }}</mat-label>
<input matInput type="number" formControlName="debit" />
</mat-form-field>
</div>
<div class="flex-20">
<mat-form-field>
<mat-label>{{ 'labels.inputs.Credit' | translate }}</mat-label>
<input matInput type="number" formControlName="credit" />
</mat-form-field>
</div>
</div>
</div>
}
</div>
<div
class="flex-fill layout-row-wrap responsive-column content"
formArrayName="glAccountEntries"
*ngFor="let credit of glAccountEntries.controls; let i = index"
>
<div class="flex-fill layout-row-wrap gap-2percent responsive-column" [formGroupName]="i">
<div class="flex-8">
{{
openingBalancesData.glAccounts[i].glAccountType.value !==
openingBalancesData.glAccounts[i - 1]?.glAccountType.value
? glAccountTypeLabel(openingBalancesData.glAccounts[i].glAccountType.value)
: ''
}}
</div>
<div class="flex-13">
{{ openingBalancesData.glAccounts[i].glAccountCode }}
</div>
<div class="flex-29">
{{ openingBalancesData.glAccounts[i].glAccountName }}
</div>
<div class="flex-20">
<mat-form-field>
<mat-label>{{ 'labels.inputs.Debit' | translate }}</mat-label>
<input matInput type="number" formControlName="debit" />
</mat-form-field>
</div>
<div class="flex-20">
<mat-form-field>
<mat-label>{{ 'labels.inputs.Credit' | translate }}</mat-label>
<input matInput type="number" formControlName="credit" />
</mat-form-field>
</div>
</div>
</div>
</div>
}
</mat-card-content>
<mat-card-actions class="layout-row gap-5px align-center responsive-column" *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>
</mat-card-actions>
@if (openingBalancesData) {
<mat-card-actions class="layout-row gap-5px align-center responsive-column">
<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>
</mat-card-actions>
}
</form>
</mat-card>
</div>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, TemplateRef, ElementRef, ViewChild, AfterViewInit, inject } from '@angular/core';
import {
UntypedFormGroup,
UntypedFormBuilder,
@@ -19,7 +19,7 @@ import { ConfigurationWizardService } from '../../configuration-wizard/configura
import { onlyOneOfTheFieldsIsRequiredValidator } from './only-one-of-the-fields-is-required.validator';
import { Dates } from 'app/core/utils/dates';
import { TranslateService } from '@ngx-translate/core';
import { NgFor, NgIf, CurrencyPipe } from '@angular/common';
import { CurrencyPipe } from '@angular/common';
import { GlAccountDisplayComponent } from '../../shared/accounting/gl-account-display/gl-account-display.component';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
@@ -37,6 +37,16 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class MigrateOpeningBalancesComponent implements OnInit, AfterViewInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private settingsService = inject(SettingsService);
private dateUtils = inject(Dates);
private route = inject(ActivatedRoute);
private router = inject(Router);
private configurationWizardService = inject(ConfigurationWizardService);
private popoverService = inject(PopoverService);
private translateService = inject(TranslateService);
/** Minimum opening balances date allowed. */
minDate = new Date(2000, 0, 1);
/** Maximum opening balances date allowed. */
@@ -70,17 +80,7 @@ export class MigrateOpeningBalancesComponent implements OnInit, AfterViewInit {
* @param {ConfigurationWizardService} configurationWizardService ConfigurationWizard Service.
* @param {PopoverService} popoverService PopoverService.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private settingsService: SettingsService,
private dateUtils: Dates,
private route: ActivatedRoute,
private router: Router,
private configurationWizardService: ConfigurationWizardService,
private popoverService: PopoverService,
private translateService: TranslateService
) {
constructor() {
this.route.data.subscribe((data: { offices: any; currencies: any }) => {
this.officeData = data.offices;
this.currencyData = data.currencies.selectedCurrencyOptions;
@@ -15,10 +15,12 @@
/>
<mat-datepicker-toggle matSuffix [for]="tillDatePicker"></mat-datepicker-toggle>
<mat-datepicker #tillDatePicker></mat-datepicker>
<mat-error *ngIf="periodicAccrualsForm.controls.tillDate.hasError('required')">
{{ 'labels.inputs.Accrue Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (periodicAccrualsForm.controls.tillDate.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Accrue Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
</div>
</mat-card-content>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
@@ -22,6 +22,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class PeriodicAccrualsComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private settingsService = inject(SettingsService);
private dateUtils = inject(Dates);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Minimum accrue date allowed. */
minDate = new Date(2000, 0, 1);
/** Maximum accrue date allowed. */
@@ -29,22 +36,6 @@ export class PeriodicAccrualsComponent implements OnInit {
/** Periodic accruals form. */
periodicAccrualsForm: UntypedFormGroup;
/**
* @param {FormBuilder} formBuilder Form Builder.
* @param {AccountingService} accountingService Accounting Service.
* @param {SettingsService} settingsService Settings Service.
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private settingsService: SettingsService,
private dateUtils: Dates,
private route: ActivatedRoute,
private router: Router
) {}
/**
* Creates periodic accruals form.
*/
@@ -15,10 +15,12 @@
/>
<mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
<mat-datepicker #datePicker></mat-datepicker>
<mat-error *ngIf="provisioningEntryForm.controls.date.hasError('required')">
{{ 'labels.inputs.Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
@if (provisioningEntryForm.controls.date.hasError('required')) {
<mat-error>
{{ 'labels.inputs.Date' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
}
</mat-form-field>
<div class="flex-fill">
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import { UntypedFormGroup, UntypedFormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
@@ -22,6 +22,13 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class CreateProvisioningEntryComponent implements OnInit {
private formBuilder = inject(UntypedFormBuilder);
private accountingService = inject(AccountingService);
private settingsService = inject(SettingsService);
private dateUtils = inject(Dates);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Minimum provisioning date allowed. */
minDate = new Date(2000, 0, 1);
/** Maximum provisioning date allowed. */
@@ -29,22 +36,6 @@ export class CreateProvisioningEntryComponent implements OnInit {
/** Provisioning entry form. */
provisioningEntryForm: UntypedFormGroup;
/**
* @param {FormBuilder} formBuilder Form Builder.
* @param {AccountingService} accountingService Accounting Service.
* @param {SettingsService} settingsService Settings Service.
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private formBuilder: UntypedFormBuilder,
private accountingService: AccountingService,
private settingsService: SettingsService,
private dateUtils: Dates,
private route: ActivatedRoute,
private router: Router
) {}
/**
* Creates the provisioning entry form.
*/
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, ViewChild } from '@angular/core';
import { Component, OnInit, ViewChild, inject } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, MatSortHeader } from '@angular/material/sort';
import {
@@ -50,6 +50,10 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class ProvisioningEntriesComponent implements OnInit {
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Provisioning entry data. */
provisioningEntryData: any;
/** Columns to be displayed in provisioning entries table. */
@@ -75,11 +79,7 @@ export class ProvisioningEntriesComponent implements OnInit {
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router
) {
constructor() {
this.route.data.subscribe((data: { provisioningEntries: any }) => {
this.provisioningEntryData = data.provisioningEntries.pageItems;
});
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { Observable } from 'rxjs';
@@ -12,10 +12,7 @@ import { AccountingService } from '../accounting.service';
*/
@Injectable()
export class ProvisioningEntriesResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the provisioning entries data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
@@ -13,10 +13,7 @@ import { AccountingService } from '../../accounting.service';
*/
@Injectable()
export class ProvisioningEntryEntriesResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the provisioning entry entries data.
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
@@ -13,10 +13,7 @@ import { AccountingService } from '../../accounting.service';
*/
@Injectable()
export class ProvisioningEntryResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the provisioning entry data.
@@ -1,46 +1,43 @@
<div class="container" *ngIf="provisioningEntry">
<div class="m-b-20 layout-row align-end gap-20px">
<button
mat-raised-button
color="primary"
(click)="createProvisioningJournalEntries()"
[disabled]="provisioningEntry.journalEntry"
*mifosxHasPermission="'CREATE_JOURNAL_ENTRY'"
>
<fa-icon icon="plus" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Create Journal Entries' | translate }}
</button>
@if (provisioningEntry) {
<div class="container">
<div class="m-b-20 layout-row align-end gap-20px">
<button
mat-raised-button
color="primary"
(click)="createProvisioningJournalEntries()"
[disabled]="provisioningEntry.journalEntry"
*mifosxHasPermission="'CREATE_JOURNAL_ENTRY'"
>
<fa-icon icon="plus" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Create Journal Entries' | translate }}
</button>
</div>
<mat-card>
<mat-card-content>
<div class="layout-row-wrap responsive-column content">
<div class="flex-16 header">
{{ 'labels.inputs.Created By' | translate }}
</div>
<div class="flex-16">
{{ provisioningEntry.createdUser }}
</div>
<div class="flex-16 header">
{{ 'labels.inputs.Created On' | translate }}
</div>
<div class="flex-16">
{{ provisioningEntry.createdDate }}
</div>
<div class="flex-18 header">
{{ 'labels.inputs.Amount to be Reserved' | translate }}
</div>
<div class="flex-18">
{{ provisioningEntry.reservedAmount }}
</div>
</div>
</mat-card-content>
</mat-card>
</div>
<mat-card>
<mat-card-content>
<div class="layout-row-wrap responsive-column content">
<div class="flex-16 header">
{{ 'labels.inputs.Created By' | translate }}
</div>
<div class="flex-16">
{{ provisioningEntry.createdUser }}
</div>
<div class="flex-16 header">
{{ 'labels.inputs.Created On' | translate }}
</div>
<div class="flex-16">
{{ provisioningEntry.createdDate }}
</div>
<div class="flex-18 header">
{{ 'labels.inputs.Amount to be Reserved' | translate }}
</div>
<div class="flex-18">
{{ provisioningEntry.reservedAmount }}
</div>
</div>
</mat-card-content>
</mat-card>
</div>
}
<!-- Search -->
<div class="container m-t-20 layout-row-wrap responsive-column gap-2percent">
@@ -62,24 +59,27 @@
<!-- Autocomplete data -->
<mat-autocomplete autoActiveFirstOption #officeNameAutocomplete="matAutocomplete">
<mat-option *ngFor="let office of filteredOfficeData | async" [value]="office.name">
{{ office.name }}
</mat-option>
@for (office of filteredOfficeData | async; track office) {
<mat-option [value]="office.name">
{{ office.name }}
</mat-option>
}
</mat-autocomplete>
<mat-autocomplete autoActiveFirstOption #loanProductAutocomplete="matAutocomplete">
<mat-option *ngFor="let loanProduct of filteredLoanProductData | async" [value]="loanProduct.name">
{{ loanProduct.name }}
</mat-option>
@for (loanProduct of filteredLoanProductData | async; track loanProduct) {
<mat-option [value]="loanProduct.name">
{{ loanProduct.name }}
</mat-option>
}
</mat-autocomplete>
<mat-autocomplete autoActiveFirstOption #provisioningCategoryAutocomplete="matAutocomplete">
<mat-option
*ngFor="let provisioningCategory of filteredProvisioningCategoryData | async"
[value]="provisioningCategory.categoryName"
>
{{ provisioningCategory.categoryName }}
</mat-option>
@for (provisioningCategory of filteredProvisioningCategoryData | async; track provisioningCategory) {
<mat-option [value]="provisioningCategory.categoryName">
{{ provisioningCategory.categoryName }}
</mat-option>
}
</mat-autocomplete>
<!--Table -->
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, ViewChild, AfterViewInit, inject } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
import { MatPaginator } from '@angular/material/paginator';
@@ -23,7 +23,7 @@ import { startWith, map, debounceTime, distinctUntilChanged, tap } from 'rxjs/op
/** Custom Services */
import { AccountingService } from '../../accounting.service';
import { NgIf, NgFor, AsyncPipe } from '@angular/common';
import { AsyncPipe } from '@angular/common';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { MatAutocompleteTrigger, MatAutocomplete, MatOption } from '@angular/material/autocomplete';
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
@@ -57,6 +57,10 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class ViewProvisioningEntryComponent implements OnInit, AfterViewInit {
private accountingService = inject(AccountingService);
private route = inject(ActivatedRoute);
private router = inject(Router);
/** Provisioning entry id. */
provisioningEntryId: string;
/** Provisioning entry. */
@@ -112,11 +116,7 @@ export class ViewProvisioningEntryComponent implements OnInit, AfterViewInit {
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
*/
constructor(
private accountingService: AccountingService,
private route: ActivatedRoute,
private router: Router
) {
constructor() {
this.route.data.subscribe(
(data: {
provisioningEntry: any;
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
/** rxjs Imports */
@@ -13,10 +13,7 @@ import { AccountingService } from '../../accounting.service';
*/
@Injectable()
export class ProvisioningJournalEntriesResolver {
/**
* @param {AccountingService} accountingService Accounting service.
*/
constructor(private accountingService: AccountingService) {}
private accountingService = inject(AccountingService);
/**
* Returns the provisioning journal entries data.
@@ -51,26 +51,30 @@
<ng-container matColumnDef="debit">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Debit' | translate }}</th>
<td mat-cell *matCellDef="let provisioningJournalEntry">
<span *ngIf="provisioningJournalEntry.entryType.value === 'DEBIT'">
{{
(provisioningJournalEntry.currency.displaySymbol || provisioningJournalEntry.currency.code) +
' ' +
provisioningJournalEntry.amount
}}
</span>
@if (provisioningJournalEntry.entryType.value === 'DEBIT') {
<span>
{{
(provisioningJournalEntry.currency.displaySymbol || provisioningJournalEntry.currency.code) +
' ' +
provisioningJournalEntry.amount
}}
</span>
}
</td>
</ng-container>
<ng-container matColumnDef="credit">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Credit' | translate }}</th>
<td mat-cell *matCellDef="let provisioningJournalEntry">
<span *ngIf="provisioningJournalEntry.entryType.value === 'CREDIT'">
{{
(provisioningJournalEntry.currency.displaySymbol || provisioningJournalEntry.currency.code) +
' ' +
provisioningJournalEntry.amount
}}
</span>
@if (provisioningJournalEntry.entryType.value === 'CREDIT') {
<span>
{{
(provisioningJournalEntry.currency.displaySymbol || provisioningJournalEntry.currency.code) +
' ' +
provisioningJournalEntry.amount
}}
</span>
}
</td>
</ng-container>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, ViewChild } from '@angular/core';
import { Component, OnInit, ViewChild, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, MatSortHeader } from '@angular/material/sort';
@@ -43,6 +43,8 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class ViewProvisioningJournalEntriesComponent implements OnInit {
private route = inject(ActivatedRoute);
/** Provisioning journal entry data. */
provisioningJournalEntryData: any;
/** Columns to be displayed in provisioning journal entries table. */
@@ -70,7 +72,7 @@ export class ViewProvisioningJournalEntriesComponent implements OnInit {
* Retrieves the provisioning journal entries data from `resolve`.
* @param {ActivatedRoute} route Activated Route.
*/
constructor(private route: ActivatedRoute) {
constructor() {
this.route.data.subscribe((data: { provisioningJournalEntry: any }) => {
this.provisioningJournalEntryData = data.provisioningJournalEntry.pageItems;
});
@@ -1,21 +1,21 @@
<div *ngIf="!data.reverted; else reverted">
<h1 mat-dialog-title>{{ 'labels.heading.Revert Transaction' | translate }}</h1>
<div mat-dialog-content>
<p>{{ 'labels.text.Revert this transaction?' | translate }}</p>
<mat-form-field class="flex-fill">
<mat-label>{{ 'labels.inputs.Comments' | translate }}</mat-label>
<textarea matInput [formControl]="comments"></textarea>
</mat-form-field>
@if (!data.reverted) {
<div>
<h1 mat-dialog-title>{{ 'labels.heading.Revert Transaction' | translate }}</h1>
<div mat-dialog-content>
<p>{{ 'labels.text.Revert this transaction?' | translate }}</p>
<mat-form-field class="flex-fill">
<mat-label>{{ 'labels.inputs.Comments' | translate }}</mat-label>
<textarea matInput [formControl]="comments"></textarea>
</mat-form-field>
</div>
<mat-dialog-actions align="end">
<button mat-button mat-dialog-close>{{ 'labels.buttons.No' | translate }}</button>
<button mat-button [mat-dialog-close]="{ revert: true, comments: comments.value }">
{{ 'labels.buttons.Yes' | translate }}
</button>
</mat-dialog-actions>
</div>
<mat-dialog-actions align="end">
<button mat-button mat-dialog-close>{{ 'labels.buttons.No' | translate }}</button>
<button mat-button [mat-dialog-close]="{ revert: true, comments: comments.value }">
{{ 'labels.buttons.Yes' | translate }}
</button>
</mat-dialog-actions>
</div>
<ng-template #reverted>
} @else {
<h1 mat-dialog-title>{{ 'labels.heading.Transaction Reverted' | translate }}</h1>
<div mat-dialog-content>
<h4>{{ 'labels.heading.Success!' | translate }}</h4>
@@ -28,4 +28,4 @@
{{ 'labels.buttons.Redirect to New Transaction' | translate }}
</button>
</mat-dialog-actions>
</ng-template>
}
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, Inject } from '@angular/core';
import { Component, inject } from '@angular/core';
import {
MatDialogRef,
MAT_DIALOG_DATA,
@@ -29,15 +29,9 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class RevertTransactionComponent {
dialogRef = inject<MatDialogRef<RevertTransactionComponent>>(MatDialogRef);
data = inject(MAT_DIALOG_DATA);
/** Comments input form control. */
comments = new UntypedFormControl('');
/**
* @param {MatDialogRef} dialogRef Component reference to dialog.
* @param {any} data Provides comments or reverted transaction ID.
*/
constructor(
public dialogRef: MatDialogRef<RevertTransactionComponent>,
@Inject(MAT_DIALOG_DATA) public data: any
) {}
}
@@ -16,9 +16,11 @@
<mat-form-field class="flex-31">
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
<mat-select [formControl]="entryTypeFilter" (selectionChange)="applyFilter($event.value, 'manualEntriesOnly')">
<mat-option *ngFor="let filter of entryTypeFilterData" [value]="filter.value">
{{ filter.option }}
</mat-option>
@for (filter of entryTypeFilterData; track filter) {
<mat-option [value]="filter.value">
{{ filter.option }}
</mat-option>
}
</mat-select>
</mat-form-field>
@@ -80,9 +82,11 @@
<!-- Autocomplete data -->
<mat-autocomplete autoActiveFirstOption #officeNameAutocomplete="matAutocomplete" [displayWith]="displayOfficeName">
<mat-option *ngFor="let office of filteredOfficeData | async" [value]="{ id: office.id, name: office.name }">
{{ office.name }}
</mat-option>
@for (office of filteredOfficeData | async; track office) {
<mat-option [value]="{ id: office.id, name: office.name }">
{{ office.name }}
</mat-option>
}
</mat-autocomplete>
<div class="mat-elevation-z8 container table-container">
@@ -139,14 +143,18 @@
<ng-container matColumnDef="debit">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Debit' | translate }}</th>
<td mat-cell *matCellDef="let journalEntry">
<span *ngIf="journalEntry.entryType.value === 'DEBIT'"> {{ journalEntry.amount | formatNumber }} </span>
@if (journalEntry.entryType.value === 'DEBIT') {
<span> {{ journalEntry.amount | formatNumber }} </span>
}
</td>
</ng-container>
<ng-container matColumnDef="credit">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Credit' | translate }}</th>
<td mat-cell *matCellDef="let journalEntry">
<span *ngIf="journalEntry.entryType.value === 'CREDIT'"> {{ journalEntry.amount | formatNumber }} </span>
@if (journalEntry.entryType.value === 'CREDIT') {
<span> {{ journalEntry.amount | formatNumber }} </span>
}
</td>
</ng-container>
@@ -1,5 +1,5 @@
/** Angular Imports */
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { Component, OnInit, ViewChild, AfterViewInit, inject } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, MatSortHeader } from '@angular/material/sort';
import { UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
@@ -17,7 +17,7 @@ import { JournalEntriesDataSource } from './journal-entry.datasource';
import { Dates } from 'app/core/utils/dates';
import { MatAutocompleteTrigger, MatOption, MatAutocomplete } from '@angular/material/autocomplete';
import { GlAccountSelectorComponent } from '../../shared/accounting/gl-account-selector/gl-account-selector.component';
import { NgFor, NgIf, AsyncPipe } from '@angular/common';
import { AsyncPipe } from '@angular/common';
import {
MatTable,
MatColumnDef,
@@ -67,6 +67,11 @@ import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
]
})
export class SearchJournalEntryComponent implements OnInit, AfterViewInit {
private accountingService = inject(AccountingService);
private settingsService = inject(SettingsService);
private dateUtils = inject(Dates);
private route = inject(ActivatedRoute);
/** Minimum transaction date allowed. */
minDate = new Date(2000, 0, 1);
/** Maximum transaction date allowed. */
@@ -185,12 +190,7 @@ export class SearchJournalEntryComponent implements OnInit, AfterViewInit {
* @param {ActivatedRoute} route Activated Route.
* @param {SettingsService} settingsService Settings Service.
*/
constructor(
private accountingService: AccountingService,
private settingsService: SettingsService,
private dateUtils: Dates,
private route: ActivatedRoute
) {
constructor() {
this.route.data.subscribe((data: { offices: any; glAccounts: any }) => {
this.officeData = data.offices;
this.glAccountData = data.glAccounts;