Skip to content

Commit

Permalink
feat: geography grouping
Browse files Browse the repository at this point in the history
  • Loading branch information
stephanoshadjipetrou committed Jul 11, 2024
1 parent 64854b7 commit d2e22ab
Show file tree
Hide file tree
Showing 7 changed files with 392 additions and 132 deletions.
2 changes: 2 additions & 0 deletions src/config/mapping/filter-options/geography.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"dataPath": "value[0].children",
"dataPathBoardConstituencyView": "value",
"dataPathPortfolioView": "value",
"label": "name",
"value": "code",
"children": "children",
Expand Down
7 changes: 5 additions & 2 deletions src/config/urls/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@
"filteroptionsdonors": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/donors/?$filter=donorId%20eq%20c06eaea9-c81b-442b-b403-dc348f3734eb%20or%20donorId%20eq%2025188dfc-7567-4e08-b8d0-088a6b83f238%20or%20donorId%20eq%20641c05fa-129d-4b57-a213-b5f6852ddc5f%20or%20donorid%20eq%20cc30fc59-b2fa-49e3-aa5a-762727daa68c&$expand=members($expand=members($expand=members($expand=members)))",
"filteroptionsreplenishmentperiods": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/replenishmentperiods",
"multicountriescountriesdata": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/MultiCountries?$expand=MultiCountryComposition($select=GeographicArea;$expand=GeographicArea($select=GeographicAreaCode_ISO3))&$select=MultiCountryName,MultiCountryComposition",
"FILTER_OPTIONS_GEOGRAPHY": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/Geographies?$filter=level eq 'World'&$expand=children($expand=children($expand=children))",
"FILTER_OPTIONS_COMPONENTS": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/ActivityAreasGrouped?$filter=type eq 'Component'",
"FILTER_OPTIONS_GEOGRAPHIES": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/Geographies?$filter=level eq 'World'&$expand=children($expand=children($expand=children))",
"FILTER_OPTIONS_GEOGRAPHIES_BOARD_CONSTITUENCY_VIEW": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/Geographies_BoardConstituencyView?&$expand=children($expand=children($expand=children))",
"FILTER_OPTIONS_GEOGRAPHIES_PORTFOLIO_VIEW": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/Geographies_PortfolioView?&$expand=children($expand=children($expand=children))",
"FILTER_OPTIONS_COMPONENTS_GROUPED": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/ActivityAreasGrouped?$filter=parentId eq null",
"FILTER_OPTIONS_COMPONENTS_UNGROUPED": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/ActivityAreas?$filter=type eq 'Component'",
"FILTER_OPTIONS_REPLENISHMENT_PERIODS": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/allFinancialIndicators?$apply=filter(financialDataSet eq 'Pledges_Contributions')/groupby((periodCovered))&$orderby=periodCovered asc",
"FILTER_OPTIONS_DONORS": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/Donors?$apply=groupby((id,name,type/name))",
"FILTER_OPTIONS_PRINCIPAL_RECIPIENTS": "https://api-gf-api-gf-02.azurewebsites.net/v4/odata/Grants?$apply=groupby((principalRecipient/type/parent/name,principalRecipient/type/parent/code,principalRecipient/type/name,principalRecipient/type/code,principalRecipient/name))",
Expand Down
232 changes: 172 additions & 60 deletions src/controllers/budgets.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,25 @@ export class BudgetsController {
@get('/budgets/radial')
@response(200)
async radial() {
let geographyMappings = [
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
];
if (this.req.query.geographyGrouping === 'Portfolio View') {
geographyMappings = [
'implementationPeriod/grant/geography_PortfolioView/name',
'implementationPeriod/grant/geography_PortfolioView/code',
];
} else if (this.req.query.geographyGrouping === 'Board Constituency View') {
geographyMappings = [
'implementationPeriod/grant/geography_BoardConstituencyView/name',
'implementationPeriod/grant/geography_BoardConstituencyView/code',
];
}
const filterString = filterFinancialIndicators(
this.req.query,
BudgetsRadialFieldsMapping.urlParams,
'implementationPeriod/grant/geography/name',
geographyMappings,
'implementationPeriod/grant/activityArea/name',
);
const url = `${urls.FINANCIAL_INDICATORS}/${filterString}`;
Expand All @@ -44,17 +59,32 @@ export class BudgetsController {
.catch(handleDataApiError);
}

@get('/budgets/sankey')
@get('/budgets/sankey/{componentField}/{geographyGrouping}')
@response(200)
async sankey() {
async sankey(
@param.path.string('componentField') componentField: string,
@param.path.string('geographyGrouping') geographyGrouping: string,
) {
let geographyMappings = [
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
];
if (geographyGrouping === 'Portfolio View') {
geographyMappings = [
'implementationPeriod/grant/geography_PortfolioView/name',
'implementationPeriod/grant/geography_PortfolioView/code',
];
} else if (geographyGrouping === 'Board Constituency View') {
geographyMappings = [
'implementationPeriod/grant/geography_BoardConstituencyView/name',
'implementationPeriod/grant/geography_BoardConstituencyView/code',
];
}
const filterString = filterFinancialIndicators(
this.req.query,
BudgetsSankeyFieldsMapping.urlParams,
[
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
],
'implementationPeriod/grant/activityArea/name',
geographyMappings,
`implementationPeriod/grant/${componentField}/name`,
);
const url = `${urls.FINANCIAL_INDICATORS}/${filterString}`;

Expand Down Expand Up @@ -160,19 +190,34 @@ export class BudgetsController {
.catch(handleDataApiError);
}

@get('/budgets/treemap/{componentField}')
@get('/budgets/treemap/{componentField}/{geographyGrouping}')
@response(200)
async treemap(@param.path.string('componentField') componentField: string) {
async treemap(
@param.path.string('componentField') componentField: string,
@param.path.string('geographyGrouping') geographyGrouping: string,
) {
let geographyMappings = [
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
];
if (geographyGrouping === 'Portfolio View') {
geographyMappings = [
'implementationPeriod/grant/geography_PortfolioView/name',
'implementationPeriod/grant/geography_PortfolioView/code',
];
} else if (geographyGrouping === 'Board Constituency View') {
geographyMappings = [
'implementationPeriod/grant/geography_BoardConstituencyView/name',
'implementationPeriod/grant/geography_BoardConstituencyView/code',
];
}
const filterString1 = filterFinancialIndicators(
this.req.query,
BudgetsTreemapFieldsMapping.urlParams1.replace(
'<componentField>',
componentField,
),
[
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
],
geographyMappings,
`implementationPeriod/grant/${componentField}/name`,
);
const url1 = `${urls.FINANCIAL_INDICATORS}/${filterString1}`;
Expand All @@ -195,7 +240,7 @@ export class BudgetsController {
'<componentField>',
componentField,
),
'implementationPeriod/grant/geography/name',
geographyMappings,
`implementationPeriod/grant/${componentField}/parent/name`,
);
url2 = `${urls.FINANCIAL_INDICATORS}/${filterString2}`;
Expand Down Expand Up @@ -297,9 +342,27 @@ export class BudgetsController {
.catch(handleDataApiError);
}

@get('/budgets/table')
@get('/budgets/table/{componentField}/{geographyGrouping}')
@response(200)
async table() {
async table(
@param.path.string('componentField') componentField: string,
@param.path.string('geographyGrouping') geographyGrouping: string,
) {
let geographyMappings = [
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
];
if (geographyGrouping === 'Portfolio View') {
geographyMappings = [
'implementationPeriod/grant/geography_PortfolioView/name',
'implementationPeriod/grant/geography_PortfolioView/code',
];
} else if (geographyGrouping === 'Board Constituency View') {
geographyMappings = [
'implementationPeriod/grant/geography_BoardConstituencyView/name',
'implementationPeriod/grant/geography_BoardConstituencyView/code',
];
}
let urlParams = BudgetsTableFieldsMapping.urlParams;
let level1Field = BudgetsTableFieldsMapping.level1Field;
let level2Field = BudgetsTableFieldsMapping.level2Field;
Expand All @@ -323,10 +386,7 @@ export class BudgetsController {
const filterString = filterFinancialIndicators(
this.req.query,
urlParams,
[
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
],
geographyMappings,
'implementationPeriod/grant/activityArea/name',
);
const url = `${urls.FINANCIAL_INDICATORS}/${filterString}`;
Expand Down Expand Up @@ -448,12 +508,28 @@ export class BudgetsController {
.catch(handleDataApiError);
}

@get('/budgets/breakdown/{cycle}/{componentField}')
@get('/budgets/breakdown/{cycle}/{componentField}/{geographyGrouping}')
@response(200)
async breakdown(
@param.path.string('cycle') cycle: string,
@param.path.string('componentField') componentField: string,
@param.path.string('geographyGrouping') geographyGrouping: string,
) {
let geographyMappings = [
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
];
if (geographyGrouping === 'Portfolio View') {
geographyMappings = [
'implementationPeriod/grant/geography_PortfolioView/name',
'implementationPeriod/grant/geography_PortfolioView/code',
];
} else if (geographyGrouping === 'Board Constituency View') {
geographyMappings = [
'implementationPeriod/grant/geography_BoardConstituencyView/name',
'implementationPeriod/grant/geography_BoardConstituencyView/code',
];
}
const years = cycle.split('-');

const filterString1 = filterFinancialIndicators(
Expand All @@ -466,10 +542,7 @@ export class BudgetsController {
'<componentField>',
componentField,
),
[
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
],
geographyMappings,
`implementationPeriod/grant/${componentField}/name`,
);
const url1 = `${urls.FINANCIAL_INDICATORS}/${filterString1}`;
Expand All @@ -496,7 +569,7 @@ export class BudgetsController {
'<componentField>',
componentField,
),
'implementationPeriod/grant/geography/name',
geographyMappings,
`implementationPeriod/grant/${componentField}/parent/name`,
);
url2 = `${urls.FINANCIAL_INDICATORS}/${filterString2}`;
Expand Down Expand Up @@ -579,24 +652,39 @@ export class BudgetsController {
.catch(handleDataApiError);
}

@get('/budgets/utilization')
@get('/budgets/utilization/{componentField}/{geographyGrouping}')
@response(200)
async utilization() {
async utilization(
@param.path.string('componentField') componentField: string,
@param.path.string('geographyGrouping') geographyGrouping: string,
) {
// (disbursement + cash balance) / budget
let geographyMappings = [
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
];
if (geographyGrouping === 'Portfolio View') {
geographyMappings = [
'implementationPeriod/grant/geography_PortfolioView/name',
'implementationPeriod/grant/geography_PortfolioView/code',
];
} else if (geographyGrouping === 'Board Constituency View') {
geographyMappings = [
'implementationPeriod/grant/geography_BoardConstituencyView/name',
'implementationPeriod/grant/geography_BoardConstituencyView/code',
];
}
const filterString1 = filterFinancialIndicators(
this.req.query,
BudgetsMetricsFieldsMapping.urlParams,
[
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
],
'implementationPeriod/grant/activityArea/name',
geographyMappings,
`implementationPeriod/grant/${componentField}/name`,
);
const filterString2 = filterFinancialIndicators(
this.req.query,
BudgetsMetricsFieldsMapping.urlParamsOrganisations,
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/activityArea/name',
geographyMappings,
`implementationPeriod/grant/${componentField}/name`,
);
const url1 = `${urls.FINANCIAL_INDICATORS}/${filterString1}`;
const url2 = `${urls.FINANCIAL_INDICATORS}/${filterString2}`;
Expand Down Expand Up @@ -806,27 +894,39 @@ export class BudgetsController {
.catch(handleDataApiError);
}

@get('/budgets/absorption')
@get('/budgets/absorption/{componentField}/{geographyGrouping}')
@response(200)
async absorption() {
async absorption(
@param.path.string('componentField') componentField: string,
@param.path.string('geographyGrouping') geographyGrouping: string,
) {
// expenditure / budget
let geographyMappings = [
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
];
if (geographyGrouping === 'Portfolio View') {
geographyMappings = [
'implementationPeriod/grant/geography_PortfolioView/name',
'implementationPeriod/grant/geography_PortfolioView/code',
];
} else if (geographyGrouping === 'Board Constituency View') {
geographyMappings = [
'implementationPeriod/grant/geography_BoardConstituencyView/name',
'implementationPeriod/grant/geography_BoardConstituencyView/code',
];
}
const filterString1 = filterFinancialIndicators(
this.req.query,
BudgetsMetricsFieldsMapping.urlParams,
[
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
],
'implementationPeriod/grant/activityArea/name',
geographyMappings,
`implementationPeriod/grant/${componentField}/name`,
);
const filterString2 = filterFinancialIndicators(
this.req.query,
BudgetsMetricsFieldsMapping.urlParamsOrganisations,
[
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
],
'implementationPeriod/grant/activityArea/name',
geographyMappings,
`implementationPeriod/grant/${componentField}/name`,
);
const url1 = `${urls.FINANCIAL_INDICATORS}/${filterString1}`;
const url2 = `${urls.FINANCIAL_INDICATORS}/${filterString2}`;
Expand Down Expand Up @@ -992,27 +1092,39 @@ export class BudgetsController {
.catch(handleDataApiError);
}

@get('/disbursements/utilization')
@get('/disbursements/utilization/{componentField}/{geographyGrouping}')
@response(200)
async disbursementsUtilization() {
async disbursementsUtilization(
@param.path.string('componentField') componentField: string,
@param.path.string('geographyGrouping') geographyGrouping: string,
) {
// expenditure / disbursement
let geographyMappings = [
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
];
if (geographyGrouping === 'Portfolio View') {
geographyMappings = [
'implementationPeriod/grant/geography_PortfolioView/name',
'implementationPeriod/grant/geography_PortfolioView/code',
];
} else if (geographyGrouping === 'Board Constituency View') {
geographyMappings = [
'implementationPeriod/grant/geography_BoardConstituencyView/name',
'implementationPeriod/grant/geography_BoardConstituencyView/code',
];
}
const filterString1 = filterFinancialIndicators(
this.req.query,
BudgetsMetricsFieldsMapping.urlParams,
[
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
],
'implementationPeriod/grant/activityArea/name',
geographyMappings,
`implementationPeriod/grant/${componentField}/name`,
);
const filterString2 = filterFinancialIndicators(
this.req.query,
BudgetsMetricsFieldsMapping.urlParamsOrganisations,
[
'implementationPeriod/grant/geography/name',
'implementationPeriod/grant/geography/code',
],
'implementationPeriod/grant/activityArea/name',
geographyMappings,
`implementationPeriod/grant/${componentField}/name`,
);
const url1 = `${urls.FINANCIAL_INDICATORS}/${filterString1}`;
const url2 = `${urls.FINANCIAL_INDICATORS}/${filterString2}`;
Expand Down
Loading

0 comments on commit d2e22ab

Please sign in to comment.