Implement organization maker-checker workflows
This commit is contained in:
@@ -41,6 +41,7 @@ import { AccountingService } from 'app/accounting/accounting.service';
|
||||
import { UsersService } from 'app/users/users.service';
|
||||
import { FixedDepositsService } from 'app/deposits/fixed-deposits/fixed-deposits.service';
|
||||
import { RecurringDepositsService } from 'app/deposits/recurring-deposits/recurring-deposits.service';
|
||||
import { OrganizationService } from 'app/organization/organization.service';
|
||||
|
||||
/**
|
||||
* One row of the rendered Command payload. The dialog turns the parsed command JSON into a tree of
|
||||
@@ -148,6 +149,7 @@ export class ViewCheckerInboxComponent {
|
||||
private usersService = inject(UsersService);
|
||||
private fixedDepositsService = inject(FixedDepositsService);
|
||||
private recurringDepositsService = inject(RecurringDepositsService);
|
||||
private organizationService = inject(OrganizationService);
|
||||
|
||||
/** Bundle handed to the shared entity lookup, so that table stays free of Angular injection. */
|
||||
private get entityFetchServices(): EntityFetchServices {
|
||||
@@ -159,7 +161,8 @@ export class ViewCheckerInboxComponent {
|
||||
accounting: this.accountingService,
|
||||
users: this.usersService,
|
||||
fixedDeposits: this.fixedDepositsService,
|
||||
recurringDeposits: this.recurringDepositsService
|
||||
recurringDeposits: this.recurringDepositsService,
|
||||
organization: this.organizationService
|
||||
};
|
||||
}
|
||||
/** Present only when opened as a popup from the Checker Inbox list; absent when reached by direct
|
||||
@@ -375,6 +378,9 @@ export class ViewCheckerInboxComponent {
|
||||
this.loadDeleteSummary(detail);
|
||||
} else if (action === 'CREATE') {
|
||||
this.createSections = this.buildCreateSections(this.jsondata);
|
||||
if ((detail?.entityName ?? '').toUpperCase() === 'GLACCOUNT') {
|
||||
this.resolveGlAccountCreateLabels(detail, this.jsondata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,6 +467,91 @@ export class ViewCheckerInboxComponent {
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* GL Account CREATE: `type`, `usage`, `parentId` and `tagId` arrive as raw numeric ids - meaningless
|
||||
* to a checker without the chart-of-accounts template, which is the same lookup data the create-GL
|
||||
* form itself already uses (`create-gl-account.component.ts`). Fetched once, purely for display: the
|
||||
* stored command payload (`jsondata`) and the already-rendered raw sections are left as they are
|
||||
* unless the lookup succeeds, so a slow or failed template call never blocks or breaks this screen.
|
||||
*/
|
||||
private resolveGlAccountCreateLabels(detail: any, payload: Record<string, any>): void {
|
||||
this.accountingService.getChartOfAccountsTemplate().subscribe({
|
||||
next: (template: any) => {
|
||||
// A slow response for a request the checker has already navigated away from must not overwrite
|
||||
// whatever is now on screen.
|
||||
if (!this.isCurrent(detail)) {
|
||||
return;
|
||||
}
|
||||
const resolved = { ...payload };
|
||||
const typeId = payload.type;
|
||||
|
||||
const typeOption = (template?.accountTypeOptions ?? []).find((option: any) => option.id === typeId);
|
||||
if (typeOption) {
|
||||
resolved.type = this.translateService.instant(`labels.inputs.accounting.${typeOption.value}`);
|
||||
}
|
||||
|
||||
const usageOption = (template?.usageOptions ?? []).find((option: any) => option.id === payload.usage);
|
||||
if (usageOption) {
|
||||
resolved.usage = usageOption.value;
|
||||
}
|
||||
|
||||
const parentAccount = this.glHeaderAccountOptions(template, typeId).find(
|
||||
(account: any) => account.id === payload.parentId
|
||||
);
|
||||
if (parentAccount) {
|
||||
resolved.parentId = parentAccount.glCode
|
||||
? `${parentAccount.name} (${parentAccount.glCode})`
|
||||
: parentAccount.name;
|
||||
}
|
||||
|
||||
const tagOption = this.glTagOptions(template, typeId).find((tag: any) => tag.id === payload.tagId);
|
||||
if (tagOption) {
|
||||
resolved.tagId = tagOption.name;
|
||||
}
|
||||
|
||||
this.createSections = this.buildCreateSections(resolved);
|
||||
},
|
||||
// Lookup failed - the raw ids already on screen from buildCreateSections() above stay as they are.
|
||||
error: () => undefined
|
||||
});
|
||||
}
|
||||
|
||||
/** Header/parent account options are partitioned by GL account type, same as the create-GL form. */
|
||||
private glHeaderAccountOptions(template: any, typeId: number): any[] {
|
||||
switch (typeId) {
|
||||
case 1:
|
||||
return template?.assetHeaderAccountOptions ?? [];
|
||||
case 2:
|
||||
return template?.liabilityHeaderAccountOptions ?? [];
|
||||
case 3:
|
||||
return template?.equityHeaderAccountOptions ?? [];
|
||||
case 4:
|
||||
return template?.incomeHeaderAccountOptions ?? [];
|
||||
case 5:
|
||||
return template?.expenseHeaderAccountOptions ?? [];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/** Allowed tag options are partitioned by GL account type, same as the create-GL form. */
|
||||
private glTagOptions(template: any, typeId: number): any[] {
|
||||
switch (typeId) {
|
||||
case 1:
|
||||
return template?.allowedAssetsTagOptions ?? [];
|
||||
case 2:
|
||||
return template?.allowedLiabilitiesTagOptions ?? [];
|
||||
case 3:
|
||||
return template?.allowedEquityTagOptions ?? [];
|
||||
case 4:
|
||||
return template?.allowedIncomeTagOptions ?? [];
|
||||
case 5:
|
||||
return template?.allowedExpensesTagOptions ?? [];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A role permission update posts the role's *entire* permission map - over 1,100 entries, of which
|
||||
* a handful are actually being changed. Rendering that as-is buries the change completely, so this
|
||||
|
||||
Reference in New Issue
Block a user