Files
cbsnexora/src/app/accounting/chart-of-accounts/gl-account-tree.service.ts
T
Felix van Hove 7fd1486c08 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.
2025-12-08 11:01:01 +01:00

116 lines
4.0 KiB
TypeScript

/** Angular Imports */
import { Injectable, inject } from '@angular/core';
/** rxjs Imports */
import { BehaviorSubject } from 'rxjs';
/** Custom Components */
import { GLAccountNode } from './gl-account-node.model';
import { TranslateService } from '@ngx-translate/core';
import { GLAccount } from 'app/shared/models/general.model';
/**
* GL Account tree service.
*/
@Injectable({
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. */
treeDataChange = new BehaviorSubject<GLAccountNode[]>([]);
/**
* Gets the chart of accounts tree nodes.
*/
get treeData(): GLAccountNode[] {
return this.treeDataChange.value;
}
/**
* Builds the chart of accounts tree and emits the value.
* @param {any} glAccountData Chart of accounts data.
*/
initialize(glAccountData: any) {
const treeData = this.buildGLAccountTree(glAccountData);
this.treeDataChange.next(treeData);
}
/**
* Builds and returns the chart of accounts tree.
* @param {any} glAccountData Chart of accounts data.
* @returns {GLAccountNode[]} Chart of accounts tree nodes.
*/
buildGLAccountTree(glAccountData: GLAccount[]): GLAccountNode[] {
const glAccountTree: GLAccountNode[] = [];
// Header nodes
glAccountTree.push(new GLAccountNode('ACCOUNTS'));
glAccountTree[0].children.push(new GLAccountNode(this.translateService.instant('labels.inputs.accounting.ASSET')));
glAccountTree[0].children.push(new GLAccountNode(this.translateService.instant('labels.inputs.accounting.EQUITY')));
glAccountTree[0].children.push(
new GLAccountNode(this.translateService.instant('labels.inputs.accounting.EXPENSE'))
);
glAccountTree[0].children.push(new GLAccountNode(this.translateService.instant('labels.inputs.accounting.INCOME')));
glAccountTree[0].children.push(
new GLAccountNode(this.translateService.instant('labels.inputs.accounting.LIABILITY'))
);
if (glAccountData.length === 0) {
return glAccountTree;
}
// Sort by parent id (so that child nodes can be added properly)
if (!glAccountData[0].parentId) {
glAccountData[0].parentId = 0;
}
glAccountData.sort((glAccountOne: GLAccount, glAccountTwo: GLAccount) => {
if (!glAccountOne.parentId) {
glAccountOne.parentId = 0;
}
return glAccountOne.parentId - glAccountTwo.parentId;
});
const glAccounts: GLAccountNode[] = [];
// Add gl accounts to any array where index for each is denoted by its id
for (const glAccount of glAccountData) {
glAccounts[glAccount.id] = new GLAccountNode(
glAccount.name,
glAccount.glCode,
glAccount.type.value,
glAccount.usage.value,
glAccount.manualEntriesAllowed,
glAccount.description
);
}
// Construct gl account tree by adding all nodes belonging to headers (with parent id = 0) by their type,
// and rest as children to respective parent nodes.
for (const glAccount of glAccountData) {
if (glAccount.parentId === 0) {
if (glAccount.type.value === 'ASSET') {
glAccountTree[0].children[0].children.push(glAccounts[glAccount.id]);
} else if (glAccount.type.value === 'EQUITY') {
glAccountTree[0].children[1].children.push(glAccounts[glAccount.id]);
} else if (glAccount.type.value === 'EXPENSE') {
glAccountTree[0].children[2].children.push(glAccounts[glAccount.id]);
} else if (glAccount.type.value === 'INCOME') {
glAccountTree[0].children[3].children.push(glAccounts[glAccount.id]);
} else if (glAccount.type.value === 'LIABILITY') {
glAccountTree[0].children[4].children.push(glAccounts[glAccount.id]);
}
} else {
if (glAccounts[glAccount.parentId]) {
glAccounts[glAccount.parentId].children.push(glAccounts[glAccount.id]);
}
}
}
return glAccountTree;
}
}