1
package org.hisp.dhis.aggregation.impl.dataelement;
4
* Copyright (c) 2004-2007, University of Oslo
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions are met:
9
* * Redistributions of source code must retain the above copyright notice, this
10
* list of conditions and the following disclaimer.
11
* * Redistributions in binary form must reproduce the above copyright notice,
12
* this list of conditions and the following disclaimer in the documentation
13
* and/or other materials provided with the distribution.
14
* * Neither the name of the HISP project nor the names of its contributors may
15
* be used to endorse or promote products derived from this software without
16
* specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
import java.util.Collection;
31
import java.util.Date;
33
import org.hisp.dhis.aggregation.AggregationService;
34
import org.hisp.dhis.dataelement.DataElement;
35
import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
36
import org.hisp.dhis.datavalue.DataValue;
37
import org.hisp.dhis.organisationunit.OrganisationUnit;
38
import org.hisp.dhis.organisationunit.OrganisationUnitHierarchy;
39
import org.hisp.dhis.period.Period;
41
import static org.hisp.dhis.system.util.MathUtils.getDays;
44
* @author Lars Helge Overland
45
* @version $Id: AverageBoolDataElementAggregation.java 4753 2008-03-14 12:48:50Z larshelg $
47
public class AverageBoolDataElementAggregation
48
extends AbstractDataElementAggregation
50
public double getAggregatedValue( DataElement dataElement, DataElementCategoryOptionCombo optionCombo, Date aggregationStartDate, Date aggregationEndDate,
51
OrganisationUnit organisationUnit )
53
Collection<OrganisationUnitHierarchy> hierarchies = aggregationCache.getOrganisationUnitHierarchies(
54
aggregationStartDate, aggregationEndDate );
56
double[] sums = getSumAndRelevantDays( dataElement.getId(), optionCombo.getId(), aggregationStartDate, aggregationEndDate,
57
hierarchies, organisationUnit.getId() );
61
double average = sums[0] / sums[1];
67
return AggregationService.NO_VALUES_REGISTERED;
71
protected Collection<DataValue> getDataValues( int dataElementId, int optionComboId, int organisationUnitId,
72
OrganisationUnitHierarchy hierarchy, Date startDate, Date endDate )
74
Collection<Integer> children = aggregationCache.getChildren( hierarchy, organisationUnitId );
76
Collection<Integer> periods = aggregationCache.getPeriodIds( startDate, endDate );
78
Collection<DataValue> values = aggregationStore.getDataValues( children, dataElementId, optionComboId, periods );
84
* Calculates the AVERAGE for DataValues which period is within or
85
* overlapping startDate and / or endDate. This method is typically used for
86
* semi-permanent DataValues. It handles the four situations where a
87
* DataValue will count for the period that startDate to endDate constitutes (
88
* referred to as d1 and d2 ):
90
* 1. startDate and endDate is between d1 - d2<br>
91
* 2. startDate is before d1 and endDate is between d1 - d2<br>
92
* 3. startDate is between d1 - d2 and endDate is after d2<br>
93
* 4. startDate is before d1 and endDate is after d2<br>
95
* The method iterates over every DataValue in the passed Collection. The
96
* number of days in each DataValue's period between d1 - d2 is summarized
97
* and addded to the total sum if the value is true. The number of days in
98
* each DataValue's period between d1 - d2 is summarized and returned at
101
* @param dataValues The datavalues to aggregate
102
* @param startDate Start date of the period to aggregate over
103
* @param endDate End date of the period to aggregate over
104
* @param aggregationStartDate The original start date of the entire
106
* @param aggregationEndDate The original end date of the entire aggregation
108
* @return The numerator and denominator of the AVERAGE value
110
protected double[] getAggregateOfValues( Collection<DataValue> dataValues, Date startDate, Date endDate,
111
Date aggregationStartDate, Date aggregationEndDate )
114
double totalRelevantDays = 0;
116
for ( DataValue dataValue : dataValues )
118
Period currentPeriod = aggregationCache.getPeriod( dataValue.getPeriod().getId() );
119
Date currentStartDate = currentPeriod.getStartDate();
120
Date currentEndDate = currentPeriod.getEndDate();
122
long relevantDays = 0;
124
if ( currentStartDate.compareTo( startDate ) >= 0 && currentEndDate.compareTo( endDate ) <= 0 )
126
relevantDays = getDays( currentEndDate ) - getDays( currentStartDate );
128
else if ( currentStartDate.compareTo( startDate ) <= 0 && currentEndDate.compareTo( startDate ) >= 0
129
&& currentEndDate.compareTo( endDate ) <= 0 )
131
relevantDays = getDays( currentEndDate ) - getDays( startDate );
133
else if ( currentStartDate.compareTo( startDate ) >= 0 && currentStartDate.compareTo( endDate ) <= 0
134
&& currentEndDate.compareTo( endDate ) >= 0 )
136
relevantDays = getDays( endDate ) - getDays( currentStartDate );
138
else if ( currentStartDate.compareTo( startDate ) <= 0 && currentEndDate.compareTo( endDate ) >= 0 )
140
relevantDays = getDays( endDate ) - getDays( startDate );
143
String stringValue = dataValue.getValue();
145
if ( stringValue != null && stringValue.toLowerCase().equals( TRUE ) )
147
totalSum += relevantDays;
150
totalRelevantDays += relevantDays;
153
double[] fraction = { totalSum, totalRelevantDays };