~mortenoh/+junk/dhis2-detailed-import-export

« back to all changes in this revision

Viewing changes to dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/multidimensional/FormAction.java

  • Committer: larshelge at gmail
  • Date: 2009-03-03 16:46:36 UTC
  • Revision ID: larshelge@gmail.com-20090303164636-2sjlrquo7ib1gf7r
Initial check-in

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.hisp.dhis.de.action.multidimensional;
 
2
 
 
3
/*
 
4
 * Copyright (c) 2004-2007, University of Oslo
 
5
 * All rights reserved.
 
6
 *
 
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.
 
17
 *
 
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.
 
28
 */
 
29
 
 
30
import java.util.ArrayList;
 
31
import java.util.Collection;
 
32
import java.util.HashMap;
 
33
import java.util.List;
 
34
import java.util.Map;
 
35
import java.util.TreeMap;
 
36
 
 
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;
 
64
 
 
65
import static org.hisp.dhis.options.SystemSettingManager.KEY_ZERO_VALUE_SAVE_MODE;
 
66
 
 
67
import com.opensymphony.xwork.Action;
 
68
 
 
69
/**
 
70
 * @author Abyot Asalefew
 
71
 * @version $Id$
 
72
 */
 
73
public class FormAction
 
74
    implements Action
 
75
{
 
76
    // -------------------------------------------------------------------------
 
77
    // Dependencies
 
78
    // -------------------------------------------------------------------------
 
79
        
 
80
    private SystemSettingManager systemSettingManager;
 
81
 
 
82
    public void setSystemSettingManager( SystemSettingManager systemSettingManager )
 
83
    {
 
84
        this.systemSettingManager = systemSettingManager;
 
85
    }
 
86
 
 
87
    private DataEntryFormService dataEntryFormService;
 
88
 
 
89
    public void setDataEntryFormService( DataEntryFormService dataEntryFormService )
 
90
    {
 
91
        this.dataEntryFormService = dataEntryFormService;
 
92
    }
 
93
 
 
94
    private DataElementOrderManager dataElementOrderManager;
 
95
 
 
96
    public void setDataElementOrderManager( DataElementOrderManager dataElementOrderManager )
 
97
    {
 
98
        this.dataElementOrderManager = dataElementOrderManager;
 
99
    }
 
100
 
 
101
    private DataValueService dataValueService;
 
102
 
 
103
    public void setDataValueService( DataValueService dataValueService )
 
104
    {
 
105
        this.dataValueService = dataValueService;
 
106
    }
 
107
 
 
108
    private DataElementCategoryOptionComboService dataElementCategoryOptionComboService;
 
109
 
 
110
    public void setDataElementCategoryOptionComboService( DataElementCategoryOptionComboService dataElementCategoryOptionComboService )
 
111
    {
 
112
        this.dataElementCategoryOptionComboService = dataElementCategoryOptionComboService;
 
113
    }
 
114
    
 
115
    private StandardCommentsManager standardCommentsManager;
 
116
 
 
117
    public void setStandardCommentsManager( StandardCommentsManager standardCommentsManager )
 
118
    {
 
119
        this.standardCommentsManager = standardCommentsManager;
 
120
    }
 
121
 
 
122
    private MinMaxDataElementStore minMaxDataElementStore;
 
123
 
 
124
    public void setMinMaxDataElementStore( MinMaxDataElementStore minMaxDataElementStore )
 
125
    {
 
126
        this.minMaxDataElementStore = minMaxDataElementStore;
 
127
    }
 
128
 
 
129
    private SelectedStateManager selectedStateManager;
 
130
 
 
131
    public void setSelectedStateManager( SelectedStateManager selectedStateManager )
 
132
    {
 
133
        this.selectedStateManager = selectedStateManager;
 
134
    }
 
135
    
 
136
    private DataElementDimensionRowOrderService dataElementDimensionRowOrderService;    
 
137
 
 
138
    public void setDataElementDimensionRowOrderService( DataElementDimensionRowOrderService dataElementDimensionRowOrderService )
 
139
    {
 
140
        this.dataElementDimensionRowOrderService = dataElementDimensionRowOrderService;
 
141
    }  
 
142
    
 
143
    private DataElementDimensionColumnOrderService dataElementDimensionColumnOrderService;    
 
144
 
 
145
    public void setDataElementDimensionColumnOrderService( DataElementDimensionColumnOrderService dataElementDimensionColumnOrderService )
 
146
    {
 
147
        this.dataElementDimensionColumnOrderService = dataElementDimensionColumnOrderService;
 
148
    }
 
149
    
 
150
    private DataEntryScreenManager dataEntryScreenManager;
 
151
 
 
152
    public void setDataEntryScreenManager( DataEntryScreenManager dataEntryScreenManager )
 
153
    {
 
154
        this.dataEntryScreenManager = dataEntryScreenManager;
 
155
    }
 
156
 
 
157
    private I18n i18n;
 
158
 
 
159
    public void setI18n( I18n i18n )
 
160
    {
 
161
        this.i18n = i18n;
 
162
    }   
 
163
 
 
164
    // -------------------------------------------------------------------------
 
165
    // DisplayPropertyHandler
 
166
    // -------------------------------------------------------------------------
 
167
 
 
168
    private DisplayPropertyHandler displayPropertyHandler;
 
169
 
 
170
    public void setDisplayPropertyHandler( DisplayPropertyHandler displayPropertyHandler )
 
171
    {
 
172
        this.displayPropertyHandler = displayPropertyHandler;
 
173
    }
 
174
    
 
175
    // -------------------------------------------------------------------------
 
176
    // Output
 
177
    // -------------------------------------------------------------------------
 
178
 
 
179
    private List<DataElement> orderedDataElements = new ArrayList<DataElement>();
 
180
 
 
181
    public List<DataElement> getOrderedDataElements()
 
182
    {
 
183
        return orderedDataElements;
 
184
    }
 
185
 
 
186
    private Map<String, DataValue> dataValueMap;
 
187
 
 
188
    public Map<String, DataValue> getDataValueMap()
 
189
    {
 
190
        return dataValueMap;
 
191
    }
 
192
 
 
193
    private Map<CalculatedDataElement, Integer> calculatedValueMap;
 
194
 
 
195
    public Map<CalculatedDataElement, Integer> getCalculatedValueMap()
 
196
    {
 
197
        return calculatedValueMap;
 
198
    }
 
199
 
 
200
    private List<String> standardComments;
 
201
 
 
202
    public List<String> getStandardComments()
 
203
    {
 
204
        return standardComments;
 
205
    }
 
206
 
 
207
    private Map<String, String> dataElementTypeMap;
 
208
 
 
209
    public Map<String, String> getDataElementTypeMap()
 
210
    {
 
211
        return dataElementTypeMap;
 
212
    }
 
213
 
 
214
    private Map<Integer, MinMaxDataElement> minMaxMap;
 
215
 
 
216
    public Map<Integer, MinMaxDataElement> getMinMaxMap()
 
217
    {
 
218
        return minMaxMap;
 
219
    }
 
220
 
 
221
    private Integer integer = 0;
 
222
 
 
223
    public Integer getInteger()
 
224
    {
 
225
        return integer;
 
226
    }
 
227
   
 
228
    private Map<Integer, Collection<DataElementCategoryOption>> orderedOptionsMap = new HashMap<Integer, Collection<DataElementCategoryOption>>();
 
229
 
 
230
    public Map<Integer, Collection<DataElementCategoryOption>> getOrderedOptionsMap()
 
231
    {
 
232
        return orderedOptionsMap;
 
233
    }
 
234
 
 
235
    private Collection<DataElementCategory> orderedCategories;
 
236
 
 
237
    public Collection<DataElementCategory> getOrderedCategories()
 
238
    {
 
239
        return orderedCategories;
 
240
    }
 
241
 
 
242
    private Integer numberOfTotalColumns;
 
243
 
 
244
    public Integer getNumberOfTotalColumns()
 
245
    {
 
246
        return numberOfTotalColumns;
 
247
    }
 
248
 
 
249
    private Map<Integer, Collection<Integer>> catColRepeat = new HashMap<Integer, Collection<Integer>>();
 
250
 
 
251
    public Map<Integer, Collection<Integer>> getCatColRepeat()
 
252
    {
 
253
        return catColRepeat;
 
254
    }
 
255
    
 
256
    private Collection<DataElementCategoryOptionCombo> orderdCategoryOptionCombos = new ArrayList<DataElementCategoryOptionCombo>();
 
257
 
 
258
    public Collection<DataElementCategoryOptionCombo> getOrderdCategoryOptionCombos()
 
259
    {
 
260
        return orderdCategoryOptionCombos;
 
261
    }    
 
262
    
 
263
    private Map<Integer, String> optionComboNames = new HashMap<Integer, String>();
 
264
 
 
265
    public Map<Integer, String> getOptionComboNames()
 
266
    {
 
267
        return optionComboNames;
 
268
    }
 
269
 
 
270
    private Boolean cdeFormExists;
 
271
 
 
272
    public Boolean getCdeFormExists()
 
273
    {
 
274
        return cdeFormExists;
 
275
    }
 
276
    
 
277
    private DataEntryForm dataEntryForm;
 
278
 
 
279
    public DataEntryForm getDataEntryForm()
 
280
    {
 
281
        return this.dataEntryForm;
 
282
    }
 
283
 
 
284
    private String customDataEntryFormCode;
 
285
 
 
286
    public String getCustomDataEntryFormCode()
 
287
    {
 
288
        return this.customDataEntryFormCode;
 
289
    }
 
290
    
 
291
    private Boolean zeroValueSaveMode;
 
292
 
 
293
    public Boolean getZeroValueSaveMode()
 
294
    {
 
295
        return zeroValueSaveMode;
 
296
    }
 
297
 
 
298
    // -------------------------------------------------------------------------
 
299
    // Input/output
 
300
    // -------------------------------------------------------------------------
 
301
 
 
302
    private Integer selectedDataSetId;
 
303
 
 
304
    public void setSelectedDataSetId( Integer selectedDataSetId )
 
305
    {
 
306
        this.selectedDataSetId = selectedDataSetId;
 
307
    }
 
308
 
 
309
    public Integer getSelectedDataSetId()
 
310
    {
 
311
        return selectedDataSetId;
 
312
    }
 
313
 
 
314
    private Integer selectedPeriodIndex;
 
315
 
 
316
    public void setSelectedPeriodIndex( Integer selectedPeriodIndex )
 
317
    {
 
318
        this.selectedPeriodIndex = selectedPeriodIndex;
 
319
    }
 
320
 
 
321
    public Integer getSelectedPeriodIndex()
 
322
    {
 
323
        return selectedPeriodIndex;
 
324
    }
 
325
    
 
326
    private String disabled = " ";
 
327
 
 
328
    // -------------------------------------------------------------------------
 
329
    // Action implementation
 
330
    // -------------------------------------------------------------------------
 
331
 
 
332
    public String execute()
 
333
        throws Exception
 
334
    {           
 
335
        zeroValueSaveMode = (Boolean) systemSettingManager.getSystemSetting( KEY_ZERO_VALUE_SAVE_MODE, false );         
 
336
        
 
337
        OrganisationUnit organisationUnit = selectedStateManager.getSelectedOrganisationUnit();
 
338
 
 
339
        DataSet dataSet = selectedStateManager.getSelectedDataSet();
 
340
 
 
341
        Period period = selectedStateManager.getSelectedPeriod();
 
342
        
 
343
        if ( dataSet.getLockedPeriods().contains( period ) )
 
344
        {
 
345
            disabled = "disabled";                        
 
346
        }
 
347
 
 
348
        Collection<DataElement> dataElements = dataSet.getDataElements();
 
349
 
 
350
        if ( dataElements.size() == 0 )
 
351
        {
 
352
            return SUCCESS;
 
353
        }
 
354
        
 
355
        for( DataElement de : dataElements )
 
356
        {  
 
357
                Collection<DataElementCategoryOptionCombo> optionCombos = dataElementCategoryOptionComboService.sortDataElementCategoryOptionCombos( de.getCategoryCombo() ) ;
 
358
                
 
359
                for( DataElementCategoryOptionCombo optionCombo : optionCombos )
 
360
                {
 
361
                        if( !orderdCategoryOptionCombos.contains( optionCombo ) )
 
362
                        {
 
363
                                orderdCategoryOptionCombos.add(optionCombo);
 
364
                        }
 
365
                }       
 
366
        }
 
367
        
 
368
        /*
 
369
         * Perform ordering of categories and their options so that they could
 
370
         * be displayed as in the paper form.        
 
371
         * 
 
372
         * Note that the total number of entry cells to be generated are the
 
373
         * multiple of options each category is going to provide.
 
374
         */
 
375
        
 
376
        DataElement sample = dataElements.iterator().next();
 
377
        
 
378
        DataElementCategoryCombo decbo = sample.getCategoryCombo();               
 
379
 
 
380
        List<DataElementCategory> categories = new ArrayList<DataElementCategory>( decbo.getCategories() );
 
381
        Map<Integer, DataElementCategory> categoryMap = new TreeMap<Integer, DataElementCategory>();
 
382
 
 
383
        numberOfTotalColumns = orderdCategoryOptionCombos.size();
 
384
        
 
385
        for ( DataElementCategory category : categories ) // Get the order of categories
 
386
        {                   
 
387
                DataElementDimensionRowOrder rowOrder = dataElementDimensionRowOrderService.getDataElementDimensionRowOrder( decbo, category );
 
388
                
 
389
                if( rowOrder != null )
 
390
                {
 
391
                        categoryMap.put( rowOrder.getDisplayOrder(), category );
 
392
                }
 
393
                else
 
394
                {
 
395
                        categoryMap.put( category.getId(), category );
 
396
                }
 
397
        }
 
398
 
 
399
        orderedCategories = categoryMap.values();
 
400
        
 
401
        for ( DataElementCategory dec : orderedCategories ) //Get the order of options 
 
402
        {
 
403
            Map<Integer, DataElementCategoryOption> optionsMap = new TreeMap<Integer, DataElementCategoryOption>();
 
404
 
 
405
            for ( DataElementCategoryOption option : dec.getCategoryOptions() )      
 
406
            {
 
407
                DataElementDimensionColumnOrder columnOrder = dataElementDimensionColumnOrderService.getDataElementDimensionColumnOrder( dec, option );
 
408
                
 
409
                if( columnOrder != null )
 
410
                {
 
411
                        optionsMap.put( columnOrder.getDisplayOrder(), option );
 
412
                }
 
413
                else
 
414
                {
 
415
                        optionsMap.put( option.getId(), option );
 
416
                }               
 
417
            }                   
 
418
 
 
419
            orderedOptionsMap.put( dec.getId(), optionsMap.values() );
 
420
        }
 
421
 
 
422
        /*
 
423
         * Calculating the number of times each category is supposed to be
 
424
         * repeated in the dataentry form.
 
425
         */
 
426
        
 
427
        int catColSpan = numberOfTotalColumns;
 
428
        
 
429
        Map<Integer, Integer> catRepeat = new HashMap<Integer, Integer>();
 
430
 
 
431
        for ( DataElementCategory cat : orderedCategories )
 
432
        {
 
433
            catColSpan = catColSpan / cat.getCategoryOptions().size();
 
434
            int total = numberOfTotalColumns / (catColSpan * cat.getCategoryOptions().size());
 
435
            Collection<Integer> cols = new ArrayList<Integer>( total );
 
436
 
 
437
            for ( int i = 0; i < total; i++ )
 
438
            {
 
439
                cols.add( i );
 
440
            }
 
441
 
 
442
            /*
 
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
 
445
            * loop.
 
446
            */
 
447
            
 
448
            catColRepeat.put( cat.getId(), cols );
 
449
            
 
450
            catRepeat.put( cat.getId(), catColSpan );
 
451
        }       
 
452
        
 
453
        for( DataElementCategoryOptionCombo deOptionCombo : orderdCategoryOptionCombos )
 
454
        {
 
455
                optionComboNames.put( deOptionCombo.getId(), dataElementCategoryOptionComboService.getOptionNames( deOptionCombo ) );           
 
456
        }
 
457
        
 
458
        // ---------------------------------------------------------------------
 
459
        // Get the min/max values
 
460
        // ---------------------------------------------------------------------
 
461
        
 
462
        Collection<MinMaxDataElement> minMaxDataElements = minMaxDataElementStore.getMinMaxDataElements(
 
463
            organisationUnit, dataElements );
 
464
 
 
465
        minMaxMap = new HashMap<Integer, MinMaxDataElement>( minMaxDataElements.size() );
 
466
 
 
467
        for ( MinMaxDataElement minMaxDataElement : minMaxDataElements )
 
468
        {
 
469
            minMaxMap.put( minMaxDataElement.getDataElement().getId(), minMaxDataElement );
 
470
        }       
 
471
 
 
472
        // ---------------------------------------------------------------------
 
473
        // Get the DataValues and create a map
 
474
        // ---------------------------------------------------------------------
 
475
 
 
476
        Collection<DataValue> dataValues = dataValueService.getDataValues( organisationUnit, period, dataElements, orderdCategoryOptionCombos );
 
477
 
 
478
        dataValueMap = new HashMap<String, DataValue>( dataValues.size() );
 
479
 
 
480
        for ( DataValue dataValue : dataValues )
 
481
        {
 
482
            Integer deId = dataValue.getDataElement().getId();
 
483
            Integer ocId = dataValue.getOptionCombo().getId();
 
484
 
 
485
            dataValueMap.put( deId.toString() + ':' + ocId.toString(), dataValue );
 
486
        }
 
487
 
 
488
        // ---------------------------------------------------------------------
 
489
        // Prepare values for unsaved CalculatedDataElements
 
490
        // ---------------------------------------------------------------------
 
491
        
 
492
        calculatedValueMap = dataEntryScreenManager.populateValuesForCalculatedDataElements( organisationUnit, dataSet, period );
 
493
        
 
494
        // ---------------------------------------------------------------------
 
495
        // Make the standard comments available
 
496
        // ---------------------------------------------------------------------
 
497
 
 
498
        standardComments = standardCommentsManager.getStandardComments();
 
499
 
 
500
        // ---------------------------------------------------------------------
 
501
        // Make the DataElement types available
 
502
        // ---------------------------------------------------------------------
 
503
 
 
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" ) );
 
508
 
 
509
        // ---------------------------------------------------------------------
 
510
        // Get the custom data entry form (if any)
 
511
        // ---------------------------------------------------------------------
 
512
 
 
513
        dataEntryForm = dataEntryFormService.getDataEntryFormByDataSet( dataSet );
 
514
        
 
515
        cdeFormExists = (dataEntryForm != null);
 
516
        
 
517
        if ( cdeFormExists )
 
518
        {            
 
519
            customDataEntryFormCode = dataEntryScreenManager.populateCustomDataEntryScreenForMultiDimensional( dataEntryForm.getHtmlCode(), 
 
520
                dataValues, calculatedValueMap, minMaxMap, disabled, zeroValueSaveMode, i18n );
 
521
        }     
 
522
        
 
523
        // ---------------------------------------------------------------------
 
524
        // Working on the display of dataelements
 
525
        // ---------------------------------------------------------------------
 
526
 
 
527
        orderedDataElements = dataElementOrderManager.getOrderedDataElements( dataSet );
 
528
 
 
529
        displayPropertyHandler.handle( orderedDataElements );
 
530
 
 
531
        return SUCCESS;
 
532
    }
 
533
}