Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

logic for step 4 #21

Merged
merged 6 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2024-03-08T08:43:07.923Z\n"
"PO-Revision-Date: 2024-03-08T08:43:07.924Z\n"
"POT-Creation-Date: 2024-03-11T13:00:38.175Z\n"
"PO-Revision-Date: 2024-03-11T13:00:38.175Z\n"

msgid "Cannot be blank: {{fieldName}}"
msgstr ""

msgid "No disaggregations selected"
msgstr ""

msgid "This analysis is not available for this module"
msgstr ""

msgid "Open analysis"
msgstr ""

Expand Down Expand Up @@ -221,16 +227,13 @@ msgstr ""
msgid "Graduates by institution ownership"
msgstr ""

msgid "Double Counts Threshold"
msgstr ""

msgid "Total"
msgid "Medical doctors analysis: General Practicioners missing and double counts"
msgstr ""

msgid "Total Newly Active Health Workers"
msgid "Disaggregations"
msgstr ""

msgid "Total Number of exits"
msgid "Double Counts Threshold"
msgstr ""

msgid "Validation Rule Group"
Expand Down
18 changes: 11 additions & 7 deletions i18n/es.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: i18next-conv\n"
"POT-Creation-Date: 2024-03-08T08:43:07.923Z\n"
"POT-Creation-Date: 2024-03-11T13:00:38.175Z\n"
"PO-Revision-Date: 2018-10-25T09:02:35.143Z\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
Expand All @@ -11,6 +11,12 @@ msgstr ""
msgid "Cannot be blank: {{fieldName}}"
msgstr ""

msgid "No disaggregations selected"
msgstr ""

msgid "This analysis is not available for this module"
msgstr ""

msgid "Open analysis"
msgstr ""

Expand Down Expand Up @@ -222,16 +228,14 @@ msgstr ""
msgid "Graduates by institution ownership"
msgstr ""

msgid "Double Counts Threshold"
msgstr ""

msgid "Total"
msgid ""
"Medical doctors analysis: General Practicioners missing and double counts"
msgstr ""

msgid "Total Newly Active Health Workers"
msgid "Disaggregations"
msgstr ""

msgid "Total Number of exits"
msgid "Double Counts Threshold"
msgstr ""

msgid "Validation Rule Group"
Expand Down
22 changes: 20 additions & 2 deletions src/CompositionRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ import { GetSettingsUseCase } from "./domain/usecases/GetSettingsUseCase";
import { SaveIssueUseCase } from "./domain/usecases/SaveIssueUseCase";
import { SaveConfigAnalysisUseCase } from "./domain/usecases/SaveConfigAnalysisUseCase";
import { D2Api } from "./types/d2-api";
import { RunPractitionersValidationUseCase } from "./domain/usecases/RunPractitionersValidationUseCase";
import { DataValueRepository } from "$/domain/repositories/DataValueRepository";
import { DataValueD2Repository } from "./data/repositories/DataValueD2Repository";
import { DataValueTestRepository } from "./data/repositories/DataValueTestRepository";
import { GetDisaggregationsUseCase } from "$/domain/repositories/GetDisaggregationsUseCase";

export type CompositionRoot = ReturnType<typeof getCompositionRoot>;

Expand All @@ -57,13 +62,17 @@ type Repositories = {
issueRepository: IssueRepository;
countryRepository: CountryRepository;
sequentialRepository: SequentialRepository;
dataValueRepository: DataValueRepository;
};

function getCompositionRoot(repositories: Repositories, metadata: MetadataItem) {
return {
countries: { getByIds: new GetCountriesByIdsUseCase(repositories.countryRepository) },
users: { getCurrent: new GetCurrentUserUseCase(repositories.usersRepository) },
modules: { get: new GetModulesUseCase(repositories.moduleRepository) },
modules: {
get: new GetModulesUseCase(repositories.moduleRepository),
getDisaggregations: new GetDisaggregationsUseCase(repositories.moduleRepository),
},
qualityAnalysis: {
get: new GetQualityAnalysisUseCase(repositories.qualityAnalysisRepository),
getById: new GetAnalysisByIdUseCase(repositories.qualityAnalysisRepository),
Expand All @@ -84,10 +93,17 @@ function getCompositionRoot(repositories: Repositories, metadata: MetadataItem)
repositories.outlierRepository,
repositories.qualityAnalysisRepository,
repositories.issueRepository,
repositories.settingsRepository,
repositories.moduleRepository
),
},
practitioners: {
run: new RunPractitionersValidationUseCase(
repositories.qualityAnalysisRepository,
repositories.moduleRepository,
repositories.dataValueRepository,
repositories.issueRepository
),
},
issues: { save: new SaveIssueUseCase(repositories.qualityAnalysisRepository, metadata) },
settings: { get: new GetSettingsUseCase(repositories.settingsRepository) },
};
Expand All @@ -105,6 +121,7 @@ export function getWebappCompositionRoot(api: D2Api, metadata: MetadataItem) {
issueRepository: new IssueD2Repository(api, metadata),
countryRepository: new CountryD2Repository(api),
sequentialRepository: new SequentialD2Repository(api, metadata),
dataValueRepository: new DataValueD2Repository(api),
};

return getCompositionRoot(repositories, metadata);
Expand All @@ -122,6 +139,7 @@ export function getTestCompositionRoot() {
issueRepository: new IssueTestRepository(),
countryRepository: new CountryTestRepository(),
sequentialRepository: new SequentialTestRepository(),
dataValueRepository: new DataValueTestRepository(),
};

return getCompositionRoot(repositories, {} as MetadataItem);
Expand Down
12 changes: 11 additions & 1 deletion src/data/common/D2DataElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class D2DataElement {
displayName: true,
displayShortName: true,
valueType: true,
categoryCombo: { id: true, displayName: true, categoryOptionCombos: true },
},
filter: { id: { in: ids } },
})
Expand All @@ -25,12 +26,21 @@ export class D2DataElement {
return {
id: d2DataElement.id,
name:
d2DataElement.displayShortName ||
d2DataElement.displayFormName ||
d2DataElement.displayShortName ||
d2DataElement.displayName,
isNumber:
d2DataElement.valueType === "NUMBER" ||
d2DataElement.valueType.includes("INTEGER"),
disaggregation: d2DataElement.categoryCombo
? {
id: d2DataElement.categoryCombo.id,
name: d2DataElement.categoryCombo.displayName,
options: d2DataElement.categoryCombo.categoryOptionCombos.map(
coc => coc.id
),
}
: undefined,
};
});
})
Expand Down
2 changes: 2 additions & 0 deletions src/data/common/D2Module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ export function getDefaultModules(metadata: MetadataItem): Module[] {
{
...metadata.dataSets.module1,
dataElements: [],
disaggregations: [],
},
{
...metadata.dataSets.module2,
dataElements: [],
disaggregations: [],
},
];
}
37 changes: 37 additions & 0 deletions src/data/repositories/DataValueD2Repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { D2Api } from "$/types/d2-api";
import { DataValue } from "$/domain/entities/DataValue";
import {
DataValueRepository,
GetDataValueOptions,
} from "$/domain/repositories/DataValueRepository";
import { FutureData, apiToFuture } from "../api-futures";
import { DataValueSetsDataValue } from "@eyeseetea/d2-api/api";

export class DataValueD2Repository implements DataValueRepository {
constructor(private api: D2Api) {}

get(options: GetDataValueOptions): FutureData<DataValue[]> {
return apiToFuture(
this.api.dataValues.getSet({
dataSet: options.moduleIds || [],
orgUnit: options.countriesIds || [],
startDate: options.startDate || undefined,
endDate: options.endDate || undefined,
period: options.period || undefined,
children: true,
})
).map(d2Response => {
return d2Response.dataValues.map(this.buildDataValue);
});
}

private buildDataValue(d2DataValue: DataValueSetsDataValue): DataValue {
return {
categoryOptionComboId: d2DataValue.categoryOptionCombo,
countryId: d2DataValue.orgUnit,
dataElementId: d2DataValue.dataElement,
period: d2DataValue.period,
value: d2DataValue.value,
};
}
}
10 changes: 10 additions & 0 deletions src/data/repositories/DataValueTestRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { DataValue } from "$/domain/entities/DataValue";
import { DataValueRepository } from "$/domain/repositories/DataValueRepository";
import { FutureData } from "../api-futures";
import { Future } from "$/domain/entities/generic/Future";

export class DataValueTestRepository implements DataValueRepository {
get(): FutureData<DataValue[]> {
return Future.success([]);
}
}
7 changes: 6 additions & 1 deletion src/data/repositories/IssueD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ export class IssueD2Repository implements IssueRepository {
enrollmentId: enrollment.enrollment,
},
messages: [
{
id: this.metadata.dataElements.correlative.id,
value: issue.correlative,
},
{
id: this.metadata.dataElements.status.id,
value: issue.status?.code || "",
Expand Down Expand Up @@ -233,6 +237,7 @@ export class IssueD2Repository implements IssueRepository {
type: issueType.id,
comments: this.getDataValue(dataValuesById, "comments"),
contactEmails: this.getDataValue(dataValuesById, "contactEmails"),
correlative: this.getDataValue(dataValuesById, "correlative"),
});
})
.compact()
Expand Down Expand Up @@ -296,7 +301,7 @@ export class IssueD2Repository implements IssueRepository {
private buildOrder(sorting: GetIssuesOptions["sorting"]): Maybe<string> {
switch (sorting.field) {
case "number":
return `${this.getDataElementIdOrThrow("issueNumber")}:${sorting.order}`;
return `${this.getDataElementIdOrThrow("correlative")}:${sorting.order}`;
case "status":
return `${this.getDataElementIdOrThrow("status")}:${sorting.order}`;
case "period":
Expand Down
1 change: 1 addition & 0 deletions src/data/repositories/MetadataD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const metadataCodes = {
actionDescription: "NHWA_DQI_Action_Description",
contactEmails: "NHWA_DQI_Contact_Emails",
comments: "NHWA_DQI_Comments",
correlative: "NHWA_DQI_Issue_Correlative_Number",
},
dataSets: { module1: "NHWA-M1-2023", module2: "NHWA-M2-2023" },
};
Expand Down
59 changes: 49 additions & 10 deletions src/data/repositories/ModuleD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { ModuleRepository } from "$/domain/repositories/ModuleRepository";
import { FutureData, apiToFuture } from "$/data/api-futures";
import { Future } from "$/domain/entities/generic/Future";
import { getDefaultModules } from "../common/D2Module";
import { DataElement } from "$/domain/entities/DataElement";
import _ from "$/domain/entities/generic/Collection";
import { Maybe } from "$/utils/ts-utils";

export class ModuleD2Repository implements ModuleRepository {
constructor(private api: D2Api, private metadata: MetadataItem) {}
Expand All @@ -17,26 +20,62 @@ export class ModuleD2Repository implements ModuleRepository {
id: true,
displayName: true,
code: true,
sections: {
id: true,
dataElements: { id: true },
},
dataSetElements: {
dataElement: { id: true, displayName: true, valueType: true },
dataElement: {
id: true,
displayFormName: true,
valueType: true,
categoryCombo: {
id: true,
displayName: true,
categoryOptionCombos: true,
},
},
categoryCombo: { id: true, displayName: true, categoryOptionCombos: true },
},
},
filter: { id: { in: ids } },
})
).map(d2Response => {
return d2Response.objects.map((d2DataSet): Module => {
const sectionDataElements = d2DataSet.sections
.flatMap(section => section.dataElements)
.map(dataElement => dataElement.id);

return {
id: d2DataSet.id,
name: d2DataSet.displayName,
dataElements: d2DataSet.dataSetElements.map(d2DataSetElement => {
return {
id: d2DataSetElement.dataElement.id,
name: d2DataSetElement.dataElement.displayName,
isNumber:
d2DataSetElement.dataElement.valueType === "NUMBER" ||
d2DataSetElement.dataElement.valueType.includes("INTEGER"),
};
}),
dataElements: _(d2DataSet.dataSetElements)
.map((d2DataSetElement): Maybe<DataElement> => {
if (!sectionDataElements.includes(d2DataSetElement.dataElement.id))
return undefined;
const d2CategoryCombo =
d2DataSetElement.categoryCombo ||
d2DataSetElement.dataElement.categoryCombo;
return {
id: d2DataSetElement.dataElement.id,
name: d2DataSetElement.dataElement.displayFormName,
isNumber:
d2DataSetElement.dataElement.valueType === "NUMBER" ||
d2DataSetElement.dataElement.valueType.includes("INTEGER"),
disaggregation: d2CategoryCombo
? {
id: d2CategoryCombo.id,
name: d2CategoryCombo.displayName,
options: d2CategoryCombo.categoryOptionCombos.map(
coc => coc.id
),
}
: undefined,
};
})
.compact()
.value(),
disaggregations: [],
};
});
});
Expand Down
14 changes: 10 additions & 4 deletions src/data/repositories/QualityAnalysisD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,17 +321,19 @@ export class QualityAnalysisD2Repository implements QualityAnalysisRepository {
status: firstEnrollment?.status || "ACTIVE",
updatedAt: this.getValueOrDefault(firstEnrollment?.updatedAt, currentDate),
updatedAtClient: this.getValueOrDefault(firstEnrollment?.updatedAtClient, currentDate),
events:
firstEnrollment?.events.map(event => {
events: _(firstEnrollment?.events || [])
.map(event => {
const section = qualityAnalysis.sections.find(
section => section.id === event.programStage
);
if (!section) return event;
const issue = section.issues.find(issue => issue.id === event.event);
if (!issue) return event;
if (!issue) return undefined;

return { ...event, dataValues: this.getDataValuesFromIssues(event, issue) };
}) || [],
})
.compact()
.value(),
};
}

Expand All @@ -340,6 +342,10 @@ export class QualityAnalysisD2Repository implements QualityAnalysisRepository {
issue: QualityAnalysisIssue
): DataValue[] {
const currentDataValues = [
{
dataElement: this.metadata.dataElements.correlative.id,
value: this.getValueOrDefault(issue.correlative),
},
{
dataElement: this.metadata.dataElements.action.id,
value: this.getValueOrDefault(issue.action?.code),
Expand Down
Loading
Loading