1
package org.hisp.dhis.de.action.multidimensional;
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.ArrayList;
31
import java.util.Collection;
32
import java.util.HashMap;
33
import java.util.List;
35
import java.util.TreeMap;
37
import org.hisp.dhis.dataelement.CalculatedDataElement;
38
import org.hisp.dhis.dataelement.DataElement;
39
import org.hisp.dhis.dataelement.DataElementCategory;
40
import org.hisp.dhis.dataelement.DataElementCategoryCombo;
41
import org.hisp.dhis.dataelement.DataElementCategoryOption;
42
import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
43
import org.hisp.dhis.dataelement.DataElementCategoryOptionComboService;
44
import org.hisp.dhis.dataelement.DataElementDimensionColumnOrder;
45
import org.hisp.dhis.dataelement.DataElementDimensionColumnOrderService;
46
import org.hisp.dhis.dataelement.DataElementDimensionRowOrder;
47
import org.hisp.dhis.dataelement.DataElementDimensionRowOrderService;
48
import org.hisp.dhis.dataset.DataEntryForm;
49
import org.hisp.dhis.dataset.DataEntryFormService;
50
import org.hisp.dhis.dataset.DataSet;
51
import org.hisp.dhis.datavalue.DataValue;
52
import org.hisp.dhis.datavalue.DataValueService;
53
import org.hisp.dhis.de.comments.StandardCommentsManager;
54
import org.hisp.dhis.options.SystemSettingManager;
55
import org.hisp.dhis.options.displayproperty.DisplayPropertyHandler;
56
import org.hisp.dhis.order.manager.DataElementOrderManager;
57
import org.hisp.dhis.de.screen.DataEntryScreenManager;
58
import org.hisp.dhis.de.state.SelectedStateManager;
59
import org.hisp.dhis.i18n.I18n;
60
import org.hisp.dhis.minmax.MinMaxDataElement;
61
import org.hisp.dhis.minmax.MinMaxDataElementStore;
62
import org.hisp.dhis.organisationunit.OrganisationUnit;
63
import org.hisp.dhis.period.Period;
65
import static org.hisp.dhis.options.SystemSettingManager.KEY_ZERO_VALUE_SAVE_MODE;
67
import com.opensymphony.xwork.Action;
70
* @author Abyot Asalefew
73
public class FormAction
76
// -------------------------------------------------------------------------
78
// -------------------------------------------------------------------------
80
private SystemSettingManager systemSettingManager;
82
public void setSystemSettingManager( SystemSettingManager systemSettingManager )
84
this.systemSettingManager = systemSettingManager;
87
private DataEntryFormService dataEntryFormService;
89
public void setDataEntryFormService( DataEntryFormService dataEntryFormService )
91
this.dataEntryFormService = dataEntryFormService;
94
private DataElementOrderManager dataElementOrderManager;
96
public void setDataElementOrderManager( DataElementOrderManager dataElementOrderManager )
98
this.dataElementOrderManager = dataElementOrderManager;
101
private DataValueService dataValueService;
103
public void setDataValueService( DataValueService dataValueService )
105
this.dataValueService = dataValueService;
108
private DataElementCategoryOptionComboService dataElementCategoryOptionComboService;
110
public void setDataElementCategoryOptionComboService( DataElementCategoryOptionComboService dataElementCategoryOptionComboService )
112
this.dataElementCategoryOptionComboService = dataElementCategoryOptionComboService;
115
private StandardCommentsManager standardCommentsManager;
117
public void setStandardCommentsManager( StandardCommentsManager standardCommentsManager )
119
this.standardCommentsManager = standardCommentsManager;
122
private MinMaxDataElementStore minMaxDataElementStore;
124
public void setMinMaxDataElementStore( MinMaxDataElementStore minMaxDataElementStore )
126
this.minMaxDataElementStore = minMaxDataElementStore;
129
private SelectedStateManager selectedStateManager;
131
public void setSelectedStateManager( SelectedStateManager selectedStateManager )
133
this.selectedStateManager = selectedStateManager;
136
private DataElementDimensionRowOrderService dataElementDimensionRowOrderService;
138
public void setDataElementDimensionRowOrderService( DataElementDimensionRowOrderService dataElementDimensionRowOrderService )
140
this.dataElementDimensionRowOrderService = dataElementDimensionRowOrderService;
143
private DataElementDimensionColumnOrderService dataElementDimensionColumnOrderService;
145
public void setDataElementDimensionColumnOrderService( DataElementDimensionColumnOrderService dataElementDimensionColumnOrderService )
147
this.dataElementDimensionColumnOrderService = dataElementDimensionColumnOrderService;
150
private DataEntryScreenManager dataEntryScreenManager;
152
public void setDataEntryScreenManager( DataEntryScreenManager dataEntryScreenManager )
154
this.dataEntryScreenManager = dataEntryScreenManager;
159
public void setI18n( I18n i18n )
164
// -------------------------------------------------------------------------
165
// DisplayPropertyHandler
166
// -------------------------------------------------------------------------
168
private DisplayPropertyHandler displayPropertyHandler;
170
public void setDisplayPropertyHandler( DisplayPropertyHandler displayPropertyHandler )
172
this.displayPropertyHandler = displayPropertyHandler;
175
// -------------------------------------------------------------------------
177
// -------------------------------------------------------------------------
179
private List<DataElement> orderedDataElements = new ArrayList<DataElement>();
181
public List<DataElement> getOrderedDataElements()
183
return orderedDataElements;
186
private Map<String, DataValue> dataValueMap;
188
public Map<String, DataValue> getDataValueMap()
193
private Map<CalculatedDataElement, Integer> calculatedValueMap;
195
public Map<CalculatedDataElement, Integer> getCalculatedValueMap()
197
return calculatedValueMap;
200
private List<String> standardComments;
202
public List<String> getStandardComments()
204
return standardComments;
207
private Map<String, String> dataElementTypeMap;
209
public Map<String, String> getDataElementTypeMap()
211
return dataElementTypeMap;
214
private Map<Integer, MinMaxDataElement> minMaxMap;
216
public Map<Integer, MinMaxDataElement> getMinMaxMap()
221
private Integer integer = 0;
223
public Integer getInteger()
228
private Map<Integer, Collection<DataElementCategoryOption>> orderedOptionsMap = new HashMap<Integer, Collection<DataElementCategoryOption>>();
230
public Map<Integer, Collection<DataElementCategoryOption>> getOrderedOptionsMap()
232
return orderedOptionsMap;
235
private Collection<DataElementCategory> orderedCategories;
237
public Collection<DataElementCategory> getOrderedCategories()
239
return orderedCategories;
242
private Integer numberOfTotalColumns;
244
public Integer getNumberOfTotalColumns()
246
return numberOfTotalColumns;
249
private Map<Integer, Collection<Integer>> catColRepeat = new HashMap<Integer, Collection<Integer>>();
251
public Map<Integer, Collection<Integer>> getCatColRepeat()
256
private Collection<DataElementCategoryOptionCombo> orderdCategoryOptionCombos = new ArrayList<DataElementCategoryOptionCombo>();
258
public Collection<DataElementCategoryOptionCombo> getOrderdCategoryOptionCombos()
260
return orderdCategoryOptionCombos;
263
private Map<Integer, String> optionComboNames = new HashMap<Integer, String>();
265
public Map<Integer, String> getOptionComboNames()
267
return optionComboNames;
270
private Boolean cdeFormExists;
272
public Boolean getCdeFormExists()
274
return cdeFormExists;
277
private DataEntryForm dataEntryForm;
279
public DataEntryForm getDataEntryForm()
281
return this.dataEntryForm;
284
private String customDataEntryFormCode;
286
public String getCustomDataEntryFormCode()
288
return this.customDataEntryFormCode;
291
private Boolean zeroValueSaveMode;
293
public Boolean getZeroValueSaveMode()
295
return zeroValueSaveMode;
298
// -------------------------------------------------------------------------
300
// -------------------------------------------------------------------------
302
private Integer selectedDataSetId;
304
public void setSelectedDataSetId( Integer selectedDataSetId )
306
this.selectedDataSetId = selectedDataSetId;
309
public Integer getSelectedDataSetId()
311
return selectedDataSetId;
314
private Integer selectedPeriodIndex;
316
public void setSelectedPeriodIndex( Integer selectedPeriodIndex )
318
this.selectedPeriodIndex = selectedPeriodIndex;
321
public Integer getSelectedPeriodIndex()
323
return selectedPeriodIndex;
326
private String disabled = " ";
328
// -------------------------------------------------------------------------
329
// Action implementation
330
// -------------------------------------------------------------------------
332
public String execute()
335
zeroValueSaveMode = (Boolean) systemSettingManager.getSystemSetting( KEY_ZERO_VALUE_SAVE_MODE, false );
337
OrganisationUnit organisationUnit = selectedStateManager.getSelectedOrganisationUnit();
339
DataSet dataSet = selectedStateManager.getSelectedDataSet();
341
Period period = selectedStateManager.getSelectedPeriod();
343
if ( dataSet.getLockedPeriods().contains( period ) )
345
disabled = "disabled";
348
Collection<DataElement> dataElements = dataSet.getDataElements();
350
if ( dataElements.size() == 0 )
355
for( DataElement de : dataElements )
357
Collection<DataElementCategoryOptionCombo> optionCombos = dataElementCategoryOptionComboService.sortDataElementCategoryOptionCombos( de.getCategoryCombo() ) ;
359
for( DataElementCategoryOptionCombo optionCombo : optionCombos )
361
if( !orderdCategoryOptionCombos.contains( optionCombo ) )
363
orderdCategoryOptionCombos.add(optionCombo);
369
* Perform ordering of categories and their options so that they could
370
* be displayed as in the paper form.
372
* Note that the total number of entry cells to be generated are the
373
* multiple of options each category is going to provide.
376
DataElement sample = dataElements.iterator().next();
378
DataElementCategoryCombo decbo = sample.getCategoryCombo();
380
List<DataElementCategory> categories = new ArrayList<DataElementCategory>( decbo.getCategories() );
381
Map<Integer, DataElementCategory> categoryMap = new TreeMap<Integer, DataElementCategory>();
383
numberOfTotalColumns = orderdCategoryOptionCombos.size();
385
for ( DataElementCategory category : categories ) // Get the order of categories
387
DataElementDimensionRowOrder rowOrder = dataElementDimensionRowOrderService.getDataElementDimensionRowOrder( decbo, category );
389
if( rowOrder != null )
391
categoryMap.put( rowOrder.getDisplayOrder(), category );
395
categoryMap.put( category.getId(), category );
399
orderedCategories = categoryMap.values();
401
for ( DataElementCategory dec : orderedCategories ) //Get the order of options
403
Map<Integer, DataElementCategoryOption> optionsMap = new TreeMap<Integer, DataElementCategoryOption>();
405
for ( DataElementCategoryOption option : dec.getCategoryOptions() )
407
DataElementDimensionColumnOrder columnOrder = dataElementDimensionColumnOrderService.getDataElementDimensionColumnOrder( dec, option );
409
if( columnOrder != null )
411
optionsMap.put( columnOrder.getDisplayOrder(), option );
415
optionsMap.put( option.getId(), option );
419
orderedOptionsMap.put( dec.getId(), optionsMap.values() );
423
* Calculating the number of times each category is supposed to be
424
* repeated in the dataentry form.
427
int catColSpan = numberOfTotalColumns;
429
Map<Integer, Integer> catRepeat = new HashMap<Integer, Integer>();
431
for ( DataElementCategory cat : orderedCategories )
433
catColSpan = catColSpan / cat.getCategoryOptions().size();
434
int total = numberOfTotalColumns / (catColSpan * cat.getCategoryOptions().size());
435
Collection<Integer> cols = new ArrayList<Integer>( total );
437
for ( int i = 0; i < total; i++ )
443
* Cols are made to be a collection simply to facilitate a for loop
444
* in the velocity template - there should be a better way of "for" doing a
448
catColRepeat.put( cat.getId(), cols );
450
catRepeat.put( cat.getId(), catColSpan );
453
for( DataElementCategoryOptionCombo deOptionCombo : orderdCategoryOptionCombos )
455
optionComboNames.put( deOptionCombo.getId(), dataElementCategoryOptionComboService.getOptionNames( deOptionCombo ) );
458
// ---------------------------------------------------------------------
459
// Get the min/max values
460
// ---------------------------------------------------------------------
462
Collection<MinMaxDataElement> minMaxDataElements = minMaxDataElementStore.getMinMaxDataElements(
463
organisationUnit, dataElements );
465
minMaxMap = new HashMap<Integer, MinMaxDataElement>( minMaxDataElements.size() );
467
for ( MinMaxDataElement minMaxDataElement : minMaxDataElements )
469
minMaxMap.put( minMaxDataElement.getDataElement().getId(), minMaxDataElement );
472
// ---------------------------------------------------------------------
473
// Get the DataValues and create a map
474
// ---------------------------------------------------------------------
476
Collection<DataValue> dataValues = dataValueService.getDataValues( organisationUnit, period, dataElements, orderdCategoryOptionCombos );
478
dataValueMap = new HashMap<String, DataValue>( dataValues.size() );
480
for ( DataValue dataValue : dataValues )
482
Integer deId = dataValue.getDataElement().getId();
483
Integer ocId = dataValue.getOptionCombo().getId();
485
dataValueMap.put( deId.toString() + ':' + ocId.toString(), dataValue );
488
// ---------------------------------------------------------------------
489
// Prepare values for unsaved CalculatedDataElements
490
// ---------------------------------------------------------------------
492
calculatedValueMap = dataEntryScreenManager.populateValuesForCalculatedDataElements( organisationUnit, dataSet, period );
494
// ---------------------------------------------------------------------
495
// Make the standard comments available
496
// ---------------------------------------------------------------------
498
standardComments = standardCommentsManager.getStandardComments();
500
// ---------------------------------------------------------------------
501
// Make the DataElement types available
502
// ---------------------------------------------------------------------
504
dataElementTypeMap = new HashMap<String, String>();
505
dataElementTypeMap.put( DataElement.TYPE_BOOL, i18n.getString( "yes_no" ) );
506
dataElementTypeMap.put( DataElement.TYPE_INT, i18n.getString( "number" ) );
507
dataElementTypeMap.put( DataElement.TYPE_STRING, i18n.getString( "text" ) );
509
// ---------------------------------------------------------------------
510
// Get the custom data entry form (if any)
511
// ---------------------------------------------------------------------
513
dataEntryForm = dataEntryFormService.getDataEntryFormByDataSet( dataSet );
515
cdeFormExists = (dataEntryForm != null);
519
customDataEntryFormCode = dataEntryScreenManager.populateCustomDataEntryScreenForMultiDimensional( dataEntryForm.getHtmlCode(),
520
dataValues, calculatedValueMap, minMaxMap, disabled, zeroValueSaveMode, i18n );
523
// ---------------------------------------------------------------------
524
// Working on the display of dataelements
525
// ---------------------------------------------------------------------
527
orderedDataElements = dataElementOrderManager.getOrderedDataElements( dataSet );
529
displayPropertyHandler.handle( orderedDataElements );