diff --git a/src/data/reports/mal-data-approval/MalDataApprovalDefaultRepository.ts b/src/data/reports/mal-data-approval/MalDataApprovalDefaultRepository.ts index 74ff106c..ac39159e 100644 --- a/src/data/reports/mal-data-approval/MalDataApprovalDefaultRepository.ts +++ b/src/data/reports/mal-data-approval/MalDataApprovalDefaultRepository.ts @@ -23,10 +23,7 @@ import { MalDataApprovalOptions, MalDataApprovalRepository, } from "../../../domain/reports/mal-data-approval/repositories/MalDataApprovalRepository"; -import { - DataDiffItem, - DataDiffItemIdentifier -} from "../../../domain/reports/mal-data-approval/entities/DataDiffItem"; +import { DataDiffItem, DataDiffItemIdentifier } from "../../../domain/reports/mal-data-approval/entities/DataDiffItem"; import { Namespaces } from "../../common/clients/storage/Namespaces"; export interface Pagination { @@ -120,7 +117,12 @@ type SqlFieldDiff = | "dataelement" | "apvddataelement" | "comment" - | "apvdcomment"; + | "apvdcomment" + | "lastupdated" + | "apvdlastupdated" + | "apvdstoredby" + | "storedby" + | "categoryoptioncomboname"; type SqlField = | "datasetuid" @@ -196,6 +198,11 @@ export class MalDataApprovalDefaultRepository implements MalDataApprovalReposito apvdDataElement: item.apvddataelement, comment: item.comment, apvdComment: item.apvdcomment, + lastUpdated: item.lastupdated, + lastUpdatedBy: item.storedby, + lastSubmissionDate: item.apvdlastupdated, + lastSubmittedBy: item.apvdstoredby, + categoryOption: item.categoryoptioncomboname, }) ); @@ -466,44 +473,44 @@ export class MalDataApprovalDefaultRepository implements MalDataApprovalReposito async duplicateDataValues(dataValues: DataDiffItemIdentifier[]): Promise { try { const approvalDataSetId = process.env.REACT_APP_APPROVE_DATASET_ID ?? "fRrt4V8ImqD"; - const uniqueDataSets = _.uniqBy(dataValues, 'dataSet'); - const uniqueDataElementsNames = _.uniq(_.map(dataValues, 'dataElement')); + const uniqueDataSets = _.uniqBy(dataValues, "dataSet"); + const uniqueDataElementsNames = _.uniq(_.map(dataValues, "dataElement")); - const DSDataElements: { dataSetElements: dataSetElementsType[] }[] = await promiseMap(uniqueDataSets, async item => - this.api - .get(`/dataSets/${item.dataSet}`, { fields: "dataSetElements[dataElement[id,name]]" }) - .getData() + const DSDataElements: { dataSetElements: dataSetElementsType[] }[] = await promiseMap( + uniqueDataSets, + async item => + this.api + .get(`/dataSets/${item.dataSet}`, { fields: "dataSetElements[dataElement[id,name]]" }) + .getData() ); const dataValueSets: dataSetsValueType[] = await promiseMap(uniqueDataSets, async item => - this.api.get("/dataValueSets", { - dataSet: item.dataSet, - period: item.period, - orgUnit: item.orgUnit, - }).getData() + this.api + .get("/dataValueSets", { + dataSet: item.dataSet, + period: item.period, + orgUnit: item.orgUnit, + }) + .getData() ); const ADSDataElementsRaw: { dataSetElements: dataSetElementsType[] } = await this.api .get(`/dataSets/${approvalDataSetId}`, { fields: "dataSetElements[dataElement[id,name]]" }) .getData(); - const ADSDataElements: dataElementsType[] = ADSDataElementsRaw.dataSetElements.map( - (element) => { - return { - id: element.dataElement.id, - name: element.dataElement.name, - }; - } - ); + const ADSDataElements: dataElementsType[] = ADSDataElementsRaw.dataSetElements.map(element => { + return { + id: element.dataElement.id, + name: element.dataElement.name, + }; + }); const dataElementsMatchedArray: { [key: string]: any }[] = DSDataElements.flatMap(DSDataElement => { - return DSDataElement.dataSetElements.flatMap((element) => { + return DSDataElement.dataSetElements.flatMap(element => { const dataElement = element.dataElement; if (uniqueDataElementsNames.includes(dataElement.name)) { const othername = dataElement.name + "-APVD"; - const ADSDataElement = ADSDataElements.find( - (DataElement) => DataElement.name === othername - ); + const ADSDataElement = ADSDataElements.find(DataElement => DataElement.name === othername); return { origId: dataElement?.id, destId: ADSDataElement?.id, @@ -513,24 +520,22 @@ export class MalDataApprovalDefaultRepository implements MalDataApprovalReposito return []; } }); - }) + }); const apvdDataValues = dataValueSets.flatMap(dataValueSet => { if (dataValueSet.dataValues) { - const data = dataValueSet.dataValues.flatMap( - (dataValue) => { - const data = { ...dataValue }; - const destId = dataElementsMatchedArray.find( - dataElementsMatchedObj => dataElementsMatchedObj.origId === dataValue.dataElement - )?.destId; - data.dataElement = destId; - data.dataSet = approvalDataSetId; - delete data.lastUpdated; - delete data.comment; - - return data.dataElement ? data : []; - } - ); + const data = dataValueSet.dataValues.flatMap(dataValue => { + const data = { ...dataValue }; + const destId = dataElementsMatchedArray.find( + dataElementsMatchedObj => dataElementsMatchedObj.origId === dataValue.dataElement + )?.destId; + data.dataElement = destId; + data.dataSet = approvalDataSetId; + delete data.lastUpdated; + delete data.comment; + + return data.dataElement ? data : []; + }); return data; } else { return []; @@ -558,7 +563,7 @@ export class MalDataApprovalDefaultRepository implements MalDataApprovalReposito .post("/dataValueSets.json", {}, { dataValues: _.reject(chunk, _.isEmpty) }) .getData(); - copyResponse.push(response) + copyResponse.push(response); } return _.every(copyResponse, item => item.status === "SUCCESS"); } else { @@ -586,7 +591,11 @@ export class MalDataApprovalDefaultRepository implements MalDataApprovalReposito }; const revokeResponse = await this.api - .delete("/dataApprovals", { ds: revokeData.dataSet, pe: revokeData.period, ou: revokeData.orgUnit }) + .delete("/dataApprovals", { + ds: revokeData.dataSet, + pe: revokeData.period, + ou: revokeData.orgUnit, + }) .getData(); return duplicateResponse && revokeResponse === ""; @@ -631,17 +640,19 @@ export class MalDataApprovalDefaultRepository implements MalDataApprovalReposito try { const response: any[] = []; dataSets.forEach(async dataSet => { - const isApproved = await this.api.get( - "/dataApprovals", - { wf: dataSet.workflow, pe: dataSet.period, ou: dataSet.orgUnit } - ).getData(); + const isApproved = await this.api + .get("/dataApprovals", { wf: dataSet.workflow, pe: dataSet.period, ou: dataSet.orgUnit }) + .getData(); if (isApproved.state === "APPROVED_HERE") { response.push( - await this.api.delete( - "/dataApprovals", - { wf: dataSet.workflow, pe: dataSet.period, ou: dataSet.orgUnit } - ).getData() + await this.api + .delete("/dataApprovals", { + wf: dataSet.workflow, + pe: dataSet.period, + ou: dataSet.orgUnit, + }) + .getData() ); } }); @@ -727,7 +738,7 @@ type DataSetRow = Record; function getISODate() { const date = new Date().toISOString(); - return date.slice(0, date.lastIndexOf(":")) + return date.slice(0, date.lastIndexOf(":")); } /* From the docs: "The variables must contain alphanumeric, dash, underscore and diff --git a/src/data/reports/mal-data-approval/sql-views/mal-data-approval-diff.sql b/src/data/reports/mal-data-approval/sql-views/mal-data-approval-diff.sql index ad1938c5..92996356 100644 --- a/src/data/reports/mal-data-approval/sql-views/mal-data-approval-diff.sql +++ b/src/data/reports/mal-data-approval/sql-views/mal-data-approval-diff.sql @@ -4,20 +4,41 @@ SELECT '${periods}' as period, sourceid, periodid, +categoryoptioncomboid, (select name from dataelement where dataelementid = datavalue.dataelementid) as dataelement, datavalue.value as value, +datavalue.storedby as storedby, +datavalue.lastupdated as lastupdated, datavalue.comment as comment, +(select name from categoryoptioncombo where categoryoptioncomboid = datavalue.categoryoptioncomboid) as categoryoptioncomboname, (select dva.value from datavalue dva -where dva.dataelementid=(select dataelementid from dataelement where name = CONCAT((select name from dataelement where dataelementid = datavalue.dataelementid), '-APVD')) +where dva.dataelementid=(select dataelementid from dataelement where uid = UPPER((select uid from dataelement where dataelementid = datavalue.dataelementid))) and dva.sourceid=datavalue.sourceid and dva.attributeoptioncomboid= datavalue.attributeoptioncomboid and dva.periodid=datavalue.periodid and dva.deleted = false and dva.categoryoptioncomboid = datavalue.categoryoptioncomboid ) as apvdvalue, + +(select dva.lastupdated from datavalue dva +where dva.dataelementid=(select dataelementid from dataelement where uid = UPPER((select uid from dataelement where dataelementid = datavalue.dataelementid))) +and dva.sourceid=datavalue.sourceid +and dva.attributeoptioncomboid= datavalue.attributeoptioncomboid +and dva.periodid=datavalue.periodid +and dva.deleted = false +and dva.categoryoptioncomboid = datavalue.categoryoptioncomboid +) as apvdlastupdated, +(select dva.storedby from datavalue dva +where dva.dataelementid=(select dataelementid from dataelement where uid = UPPER((select uid from dataelement where dataelementid = datavalue.dataelementid))) +and dva.sourceid=datavalue.sourceid +and dva.attributeoptioncomboid= datavalue.attributeoptioncomboid +and dva.periodid=datavalue.periodid +and dva.deleted = false +and dva.categoryoptioncomboid = datavalue.categoryoptioncomboid +) as apvdstoredby, (select dva.comment from datavalue dva -where dva.dataelementid=(select dataelementid from dataelement where name = CONCAT((select name from dataelement where dataelementid = datavalue.dataelementid), '-APVD')) +where dva.dataelementid=(select dataelementid from dataelement where uid = UPPER((select uid from dataelement where dataelementid = datavalue.dataelementid))) and dva.sourceid=datavalue.sourceid and dva.attributeoptioncomboid= datavalue.attributeoptioncomboid and dva.periodid=datavalue.periodid @@ -28,23 +49,24 @@ max(lastupdated) as lastupdated FROM datavalue WHERE +datavalue.dataelementid not in (select dataelementid from dataelement where valuetype = 'FILE_RESOURCE') and datavalue.sourceid in (select organisationunitid from organisationunit where uid ~ ('^' || replace('${orgUnits}', '-', '|') || '$')) and datavalue.periodid in (select periodid from _periodstructure where iso ~ ('^' || replace('${periods}', '-', '|') || '$')) and datavalue.dataelementid in ( select dse.dataelementid from datasetelement dse where dse.datasetid = (select datasetid from dataset where uid ~ ('^' || replace('${dataSets}', '-', '|') || '$')) ) and datavalue.deleted = false and datavalue.dataelementid not in (select dataelementid from dataelement where name='MAL - Submission date') and (datavalue.value != (select dva.value from datavalue dva -where dva.dataelementid=(select dataelementid from dataelement where name = CONCAT((select name from dataelement where dataelementid = datavalue.dataelementid), '-APVD')) +where dva.dataelementid=(select dataelementid from dataelement where uid= UPPER((select uid from dataelement where dataelementid = datavalue.dataelementid))) and dva.sourceid=datavalue.sourceid and dva.attributeoptioncomboid= datavalue.attributeoptioncomboid and dva.periodid=datavalue.periodid and dva.deleted = false and dva.categoryoptioncomboid = datavalue.categoryoptioncomboid) or (datavalue.value is not null and ((select dva.value from datavalue dva -where dva.dataelementid=(select dataelementid from dataelement where name = CONCAT((select name from dataelement where dataelementid = datavalue.dataelementid), '-APVD')) +where dva.dataelementid=(select dataelementid from dataelement where uid = UPPER((select uid from dataelement where dataelementid = datavalue.dataelementid))) and dva.sourceid=datavalue.sourceid and dva.attributeoptioncomboid= datavalue.attributeoptioncomboid and dva.periodid=datavalue.periodid and dva.deleted = false and dva.categoryoptioncomboid = datavalue.categoryoptioncomboid) is null))) -GROUP BY datavalue.periodid, datavalue.sourceid, datavalue.attributeoptioncomboid, datavalue.dataelementid, datavalue.categoryoptioncomboid \ No newline at end of file +GROUP BY datavalue.periodid, datavalue.sourceid, datavalue.attributeoptioncomboid, datavalue.dataelementid, datavalue.categoryoptioncomboid diff --git a/src/domain/reports/mal-data-approval/entities/DataDiffItem.ts b/src/domain/reports/mal-data-approval/entities/DataDiffItem.ts index 8f6f8147..cdbc7234 100644 --- a/src/domain/reports/mal-data-approval/entities/DataDiffItem.ts +++ b/src/domain/reports/mal-data-approval/entities/DataDiffItem.ts @@ -8,6 +8,11 @@ export interface DataDiffItem { apvdDataElement: string | undefined; comment: string | undefined; apvdComment: string | undefined; + lastUpdated: string | undefined; + lastUpdatedBy: string | undefined; + lastSubmissionDate: string | undefined; + lastSubmittedBy: string | undefined; + categoryOption: string | undefined; } export interface DataDiffItemIdentifier { @@ -20,25 +25,11 @@ export interface DataDiffItemIdentifier { } export function getDataDiffItemId(item: DataDiffItem): string { - return [ - item.dataSetUid, - item.period, - item.orgUnitUid, - item.dataElement, - item.value, - item.comment, - ].join("|||"); + return [item.dataSetUid, item.period, item.orgUnitUid, item.dataElement, item.value, item.comment].join("|||"); } export function parseDataDiffItemId(string: string): DataDiffItemIdentifier | undefined { - const [ - dataSet, - period, - orgUnit, - dataElement, - value, - comment, - ] = string.split("|||"); + const [dataSet, period, orgUnit, dataElement, value, comment] = string.split("|||"); if (!dataSet || !period || !orgUnit || !dataElement || !value) return undefined; diff --git a/src/webapp/reports/mal-data-approval/DataDiffViewModel.ts b/src/webapp/reports/mal-data-approval/DataDiffViewModel.ts index c895a123..4b5a9a4d 100644 --- a/src/webapp/reports/mal-data-approval/DataDiffViewModel.ts +++ b/src/webapp/reports/mal-data-approval/DataDiffViewModel.ts @@ -12,6 +12,11 @@ export interface DataDiffViewModel { apvdDataElement: string | undefined; comment: string | undefined; apvdComment: string | undefined; + lastUpdated: string | undefined; + lastUpdatedBy: string | undefined; + lastSubmissionDate: string | undefined; + lastSubmittedBy: string | undefined; + categoryOption: string | undefined; } export function getDataDiffViews(_config: Config, items: DataDiffItem[]): DataDiffViewModel[] { @@ -27,6 +32,11 @@ export function getDataDiffViews(_config: Config, items: DataDiffItem[]): DataDi apvdDataElement: item.apvdDataElement, comment: item.comment, apvdComment: item.apvdComment, + lastUpdated: item.lastUpdated, + lastUpdatedBy: item.lastUpdatedBy, + lastSubmissionDate: item.lastSubmissionDate, + lastSubmittedBy: item.lastSubmittedBy, + categoryOption: item.categoryOption, }; }); } diff --git a/src/webapp/reports/mal-data-approval/DataDifferencesList.tsx b/src/webapp/reports/mal-data-approval/DataDifferencesList.tsx index 713d7b92..1ae59be6 100644 --- a/src/webapp/reports/mal-data-approval/DataDifferencesList.tsx +++ b/src/webapp/reports/mal-data-approval/DataDifferencesList.tsx @@ -27,7 +27,12 @@ interface DataDifferencesListProps { isUpdated: () => void; } -export const DataDifferencesList: React.FC = ({ selectedIds, revoke, isMalAdmin, isUpdated }) => { +export const DataDifferencesList: React.FC = ({ + selectedIds, + revoke, + isMalAdmin, + isUpdated, +}) => { const { compositionRoot, config } = useAppContext(); const [visibleColumns, setVisibleColumns] = useState(); const snackbar = useSnackbar(); @@ -40,6 +45,11 @@ export const DataDifferencesList: React.FC = ({ select { name: "comment", text: i18n.t("Comment"), sortable: false }, { name: "apvdValue", text: i18n.t("Approved value"), sortable: false }, { name: "apvdComment", text: i18n.t("Approved value comment"), sortable: false }, + { name: "lastUpdated", text: i18n.t("Last updated"), sortable: false }, + { name: "lastUpdatedBy", text: i18n.t("Last updated by"), sortable: false }, + { name: "lastSubmissionDate", text: i18n.t("Last submission date"), sortable: false }, + { name: "lastSubmittedBy", text: i18n.t("Last submitted by"), sortable: false }, + { name: "categoryOption", text: i18n.t("Category Option"), sortable: false }, ], actions: [ {