=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java 2013-04-19 15:02:38 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataelement/DataElement.java 2013-05-25 06:19:23 +0000 @@ -1,7 +1,7 @@ package org.hisp.dhis.dataelement; /* - * Copyright (c) 2004-2012, University of Oslo + * Copyright (c) 2004-2013, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without === modified file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetService.java' --- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetService.java 2012-09-10 08:50:51 +0000 +++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DataValueSetService.java 2013-05-25 06:19:23 +0000 @@ -27,6 +27,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import org.hisp.dhis.dxf2.importsummary.ImportSummary; +import org.hisp.dhis.dxf2.metadata.ImportOptions; +import org.hisp.dhis.scheduling.TaskId; + import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; @@ -34,18 +38,14 @@ import java.util.Date; import java.util.Set; -import org.hisp.dhis.dxf2.importsummary.ImportSummary; -import org.hisp.dhis.dxf2.metadata.ImportOptions; -import org.hisp.dhis.scheduling.TaskId; - public interface DataValueSetService { void writeDataValueSet( String dataSet, String period, String orgUnit, OutputStream out ); - + void writeDataValueSet( Set dataSets, Date startDate, Date endDate, Set orgUnits, OutputStream out ); - + void writeDataValueSetCsv( Set dataSets, Date startDate, Date endDate, Set orgUnits, Writer writer ); - + ImportSummary saveDataValueSet( InputStream in ); ImportSummary saveDataValueSetJson( InputStream in ); @@ -59,4 +59,6 @@ ImportSummary saveDataValueSetJson( InputStream in, ImportOptions importOptions, TaskId taskId ); ImportSummary saveDataValueSetCsv( Reader reader, ImportOptions importOptions, TaskId id ); + + ImportSummary saveDataValueSetPdf( InputStream in, ImportOptions importOptions, TaskId id ); } === modified file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java' --- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java 2013-04-19 16:05:26 +0000 +++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/datavalueset/DefaultDataValueSetService.java 2013-05-25 06:19:23 +0000 @@ -27,25 +27,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import static org.hisp.dhis.importexport.ImportStrategy.NEW; -import static org.hisp.dhis.importexport.ImportStrategy.NEW_AND_UPDATES; -import static org.hisp.dhis.importexport.ImportStrategy.UPDATES; -import static org.hisp.dhis.system.notification.NotificationLevel.ERROR; -import static org.hisp.dhis.system.notification.NotificationLevel.INFO; -import static org.hisp.dhis.system.util.ConversionUtils.wrap; -import static org.hisp.dhis.system.util.DateUtils.getDefaultDate; - -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - +import au.com.bytecode.opencsv.CSVReader; import org.amplecode.quick.BatchHandler; import org.amplecode.quick.BatchHandlerFactory; import org.amplecode.staxwax.factory.XMLFactory; @@ -66,6 +48,7 @@ import org.hisp.dhis.dxf2.importsummary.ImportStatus; import org.hisp.dhis.dxf2.importsummary.ImportSummary; import org.hisp.dhis.dxf2.metadata.ImportOptions; +import org.hisp.dhis.dxf2.pdfform.PdfDataEntryFormUtil; import org.hisp.dhis.dxf2.utils.JacksonUtils; import org.hisp.dhis.importexport.ImportStrategy; import org.hisp.dhis.jdbc.batchhandler.DataValueBatchHandler; @@ -82,7 +65,22 @@ import org.hisp.dhis.user.CurrentUserService; import org.springframework.beans.factory.annotation.Autowired; -import au.com.bytecode.opencsv.CSVReader; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static org.hisp.dhis.importexport.ImportStrategy.*; +import static org.hisp.dhis.system.notification.NotificationLevel.ERROR; +import static org.hisp.dhis.system.notification.NotificationLevel.INFO; +import static org.hisp.dhis.system.util.ConversionUtils.wrap; +import static org.hisp.dhis.system.util.DateUtils.getDefaultDate; /** * @author Lars Helge Overland @@ -240,6 +238,23 @@ } } + public ImportSummary saveDataValueSetPdf( InputStream in, ImportOptions importOptions, TaskId id ) + { + try + { + DataValueSet dataValueSet = PdfDataEntryFormUtil.getDataValueSet( in ); + + return saveDataValueSet( importOptions, id, dataValueSet ); + } + catch ( RuntimeException ex ) + { + log.error( DebugUtils.getStackTrace( ex ) ); + notifier.clear( id ).notify( id, ERROR, "Unfortunately the process failed, check the logs", true ); + return new ImportSummary( ImportStatus.ERROR, "The import process failed: " + ex.getMessage() ); + } + } + + private ImportSummary saveDataValueSet( ImportOptions importOptions, TaskId id, DataValueSet dataValueSet ) { notifier.clear( id ).notify( id, "Process started" ); @@ -352,9 +367,9 @@ { continue; } - + String valueValid = ValidationUtils.dataValueIsValid( dataValue.getValue(), dataElement ); - + if ( valueValid != null ) { summary.getConflicts().add( new ImportConflict( DataValue.class.getSimpleName(), valueValid ) ); === added directory 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform' === added file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/DefaultPdfDataEntryFormService.java' --- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/DefaultPdfDataEntryFormService.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/DefaultPdfDataEntryFormService.java 2013-05-25 06:19:23 +0000 @@ -0,0 +1,848 @@ +package org.hisp.dhis.dxf2.pdfform; + +/* + * Copyright (c) 2004-2013, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.lowagie.text.Chunk; +import com.lowagie.text.Document; +import com.lowagie.text.DocumentException; +import com.lowagie.text.Element; +import com.lowagie.text.Font; +import com.lowagie.text.Paragraph; +import com.lowagie.text.Phrase; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.CMYKColor; +import com.lowagie.text.pdf.PdfAnnotation; +import com.lowagie.text.pdf.PdfAppearance; +import com.lowagie.text.pdf.PdfBorderDictionary; +import com.lowagie.text.pdf.PdfContentByte; +import com.lowagie.text.pdf.PdfFormField; +import com.lowagie.text.pdf.PdfPCell; +import com.lowagie.text.pdf.PdfPTable; +import com.lowagie.text.pdf.PdfWriter; +import com.lowagie.text.pdf.RadioCheckField; +import com.lowagie.text.pdf.TextField; +import org.hisp.dhis.dataelement.DataElement; +import org.hisp.dhis.dataset.DataSet; +import org.hisp.dhis.dataset.DataSetService; +import org.hisp.dhis.dataset.Section; +import org.hisp.dhis.i18n.I18nFormat; +import org.hisp.dhis.option.OptionService; +import org.hisp.dhis.option.OptionSet; +import org.hisp.dhis.period.CalendarPeriodType; +import org.hisp.dhis.period.MonthlyPeriodType; +import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodType; +import org.hisp.dhis.program.ProgramStage; +import org.hisp.dhis.program.ProgramStageDataElement; +import org.hisp.dhis.program.ProgramStageSection; +import org.hisp.dhis.program.ProgramStageService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.awt.*; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Collection; +import java.util.List; + +public class DefaultPdfDataEntryFormService + implements PdfDataEntryFormService +{ + + private static final Color COLOR_BACKGROUDTEXTBOX = Color.LIGHT_GRAY; + + private static final String TEXT_BLANK = " "; + + // --- All the Settings Related + private static final int TEXTBOXWIDTH_NUMBERTYPE = 20; + + private static final int TEXTBOXWIDTH = 200; + + private static final int PERIODRANGE_PREVYEARS = 1; + + private static final int PERIODRANGE_FUTUREYEARS = 2; + + private static Integer MAX_OPTIONS_DISPLAYED = 30; + + private static Integer PROGRAM_FORM_ROW_NUMBER = 10; + + // Variables + + private PdfFormFontSettings pdfFormFontSettings; + + private I18nFormat format; + + // ------------------------------------------------------------------------- + // Dependencies + // ------------------------------------------------------------------------- + + @Autowired + private DataSetService dataSetService; + + @Autowired + private ProgramStageService programStageService; + + @Autowired + private OptionService optionService; + + // ------------------------------------------------------------------------- + // METHODS / CLASSES + // ------------------------------------------------------------------------- + + @Override + public void generatePDFDataEntryForm( Document document, PdfWriter writer, String inputUid, int typeId, + Rectangle pageSize, PdfFormFontSettings pdfFormFontSettings, I18nFormat format ) + { + try + { + + // STEP 1. Assign the parameters to the global variable + this.pdfFormFontSettings = pdfFormFontSettings; + this.format = format; + + // STEP 2. Set Page Size + document.setPageSize( pageSize ); + + // STEP 3. PDF Document Open + document.open(); + + // STEP 3. Generate the PDF Form + if ( typeId == PdfDataEntryFormUtil.DATATYPE_DATASET ) + { + setDataSet_DocumentContent( document, writer, inputUid ); + } + else if ( typeId == PdfDataEntryFormUtil.DATATYPE_PROGRAMSTAGE ) + { + setProgramStage_DocumentContent( document, writer, inputUid ); + } + + // STEP 4. Close the PDF Document + document.close(); + + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } + + } + + // ----------------------------------------------------------------------------- + // --- Retrieve Document Content - DataSet [START] + + private void setDataSet_DocumentContent( Document document, PdfWriter writer, String dataSetUid ) + throws IOException, DocumentException, ParseException, Exception + { + + DataSet dataSet = dataSetService.getDataSet( dataSetUid ); + + if ( dataSet == null ) + { + throw new Exception( "Error - DataSet not found for UID " + dataSetUid ); + } + else + { + // Step 1. Set DataSet Name/Description + setDataSet_DocumentTopSection( document, dataSet ); + + // Add a line space + document.add( Chunk.NEWLINE ); + + // Step 2. Generate period listings + List periods = getPeriods_DataSet( dataSet.getPeriodType() ); + + // Step 3. 'Main Table' Create and Set + // The 'Main Table' is used to hold the layout of the page content. + PdfPTable mainTable = new PdfPTable( 1 ); // Table with 1 cell. + setMainTable( mainTable ); + + // Step 4. Add Organisation & Period input textfield + insertTable_OrgAndPeriod( mainTable, writer, periods ); + + // Step 5. Insert DataSet Info - [The MAIN Section] + insertTable_DataSet( mainTable, writer, dataSet ); + + // Step 6. Add the mainTable with content in it to the document. + document.add( mainTable ); + + document.add( Chunk.NEWLINE ); + document.add( Chunk.NEWLINE ); + + // Step. 7 - Add 'Save As' Button + insertSaveAsButton( document, writer, PdfDataEntryFormUtil.LABELCODE_BUTTON_SAVEAS ); + } + } + + private void setDataSet_DocumentTopSection( Document document, DataSet dataSet ) + throws DocumentException + { + document.add( new Paragraph( dataSet.getDisplayName(), pdfFormFontSettings + .getFont( PdfFormFontSettings.FONTTYPE_TITLE ) ) ); + + document.add( new Paragraph( dataSet.getDescription(), pdfFormFontSettings + .getFont( PdfFormFontSettings.FONTTYPE_DESCRIPTION ) ) ); + } + + private List getPeriods_DataSet( PeriodType periodType ) + throws ParseException + { + Period period = setPeriodDateRange(); + + return ((CalendarPeriodType) periodType).generatePeriods( period.getStartDate(), period.getEndDate() ); + } + + private void setMainTable( PdfPTable mainTable ) + { + mainTable.setWidthPercentage( 90.0f ); // Use 90% of space for Main + // Table Width. + mainTable.setHorizontalAlignment( Element.ALIGN_LEFT ); + } + + private void insertTable_DataSet( PdfPTable mainTable, PdfWriter writer, DataSet dataSet ) + throws IOException, DocumentException + { + Rectangle rectangle = new Rectangle( TEXTBOXWIDTH, PdfDataEntryFormUtil.CONTENT_HEIGHT_DEFAULT ); + + if ( dataSet.getSections().size() > 0 ) + { + // Sectioned Ones + for ( Section section : dataSet.getSections() ) + { + insertTable_DataSetSections( mainTable, writer, rectangle, section.getDataElements(), + section.getDisplayName() ); + } + + } + else + { + // Default one + insertTable_DataSetSections( mainTable, writer, rectangle, dataSet.getDataElements(), "" ); + } + + } + + private void insertTable_DataSetSections( PdfPTable mainTable, PdfWriter writer, Rectangle rectangle, + Collection dataElements, String sectionName ) + throws IOException, DocumentException + { + + // Add Section Name and Section Spacing + insertTable_TextRow( writer, mainTable, rectangle, TEXT_BLANK ); + + if ( sectionName != "" ) + { + insertTable_TextRow( writer, mainTable, rectangle, sectionName, + pdfFormFontSettings.getFont( PdfFormFontSettings.FONTTYPE_SECTIONHEADER ) ); + } + + // Create A Table To Add For Each Section + PdfPTable table = new PdfPTable( 2 ); // Code 1 + + for ( DataElement dataElement : dataElements ) + { + + addCell_Text( table, dataElement.getDisplayName(), Element.ALIGN_RIGHT ); + + String strFieldLabel = PdfDataEntryFormUtil.LABELCODE_DATAENTRYTEXTFIELD + dataElement.getUid() + "_" + + dataElement.getCategoryCombo().getSortedOptionCombos().get( 0 ).getUid(); + + String dataElementTextType = dataElement.getType(); + + // Yes Only case - render as Checkbox + if ( dataElementTextType.equals( DataElement.VALUE_TYPE_TRUE_ONLY ) ) + { + addCell_WithCheckBox( table, writer, strFieldLabel ); + } + else if ( dataElementTextType.equals( DataElement.VALUE_TYPE_BOOL ) ) + { + // Create Yes - true, No - false, Select.. + String[] optionList = new String[]{ "[No Value]", "Yes", "No" }; + String[] valueList = new String[]{ "", "true", "false" }; + + // addCell_WithRadioButton(table, writer, strFieldLabel); + addCell_WithDropDownListField( table, strFieldLabel, optionList, valueList, rectangle, writer ); + } + else if ( dataElementTextType.equals( DataElement.VALUE_TYPE_NUMBER ) ) + { + rectangle = new Rectangle( TEXTBOXWIDTH_NUMBERTYPE, PdfDataEntryFormUtil.CONTENT_HEIGHT_DEFAULT ); + + addCell_WithTextField( table, rectangle, writer, strFieldLabel, PdfFieldCell.TYPE_TEXT_NUMBER ); + } + // if(dataElementTextType.equals(DataElement.VALUE_TYPE_DATE)) + else + { + // NOTE: When Rendering for DataSet, DataElement's OptionSet + // does not get rendered. + // Only for events, it gets rendered as dropdown list. + addCell_WithTextField( table, rectangle, writer, strFieldLabel ); + + } + + } + + PdfPCell cell_withInnerTable = new PdfPCell( table ); + cell_withInnerTable.setBorder( Rectangle.NO_BORDER ); + + mainTable.addCell( cell_withInnerTable ); + + } + + // --- Retrieve Document Content - DataSet [END] + // ----------------------------------------------------------------------------- + + // ----------------------------------------------------------------------------- + // --- Retrieve Document Content - ProgramStage [START] + + private void setProgramStage_DocumentContent( Document document, PdfWriter writer, String programStageUid ) + throws IOException, DocumentException, ParseException, Exception + { + + // Get ProgramStage + ProgramStage programStage = programStageService.getProgramStage( programStageUid ); + + if ( programStage == null ) + { + throw new Exception( "Error - ProgramStage not found for UID " + programStageUid ); + } + else + { + + // STEP 1. Get Rectangle with TextBox Width to be used + Rectangle rectangle = new Rectangle( 0, 0, TEXTBOXWIDTH, PdfDataEntryFormUtil.CONTENT_HEIGHT_DEFAULT ); + + // STEP 2. Create Main Layout table and set the properties + PdfPTable mainTable = getProgramStageMainTable(); + + // STEP 3. Generate Period List for ProgramStage + List periods = getProgramStagePeriodList(); + + // STEP 4. Add Org Unit, Period, Hidden ProgramStageID Field + // Add Organisation & Period input textfield + insertTable_OrgAndPeriod( mainTable, writer, periods ); + + insertTable_TextRow( writer, mainTable, rectangle, TEXT_BLANK ); + + // Add ProgramStage Field - programStage.getId(); + insertTable_HiddenValue( mainTable, rectangle, writer, + PdfDataEntryFormUtil.LABELCODE_PROGRAMSTAGEIDTEXTBOX, String.valueOf( programStage.getId() ) ); + + // STEP 5. Add ProgramStage Content to PDF - [The Main Section] + insertTable_ProgramStage( mainTable, writer, programStage ); + + // STEP 6. Add the mainTable to document + document.add( mainTable ); + + } + + } + + private void insertTable_ProgramStage( PdfPTable mainTable, PdfWriter writer, ProgramStage programStage ) + throws IOException, DocumentException + { + Rectangle rectangle = new Rectangle( TEXTBOXWIDTH, PdfDataEntryFormUtil.CONTENT_HEIGHT_DEFAULT ); + + // Add Program Stage Sections + if ( programStage.getProgramStageSections().size() > 0 ) + { + // Sectioned Ones + for ( ProgramStageSection section : programStage.getProgramStageSections() ) + { + insertTable_ProgramStageSections( mainTable, rectangle, writer, section.getProgramStageDataElements() ); + } + + } + else + { + // Default one + insertTable_ProgramStageSections( mainTable, rectangle, writer, programStage.getProgramStageDataElements() ); + } + + } + + private void insertTable_ProgramStageSections( PdfPTable mainTable, Rectangle rectangle, PdfWriter writer, + Collection programStageDataElements ) + throws IOException, DocumentException + { + + // Add one to column count due to date entry + one hidden height set + // field. + int colCount = programStageDataElements.size() + 1 + 1; + + PdfPTable table = new PdfPTable( colCount ); // Code 1 + + float totalWidth = 800f; + float firstCellWidth_dateEntry = PdfDataEntryFormUtil.UNITSIZE_DEFAULT * 3; + float lastCellWidth_hidden = PdfDataEntryFormUtil.UNITSIZE_DEFAULT; + // float dataElementCell_offset = 4f; + float dataElementCellWidth = (totalWidth - firstCellWidth_dateEntry - lastCellWidth_hidden) + / programStageDataElements.size(); + + // Create 2 types of Rectangles, one for Date field, one for data + // elements + // - to be used when rendering them. + Rectangle rectangleDate = new Rectangle( 0, 0, PdfDataEntryFormUtil.UNITSIZE_DEFAULT * 2, + PdfDataEntryFormUtil.UNITSIZE_DEFAULT ); + Rectangle rectangleDataElement = new Rectangle( 0, 0, dataElementCellWidth, + PdfDataEntryFormUtil.UNITSIZE_DEFAULT ); + + // Cell Width Set + float[] cellWidths = new float[colCount]; + + // Date Field Settings + cellWidths[0] = firstCellWidth_dateEntry; + + for ( int i = 1; i < colCount - 1; i++ ) + { + cellWidths[i] = dataElementCellWidth; + } + + cellWidths[colCount - 1] = lastCellWidth_hidden; + + table.setWidths( cellWidths ); + + // Create Header + table.addCell( new PdfPCell( new Phrase( "Date" ) ) ); + + // Add Program Data Elements Columns + for ( ProgramStageDataElement programStageDataElement : programStageDataElements ) + { + DataElement dataElement = programStageDataElement.getDataElement(); + + table.addCell( new PdfPCell( new Phrase( dataElement.getDisplayFormName() ) ) ); + } + + table.addCell( new PdfPCell( new Phrase( TEXT_BLANK ) ) ); + + // ADD A HIDDEN INFO FOR ProgramStageID + // Print rows, having the data elements repeating on each column. + + for ( int rowNo = 1; rowNo <= PROGRAM_FORM_ROW_NUMBER; rowNo++ ) + { + + // Add Date Column + String strFieldDateLabel = PdfDataEntryFormUtil.LABELCODE_DATADATETEXTFIELD + Integer.toString( rowNo ); + + addCell_WithTextField( table, rectangleDate, writer, strFieldDateLabel ); + + // Add Program Data Elements Columns + for ( ProgramStageDataElement programStageDataElement : programStageDataElements ) + { + DataElement dataElement = programStageDataElement.getDataElement(); + + OptionSet optionSet = dataElement.getOptionSet(); + String optionSetName = ""; + + // addCell_Text(table, dataElement.getFormName()); + + String strFieldLabel = PdfDataEntryFormUtil.LABELCODE_DATAENTRYTEXTFIELD + + Integer.toString( dataElement.getId() ) + // + "_" + Integer.toString(programStageId) + "_" + + // Integer.toString(rowNo); + + "_" + Integer.toString( rowNo ); + + if ( optionSet != null ) + { + optionSetName = optionSet.getName(); + + String query = ""; // Get All Option + + // TODO: This gets repeated <-- Create an array of the + // options. and apply only once. + List options = optionService.getOptions( optionSet.getId(), query, MAX_OPTIONS_DISPLAYED ); + + addCell_WithDropDownListField( table, strFieldLabel, options.toArray( new String[0] ), + options.toArray( new String[0] ), rectangleDataElement, writer ); + // (int)(rectangleDataElement.getWidth()) + } + else + { + // NOTE: When Rendering for DataSet, DataElement's OptionSet + // does not get rendered. + // Only for events, it gets rendered as dropdown list. + addCell_WithTextField( table, rectangleDataElement, writer, strFieldLabel ); + } + } + + addCell_Text( table, TEXT_BLANK, Element.ALIGN_LEFT ); + + } + + PdfPCell cell_withInnerTable = new PdfPCell( table ); + cell_withInnerTable.setBorder( Rectangle.NO_BORDER ); + + mainTable.addCell( cell_withInnerTable ); + + } + + private List getProgramStagePeriodList() + throws ParseException + { + Period period = setPeriodDateRange(); + + PeriodType periodType = PeriodType.getPeriodTypeByName( MonthlyPeriodType.NAME ); + + return ((CalendarPeriodType) periodType).generatePeriods( period.getStartDate(), period.getEndDate() ); + } + + private PdfPTable getProgramStageMainTable() + { + PdfPTable mainTable = new PdfPTable( 1 ); // Code 1 + + mainTable.setTotalWidth( 800f ); + mainTable.setLockedWidth( true ); + mainTable.setHorizontalAlignment( Element.ALIGN_LEFT ); + + return mainTable; + } + + // --- Retrieve Document Content - ProgramStage [END] + // ----------------------------------------------------------------------------- + + // ----------------------------------------------------------------------------- + // ------------ Insert Section/Item Related Methods [START] ------------ + + private void insertTable_OrgAndPeriod( PdfPTable mainTable, PdfWriter writer, List periods ) + throws IOException, DocumentException + { + // Input TextBox size + Rectangle rectangle = new Rectangle( TEXTBOXWIDTH, PdfDataEntryFormUtil.CONTENT_HEIGHT_DEFAULT ); + + // Add Organization ID/Period textfield + // Create A table to add for each group AT HERE + PdfPTable table = new PdfPTable( 2 ); // Code 1 + + addCell_Text( table, "OrganizationID", Element.ALIGN_LEFT ); + addCell_WithTextField( table, rectangle, writer, PdfDataEntryFormUtil.LABELCODE_ORGID, + PdfFieldCell.TYPE_TEXT_ORGUNIT ); + + String[] periodsTitle = getPeriodTitles( periods, format ); + String[] periodsValue = getPeriodValues( periods ); + + addCell_Text( table, "PeriodID", Element.ALIGN_LEFT ); + addCell_WithDropDownListField( table, PdfDataEntryFormUtil.LABELCODE_PERIODID, periodsTitle, periodsValue, + rectangle, writer ); + + // Add to the main table + PdfPCell cell_withInnerTable = new PdfPCell( table ); + // cell_withInnerTable.setPadding(0); + cell_withInnerTable.setBorder( Rectangle.NO_BORDER ); + + cell_withInnerTable.setHorizontalAlignment( Element.ALIGN_LEFT ); + + mainTable.addCell( cell_withInnerTable ); + } + + private void insertTable_HiddenValue( PdfPTable mainTable, Rectangle rectangle, PdfWriter writer, String fieldName, + String value ) + throws IOException, DocumentException + { + + // Add Organization ID/Period textfield + // Create A table to add for each group AT HERE + PdfPTable table = new PdfPTable( 1 ); // Code 1 + + addCell_WithTextField( table, rectangle, writer, fieldName, value ); + + // Add to the main table + PdfPCell cell_withInnerTable = new PdfPCell( table ); + // cell_withInnerTable.setPadding(0); + cell_withInnerTable.setBorder( Rectangle.NO_BORDER ); + mainTable.addCell( cell_withInnerTable ); + } + + private void insertTable_TextRow( PdfWriter writer, PdfPTable mainTable, Rectangle rectangle, String text ) + throws IOException, DocumentException + { + insertTable_TextRow( writer, mainTable, rectangle, text, + pdfFormFontSettings.getFont( PdfFormFontSettings.FONTTYPE_BODY ) ); + } + + private void insertTable_TextRow( PdfWriter writer, PdfPTable mainTable, Rectangle rectangle, String text, Font font ) + throws IOException, DocumentException + { + + // Add Organization ID/Period textfield + // Create A table to add for each group AT HERE + PdfPTable table = new PdfPTable( 1 ); + table.setHorizontalAlignment( Element.ALIGN_LEFT ); + + addCell_Text( table, text, Element.ALIGN_LEFT, font ); + + // Add to the main table + PdfPCell cell_withInnerTable = new PdfPCell( table ); + cell_withInnerTable.setBorder( Rectangle.NO_BORDER ); + mainTable.addCell( cell_withInnerTable ); + } + + // Insert 'Save As' button to document. + private void insertSaveAsButton( Document document, PdfWriter writer, String name ) + throws DocumentException + { + // Button Table + PdfPTable tableButton = new PdfPTable( 1 ); + + tableButton.setWidthPercentage( 20.0f ); + float buttonHeight = PdfDataEntryFormUtil.UNITSIZE_DEFAULT + 5; + + tableButton.setHorizontalAlignment( PdfPTable.ALIGN_CENTER ); + + String jsAction = "app.execMenuItem('SaveAs');"; + + addCell_WithPushButtonField( tableButton, name, buttonHeight, jsAction, writer ); + + document.add( tableButton ); + } + + // ------------ Insert Section/Item Related Methods [END] ------------ + // ----------------------------------------------------------------------------- + + // ----------------------------------------------------------------------------- + // ------------ Add Control To Cell Related Methods [START] ------------ + + private void addCell_Text( PdfPTable table, String text, int horizontalAlignment ) + { + addCell_Text( table, text, horizontalAlignment, pdfFormFontSettings.getFont( PdfFormFontSettings.FONTTYPE_BODY ) ); + } + + private void addCell_Text( PdfPTable table, String text, int horizontalAlignment, Font font ) + { + PdfPCell cell = PdfDataEntryFormUtil.getPdfPCell( PdfDataEntryFormUtil.CELL_MIN_HEIGHT_DEFAULT, + PdfDataEntryFormUtil.CELL_COLUMN_TYPE_LABEL ); + + cell.setHorizontalAlignment( horizontalAlignment ); + + cell.setPhrase( new Phrase( text, font ) ); + + table.addCell( cell ); + } + + private void addCell_WithTextField( PdfPTable table, Rectangle rect, PdfWriter writer, String strfldName ) + throws IOException, DocumentException + { + addCell_WithTextField( table, rect, writer, strfldName, PdfFieldCell.TYPE_DEFAULT, "" ); + } + + private void addCell_WithTextField( PdfPTable table, Rectangle rect, PdfWriter writer, String strfldName, + int fieldCellType ) + throws IOException, DocumentException + { + addCell_WithTextField( table, rect, writer, strfldName, fieldCellType, "" ); + } + + private void addCell_WithTextField( PdfPTable table, Rectangle rect, PdfWriter writer, String strfldName, + String value ) + throws IOException, DocumentException + { + addCell_WithTextField( table, rect, writer, strfldName, PdfFieldCell.TYPE_DEFAULT, value ); + } + + private void addCell_WithTextField( PdfPTable table, Rectangle rect, PdfWriter writer, String strfldName, + int fieldCellType, String value ) + throws IOException, DocumentException + { + TextField nameField = new TextField( writer, rect, strfldName ); + // table.getc + + nameField.setBorderWidth( 1 ); + nameField.setBorderColor( Color.BLACK ); + nameField.setBorderStyle( PdfBorderDictionary.STYLE_SOLID ); + nameField.setBackgroundColor( COLOR_BACKGROUDTEXTBOX ); + + nameField.setText( value ); + + nameField.setAlignment( Element.ALIGN_RIGHT ); + nameField.setFontSize( PdfDataEntryFormUtil.UNITSIZE_DEFAULT ); + + PdfPCell cell = PdfDataEntryFormUtil.getPdfPCell( PdfDataEntryFormUtil.CELL_MIN_HEIGHT_DEFAULT, + PdfDataEntryFormUtil.CELL_COLUMN_TYPE_ENTRYFIELD ); + cell.setCellEvent( new PdfFieldCell( nameField.getTextField(), (int) (rect.getWidth()), fieldCellType, writer ) ); + + table.addCell( cell ); + } + + private void addCell_WithDropDownListField( PdfPTable table, String strfldName, String[] optionList, + String[] valueList, Rectangle rect, PdfWriter writer ) + throws IOException, DocumentException + { + + // If there is option, then create name-value set in 2 dimension array + // and set it as dropdown option name-value list. + String[][] optionValueList = new String[optionList.length][2]; + + for ( int i = 0; i < optionList.length; i++ ) + { + optionValueList[i][1] = optionList[i]; + optionValueList[i][0] = valueList[i]; + } + + // Code 2 create DROP-DOWN LIST + PdfFormField dropDown = PdfFormField.createCombo( writer, true, optionValueList, 0 ); + + dropDown.setWidget( rect, PdfAnnotation.HIGHLIGHT_INVERT ); + dropDown.setFieldName( strfldName ); + + dropDown.setMKBorderColor( CMYKColor.BLACK ); + + // Combine + + PdfPCell cell = PdfDataEntryFormUtil.getPdfPCell( PdfDataEntryFormUtil.CELL_MIN_HEIGHT_DEFAULT, + PdfDataEntryFormUtil.CELL_COLUMN_TYPE_ENTRYFIELD ); + cell.setCellEvent( new PdfFieldCell( dropDown, (int) (rect.getWidth()), writer ) ); + + table.addCell( cell ); + } + + private void addCell_WithCheckBox( PdfPTable table, PdfWriter writer, String strfldName ) + throws IOException, DocumentException + { + float sizeDefault = PdfDataEntryFormUtil.UNITSIZE_DEFAULT; + + PdfContentByte canvas = writer.getDirectContent(); + + PdfAppearance[] onOff = new PdfAppearance[2]; + onOff[0] = canvas.createAppearance( sizeDefault + 2, sizeDefault + 2 ); + onOff[0].rectangle( 1, 1, sizeDefault, sizeDefault ); + onOff[0].stroke(); + onOff[1] = canvas.createAppearance( sizeDefault + 2, sizeDefault + 2 ); + onOff[1].setRGBColorFill( 255, 128, 128 ); + onOff[1].rectangle( 1, 1, sizeDefault, sizeDefault ); + onOff[1].fillStroke(); + onOff[1].moveTo( 1, 1 ); + onOff[1].lineTo( sizeDefault + 1, sizeDefault + 1 ); + onOff[1].moveTo( 1, sizeDefault + 1 ); + onOff[1].lineTo( sizeDefault + 1, 1 ); + onOff[1].stroke(); + + Rectangle rect = new Rectangle( sizeDefault, sizeDefault ); + + RadioCheckField checkbox = new RadioCheckField( writer, rect, "Yes", "on" ); + checkbox.setBorderWidth( 1 ); + checkbox.setBorderColor( Color.BLACK ); + + PdfFormField checkboxfield = checkbox.getCheckField(); + checkboxfield.setFieldName( strfldName ); + + checkboxfield.setAppearance( PdfAnnotation.APPEARANCE_NORMAL, "", onOff[0] ); + checkboxfield.setAppearance( PdfAnnotation.APPEARANCE_NORMAL, "true", onOff[1] ); + + PdfPCell cell = PdfDataEntryFormUtil.getPdfPCell( PdfDataEntryFormUtil.CELL_MIN_HEIGHT_DEFAULT, + PdfDataEntryFormUtil.CELL_COLUMN_TYPE_ENTRYFIELD ); + + cell.setCellEvent( new PdfFieldCell( checkboxfield, (int) (rect.getWidth()), writer ) ); + + table.addCell( cell ); + } + + private void addCell_WithRadioButton( PdfPTable table, PdfWriter writer, String strfldName ) + throws IOException, DocumentException + { + + // Add to the main table + PdfPCell cell = PdfDataEntryFormUtil.getPdfPCell( PdfDataEntryFormUtil.CELL_MIN_HEIGHT_DEFAULT, + PdfDataEntryFormUtil.CELL_COLUMN_TYPE_ENTRYFIELD ); + + // RADIO BUTTON FIELD + PdfFormField radiogroupField = PdfFormField.createRadioButton( writer, true ); + radiogroupField.setFieldName( strfldName ); + + cell.setCellEvent( new PdfFieldCell( radiogroupField, new String[]{ "Yes", "No", "null" }, new String[]{ + "true", "false", "" }, "", 30.0f, PdfFieldCell.TYPE_RADIOBUTTON, writer ) ); + + table.addCell( cell ); + + // Last - Add Annotation + writer.addAnnotation( radiogroupField ); + + } + + private void addCell_WithPushButtonField( PdfPTable table, String strfldName, float buttonHeight, String jsAction, + PdfWriter writer ) + { + PdfPCell cell = PdfDataEntryFormUtil.getPdfPCell( buttonHeight, + PdfDataEntryFormUtil.CELL_COLUMN_TYPE_ENTRYFIELD ); + cell.setCellEvent( new PdfFieldCell( null, jsAction, "BTN_SAVEPDF", "Save PDF", PdfFieldCell.TYPE_BUTTON, + writer ) ); + + table.addCell( cell ); + } + + // ------------ Add Control To Cell Related Methods [END] ------------ + // ----------------------------------------------------------------------------- + + // ----------------------------------------------------------------------------- + // ------------ Period Related Methods [START] ------------ + + public String[] getPeriodValues( List periods ) + { + String[] periodValues = new String[periods.size()]; + + for ( int i = 0; i < periods.size(); i++ ) + { + periodValues[i] = periods.get( i ).getExternalId(); + } + + return periodValues; + } + + public String[] getPeriodTitles( List periods, I18nFormat format ) + { + String[] periodTitles = new String[periods.size()]; + + for ( int i = 0; i < periods.size(); i++ ) + { + periodTitles[i] = format.formatPeriod( periods.get( i ) ); + } + + return periodTitles; + } + + private Period setPeriodDateRange() + throws ParseException + { + + Period period = new Period(); + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat( Period.DEFAULT_DATE_FORMAT ); + + Calendar currentDate = Calendar.getInstance(); + + int currYear = currentDate.get( Calendar.YEAR ); + int startYear = currYear - PERIODRANGE_PREVYEARS; + int endYear = currYear + PERIODRANGE_FUTUREYEARS; + + period.setStartDate( simpleDateFormat.parse( String.valueOf( startYear ) + "-01-01" ) ); + period.setEndDate( simpleDateFormat.parse( String.valueOf( endYear ) + "-01-01" ) ); + + return period; + } + + // ------------ Period Related Methods [END] ------------ + // ----------------------------------------------------------------------------- + +} === added file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfDataEntryFormService.java' --- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfDataEntryFormService.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfDataEntryFormService.java 2013-05-25 06:19:23 +0000 @@ -0,0 +1,40 @@ +package org.hisp.dhis.dxf2.pdfform; + +/* + * Copyright (c) 2004-2013, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.lowagie.text.Document; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.PdfWriter; +import org.hisp.dhis.i18n.I18nFormat; + +public interface PdfDataEntryFormService +{ + void generatePDFDataEntryForm( Document document, PdfWriter writer, String inputUid, int typeId, + Rectangle pageSize, PdfFormFontSettings pdfFormFontSettings, I18nFormat format ); + +} === added file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfDataEntryFormUtil.java' --- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfDataEntryFormUtil.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfDataEntryFormUtil.java 2013-05-25 06:19:23 +0000 @@ -0,0 +1,277 @@ +package org.hisp.dhis.dxf2.pdfform; + +/* + * Copyright (c) 2004-2013, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.lowagie.text.Document; +import com.lowagie.text.Element; +import com.lowagie.text.Font; +import com.lowagie.text.HeaderFooter; +import com.lowagie.text.PageSize; +import com.lowagie.text.Phrase; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.AcroFields; +import com.lowagie.text.pdf.AcroFields.Item; +import com.lowagie.text.pdf.PdfPCell; +import com.lowagie.text.pdf.PdfReader; +import org.hisp.dhis.dxf2.datavalueset.DataValueSet; +import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodType; + +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; + + +public class PdfDataEntryFormUtil +{ + + // public Static Values + public static final int DATATYPE_DATASET = 0; + public static final int DATATYPE_PROGRAMSTAGE = 1; + + public static final float UNITSIZE_DEFAULT = 10; + + // Label Names + public static final String LABELCODE_TEXTFIELD = "TXFD_"; + + public static final String LABELCODE_BUTTON = "BTNFD_"; + + public static final String LABELCODE_ORGID = LABELCODE_TEXTFIELD + "OrgID"; + + public static final String LABELCODE_PERIODID = LABELCODE_TEXTFIELD + "PeriodID"; + + public static final String LABELCODE_BUTTON_SAVEAS = LABELCODE_BUTTON + "SaveAs"; + + public static final String LABELCODE_DATADATETEXTFIELD = "TXFDDT_"; + + public static final String LABELCODE_DATAENTRYTEXTFIELD = "TXFDDV_"; + + public static final String LABELCODE_PROGRAMSTAGEIDTEXTBOX = "TXPSTGID_"; + + + // Cell Related + + public final static float CELL_MIN_HEIGHT_DEFAULT = 13; + + public final static float CONTENT_HEIGHT_DEFAULT = 11; + + public final static int CELL_COLUMN_TYPE_LABEL = 0; + + public final static int CELL_COLUMN_TYPE_ENTRYFIELD = 1; + + + // private static values + private static final String DATAVALUE_IMPORT_STOREBY = "admin"; + + private static final String DATAVALUE_IMPORT_COMMENT = "Imported by PDF Data Entry Form"; + + private static final String DATAVALUE_IMPORT_TIMESTAMP_DATEFORMAT = "yyyy-MM-dd"; + + private static final String FOOTERTEXT_DEFAULT = "PDF Template generated from DHIS %s on %s"; + + private static final String DATEFORMAT_FOOTER_DEFAULT = "MMMM dd, yyyy"; + + + // ------------------------------------------------------------------------- + // METHODS + // ------------------------------------------------------------------------- + + // ------------------------------------------------------------------------- + // --- Document Setting Related [START] + + public static void setFooterOnDocument( Document document, String footerText, Font font ) + { + boolean isNumbered = true; + + HeaderFooter footer = new HeaderFooter( new Phrase( footerText, font ), isNumbered ); + footer.setBorder( Rectangle.NO_BORDER ); + footer.setAlignment( Element.ALIGN_RIGHT ); + document.setFooter( footer ); + + } + + // Set DefaultFooter + public static void setDefaultFooterOnDocument( Document document, String serverName, Font font ) + { + // Set Footer + String strFooterText = String.format( FOOTERTEXT_DEFAULT, serverName, (new SimpleDateFormat( + DATEFORMAT_FOOTER_DEFAULT )).format( new Date() ) ); + + setFooterOnDocument( document, strFooterText, font ); + + } + + public static Rectangle getDefaultPageSize( int typeId ) + { + + if ( typeId == PdfDataEntryFormUtil.DATATYPE_PROGRAMSTAGE ) + { + return new Rectangle( PageSize.A4.getLeft(), + PageSize.A4.getBottom(), PageSize.A4.getTop(), PageSize.A4.getRight() ); + } + else + { + return PageSize.A4; + } + + } + + // --- Document Setting Related [END] + // ------------------------------------------------------------------------- + + // ------------------------------------------------------------------------- + // --- PdfPCell Related [START] + + public static PdfPCell getPdfPCell( float minHeight ) + { + return getPdfPCell( minHeight, CELL_COLUMN_TYPE_LABEL ); + } + + public static PdfPCell getPdfPCell( float minHeight, int cellContentType ) + { + PdfPCell cell = new PdfPCell(); + cell.setMinimumHeight( minHeight ); + cell.setBorder( Rectangle.NO_BORDER ); + + if ( cellContentType == CELL_COLUMN_TYPE_LABEL ) + { + cell.setHorizontalAlignment( Element.ALIGN_RIGHT ); + cell.setVerticalAlignment( Element.ALIGN_TOP ); + } + else if ( cellContentType == CELL_COLUMN_TYPE_ENTRYFIELD ) + { + cell.setHorizontalAlignment( Element.ALIGN_CENTER ); + cell.setVerticalAlignment( Element.ALIGN_MIDDLE ); + } + + return cell; + } + + + // --- PdfPCell Related [END] + // ------------------------------------------------------------------------- + + + // Retreive DataValue Informations from PDF inputStream. + public static DataValueSet getDataValueSet( InputStream in ) + throws RuntimeException + { + PdfReader reader = null; + + DataValueSet dataValueSet = new DataValueSet(); + + List dataValueList = new ArrayList(); + + try + { + + reader = new PdfReader( in ); // new PdfReader(in, null); + + AcroFields form = reader.getAcroFields(); + + if ( form != null ) + { + + // TODO: MOVE THESE STATIC NAME VALUES TO inside of service + // class or PDFForm Class <-- should be in PDFForm Class. + String strOrgUID = form.getField( PdfDataEntryFormUtil.LABELCODE_ORGID ); + String strPeriodID = form.getField( PdfDataEntryFormUtil.LABELCODE_PERIODID ); + + Period period = PeriodType.createPeriodExternalId( strPeriodID ); + + // Loop Through the Fields and get data. + HashMap fields = form.getFields(); + Set> entrySet = fields.entrySet(); + + Set fldNames = form.getFields().keySet(); + + for ( String fldName : fldNames ) + { + + if ( fldName.startsWith( PdfDataEntryFormUtil.LABELCODE_DATAENTRYTEXTFIELD ) ) + { + + String[] strArrFldName = fldName.split( "_" ); + + // Create DataValues to be put in a DataValueSet + org.hisp.dhis.dxf2.datavalue.DataValue dataValue = new org.hisp.dhis.dxf2.datavalue.DataValue(); + + dataValue.setDataElement( strArrFldName[1] ); + dataValue.setCategoryOptionCombo( strArrFldName[2] ); + dataValue.setOrgUnit( strOrgUID ); + dataValue.setPeriod( period.getIsoDate() ); + + dataValue.setValue( form.getField( fldName ) ); + + dataValue.setStoredBy( DATAVALUE_IMPORT_STOREBY ); + dataValue.setComment( DATAVALUE_IMPORT_COMMENT ); + dataValue.setFollowup( false ); + dataValue.setTimestamp( new SimpleDateFormat( DATAVALUE_IMPORT_TIMESTAMP_DATEFORMAT ) + .format( new Date() ) ); + + dataValueList.add( dataValue ); + + } + } + + dataValueSet.setDataValues( dataValueList ); + + } + else + { + throw new RuntimeException( "Could not generate PDF AcroFields form from the file." ); + } + + } + catch ( Exception e ) + { + throw new RuntimeException( e.getMessage() ); + } + finally + { + reader.close(); + } + + return dataValueSet; + } + + + // ----------------------------------------------------------------------------- + // --- For Import - ProgramStage [START] + + + // --- For Import - ProgramStage [END] + // ----------------------------------------------------------------------------- + + +} === added file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfFieldCell.java' --- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfFieldCell.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfFieldCell.java 2013-05-25 06:19:23 +0000 @@ -0,0 +1,258 @@ +package org.hisp.dhis.dxf2.pdfform; + +/* + * Copyright (c) 2004-2013, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.lowagie.text.Element; +import com.lowagie.text.Phrase; +import com.lowagie.text.Rectangle; +import com.lowagie.text.pdf.ColumnText; +import com.lowagie.text.pdf.GrayColor; +import com.lowagie.text.pdf.PdfAction; +import com.lowagie.text.pdf.PdfAnnotation; +import com.lowagie.text.pdf.PdfBorderDictionary; +import com.lowagie.text.pdf.PdfContentByte; +import com.lowagie.text.pdf.PdfFormField; +import com.lowagie.text.pdf.PdfName; +import com.lowagie.text.pdf.PdfPCell; +import com.lowagie.text.pdf.PdfPCellEvent; +import com.lowagie.text.pdf.PdfPTable; +import com.lowagie.text.pdf.PdfWriter; +import com.lowagie.text.pdf.PushbuttonField; +import com.lowagie.text.pdf.RadioCheckField; + +public class PdfFieldCell + implements PdfPCellEvent +{ + + public final static int TYPE_DEFAULT = 0; + + public final static int TYPE_BUTTON = 1; + + public final static int TYPE_TEXT_ORGUNIT = 2; + + public final static int TYPE_TEXT_NUMBER = 3; + + public final static int TYPE_CHECKBOX = 4; + + public final static int TYPE_RADIOBUTTON = 5; + + private final static float RADIOBUTTON_WIDTH = 10.0f; + + private final static float RADIOBUTTON_TEXTOFFSET = 3.0f; + + private PdfFormField parent; + + private PdfFormField formField; + + private PdfWriter writer; + + private float width; + + private int type; + + private String jsAction; + + private String[] values; + + private String[] texts; + + private String checkValue; + + private String text; + + private String name; + + public PdfFieldCell( PdfFormField formField, int width, PdfWriter writer ) + { + this.formField = formField; + this.width = width; + this.writer = writer; + this.type = TYPE_DEFAULT; + } + + public PdfFieldCell( PdfFormField formField, int width, int type, PdfWriter writer ) + { + this.formField = formField; + this.width = width; + this.writer = writer; + this.type = type; + } + + public PdfFieldCell( PdfFormField formField, String jsAction, String name, String text, int type, PdfWriter writer ) + { + this.formField = formField; + this.writer = writer; + this.type = type; + this.name = name; + this.text = text; + this.jsAction = jsAction; + } + + public PdfFieldCell( PdfFormField parent, String[] texts, String[] values, String checkValue, float width, + int type, PdfWriter writer ) + { + this.writer = writer; + this.type = type; + this.parent = parent; + this.texts = texts; + this.values = values; + this.checkValue = checkValue; + this.width = width; + } + + public void cellLayout( PdfPCell cell, Rectangle rect, PdfContentByte[] canvas ) + { + try + { + + PdfContentByte cb = null; + + if ( type == TYPE_RADIOBUTTON ) + { + cb = canvas[PdfPTable.TEXTCANVAS]; + } + else + { + cb = canvas[PdfPTable.LINECANVAS]; + } + + switch ( type ) + { + + case TYPE_RADIOBUTTON: + + if ( parent != null ) + { + + float leftLoc = rect.getLeft(); + float rightLoc = rect.getLeft() + RADIOBUTTON_WIDTH; + + try + { + + String text; + String value; + + for ( int i = 0; i < texts.length; i++ ) + { + + text = texts[i]; + value = values[i]; + + Rectangle radioRec = new Rectangle( leftLoc, rect.getBottom(), rightLoc, rect.getTop() ); + + RadioCheckField rf = new RadioCheckField( writer, radioRec, "RDBtn_" + text, value ); + + if ( value == checkValue ) + rf.setChecked( true ); + + rf.setBorderColor( GrayColor.GRAYBLACK ); + rf.setBackgroundColor( GrayColor.GRAYWHITE ); + rf.setCheckType( RadioCheckField.TYPE_CIRCLE ); + + parent.addKid( rf.getRadioField() ); + + leftLoc = rightLoc; + rightLoc += width; + + ColumnText.showTextAligned( cb, Element.ALIGN_LEFT, new Phrase( text ), leftLoc + + RADIOBUTTON_TEXTOFFSET, (radioRec.getBottom() + radioRec.getTop()) / 2, 0 ); + + leftLoc = rightLoc; + rightLoc += RADIOBUTTON_WIDTH; + + } + + } + catch ( Exception ex ) + { + throw new RuntimeException( ex.getMessage() ); + } + + writer.addAnnotation( parent ); + + } + + break; + + case TYPE_BUTTON: + // Add the push button + PushbuttonField button = new PushbuttonField( writer, rect, name ); + button.setBackgroundColor( new GrayColor( 0.75f ) ); + button.setBorderColor( GrayColor.GRAYBLACK ); + button.setBorderWidth( 1 ); + button.setBorderStyle( PdfBorderDictionary.STYLE_BEVELED ); + button.setTextColor( GrayColor.GRAYBLACK ); + button.setFontSize( PdfDataEntryFormUtil.UNITSIZE_DEFAULT ); + button.setText( text ); + button.setLayout( PushbuttonField.LAYOUT_ICON_LEFT_LABEL_RIGHT ); + button.setScaleIcon( PushbuttonField.SCALE_ICON_ALWAYS ); + button.setProportionalIcon( true ); + button.setIconHorizontalAdjustment( 0 ); + + formField = button.getField(); + formField.setAction( PdfAction.javaScript( jsAction, writer ) ); + + break; + + case TYPE_CHECKBOX: + + // Start from the middle of the cell width. + float startingPoint = rect.getLeft() + ((rect.getWidth() + width) / 2.0f); + + formField.setWidget( + new Rectangle( startingPoint, rect.getBottom(), startingPoint + width, rect.getTop() ), + PdfAnnotation.HIGHLIGHT_NONE ); + + break; + + case TYPE_TEXT_ORGUNIT: + formField.setAdditionalActions( PdfName.BL, PdfAction.javaScript( + "if(event.value == '') app.alert('Warning! Please Enter The Org ID.');", writer ) ); + + case TYPE_TEXT_NUMBER: + + default: + + formField.setWidget( + new Rectangle( rect.getLeft(), rect.getBottom(), rect.getLeft() + width, rect.getTop() ), + PdfAnnotation.HIGHLIGHT_NONE ); + + break; + + } + + writer.addAnnotation( formField ); + + } + catch ( Exception ex ) + { + throw new RuntimeException( ex.getMessage() ); + } + } +} \ No newline at end of file === added file 'dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfFormFontSettings.java' --- dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfFormFontSettings.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-dxf2/src/main/java/org/hisp/dhis/dxf2/pdfform/PdfFormFontSettings.java 2013-05-25 06:19:23 +0000 @@ -0,0 +1,164 @@ +package org.hisp.dhis.dxf2.pdfform; + +/* + * Copyright (c) 2004-2013, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.lowagie.text.Font; +import java.awt.*; + +public class PdfFormFontSettings +{ + // Font Types + public final static int FONTTYPE_BODY = 0; + + public final static int FONTTYPE_TITLE = 1; + + public final static int FONTTYPE_DESCRIPTION = 2; + + public final static int FONTTYPE_SECTIONHEADER = 3; + + public final static int FONTTYPE_FOOTER = 4; + + // Font Default Sizes + private final static float FONTSIZE_BODY = 10; + + private final static float FONTSIZE_TITLE = 16; + + private final static float FONTSIZE_DESCRIPTION = 11; + + private final static float FONTSIZE_SECTIONHEADER = 14; + + private final static float FONTSIZE_FOOTER = 8; + + // Font Family Default + private final static String FONTFAMILY = "HELVETICA"; + + // private variables + private Font fontBody; + + private Font fontTitle; + + private Font fontDescription; + + private Font fontSectionHeader; + + private Font fontFooter; + + public PdfFormFontSettings() + { + fontBody = createFont( FONTTYPE_BODY ); + fontTitle = createFont( FONTTYPE_TITLE ); + fontDescription = createFont( FONTTYPE_DESCRIPTION ); + fontSectionHeader = createFont( FONTTYPE_SECTIONHEADER ); + fontFooter = createFont( FONTTYPE_FOOTER ); + } + + public void setFont( int fontType, Font font ) + { + + switch ( fontType ) + { + case FONTTYPE_BODY: + fontBody = font; + break; + case FONTTYPE_TITLE: + fontTitle = font; + break; + case FONTTYPE_DESCRIPTION: + fontDescription = font; + break; + case FONTTYPE_SECTIONHEADER: + fontSectionHeader = font; + break; + case FONTTYPE_FOOTER: + fontFooter = font; + break; + } + + } + + public Font getFont( int fontType ) + { + Font font = null; + + switch ( fontType ) + { + case FONTTYPE_BODY: + font = fontBody; + break; + case FONTTYPE_TITLE: + font = fontTitle; + break; + case FONTTYPE_DESCRIPTION: + font = fontDescription; + break; + case FONTTYPE_SECTIONHEADER: + font = fontSectionHeader; + break; + case FONTTYPE_FOOTER: + font = fontFooter; + break; + } + + return font; + } + + private Font createFont( int fontType ) + { + Font font = new Font(); + font.setFamily( FONTFAMILY ); + + switch ( fontType ) + { + case FONTTYPE_BODY: + font.setSize( FONTSIZE_BODY ); + break; + case FONTTYPE_TITLE: + font.setSize( FONTSIZE_TITLE ); + font.setStyle( java.awt.Font.BOLD ); + font.setColor( new Color( 0, 0, 128 ) ); // Navy Color + break; + case FONTTYPE_DESCRIPTION: + font.setSize( FONTSIZE_DESCRIPTION ); + font.setColor( Color.DARK_GRAY ); + break; + case FONTTYPE_SECTIONHEADER: + font.setSize( FONTSIZE_SECTIONHEADER ); + font.setStyle( java.awt.Font.BOLD ); + font.setColor( new Color( 70, 130, 180 ) ); // Steel Blue Color + break; + case FONTTYPE_FOOTER: + font.setSize( FONTSIZE_FOOTER ); + break; + default: + font.setSize( FONTSIZE_BODY ); + break; + } + + return font; + } +} === modified file 'dhis-2/dhis-dxf2/src/main/resources/META-INF/dhis/beans.xml' --- dhis-2/dhis-dxf2/src/main/resources/META-INF/dhis/beans.xml 2013-05-17 10:26:46 +0000 +++ dhis-2/dhis-dxf2/src/main/resources/META-INF/dhis/beans.xml 2013-05-23 04:30:18 +0000 @@ -195,5 +195,8 @@ class="org.hisp.dhis.dxf2.metadata.importers.DefaultIdentifiableObjectImporter" scope="prototype"> + + + === added file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/PDFFormController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/PDFFormController.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/PDFFormController.java 2013-05-25 06:19:23 +0000 @@ -0,0 +1,246 @@ +package org.hisp.dhis.api.controller; + +/* + * Copyright (c) 2004-2013, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.lowagie.text.Document; +import com.lowagie.text.DocumentException; +import com.lowagie.text.pdf.PdfWriter; +import org.hisp.dhis.api.utils.ContextUtils; +import org.hisp.dhis.api.utils.ContextUtils.CacheStrategy; +import org.hisp.dhis.api.utils.PdfDataEntryFormImportUtil; +import org.hisp.dhis.common.IdentifiableObject.IdentifiableProperty; +import org.hisp.dhis.dxf2.datavalueset.DataValueSetService; +import org.hisp.dhis.dxf2.metadata.ImportOptions; +import org.hisp.dhis.dxf2.pdfform.PdfDataEntryFormService; +import org.hisp.dhis.dxf2.pdfform.PdfDataEntryFormUtil; +import org.hisp.dhis.dxf2.pdfform.PdfFormFontSettings; +import org.hisp.dhis.i18n.I18nManager; +import org.hisp.dhis.i18n.I18nManagerException; +import org.hisp.dhis.importexport.ImportStrategy; +import org.hisp.dhis.scheduling.TaskCategory; +import org.hisp.dhis.scheduling.TaskId; +import org.hisp.dhis.system.notification.Notifier; +import org.hisp.dhis.system.util.StreamUtils; +import org.hisp.dhis.user.CurrentUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.ParseException; + +/** + * @author James Chang + */ + +@Controller +@RequestMapping(value = "/pdfForm") +public class PDFFormController +{ + // ------------------------------------------------------------------------- + // Dependencies + // ------------------------------------------------------------------------- + + @Autowired + private CurrentUserService currentUserService; + + @Autowired + private Notifier notifier; + + @Autowired + private DataValueSetService dataValueSetService; + + @Autowired + private I18nManager i18nManager; + + @Autowired + private PdfDataEntryFormService pdfDataEntryFormService; + + @Autowired + private ContextUtils contextUtils; + + // ------------------------------------------------------------------------- + // GET / POST + // ------------------------------------------------------------------------- + + // --------------------- Data Set Related --------------------- + + @RequestMapping(value = "/dataSet/{dataSetUid}", method = RequestMethod.GET) + public void getFormPDF_DataSet( HttpServletRequest request, HttpServletResponse response, + @PathVariable String dataSetUid ) + throws Exception + { + // STEP 1. - Create Document and PdfWriter - with OutputStream and + // document tie. + Document document = new Document(); // TODO: can specify the size of + // document - like letter or A4 + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PdfWriter writer = PdfWriter.getInstance( document, baos ); + + // STEP 2. Generate PDF Document Contents + PdfFormFontSettings pdfFormFontSettings = new PdfFormFontSettings(); + + PdfDataEntryFormUtil.setDefaultFooterOnDocument( document, request.getServerName(), + pdfFormFontSettings.getFont( PdfFormFontSettings.FONTTYPE_FOOTER ) ); + + pdfDataEntryFormService.generatePDFDataEntryForm( document, writer, dataSetUid, + PdfDataEntryFormUtil.DATATYPE_DATASET, + PdfDataEntryFormUtil.getDefaultPageSize( PdfDataEntryFormUtil.DATATYPE_DATASET ), + new PdfFormFontSettings(), i18nManager.getI18nFormat() ); + + // STEP 3. - Response Header/Content Type Set + contextUtils.configureResponse( response, ContextUtils.CONTENT_TYPE_PDF, CacheStrategy.NO_CACHE ); + response.setContentLength( baos.size() ); + + // STEP 4. - Output the data into Stream and close the stream. + // write ByteArrayOutputStream to the ServletOutputStream + writeToOutputStream( baos, response ); + + } + + @RequestMapping(value = "/DataSet", method = RequestMethod.POST) + // , consumes = MEDIA_TYPE_PDF) + public void sendFormPDF_DataSet( HttpServletRequest request, HttpServletResponse response ) + throws Exception + { + + // Step 1. Set up Import Option + ImportStrategy strategy = ImportStrategy.NEW_AND_UPDATES; + IdentifiableProperty dataElementIdScheme = IdentifiableProperty.UID; + IdentifiableProperty orgUnitIdScheme = IdentifiableProperty.UID; + boolean dryRun = false; + boolean skipExistingCheck = false; // THIS IS THE DEFAULT CHOICE. DO WE + // USE THIS? + + ImportOptions options = new ImportOptions( dataElementIdScheme, orgUnitIdScheme, dryRun, strategy, + skipExistingCheck ); + + // Step 2. Generate Task ID + TaskId taskId = new TaskId( TaskCategory.DATAVALUE_IMPORT, currentUserService.getCurrentUser() ); + + notifier.clear( taskId ); + + // Step 3. Input Stream Check + InputStream in = request.getInputStream(); + + in = StreamUtils.wrapAndCheckCompressionFormat( in ); + + // No logging? + // log.info( options ); + + // Step 4. Save (Import) the data values. + dataValueSetService.saveDataValueSetPdf( in, options, taskId ); + + // Step 5. Set the response - just simple OK response. + ContextUtils.okResponse( response, "" ); + + } + + // --------------------- Program Stage Related --------------------- + + @RequestMapping(value = "/programStage/{programStageUid}", method = RequestMethod.GET) + public void getFormPDF_ProgramStage( HttpServletRequest request, HttpServletResponse response, @PathVariable + String programStageUid ) + throws IOException, DocumentException, ParseException, I18nManagerException + { + + // STEP 1. - Create Document and PdfWriter - with OutputStream and + // document tie. + Document document = new Document(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PdfWriter writer = PdfWriter.getInstance( document, baos ); + + // STEP 2. Generate PDF Document Contents + PdfFormFontSettings pdfFormFontSettings = new PdfFormFontSettings(); + + PdfDataEntryFormUtil.setDefaultFooterOnDocument( document, request.getServerName(), + pdfFormFontSettings.getFont( PdfFormFontSettings.FONTTYPE_FOOTER ) ); + + pdfDataEntryFormService.generatePDFDataEntryForm( document, writer, programStageUid, + PdfDataEntryFormUtil.DATATYPE_PROGRAMSTAGE, + PdfDataEntryFormUtil.getDefaultPageSize( PdfDataEntryFormUtil.DATATYPE_PROGRAMSTAGE ) + // , new Rectangle( PageSize.A4.getLeft(), + // PageSize.A4.getBottom(), PageSize.A4.getTop(), + // PageSize.A4.getRight() ) + , new PdfFormFontSettings(), i18nManager.getI18nFormat() ); + + // STEP 3. - Response Header/Content Type Set + contextUtils.configureResponse( response, ContextUtils.CONTENT_TYPE_PDF, CacheStrategy.NO_CACHE ); + response.setContentLength( baos.size() ); + + // STEP 4. - write ByteArrayOutputStream to the ServletOutputStream + writeToOutputStream( baos, response ); + } + + @RequestMapping(value = "/programStage", method = RequestMethod.POST) + // , consumes = MEDIA_TYPE_PDF) + public void sendFormPDF_ProgramStage( HttpServletRequest request, HttpServletResponse response ) + throws IOException, Exception + { + + InputStream in = request.getInputStream(); + + // Temporarily using Util class from same project. + PdfDataEntryFormImportUtil pdfDataEntryFormImportUtil = new PdfDataEntryFormImportUtil(); + + pdfDataEntryFormImportUtil.ImportProgramStage( in, i18nManager.getI18nFormat() ); + + // Step 5. Set the response - just simple OK response. + ContextUtils.okResponse( response, "" ); + + } + + // ----------------------------------------------------------------------------- + // ---------------------- Helper Class Related [START] + // ---------------------- + + private void writeToOutputStream( ByteArrayOutputStream baos, HttpServletResponse response ) + throws IOException + { + OutputStream os = null; + + try + { + os = response.getOutputStream(); + baos.writeTo( os ); + } + finally + { + os.flush(); + os.close(); + } + + } +} \ No newline at end of file === added file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/utils/PdfDataEntryFormImportUtil.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/utils/PdfDataEntryFormImportUtil.java 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/utils/PdfDataEntryFormImportUtil.java 2013-05-25 06:19:23 +0000 @@ -0,0 +1,371 @@ +package org.hisp.dhis.api.utils; + +/* + * Copyright (c) 2004-2013, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import com.lowagie.text.pdf.AcroFields; +import com.lowagie.text.pdf.PdfReader; +import org.hisp.dhis.dataelement.DataElement; +import org.hisp.dhis.dataelement.DataElementService; +import org.hisp.dhis.dxf2.pdfform.PdfDataEntryFormUtil; +import org.hisp.dhis.i18n.I18nFormat; +import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.organisationunit.OrganisationUnitService; +import org.hisp.dhis.patientdatavalue.PatientDataValue; +import org.hisp.dhis.patientdatavalue.PatientDataValueService; +import org.hisp.dhis.program.Program; +import org.hisp.dhis.program.ProgramInstance; +import org.hisp.dhis.program.ProgramInstanceService; +import org.hisp.dhis.program.ProgramStage; +import org.hisp.dhis.program.ProgramStageInstance; +import org.hisp.dhis.program.ProgramStageInstanceService; +import org.hisp.dhis.program.ProgramStageService; +import org.hisp.dhis.user.CurrentUserService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class PdfDataEntryFormImportUtil +{ + private static final String DATAVALUE_IMPORT_STOREBY = "admin"; + + private static final String DATAVALUE_IMPORT_COMMENT = "Imported by PDF Data Entry Form"; + + private static final String DATAVALUE_IMPORT_TIMESTAMP_DATEFORMAT = "yyyy-MM-dd"; + + // ------------------------------------------------------------------------- + // DEPENDENCIES + // ------------------------------------------------------------------------- + + @Autowired + private OrganisationUnitService organisationUnitService; + + @Autowired + private DataElementService dataElementService; + + @Autowired + private CurrentUserService currentUserService; + + @Autowired + private ProgramInstanceService programInstanceService; + + @Autowired + private ProgramStageService programStageService; + + @Autowired + private ProgramStageInstanceService programStageInstanceService; + + @Autowired + private PatientDataValueService patientDataValueService; + + // ------------------------------------------------------------------------- + // METHODS + // ------------------------------------------------------------------------- + + public void ImportProgramStage( InputStream in, I18nFormat format ) + throws Exception + { + int programStageInstanceId; + ProgramStageInstance programStageInstance; + + PdfReader reader = new PdfReader( in, null ); + + AcroFields form = reader.getAcroFields(); + + String strOrgID = form.getField( PdfDataEntryFormUtil.LABELCODE_ORGID ); + int organisationUnitId = Integer.parseInt( strOrgID ); + + String strPeriodID = form.getField( PdfDataEntryFormUtil.LABELCODE_PERIODID ); + Date executionDateInput = format.parseDate( strPeriodID ); + Calendar executeDateCal = Calendar.getInstance(); + executeDateCal.setTime( executionDateInput ); + + int programStageId = Integer.valueOf( form.getField( PdfDataEntryFormUtil.LABELCODE_PROGRAMSTAGEIDTEXTBOX ) ); + + ProgramStageInstanceDataManager programStageInstanceDataManager = new ProgramStageInstanceDataManager(); + + // Loop Through the Fields and get data. + Set fldNames = form.getFields().keySet(); + + // Create Organized data + for ( String fldName : fldNames ) + { + // If the value in the textfield is not empty, proceed to add + // it. + if ( !form.getField( fldName ).trim().equals( "" ) ) + { + if ( fldName.startsWith( PdfDataEntryFormUtil.LABELCODE_DATADATETEXTFIELD ) ) + { + + String[] strArrFldName = fldName.split( "_" ); + int rowNumber = Integer.parseInt( strArrFldName[1] ); + + programStageInstanceDataManager.addDateData( Integer.parseInt( form.getField( fldName ) ), + rowNumber ); + } + else if ( fldName.startsWith( PdfDataEntryFormUtil.LABELCODE_DATAENTRYTEXTFIELD ) ) + { + + String[] strArrFldName = fldName.split( "_" ); + int dataElementId = Integer.parseInt( strArrFldName[1] ); + int rowNumber = Integer.parseInt( strArrFldName[2] ); + + programStageInstanceDataManager.addDataElementData( dataElementId, form.getField( fldName ), + rowNumber ); + + } + } + } + + // For each row, add new programStageInstance and add data elements + // to it. + for ( Map.Entry entry : programStageInstanceDataManager + .getProgramStageInstanceData().entrySet() ) + { + Integer key = entry.getKey(); // rowNumber + ProgramStageInstanceStoage programStageInstanceStoage = entry.getValue(); + + int date = programStageInstanceStoage.getDate(); + executeDateCal.set( Calendar.DATE, date ); + Date executionDate = executeDateCal.getTime(); + + // Step 2. Create Program Stage Instance - If does not exists + // already. + programStageInstanceId = addNewProgramStageInstance( programStageId, organisationUnitId, executionDate ); + + programStageInstance = programStageInstanceService.getProgramStageInstance( programStageInstanceId ); + + for ( Map.Entry dataElementsEntry : programStageInstanceStoage.getDataElementsValue() + .entrySet() ) + { + Integer dataElementId = dataElementsEntry.getKey(); + String value = dataElementsEntry.getValue(); + + // Step 3. Insert Data + insertValue_ProgramStageDataElement( programStageInstance, dataElementId, value ); + } + + } + + reader.close(); + } + + private int addNewProgramStageInstance( int programStageId, int organisationUnitId, Date executionDate ) + throws Exception + { + OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( organisationUnitId ); + + if ( organisationUnit == null ) + { + throw new Exception( "Invalid organisation unit identifier: " + organisationUnitId ); + } + + ProgramStage programStage = programStageService.getProgramStage( programStageId ); + Program program = programStage.getProgram(); + + ProgramInstance programInstance = programInstanceService.getProgramInstances( program ).iterator().next(); + + ProgramStageInstance programStageInstance = new ProgramStageInstance(); + programStageInstance.setProgramInstance( programInstance ); + programStageInstance.setProgramStage( programStage ); + programStageInstance.setDueDate( executionDate ); + programStageInstance.setExecutionDate( executionDate ); + programStageInstance.setOrganisationUnit( organisationUnit ); + + return programStageInstanceService.addProgramStageInstance( programStageInstance ); + } + + private void insertValue_ProgramStageDataElement( ProgramStageInstance programStageInstance, int dataElementId, + String value ) + throws IOException, Exception + { + + DataElement dataElement = dataElementService.getDataElement( dataElementId ); + + PatientDataValue patientDataValue = patientDataValueService.getPatientDataValue( programStageInstance, + dataElement ); + + if ( value != null && value.trim().length() == 0 ) + { + value = null; + } + + // --------------------------------------------------------------------- + // Save value + // --------------------------------------------------------------------- + + if ( programStageInstance.getExecutionDate() == null ) + { + programStageInstance.setExecutionDate( new Date() ); + programStageInstanceService.updateProgramStageInstance( programStageInstance ); + } + + // providedElsewhere = (providedElsewhere == null) ? false : + // providedElsewhere; + String storedBy = currentUserService.getCurrentUsername(); + + if ( patientDataValue == null && value != null ) + { + // LOG.debug( "Adding PatientDataValue, value added" ); + + patientDataValue = new PatientDataValue( programStageInstance, dataElement, new Date(), value ); + patientDataValue.setStoredBy( storedBy ); + // patientDataValue.setProvidedElsewhere( providedElsewhere ); + + patientDataValueService.savePatientDataValue( patientDataValue ); + } + + if ( patientDataValue != null && value == null ) + { + patientDataValueService.deletePatientDataValue( patientDataValue ); + } + else if ( patientDataValue != null && value != null ) + { + // LOG.debug( "Updating PatientDataValue, value added/changed" ); + + patientDataValue.setValue( value ); + patientDataValue.setTimestamp( new Date() ); + // patientDataValue.setProvidedElsewhere( providedElsewhere ); + patientDataValue.setStoredBy( storedBy ); + + patientDataValueService.updatePatientDataValue( patientDataValue ); + } + + } + + // ----------------------------------------------------------------------------- + // ------------ Helper Classes [START] ------------ + + class ProgramStageInstanceDataManager + { + Map programStageInstanceData; + + public Map getProgramStageInstanceData() + { + return programStageInstanceData; + } + + public ProgramStageInstanceDataManager() + { + programStageInstanceData = new HashMap(); + } + + public void addDateData( int date, int rowNumber ) + { + // Obsolete - get Date from strDateData + + // If it already exists, add to existing. + // Otherwise, create one and add value in it. + if ( programStageInstanceData.containsKey( rowNumber ) ) + { + // add to existing + programStageInstanceData.get( rowNumber ).setDate( date ); + } + else + { + // Create and add + ProgramStageInstanceStoage programStageInstanceStoage = new ProgramStageInstanceStoage(); + programStageInstanceStoage.setDate( date ); + + programStageInstanceData.put( rowNumber, programStageInstanceStoage ); + } + + } + + public void addDataElementData( int dataElementId, String value, int rowNumber ) + { + // If it already exists, add to existing. + // Otherwise, create one and add value in it. + if ( programStageInstanceData.containsKey( rowNumber ) ) + { + // add to existing + programStageInstanceData.get( rowNumber ).addDataElements( dataElementId, value ); + } + else + { + // Create and add + ProgramStageInstanceStoage programStageInstanceStoage = new ProgramStageInstanceStoage(); + programStageInstanceStoage.addDataElements( dataElementId, value ); + + programStageInstanceData.put( rowNumber, programStageInstanceStoage ); + } + + } + + } + + class ProgramStageInstanceStoage + { + int date; + + Map dataElementsValue; + + // ------------------------------------------------------------------------- + // GET/SET + // ------------------------------------------------------------------------- + + public int getDate() + { + return date; + } + + public void setDate( int date ) + { + this.date = date; + } + + public Map getDataElementsValue() + { + return dataElementsValue; + } + + // ------------------------------------------------------------------------- + // CONSTRUCTOR + // ------------------------------------------------------------------------- + + public ProgramStageInstanceStoage() + { + dataElementsValue = new HashMap(); + } + + // ------------------------------------------------------------------------- + // METHODS + // ------------------------------------------------------------------------- + + public void addDataElements( Integer dataElementId, String value ) + { + dataElementsValue.put( dataElementId, value ); + } + } + +} === modified file 'dhis-2/dhis-web/dhis-web-importexport/pom.xml' --- dhis-2/dhis-web/dhis-web-importexport/pom.xml 2013-03-22 13:47:40 +0000 +++ dhis-2/dhis-web/dhis-web-importexport/pom.xml 2013-05-23 04:30:18 +0000 @@ -47,6 +47,10 @@ org.hisp.dhis + dhis-dxf2 + + + org.hisp.dhis dhis-web-commons === modified file 'dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/util/ImportDataValueTask.java' --- dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/util/ImportDataValueTask.java 2012-04-15 20:21:18 +0000 +++ dhis-2/dhis-web/dhis-web-importexport/src/main/java/org/hisp/dhis/importexport/action/util/ImportDataValueTask.java 2013-05-25 06:19:23 +0000 @@ -27,13 +27,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import java.io.InputStream; -import java.io.Reader; - import org.hisp.dhis.dxf2.datavalueset.DataValueSetService; import org.hisp.dhis.dxf2.metadata.ImportOptions; import org.hisp.dhis.scheduling.TaskId; +import java.io.InputStream; +import java.io.Reader; + /** * @author Lars Helge Overland */ @@ -41,14 +41,16 @@ implements Runnable { public static final String FORMAT_CSV = "csv"; - + + public static final String FORMAT_PDF = "pdf"; + private DataValueSetService dataValueSetService; private InputStream in; private Reader reader; private ImportOptions options; private TaskId taskId; private String format; - + public ImportDataValueTask( DataValueSetService dataValueSetService, InputStream in, Reader reader, ImportOptions options, TaskId taskId, String format ) { this.dataValueSetService = dataValueSetService; @@ -58,7 +60,7 @@ this.taskId = taskId; this.format = format; } - + @Override public void run() { @@ -66,6 +68,10 @@ { dataValueSetService.saveDataValueSetCsv( reader, options, taskId ); } + else if ( FORMAT_PDF.equals( format ) ) + { + dataValueSetService.saveDataValueSetPdf( in, options, taskId ); + } else { dataValueSetService.saveDataValueSet( in, options, taskId ); === modified file 'dhis-2/dhis-web/dhis-web-importexport/src/main/resources/org/hisp/dhis/importexport/i18n_module.properties' --- dhis-2/dhis-web/dhis-web-importexport/src/main/resources/org/hisp/dhis/importexport/i18n_module.properties 2013-04-19 07:37:53 +0000 +++ dhis-2/dhis-web/dhis-web-importexport/src/main/resources/org/hisp/dhis/importexport/i18n_module.properties 2013-05-23 04:30:18 +0000 @@ -263,6 +263,7 @@ intro_xls_metadata_export=Excel Spreadsheet (XLS) is a commonly used spreadsheet file format from Microsoft. intro_xml_data_import=Import data values on the DXF 2 XML format which is used for data exchange by DHIS 2 and other software. intro_csv_data_import=Import data values on the CSV format which is used for data exchange by DHIS 2 and other third-party software. +intro_pdf_data_import=Import data values on the PDF Data Entry Form. intro_dhis14_import=Import data from DHIS 1.4 installations. DHIS 1.4 is the predecessor of DHIS 2. intro_data_export=Export data values. This is the regular export function which exports data to the DHIS 2 exchange format called DXF 2. intro_metadata_export=Export meta data like data elements and organisation units to the standard DHIS 2 exchange format. @@ -292,6 +293,7 @@ xml=XML xml_data_import=XML Data Import csv_data_import=CSV Data Import +pdf_data_import=PDF Data Import no_data_values_found=No data values found create_new_route=Create new route integration=Integration === modified file 'dhis-2/dhis-web/dhis-web-importexport/src/main/webapp/dhis-web-importexport/index.vm' --- dhis-2/dhis-web/dhis-web-importexport/src/main/webapp/dhis-web-importexport/index.vm 2013-05-23 09:36:40 +0000 +++ dhis-2/dhis-web/dhis-web-importexport/src/main/webapp/dhis-web-importexport/index.vm 2013-05-25 05:54:08 +0000 @@ -11,6 +11,7 @@ #introListImgItem( "dxf2MetaDataImport.action" "metadata_import" "import" ) #introListImgItem( "displayImportDataValueForm.action?importFormat=xml" "xml_data_import" "import" ) #introListImgItem( "displayImportDataValueForm.action?importFormat=csv" "csv_data_import" "import" ) + #introListImgItem( "displayImportDataValueForm.action?importFormat=pdf" "pdf_data_import" "import" ) #introListImgItem( "displayExternalImportMenu.action" "dhis14_import" "import" ) #introListImgItem( "dxf2MetaDataExport.action" "metadata_export" "export" ) === modified file 'dhis-2/dhis-web/dhis-web-importexport/src/main/webapp/dhis-web-importexport/mainMenu.vm' --- dhis-2/dhis-web/dhis-web-importexport/src/main/webapp/dhis-web-importexport/mainMenu.vm 2013-04-20 12:35:07 +0000 +++ dhis-2/dhis-web/dhis-web-importexport/src/main/webapp/dhis-web-importexport/mainMenu.vm 2013-05-23 04:30:18 +0000 @@ -5,6 +5,7 @@
  • $i18n.getString( "metadata_import" ) 
  • $i18n.getString( "xml_data_import" ) 
  • $i18n.getString( "csv_data_import" ) 
  • +
  • $i18n.getString( "pdf_data_import" ) 
  • $i18n.getString( "dhis14_import" ) 
  • $i18n.getString( "gml_import" ) 
  • === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/resources/org/hisp/dhis/dataset/i18n_module.properties' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/resources/org/hisp/dhis/dataset/i18n_module.properties 2013-01-23 09:08:59 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/resources/org/hisp/dhis/dataset/i18n_module.properties 2013-05-23 04:30:18 +0000 @@ -108,4 +108,5 @@ object_not_deleted_associated_by_objects=Object not deleted because it is associated by objects of type auto_save_data_entry_forms=Auto-save data entry forms notify_completing_user=Send notification to completing user -insert_images=Insert images \ No newline at end of file +insert_images=Insert images +pdf_data_entry_form=Get PDF for Data Entry \ No newline at end of file === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/dataSetList.vm' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/dataSetList.vm 2013-03-13 11:47:27 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-dataset/src/main/webapp/dhis-web-maintenance-dataset/dataSetList.vm 2013-05-23 04:30:18 +0000 @@ -31,7 +31,7 @@ - + @@ -73,6 +73,12 @@ #end + #if( $security.canUpdate( $dataSet ) ) + $i18n.getString( 'pdf_data_entry_form' ) + #else + + #end + #if( $security.canWrite( $dataSet ) ) $i18n.getString( 'edit_compulsory_data_elements' ) #else === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module.properties' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module.properties 2013-05-24 09:10:42 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/resources/org/hisp/dhis/patient/i18n_module.properties 2013-05-25 05:54:08 +0000 @@ -364,6 +364,7 @@ capture_coordinates = Capture coordinates task_stragely = Task strategy last_month = Last month +pdf_data_entry_form=Get PDF for Data Entry last_3_month = Last 3 months last_6_month = Last 6 months last_12_month = Last 12 months === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/programStage.vm' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/programStage.vm 2013-03-01 14:09:05 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-patient/src/main/webapp/dhis-web-maintenance-patient/programStage.vm 2013-05-23 04:30:18 +0000 @@ -19,7 +19,7 @@
    $i18n.getString( "name" )
    - + @@ -41,8 +41,10 @@ #if( $program.type=='1' ) $i18n.getString( 'remove' ) #end + $i18n.getString( 'show_details' )$i18n.getString( 'section_management' ) + $i18n.getString( 'pdf_data_entry_form' )$i18n.getString( 'design_data_entry_form' )
    $i18n.getString( "name" )