diff --git a/imxweb/projects/att/src/lib/decision/attestation-case.component.ts b/imxweb/projects/att/src/lib/decision/attestation-case.component.ts
index 71cfcee1a..4c6626eb1 100644
--- a/imxweb/projects/att/src/lib/decision/attestation-case.component.ts
+++ b/imxweb/projects/att/src/lib/decision/attestation-case.component.ts
@@ -41,6 +41,7 @@ import {
ColumnDependentReference,
MetadataService,
SnackBarService,
+ SqlWizardApiService,
SystemInfoService,
} from 'qbm';
import {
@@ -84,6 +85,7 @@ export class AttestationCaseComponent implements OnDestroy, OnInit {
public selectedHyperviewUID: string;
public selectedOption: AttestationRelatedObject;
public relatedOptions: AttestationRelatedObject[] = [];
+ public isHistoryAvailable = false;
private readonly subscriptions$: Subscription[] = [];
@@ -110,7 +112,8 @@ export class AttestationCaseComponent implements OnDestroy, OnInit {
private readonly systemInfoService: SystemInfoService,
private readonly logger: ClassloggerService,
private readonly metadataService: MetadataService,
- authentication: AuthenticationService
+ private readonly sqlService: SqlWizardApiService,
+ authentication: AuthenticationService,
) {
this.case = data.case;
this.approvers = data.approvers;
@@ -143,7 +146,9 @@ export class AttestationCaseComponent implements OnDestroy, OnInit {
this.policyTabTitle = await this.translate.get('#LDS#Heading Policy Violations').toPromise();
const info = await this.systemInfoService.get();
this.canAnalyzeRisk = info.PreProps.includes('RISKINDEX') && this.case.RiskIndex.value > 0;
- } finally {
+ const filterProperties = await this.sqlService.getFilterProperties('AttestationCase');
+ this.isHistoryAvailable = ['UID_AttestationPolicy','ObjectKeyBase','UID_AttestationCase'].every((col) => filterProperties.findIndex((prop) => prop.PropertyId === col) !== -1);
+ }finally {
this.busyService.hide(overlay);
}
}
@@ -243,7 +248,7 @@ export class AttestationCaseComponent implements OnDestroy, OnInit {
ObjectKey: relatedObject.ObjectKey,
Display: `${relatedObject.Display} - ${this.metadataService.tables[objectType.TableName].DisplaySingular}`,
};
- })
+ }),
)) || [];
}
diff --git a/imxweb/projects/qer/src/lib/itshop/request-info/approver-container.ts b/imxweb/projects/qer/src/lib/itshop/request-info/approver-container.ts
index ce79a1af4..9e8d77c2b 100644
--- a/imxweb/projects/qer/src/lib/itshop/request-info/approver-container.ts
+++ b/imxweb/projects/qer/src/lib/itshop/request-info/approver-container.ts
@@ -118,12 +118,31 @@ export class ApproverContainer {
public getApproverAdditionalInfo(approver: { display: string, data: EntityData[] }[], additionalInfoDisplay: string):{[key:string]: {[key:string]: {string}}}
{
const returnValue = {};
+
for (const elem of approver) {
returnValue[elem.display] = {};
- for(const data of elem.data){
- if(data.Columns.UID_ComplianceRule?.Value)
- returnValue[elem.display][data.Columns.UID_PersonHead.DisplayValue] = `(${additionalInfoDisplay}: ${(data.Columns.UID_ComplianceRule?.DisplayValue ?? '')})`;
- }
+ for (const data of elem.data) {
+ // Find all entries for the same approver in the given working step without a decision yet
+ const elements =
+ this.request.pwoData.WorkflowData?.Entities?.filter(
+ (elem) =>
+ elem.Columns?.UID_PersonHead?.Value === data.Columns?.UID_PersonHead?.Value &&
+ elem.Columns?.UID_QERWorkingStep?.Value === data.Columns?.UID_QERWorkingStep?.Value &&
+ (elem.Columns?.Decision?.Value ?? '') === '',
+ ) ?? [];
+
+ if (!!elements.length) {
+ // Get the one with the lowest sublevel number, that has a compliance rule assigned
+ const lowestElement = elements
+ .filter((elem) => elem.Columns?.SubLevelNumber && elem.Columns?.UID_ComplianceRule?.Value !== '')
+ .reduce((min, e) => (e.Columns!.SubLevelNumber!.Value < min.Columns!.SubLevelNumber!.Value ? e : min), elements[0]);
+ if (lowestElement && lowestElement.Columns?.UID_ComplianceRule?.Value !== '') {
+ // Assign the compliance rule display value to the return object
+ returnValue[elem.display][data.Columns?.UID_PersonHead?.DisplayValue ?? ''] =
+ `(${additionalInfoDisplay}: ${lowestElement.Columns?.UID_ComplianceRule?.DisplayValue ?? ''})`;
+ }
+ }
+ }
}
return returnValue;
}
diff --git a/imxweb/projects/qer/src/lib/itshopapprove/decision-step.service.ts b/imxweb/projects/qer/src/lib/itshopapprove/decision-step.service.ts
index d78173576..ad762bcee 100644
--- a/imxweb/projects/qer/src/lib/itshopapprove/decision-step.service.ts
+++ b/imxweb/projects/qer/src/lib/itshopapprove/decision-step.service.ts
@@ -32,10 +32,12 @@ import { EntityService, AuthenticationService, ColumnDependentReference, BaseRea
providedIn: 'root',
})
export class DecisionStepSevice {
-
public isEscalationApprover: boolean = false;
private uidUser: string;
- constructor(private readonly entityService: EntityService, authentication: AuthenticationService) {
+ constructor(
+ private readonly entityService: EntityService,
+ authentication: AuthenticationService,
+ ) {
authentication.onSessionResponse.subscribe((session) => (this.uidUser = session.UserUid));
}
@@ -48,7 +50,7 @@ export class DecisionStepSevice {
}
public getAdditionalInfoCdr(entity: TypedEntity, extended: any, display: string): ColumnDependentReference {
- const step = getWorkflowDataWithSmallestSublevel(extended, entity, this.uidUser, this.isEscalationApprover);
+ const step = getWorkflowDataWithSmallestSublevel(extended, entity, this.uidUser, this.isEscalationApprover);
if (!step) {
return undefined;
@@ -74,7 +76,7 @@ export class DecisionStepSevice {
const smallest = getWorkflowDataWithSmallestSublevel(extended, entity, uidUser, this.isEscalationApprover);
const uniqueUsersMap =
extended?.WorkflowSteps?.Entities?.filter(
- (elem: EntityData) => elem.Columns.UID_QERWorkingStep.Value === smallest?.Columns?.UID_QERWorkingStep.Value
+ (elem: EntityData) => elem.Columns.UID_QERWorkingStep.Value === smallest?.Columns?.UID_QERWorkingStep.Value,
)?.reduce((acc, current) => {
return { ...acc, [current.Keys[0]]: current };
}, {}) ?? [];
@@ -108,14 +110,24 @@ export function getSubLevel(entity: TypedEntity, extended: any, uidUser: string,
* @returns The step with the smallest sublevel in the current main level, that needs to be approved by the current user.
* If no such step exists, the value is undefined.
*/
-
-export function getWorkflowDataWithSmallestSublevel(extended: any, entity: TypedEntity, uidUser: string, isEscalationApprover: boolean): EntityData | undefined {
- return extended?.WorkflowData?.Entities?.filter(
+export function getWorkflowDataWithSmallestSublevel(
+ extended: any,
+ entity: TypedEntity,
+ uidUser: string,
+ isEscalationApprover: boolean,
+): EntityData | undefined {
+ const filteredData = extended?.WorkflowData?.Entities?.filter(
(data: EntityData) =>
- (isEscalationApprover || data?.Columns?.UID_PersonHead.Value === uidUser) &&
+ (isEscalationApprover || data?.Columns?.UID_PersonHead.Value === uidUser) &&
(data?.Columns?.Decision?.Value ?? '') === '' &&
- data.Columns?.LevelNumber.Value === entity.GetEntity().GetColumn('DecisionLevel').GetValue()
- )?.reduce((lowestSublevel, current) => {
- return current.Columns.SubLevelNumber.Value < lowestSublevel.Columns.SubLevelNumber.Value ? current : lowestSublevel;
- });
+ data.Columns?.LevelNumber.Value === entity.GetEntity().GetColumn('DecisionLevel').GetValue(),
+ );
+
+ if (filteredData && filteredData.length > 0) {
+ return filteredData.reduce((lowestSublevel, current) => {
+ return current.Columns.SubLevelNumber.Value < lowestSublevel.Columns.SubLevelNumber.Value ? current : lowestSublevel;
+ });
+ }
+
+ return undefined;
}
diff --git a/imxweb/projects/qer/src/lib/itshopapprove/inquiries/inquiries.component.ts b/imxweb/projects/qer/src/lib/itshopapprove/inquiries/inquiries.component.ts
index e2cdcffaa..98f6fcee7 100644
--- a/imxweb/projects/qer/src/lib/itshopapprove/inquiries/inquiries.component.ts
+++ b/imxweb/projects/qer/src/lib/itshopapprove/inquiries/inquiries.component.ts
@@ -30,18 +30,18 @@ import { Subscription } from 'rxjs';
import { TranslateService } from '@ngx-translate/core';
import { PwoExtendedData, ViewConfigData } from 'imx-api-qer';
-import { ValType, ExtendedTypedEntityCollection, TypedEntity, EntitySchema, DataModel, EntityData } from 'imx-qbm-dbts';
+import { DataModel, EntitySchema, ExtendedTypedEntityCollection, TypedEntity, ValType } from 'imx-qbm-dbts';
import {
- DataSourceToolbarSettings,
- ClassloggerService,
AuthenticationService,
+ BusyService,
+ ClassloggerService,
+ ClientPropertyForTableColumns,
+ ConfirmationService,
+ DataSourceToolbarSettings,
+ DataSourceToolbarViewConfig,
DataTableComponent,
SettingsService,
SnackBarService,
- ClientPropertyForTableColumns,
- BusyService,
- DataSourceToolbarViewConfig,
- ConfirmationService,
} from 'qbm';
import { ApprovalsSidesheetComponent } from '../approvals-sidesheet/approvals-sidesheet.component';
import { Approval } from '../approval';
@@ -124,7 +124,7 @@ export class InquiriesComponent implements OnInit, OnDestroy {
}
this.getData();
this.table.clearSelection();
- })
+ }),
);
this.approvalsService.isChiefApproval = false;
this.subscriptions.push(authentication.onSessionResponse.subscribe((session) => (this.userUid = session.UserUid)));
@@ -139,7 +139,6 @@ export class InquiriesComponent implements OnInit, OnDestroy {
this.viewConfig = await this.viewConfigService.getInitialDSTExtension(this.dataModel, this.viewConfigPath);
await this.getData(undefined, true);
-
} finally {
isBusy.endBusy();
}
@@ -164,7 +163,6 @@ export class InquiriesComponent implements OnInit, OnDestroy {
try {
this.approvalsCollection = isInitialLoad ? { totalCount: 0, Data: [] } : await this.getDataFromService();
this.hasData = this.approvalsCollection?.totalCount > 0 || (this.navigationState.search ?? '') !== '';
-
this.updateTable();
} finally {
@@ -178,8 +176,8 @@ export class InquiriesComponent implements OnInit, OnDestroy {
*/
private async getDataFromService(): Promise> {
const result = await this.approvalsService.get(this.navigationState);
- if(this.uidHelperPwo && result.totalCount === 0 && !this.isInitialLoadedWithServer){
- this.confirmation.confirm({Message: '#LDS#The request could not be found. You may not have permission to view this request.'});
+ if (this.uidHelperPwo && result.totalCount === 0 && !this.isInitialLoadedWithServer) {
+ this.confirmation.confirm({ Message: '#LDS#The request could not be found. You may not have permission to view this request.' });
}
// checks, if the data is loaded from the server for the first time
this.isInitialLoadedWithServer = true;
@@ -226,16 +224,6 @@ export class InquiriesComponent implements OnInit, OnDestroy {
}
}
- public getInquiryText(pwo: Approval): string {
- return this.getPwoData(pwo).Columns.ReasonHead.Value;
- }
- public getInquirer(pwo: Approval): string {
- return this.getPwoData(pwo).Columns.DisplayPersonHead.Value;
- }
- public getQueryDate(pwo: Approval): Date {
- return new Date(this.getPwoData(pwo).Columns.DateHead.Value);
- }
-
public onSearch(keywords: string): Promise {
const navigationState = {
...this.navigationState,
@@ -248,23 +236,14 @@ export class InquiriesComponent implements OnInit, OnDestroy {
return this.getData(navigationState);
}
- private getPwoData(pwo: Approval): EntityData {
- const questionHistory = pwo.pwoData.WorkflowHistory.Entities.filter(
- (entityData) => entityData.Columns.DecisionLevel.Value === pwo.DecisionLevel.value
- ).sort((item1, item2) => this.ascendingDate(item1.Columns.XDateInserted?.Value, item2.Columns.XDateInserted?.Value));
- return questionHistory[0];
+ public getInquiryText(pwo: Approval): string {
+ return this.actionService.getPwoData(pwo, this.userUid)?.Columns?.ReasonHead.Value || '';
}
-
- private ascendingDate(value1: Date, value2: Date): number {
- if (value1 < value2) {
- return 1;
- }
-
- if (value1 > value2) {
- return -1;
- }
-
- return 0;
+ public getInquirer(pwo: Approval): string {
+ return this.actionService.getPwoData(pwo, this.userUid)?.Columns?.DisplayPersonHead.Value || '';
+ }
+ public getQueryDate(pwo: Approval): string {
+ return this.actionService.getPwoData(pwo, this.userUid)?.Columns?.DateHead.Value ?? '';
}
private updateTable(): void {
diff --git a/imxweb/projects/qer/src/lib/itshopapprove/workflow-action/workflow-action.service.ts b/imxweb/projects/qer/src/lib/itshopapprove/workflow-action/workflow-action.service.ts
index 9c35848c8..561023c4c 100644
--- a/imxweb/projects/qer/src/lib/itshopapprove/workflow-action/workflow-action.service.ts
+++ b/imxweb/projects/qer/src/lib/itshopapprove/workflow-action/workflow-action.service.ts
@@ -64,7 +64,7 @@ export class WorkflowActionService {
private readonly approvalsService: ApprovalsService,
private readonly justificationService: JustificationService,
private readonly userService: UserModelService,
- private readonly extService: ExtService
+ private readonly extService: ExtService,
) {}
public async directDecisions(requests: Approval[], userUid: string): Promise {
@@ -89,7 +89,7 @@ export class WorkflowActionService {
if (workFlowDataCollection && workFlowDataCollection.Data) {
const levelNumbers = request.getLevelNumbers(userUid);
workflow.data[request.key] = workFlowDataCollection.Data.filter((item) => levelNumbers.includes(item.LevelNumber.value)).map(
- (item) => item.GetEntity()
+ (item) => item.GetEntity(),
);
}
}
@@ -360,7 +360,7 @@ export class WorkflowActionService {
Reason: actionParameters.reason.column.GetValue(),
UidJustification: actionParameters.justification?.column?.GetValue(),
Decision: true,
- SubLevel: getSubLevel(request, request.pwoData, user,isEscalation),
+ SubLevel: getSubLevel(request, request.pwoData, user, isEscalation),
});
},
});
@@ -487,22 +487,22 @@ export class WorkflowActionService {
this.entityService.createLocalEntityColumn(
{ Type: ValType.Date, ColumnName: 'DateHead', Display: '#LDS#Inquiry made on' },
undefined,
- pwo.Columns.DateHead
- )
+ pwo.Columns.DateHead,
+ ),
),
new BaseReadonlyCdr(
this.entityService.createLocalEntityColumn(
{ Type: ValType.String, ColumnName: 'ReasonHead', Display: '#LDS#Inquiry' },
undefined,
- pwo.Columns.ReasonHead
- )
+ pwo.Columns.ReasonHead,
+ ),
),
new BaseReadonlyCdr(
this.entityService.createLocalEntityColumn(
{ Type: ValType.String, ColumnName: 'DisplayPersonHead', Display: '#LDS#Inquiry made by' },
undefined,
- pwo.Columns.DisplayPersonHead
- )
+ pwo.Columns.DisplayPersonHead,
+ ),
),
];
@@ -518,13 +518,21 @@ export class WorkflowActionService {
});
}
- public getPwoData(pwo: Approval, userUid: string): EntityData {
- return pwo.pwoData.WorkflowHistory.Entities.find(
+ public getPwoData(pwo: Approval, userUid: string): EntityData | undefined {
+ const questionHistory = pwo.pwoData.WorkflowHistory?.Entities?.filter(
(entityData) =>
- entityData.Columns.DecisionType.Value === 'Query' &&
- entityData.Columns.UID_PersonRelated.Value === userUid &&
- entityData.Columns.DecisionLevel.Value === pwo.DecisionLevel.value
- );
+ entityData.Columns?.DecisionType.Value === 'Query' &&
+ entityData.Columns?.UID_PersonRelated.Value === userUid &&
+ entityData.Columns?.DecisionLevel.Value === pwo.DecisionLevel.value,
+ ).sort((a, b) => {
+ const d1 = a.Columns?.XDateInserted?.Value;
+ const d2 = b.Columns?.XDateInserted?.Value;
+
+ if (!d1 || !d2) return 0;
+ // Sort descending
+ return new Date(d2).getTime() - new Date(d1).getTime();
+ });
+ return questionHistory?.[0];
}
private async editAction(config: WorkflowActionEditWrapper): Promise {
@@ -612,7 +620,7 @@ export class WorkflowActionService {
FkRelation: fkRelation,
MinLen: 1,
},
- [this.person.createFkProviderItem(fkRelation)]
+ [this.person.createFkProviderItem(fkRelation)],
);
return new BaseCdr(column, display);
@@ -637,7 +645,7 @@ export class WorkflowActionService {
this.person.createFkProviderItem(fkRelation, [
{ ColumnName: 'UID_Person', CompareOp: CompareOperator.NotEqual, Type: FilterType.Compare, Value1: uidPerson },
]),
- ]
+ ],
);
return new BaseCdr(column, '#LDS#Recipient of the inquiry');
@@ -646,13 +654,13 @@ export class WorkflowActionService {
private async checkTermsOfUse(requests: Approval[]): Promise<{ isChecked: boolean; isAuthenticated: boolean }> {
// get all cart items with terms of uses
const approvalItemsWithTermsOfUseToAccept = requests.filter(
- (item) => item.UID_QERTermsOfUse?.value !== null && item.UID_QERTermsOfUse?.value !== ''
+ (item) => item.UID_QERTermsOfUse?.value !== null && item.UID_QERTermsOfUse?.value !== '',
);
if (approvalItemsWithTermsOfUseToAccept.length > 0) {
this.logger.debug(
this,
- `There are ${approvalItemsWithTermsOfUseToAccept.length} service items with terms of use the user have to accepted.`
+ `There are ${approvalItemsWithTermsOfUseToAccept.length} service items with terms of use the user have to accepted.`,
);
const termsOfUseAccepted = await this.sideSheet
diff --git a/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.html b/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.html
index f31f65050..548c086a0 100644
--- a/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.html
+++ b/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.html
@@ -14,7 +14,7 @@
diff --git a/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.ts b/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.ts
index 7b41bf7d5..8462055a2 100644
--- a/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.ts
+++ b/imxweb/projects/qer/src/lib/service-items-edit/service-items-edit-form/service-items-edit-form.component.ts
@@ -35,7 +35,7 @@ import { MatSlideToggleChange } from '@angular/material/slide-toggle';
import { TranslateService } from '@ngx-translate/core';
import { IEntity, IEntityColumn, TypedEntity } from 'imx-qbm-dbts';
-import { BaseCdr, ClassloggerService, ColumnDependentReference, CdrFactoryService, ExtService, BusyService } from 'qbm';
+import { BaseCdr, BusyService, CdrFactoryService, ClassloggerService, ColumnDependentReference, ExtService } from 'qbm';
import { QerPermissionsService } from '../../admin/qer-permissions.service';
import { OwnerControlComponent } from '../../owner-control/owner-control.component';
import { ProjectConfigurationService } from '../../project-configuration/project-configuration.service';
@@ -90,8 +90,8 @@ export class ServiceItemsEditFormComponent implements OnInit, OnChanges {
private readonly translate: TranslateService,
private readonly permission: QerPermissionsService,
private readonly projectConfig: ProjectConfigurationService,
- private readonly cdrFactoryService: CdrFactoryService
- ) {}
+ private readonly cdrFactoryService: CdrFactoryService,
+ ) { }
get getSelectedUidPerson(): string {
return this.ownercontrol?.uidPersonSelected;
@@ -187,7 +187,11 @@ export class ServiceItemsEditFormComponent implements OnInit, OnChanges {
// Handle the requestable (IsInActive column) outside the context of a CDR editor so the UI can invert the meaning to make
// more sense to the user
// This should be inversed on the api data response at some point, but until then we handle it in the UI
- this.isInActiveFormControl.setValue(!this.getColumn('IsInActive')?.GetValue());
+ const isInActiveColumn = this.getColumn('IsInActive');
+ this.isInActiveFormControl.setValue(!isInActiveColumn?.GetValue());
+ isInActiveColumn?.GetMetadata().CanEdit()
+ ? this.isInActiveFormControl.enable({ emitEvent: false })
+ : this.isInActiveFormControl.disable({ emitEvent: false });
this.onFormControlCreated(this.isInActiveFormControl);
}
diff --git a/imxweb/projects/rps/src/lib/list-report-viewer/list-report-viewer.component.ts b/imxweb/projects/rps/src/lib/list-report-viewer/list-report-viewer.component.ts
index 15f7aabde..d592a18fc 100644
--- a/imxweb/projects/rps/src/lib/list-report-viewer/list-report-viewer.component.ts
+++ b/imxweb/projects/rps/src/lib/list-report-viewer/list-report-viewer.component.ts
@@ -27,7 +27,14 @@
import { Component, Input, OnInit } from '@angular/core';
import { CollectionLoadParameters, DataModel, DisplayColumns, EntitySchema } from 'imx-qbm-dbts';
-import { BusyService, ClassloggerService, DataSourceToolbarGroupData, DataSourceToolbarSettings, createGroupData } from 'qbm';
+import {
+ BusyService,
+ ClassloggerService,
+ DataSourceToolbarExportMethod,
+ DataSourceToolbarGroupData,
+ DataSourceToolbarSettings,
+ createGroupData,
+} from 'qbm';
import { ListReportDataProvider } from './list-report-data-provider.interface';
/**
@@ -136,8 +143,11 @@ export class ListReportViewerComponent implements OnInit {
this.logger.warn(this, 'There was a problem, loading the columns. The displays of the objects will be shown instead');
}
- const exportMethod = this.dataService.exportReports(this.navigationState);
- exportMethod.initialColumns = displayedColumns.map((col) => col.ColumnName);
+ let exportMethod: DataSourceToolbarExportMethod | undefined;
+ if (this.dataService.exportReports) {
+ exportMethod = this.dataService.exportReports(this.navigationState);
+ exportMethod.initialColumns = displayedColumns.map((col) => col.ColumnName);
+ }
this.dstSettings = {
dataSource: data,
@@ -186,7 +196,7 @@ export class ListReportViewerComponent implements OnInit {
},
...parameters,
}),
- []
+ [],
);
}
}