Skip to content

Commit 93e5df8

Browse files
Merge pull request #333 from davidwatkins73/waltz-330-asset-costs
Asset cost views will always try to show latest year.
2 parents 1f05f39 + 214ca96 commit 93e5df8

10 files changed

Lines changed: 100 additions & 57 deletions

File tree

waltz-data/src/main/java/com/khartec/waltz/data/asset_cost/AssetCostDao.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@
2424
import com.khartec.waltz.model.cost.*;
2525
import com.khartec.waltz.schema.tables.records.AssetCostRecord;
2626
import org.jooq.*;
27+
import org.jooq.impl.DSL;
2728
import org.springframework.beans.factory.annotation.Autowired;
2829
import org.springframework.stereotype.Repository;
2930

3031
import java.util.Arrays;
3132
import java.util.List;
33+
import java.util.Optional;
3234

3335
import static com.khartec.waltz.schema.tables.Application.APPLICATION;
3436
import static com.khartec.waltz.schema.tables.AssetCost.ASSET_COST;
@@ -118,4 +120,12 @@ public List<ApplicationCost> findAppCostsByAppIdSelector(int year, Select<Record
118120
.fetch(appCostMapper);
119121
}
120122

123+
124+
public Optional<Integer> findLatestYear() {
125+
Integer year = dsl
126+
.select(DSL.max(ASSET_COST.YEAR).as("latest"))
127+
.from(ASSET_COST)
128+
.fetchOne("latest", Integer.class);
129+
return Optional.ofNullable(year);
130+
}
121131
}

waltz-jobs/src/main/java/com/khartec/waltz/jobs/AssetCostHarness.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@
2424
import com.khartec.waltz.model.application.ApplicationIdSelectionOptions;
2525
import com.khartec.waltz.model.application.HierarchyQueryScope;
2626
import com.khartec.waltz.model.application.ImmutableApplicationIdSelectionOptions;
27-
import com.khartec.waltz.model.cost.AssetCostQueryOptions;
2827
import com.khartec.waltz.model.cost.AssetCostStatistics;
2928
import com.khartec.waltz.model.cost.CostBandTally;
30-
import com.khartec.waltz.model.cost.ImmutableAssetCostQueryOptions;
3129
import com.khartec.waltz.service.DIConfiguration;
3230
import com.khartec.waltz.service.asset_cost.AssetCostService;
3331
import org.jooq.DSLContext;
@@ -61,16 +59,12 @@ public static void main(String[] args) {
6159
.build())
6260
.build();
6361

64-
AssetCostQueryOptions options = ImmutableAssetCostQueryOptions.builder()
65-
.idSelectionOptions(appIdSelectionOptions)
66-
.year(2015)
67-
.build();
6862

6963
Select<Record1<Long>> selector = selectorFactory.apply(appIdSelectionOptions);
7064
List<CostBandTally> res = dao.calculateCostBandStatisticsByAppIdSelector(2015, selector);
7165

7266

73-
AssetCostStatistics stats = service.calculateStatisticsByAppIds(options);
67+
AssetCostStatistics stats = service.calculateStatisticsByAppIds(appIdSelectionOptions);
7468

7569
System.out.println("-- end, dur: " + (System.currentTimeMillis() - st));
7670

waltz-jobs/src/main/java/com/khartec/waltz/jobs/sample/AssetCostGenerator.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ public class AssetCostGenerator {
3838

3939
private static final Random rnd = new Random();
4040

41+
private static final int year = 2015;
42+
private static final String provenance = "waltz";
43+
4144

4245
public static void main(String[] args) {
4346
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(DIConfiguration.class);
@@ -48,7 +51,10 @@ public static void main(String[] args) {
4851
List<AssetCostRecord> appDevCosts = generateRecords(applicationService, CostKind.APPLICATION_DEVELOPMENT, 10_000, 10_000_000);
4952
List<AssetCostRecord> infraCosts = generateRecords(applicationService, CostKind.INFRASTRUCTURE, 1_000, 50_000);
5053

51-
dsl.deleteFrom(ASSET_COST).execute();
54+
dsl.deleteFrom(ASSET_COST)
55+
.where(ASSET_COST.YEAR.eq(year))
56+
.and(ASSET_COST.PROVENANCE.eq(provenance))
57+
.execute();
5258

5359
dsl.batchInsert(appDevCosts).execute();
5460
dsl.batchInsert(infraCosts).execute();
@@ -64,7 +70,7 @@ private static List<AssetCostRecord> generateRecords(ApplicationService applicat
6470
.cost(ImmutableCost.builder()
6571
.currencyCode("EUR")
6672
.amount(generateAmount(low, high))
67-
.year(2015)
73+
.year(year)
6874
.kind(kind)
6975
.build())
7076
.build())

waltz-ng/client/app-groups/app-group-view.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ function controller($scope,
151151
dataFlowViewService.initialise(id, 'APP_GROUP', 'EXACT')
152152
.then(flows => vm.dataFlows = flows);
153153

154-
assetCostViewService.initialise(id, 'APP_GROUP', 'EXACT', 2015)
154+
assetCostViewService.initialise(appIdSelector, 2016)
155155
.then(costs => vm.assetCostData = costs);
156156

157157
bookmarkStore

waltz-ng/client/asset-cost/services/asset-cost-store.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,30 @@
1616
*
1717
*/
1818

19-
const service = (http, root) => {
19+
const service = ($http, root) => {
2020

2121
const BASE = `${root}/asset-cost`;
2222

2323
const findByCode = code =>
24-
http.get(`${BASE}/code/${code}`)
24+
$http.get(`${BASE}/code/${code}`)
2525
.then(result => result.data);
2626

2727

2828
const findAppCostsByAppIds = (options) =>
29-
http.post(`${BASE}/app-cost/apps`, options)
29+
$http.post(`${BASE}/app-cost/apps`, options)
3030
.then(result => result.data);
3131

3232

33-
const findStatsByAppIds = (options) =>
34-
http.post(`${BASE}/app-cost/apps/stats`, options)
35-
.then(result => result.data);
33+
const findStatsByAppIds = (options, year) => {
34+
var path = `${BASE}/app-cost/apps/stats`;
35+
const params = year
36+
? { params: { year } }
37+
: {};
3638

39+
return $http
40+
.post(path, options, params)
41+
.then(result => result.data);
42+
};
3743

3844
return {
3945
findByCode,

waltz-ng/client/asset-cost/services/asset-cost-view-service.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { checkIsApplicationIdSelector } from '../../common/checks';
2+
13
const initData = {
24
loadingStats: false,
35
loadingCosts: false,
@@ -12,18 +14,14 @@ function service($q,
1214

1315
let data = initData;
1416

15-
function initialise(id, kind, scope = 'CHILDREN', year = 2015) {
17+
function initialise(selector, year) {
18+
checkIsApplicationIdSelector(selector);
19+
1620
data = { ...initData };
1721
data.loadingStats = true;
18-
data.options = {
19-
year,
20-
idSelectionOptions: {
21-
scope,
22-
entityReference: { id, kind }
23-
}
24-
};
22+
data.options = selector;
2523
return assetCostStore
26-
.findStatsByAppIds(data.options)
24+
.findStatsByAppIds(data.options, year)
2725
.then(stats => {
2826
data.loadingStats = false;
2927
data.stats = stats;

waltz-ng/client/capabilities/capability-view.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ function controller($q,
210210
ratingStore.findByAppIdSelector(appIdSelector),
211211
dataFlowViewService.initialise(capability.id, 'CAPABILITY', 'CHILDREN'),
212212
complexityStore.findBySelector(capability.id, 'CAPABILITY', 'CHILDREN'),
213-
assetCostViewService.initialise(capability.id, 'CAPABILITY', 'CHILDREN', 2015),
213+
assetCostViewService.initialise(appIdSelector, 2016),
214214
techStatsService.findBySelector(capability.id, 'CAPABILITY', 'CHILDREN'),
215215
sourceDataRatingStore.findAll()
216216
]).then(([

waltz-ng/client/org-units/services/org-unit-view-data.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,17 @@ function service($q,
3838

3939
const rawData = {};
4040

41+
42+
4143
function loadAll(orgUnitId) {
4244

45+
const appIdSelector = {
46+
entityReference: {
47+
id: orgUnitId,
48+
kind: 'ORG_UNIT'
49+
},
50+
scope: 'CHILDREN'
51+
};
4352

4453
const promises = [
4554
orgUnitStore.findAll(),
@@ -49,7 +58,7 @@ function service($q,
4958
perspectiveStore.findByCode('BUSINESS'),
5059
dataFlowViewService.initialise(orgUnitId, "ORG_UNIT", "CHILDREN"),
5160
changeLogStore.findByEntityReference('ORG_UNIT', orgUnitId),
52-
assetCostViewService.initialise(orgUnitId, 'ORG_UNIT', 'CHILDREN', 2015)
61+
assetCostViewService.initialise(appIdSelector, 2016)
5362
];
5463

5564
return $q.all(promises)

waltz-service/src/main/java/com/khartec/waltz/service/asset_cost/AssetCostService.java

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,21 @@
1717

1818
package com.khartec.waltz.service.asset_cost;
1919

20-
import com.khartec.waltz.common.Checks;
2120
import com.khartec.waltz.data.application.ApplicationIdSelectorFactory;
2221
import com.khartec.waltz.data.asset_cost.AssetCostDao;
2322
import com.khartec.waltz.data.asset_cost.AssetCostStatsDao;
23+
import com.khartec.waltz.model.application.ApplicationIdSelectionOptions;
2424
import com.khartec.waltz.model.cost.*;
2525
import org.jooq.Record1;
2626
import org.jooq.Select;
2727
import org.springframework.beans.factory.annotation.Autowired;
2828
import org.springframework.stereotype.Service;
2929

30+
import java.util.Collections;
3031
import java.util.List;
3132

33+
import static com.khartec.waltz.common.Checks.checkNotNull;
34+
3235

3336
@Service
3437
public class AssetCostService {
@@ -42,9 +45,9 @@ public class AssetCostService {
4245
public AssetCostService(AssetCostDao assetCodeDao,
4346
AssetCostStatsDao assetCostStatsDao,
4447
ApplicationIdSelectorFactory idSelectorFactory) {
45-
Checks.checkNotNull(assetCodeDao, "assetCodeDao cannot be null");
46-
Checks.checkNotNull(assetCostStatsDao, "assetCostStatsDao cannot be null");
47-
Checks.checkNotNull(idSelectorFactory, "idSelectorFactory cannot be null");
48+
checkNotNull(assetCodeDao, "assetCodeDao cannot be null");
49+
checkNotNull(assetCostStatsDao, "assetCostStatsDao cannot be null");
50+
checkNotNull(idSelectorFactory, "idSelectorFactory cannot be null");
4851

4952
this.assetCostDao = assetCodeDao;
5053
this.assetCostStatsDao = assetCostStatsDao;
@@ -53,7 +56,7 @@ public AssetCostService(AssetCostDao assetCodeDao,
5356

5457

5558
public List<AssetCost> findByAssetCode(String code) {
56-
Checks.checkNotNull(code, "code cannot be null");
59+
checkNotNull(code, "code cannot be null");
5760
return assetCostDao.findByAssetCode(code);
5861
}
5962

@@ -63,25 +66,37 @@ public List<AssetCost> findByAppId(long appId) {
6366
}
6467

6568

66-
public List<ApplicationCost> findAppCostsByAppIds(AssetCostQueryOptions options) {
67-
Checks.checkNotNull(options, "options cannot be null");
68-
Select<Record1<Long>> selector = idSelectorFactory.apply(options.idSelectionOptions());
69-
return assetCostDao.findAppCostsByAppIdSelector(options.year(), selector);
69+
public List<ApplicationCost> findAppCostsByAppIds(ApplicationIdSelectionOptions options) {
70+
checkNotNull(options, "options cannot be null");
71+
Select<Record1<Long>> selector = idSelectorFactory.apply(options);
72+
73+
return assetCostDao
74+
.findLatestYear()
75+
.map(year -> assetCostDao.findAppCostsByAppIdSelector(year, selector))
76+
.orElse(Collections.emptyList());
7077
}
7178

7279

73-
public AssetCostStatistics calculateStatisticsByAppIds(AssetCostQueryOptions options) {
74-
Checks.checkNotNull(options, "options cannot be null");
80+
public AssetCostStatistics calculateStatisticsByAppIds(ApplicationIdSelectionOptions options) {
81+
checkNotNull(options, "options cannot be null");
82+
83+
Select<Record1<Long>> appIdSelector = idSelectorFactory.apply(options);
7584

76-
Select<Record1<Long>> appIdSelector = idSelectorFactory.apply(options.idSelectionOptions());
85+
return assetCostDao
86+
.findLatestYear()
87+
.map(year -> {
88+
List<CostBandTally> costBandCounts = assetCostStatsDao
89+
.calculateCostBandStatisticsByAppIdSelector(year, appIdSelector);
7790

78-
List<CostBandTally> costBandCounts = assetCostStatsDao.calculateCostBandStatisticsByAppIdSelector(options.year(), appIdSelector);
79-
Cost totalCost = assetCostStatsDao.calculateTotalCostByAppIdSelector(options.year(), appIdSelector);
91+
Cost totalCost = assetCostStatsDao
92+
.calculateTotalCostByAppIdSelector(year, appIdSelector);
8093

81-
return ImmutableAssetCostStatistics.builder()
82-
.costBandCounts(costBandCounts)
83-
.totalCost(totalCost)
84-
.build();
94+
return ImmutableAssetCostStatistics.builder()
95+
.costBandCounts(costBandCounts)
96+
.totalCost(totalCost)
97+
.build();
98+
})
99+
.orElse(null);
85100

86101
}
87102

waltz-web/src/main/java/com/khartec/waltz/web/endpoints/api/AssetCostEndpoint.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,23 @@
1717

1818
package com.khartec.waltz.web.endpoints.api;
1919

20+
import com.khartec.waltz.model.application.ApplicationIdSelectionOptions;
2021
import com.khartec.waltz.model.cost.ApplicationCost;
2122
import com.khartec.waltz.model.cost.AssetCost;
22-
import com.khartec.waltz.model.cost.AssetCostQueryOptions;
2323
import com.khartec.waltz.model.cost.AssetCostStatistics;
2424
import com.khartec.waltz.service.asset_cost.AssetCostService;
25-
import com.khartec.waltz.web.DatumRoute;
2625
import com.khartec.waltz.web.ListRoute;
2726
import com.khartec.waltz.web.endpoints.Endpoint;
2827
import org.springframework.beans.factory.annotation.Autowired;
2928
import org.springframework.stereotype.Service;
3029
import spark.Request;
30+
import spark.Response;
3131

3232
import java.io.IOException;
33+
import java.util.List;
3334

3435
import static com.khartec.waltz.web.WebUtilities.mkPath;
35-
import static com.khartec.waltz.web.WebUtilities.readBody;
36+
import static com.khartec.waltz.web.WebUtilities.readOptionsFromBody;
3637
import static com.khartec.waltz.web.endpoints.EndpointUtilities.*;
3738

3839

@@ -59,18 +60,22 @@ public void register() {
5960

6061
ListRoute<AssetCost> findByAssetCodeRoute = (request, response) -> assetCostService.findByAssetCode(request.params("code"));
6162

62-
ListRoute<ApplicationCost> findAppCostsByAppIds = (request, response) -> assetCostService.findAppCostsByAppIds(readQueryOptions(request));
63-
64-
DatumRoute<AssetCostStatistics> calcStatisticsByAppIdsRoute = (request, response) ->
65-
assetCostService.calculateStatisticsByAppIds(readQueryOptions(request));
66-
6763
getForList(findByAssetCodePath, findByAssetCodeRoute);
68-
postForList(findAppCostsByAppIdsPath, findAppCostsByAppIds);
69-
postForDatum(calcStatisticsByAppIdsPath, calcStatisticsByAppIdsRoute);
64+
postForList(findAppCostsByAppIdsPath, this::findAppCostsByAppIds);
65+
postForDatum(calcStatisticsByAppIdsPath, this::calcStatisticsByAppIdsRoute);
7066

7167
}
7268

73-
private AssetCostQueryOptions readQueryOptions(Request request) throws IOException {
74-
return readBody(request, AssetCostQueryOptions.class);
69+
private AssetCostStatistics calcStatisticsByAppIdsRoute(Request request, Response response) throws IOException {
70+
ApplicationIdSelectionOptions selectorOptions = readOptionsFromBody(request);
71+
return assetCostService.calculateStatisticsByAppIds(selectorOptions);
7572
}
73+
74+
75+
private List<ApplicationCost> findAppCostsByAppIds(Request request, Response response) throws IOException {
76+
ApplicationIdSelectionOptions selectorOptions = readOptionsFromBody(request);
77+
return assetCostService.findAppCostsByAppIds(selectorOptions);
78+
}
79+
80+
7681
}

0 commit comments

Comments
 (0)