001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.module.endow.report.util;
017    
018    import java.awt.Color;
019    import java.math.BigDecimal;
020    import java.text.DecimalFormat;
021    import java.text.NumberFormat;
022    import java.util.Date;
023    import java.util.List;
024    
025    import org.kuali.kfs.module.endow.report.util.EndowmentReportFooterDataHolder.BenefittingForFooter;
026    
027    import com.lowagie.text.BadElementException;
028    import com.lowagie.text.Document;
029    import com.lowagie.text.Element;
030    import com.lowagie.text.Font;
031    import com.lowagie.text.FontFactory;
032    import com.lowagie.text.PageSize;
033    import com.lowagie.text.Paragraph;
034    import com.lowagie.text.Phrase;
035    import com.lowagie.text.Rectangle;
036    import com.lowagie.text.pdf.PdfPCell;
037    import com.lowagie.text.pdf.PdfPTable;
038    
039    public abstract class EndowmentReportPrintBase {
040       
041        public final String ZERO_FOR_REPORT = "0.00";
042        
043        public static final int KEMIDS_SELECTED_COLUMN_NUM = 5;
044        public static final int REQUEST_INFO_TABLE_WIDTH = 100;
045        public static final int CRITERIA_TABLE_WIDTH = 80;
046        public static final int MULTIPLE_KEMID_TABLE_WIDTH = 80;
047        public static final int KEMID_SELECTED_TABLE_WIDTH = 80;
048        public static final int FULL_TABLE_WIDTH = 100;
049        
050        public static final Font headerShheetTitleFont = FontFactory.getFont(FontFactory.HELVETICA, 10, Font.BOLD);
051        public static final Font headerSheetRegularFont = FontFactory.getFont(FontFactory.HELVETICA, 10, Font.NORMAL, Color.DARK_GRAY);
052        
053        public static final Font titleFont = FontFactory.getFont(FontFactory.HELVETICA, 8, Font.BOLD);
054        public static final Font regularFont = FontFactory.getFont(FontFactory.HELVETICA, 8, Font.NORMAL, Color.DARK_GRAY);
055        public static final Font headerFont = FontFactory.getFont(FontFactory.HELVETICA, 8, Font.NORMAL, Color.GRAY);
056        
057        public static final Font footerTitleFont = FontFactory.getFont(FontFactory.HELVETICA, 7, Font.BOLD);
058        public static final Font footerRegularFont = FontFactory.getFont(FontFactory.HELVETICA, 7, Font.NORMAL, Color.DARK_GRAY);
059        
060        protected static final Rectangle LETTER_PORTRAIT = PageSize.LETTER;
061        protected static final Rectangle LETTER_LANDSCAPE = PageSize.LETTER.rotate();
062        
063        protected static final String FORMAT192 = "#,###,###,###,###,###,##0.00";
064        protected static final String FORMAT195 = "##,###,###,###,##0.00000";
065        protected static final String FORMAT164 = "###,###,###,##0.0000";
066        
067        /** 
068         * Generates the report header sheet
069         * 
070         * @param reportRequestHeaderDataHolder
071         * @param document
072         * @return
073         */
074        public boolean printReportHeaderPage(EndowmentReportHeaderDataHolder reportRequestHeaderDataHolder, Document document, String listKemidsInHeader) {
075            
076            try {
077                // report header
078                Phrase header = new Paragraph(new Date().toString());
079                Paragraph title = new Paragraph(reportRequestHeaderDataHolder.getInstitutionName());
080                title.setAlignment(Element.ALIGN_CENTER);
081                title.add("\nReport Request Header Sheet\n\n");
082                document.add(title);
083                
084                PdfPTable requestTable = new PdfPTable(2);
085                requestTable.setWidthPercentage(REQUEST_INFO_TABLE_WIDTH);
086                int[] requestWidths = {20, 80};
087                requestTable.setWidths(requestWidths);
088                requestTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
089                            
090                Paragraph reportRequested = new Paragraph(reportRequestHeaderDataHolder.getReportRequested(), headerSheetRegularFont);
091                Paragraph dateRequested = new Paragraph(new Date().toString(), headerSheetRegularFont);
092                Paragraph requestedBy = new Paragraph(reportRequestHeaderDataHolder.getRequestedBy(), headerSheetRegularFont);
093                Paragraph endowmentOption = new Paragraph(reportRequestHeaderDataHolder.getEndowmentOption(), headerSheetRegularFont);
094                Paragraph reportOption = new Paragraph(reportRequestHeaderDataHolder.getReportOption(), headerSheetRegularFont);
095                
096                requestTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("Report Requested:", Element.ALIGN_RIGHT));
097                requestTable.addCell(reportRequested);
098                requestTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("Date Requested:", Element.ALIGN_RIGHT));
099                requestTable.addCell(dateRequested);
100                requestTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("Reqeusted by:", Element.ALIGN_RIGHT));
101                requestTable.addCell(requestedBy);
102                requestTable.addCell("");
103                requestTable.addCell("");
104                requestTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("Endowment Option:", Element.ALIGN_RIGHT));
105                requestTable.addCell(endowmentOption);
106                requestTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("Report Option:", Element.ALIGN_RIGHT));
107                requestTable.addCell(reportOption);
108                document.add(requestTable);
109                
110                // Criteria
111                Paragraph criteria = new Paragraph("\nCriteria:\n\n");
112                document.add(criteria);
113                
114                PdfPTable criteriaTable = new PdfPTable(2);
115                criteriaTable.setWidthPercentage(CRITERIA_TABLE_WIDTH);
116                int[] criteriaWidths = {30, 50};
117                criteriaTable.setWidths(criteriaWidths);
118                criteriaTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
119        
120                Paragraph benefittingCampus = new Paragraph(reportRequestHeaderDataHolder.getBenefittingCampus(), headerSheetRegularFont);
121                Paragraph benefittingChart = new Paragraph(reportRequestHeaderDataHolder.getBenefittingChart(), headerSheetRegularFont);
122                Paragraph benefittingOrganization = new Paragraph(reportRequestHeaderDataHolder.getBenefittingOrganization(), headerSheetRegularFont);
123                Paragraph kemidTypeCode = new Paragraph(reportRequestHeaderDataHolder.getKemidTypeCode(), headerSheetRegularFont);
124                Paragraph kemidPurposeCode = new Paragraph(reportRequestHeaderDataHolder.getKemidPurposeCode(), headerSheetRegularFont);            
125                Paragraph combinationGroupCode = new Paragraph(reportRequestHeaderDataHolder.getCombineGroupCode(), headerSheetRegularFont);
126                
127                criteriaTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("Benefitting Campus:", Element.ALIGN_RIGHT));
128                criteriaTable.addCell(benefittingCampus);
129                criteriaTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("Benefitting Chart:", Element.ALIGN_RIGHT));
130                criteriaTable.addCell(benefittingChart);
131                criteriaTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("Benefitting Organization:", Element.ALIGN_RIGHT));
132                criteriaTable.addCell(benefittingOrganization);
133                criteriaTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("KEMID Type Code:", Element.ALIGN_RIGHT));
134                criteriaTable.addCell(kemidTypeCode);
135                criteriaTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("KEMID Purpose Code:", Element.ALIGN_RIGHT));
136                criteriaTable.addCell(kemidPurposeCode);
137                criteriaTable.addCell(createCellWithDefaultFontAndWithoutBorderLine("Combine Group Code:", Element.ALIGN_RIGHT));
138                criteriaTable.addCell(combinationGroupCode);
139                document.add(criteriaTable);
140                
141                // kemids with multiple benefitting organization
142                Paragraph kemidWithMultipleBenefittingOrganization = new Paragraph("\nKEMIDs with Multiple Benefitting Organizations:\n\n");
143                document.add(kemidWithMultipleBenefittingOrganization);
144                
145                List<KemidsWithMultipleBenefittingOrganizationsDataHolder> kemidsWithMultipleBenefittingOrganizationsDataHolder = reportRequestHeaderDataHolder.getKemidsWithMultipleBenefittingOrganizationsDataHolders();
146                if (kemidsWithMultipleBenefittingOrganizationsDataHolder != null && !kemidsWithMultipleBenefittingOrganizationsDataHolder.isEmpty()) {
147                    PdfPTable kemidWithMultipleBenefittingOrganizationTable = new PdfPTable(5);
148                    kemidWithMultipleBenefittingOrganizationTable.setWidthPercentage(MULTIPLE_KEMID_TABLE_WIDTH);
149                    kemidWithMultipleBenefittingOrganizationTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
150                    
151                    Paragraph kemid = new Paragraph("KEMID", titleFont);
152                    Paragraph campus = new Paragraph("Campus", titleFont);
153                    Paragraph chart = new Paragraph("Chart", titleFont);
154                    Paragraph organization = new Paragraph("Organziation", titleFont);
155                    Paragraph percent = new Paragraph("Percent", titleFont);
156                    kemidWithMultipleBenefittingOrganizationTable.addCell(kemid);
157                    kemidWithMultipleBenefittingOrganizationTable.addCell(campus);
158                    kemidWithMultipleBenefittingOrganizationTable.addCell(chart);
159                    kemidWithMultipleBenefittingOrganizationTable.addCell(organization);
160                    kemidWithMultipleBenefittingOrganizationTable.addCell(percent);
161                    
162                    for (KemidsWithMultipleBenefittingOrganizationsDataHolder kmbo : kemidsWithMultipleBenefittingOrganizationsDataHolder) {
163                        kemidWithMultipleBenefittingOrganizationTable.addCell(new Paragraph(kmbo.getKemid(), headerSheetRegularFont));
164                        kemidWithMultipleBenefittingOrganizationTable.addCell(new Paragraph(kmbo.getCampus(), headerSheetRegularFont));
165                        kemidWithMultipleBenefittingOrganizationTable.addCell(new Paragraph(kmbo.getChart(), headerSheetRegularFont));
166                        kemidWithMultipleBenefittingOrganizationTable.addCell(new Paragraph(kmbo.getOrganization(), headerSheetRegularFont));            
167                        kemidWithMultipleBenefittingOrganizationTable.addCell(new Paragraph(kmbo.getPercent().toString(), headerSheetRegularFont));
168                    }
169                    document.add(kemidWithMultipleBenefittingOrganizationTable);
170                } else {
171                    Paragraph noneExistMessage = new Paragraph("NONE EXIST\n\n", headerSheetRegularFont);
172                    document.add(noneExistMessage);
173                }
174                
175                // kemids selected
176                if ("Y".equalsIgnoreCase(listKemidsInHeader)) {
177                    List<String> kemidsSelected = reportRequestHeaderDataHolder.getKemidsSelected();
178                    int totalKemidsSelected = reportRequestHeaderDataHolder.getKemidsSelected().size();
179                    Paragraph kemidsSelectedTitle = new Paragraph("\nKEMIDs Selected: " + totalKemidsSelected + "\n\n");
180                    document.add(kemidsSelectedTitle);
181                    
182                    PdfPTable kemidsTable = new PdfPTable(KEMIDS_SELECTED_COLUMN_NUM);
183                    kemidsTable.setWidthPercentage(KEMID_SELECTED_TABLE_WIDTH);
184                    kemidsTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
185                    
186                    for (int i = 0; i < totalKemidsSelected ; i++) {
187                        kemidsTable.addCell(new Paragraph(kemidsSelected.get(i), headerSheetRegularFont) );                
188                    }
189                    // to fill out the rest of the empty cells. Otherwise, the row won't be displayed
190                    if (totalKemidsSelected % KEMIDS_SELECTED_COLUMN_NUM != 0) {
191                        for (int i = 0; i < (KEMIDS_SELECTED_COLUMN_NUM - totalKemidsSelected % KEMIDS_SELECTED_COLUMN_NUM) ; i++) {
192                            kemidsTable.addCell("");
193                        }
194                    }
195                    document.add(kemidsTable);
196                }
197            
198            } catch (Exception e) {
199                return false;
200            }  
201    
202            return true;
203        }
204        
205        /**
206         * Generates the footer
207         * 
208         * @param footerData
209         * @param document
210         */
211        public boolean printFooter(EndowmentReportFooterDataHolder footerData, Document document) {
212        
213            if (footerData == null) {
214                return false;
215            }
216            
217            try {
218                document.add(new Phrase("\n"));
219                
220                PdfPTable table = new PdfPTable(2);
221                table.setWidthPercentage(FULL_TABLE_WIDTH);
222                int[] colWidths = {40, 60};
223                table.setWidths(colWidths);
224                table.getDefaultCell().setPadding(2);
225                
226                // left column
227                PdfPTable leftTable = new PdfPTable(2);
228                leftTable.setWidths(colWidths);
229                leftTable.setWidthPercentage(40);
230                
231                leftTable.addCell(createCell("Reference: ", footerTitleFont, Element.ALIGN_LEFT, false));
232                leftTable.addCell(createCell(footerData.getReference(), footerRegularFont, Element.ALIGN_LEFT, false));
233                leftTable.addCell(createCell("Date Established: ", footerTitleFont, Element.ALIGN_LEFT, false));
234                leftTable.addCell(createCell(footerData.getEstablishedDate(), footerRegularFont, Element.ALIGN_LEFT, false));
235                leftTable.addCell(createCell("KEMID Type: ", footerTitleFont, Element.ALIGN_LEFT, false));
236                leftTable.addCell(createCell(footerData.getKemidType(), footerRegularFont, Element.ALIGN_LEFT, false));
237                leftTable.addCell(createCell("KEMID Purpose: ", footerTitleFont, Element.ALIGN_LEFT, false));
238                leftTable.addCell(createCell(footerData.getKemidPurpose(), footerRegularFont, Element.ALIGN_LEFT, false));
239                leftTable.addCell(createCell("Report Run Date: ", footerTitleFont, Element.ALIGN_LEFT, false));
240                leftTable.addCell(createCell(footerData.getReportRunDate(), footerRegularFont, Element.ALIGN_LEFT, false));
241                table.addCell(leftTable);
242                
243                // right column
244                PdfPTable rightTable = new PdfPTable(4);
245                rightTable.setWidthPercentage(60);
246                
247                PdfPCell cellBenefitting = new PdfPCell(new Paragraph("BENEFITTING\n", titleFont));
248                cellBenefitting.setColspan(4);
249                cellBenefitting.setBorderWidth(0);
250                rightTable.addCell(cellBenefitting);  
251                
252                rightTable.addCell(createCell("Campus", footerTitleFont, Element.ALIGN_LEFT, false));
253                rightTable.addCell(createCell("Chart", footerTitleFont, Element.ALIGN_LEFT, false));
254                rightTable.addCell(createCell("Organizaztion", footerTitleFont, Element.ALIGN_LEFT, false));
255                rightTable.addCell(createCell("Percent", footerTitleFont, Element.ALIGN_LEFT, false));
256                
257                List<BenefittingForFooter> benefittingList = footerData.getBenefittingList();
258                if (benefittingList != null) {
259                    for (BenefittingForFooter benefitting : benefittingList) {
260                        rightTable.addCell(createCell(benefitting.getCampusName(), footerRegularFont, Element.ALIGN_LEFT, Element.ALIGN_TOP, false));
261                        rightTable.addCell(createCell(benefitting.getChartName(), footerRegularFont, Element.ALIGN_LEFT, Element.ALIGN_TOP, false));
262                        rightTable.addCell(createCell(benefitting.getOrganizationName(), footerRegularFont, Element.ALIGN_LEFT, Element.ALIGN_TOP, false));
263                        rightTable.addCell(createCell(benefitting.getBenefittingPercent(), footerRegularFont, Element.ALIGN_LEFT, Element.ALIGN_TOP, false));
264                    }
265                }
266                
267                table.addCell(rightTable);
268                
269                document.add(table);
270                
271            } catch (Exception e) {
272                return false;
273            }
274            
275            return true;
276        }
277        
278        /**
279         * Creates a cell
280         * 
281         * @param s
282         * @param alignment
283         * @return
284         */
285        protected PdfPCell createCellWithDefaultFontAndBorderLine(String s, int alignment) throws BadElementException {        
286            return createCell(s, regularFont, alignment, true);
287        }
288        
289        /**
290         * Creates a cell without borderline
291         * 
292         * @param s
293         * @param alignment
294         * @return
295         * @throws BadElementException
296         */
297        protected PdfPCell createCellWithDefaultFontAndWithoutBorderLine(String s, int alignment) throws BadElementException {        
298            return createCell(s, headerSheetRegularFont, alignment, false);
299        }
300        
301        /**
302         * Create a cell with the given font, alignment, and borderline option 
303         * 
304         * @param content
305         * @param font
306         * @param alignment
307         * @param borderLine
308         * @return
309         */
310        public PdfPCell createCell(String contents, Font font, int horizontalAlignment, boolean borderLine) {
311            return createCell(contents, font, horizontalAlignment, Element.ALIGN_BOTTOM, borderLine);
312        } 
313        
314        /**
315         * Creates a call with given font, alignments, and borderline
316         * 
317         * @param contents
318         * @param font
319         * @param horizontalAlignment
320         * @param verticalAlignment
321         * @param borderLine
322         * @return
323         */
324        public PdfPCell createCell(String contents, Font font, int horizontalAlignment, int verticalAlignment, boolean borderLine) {
325            if (contents == null) contents = "";
326            Phrase phr = new Phrase(contents, font);
327            PdfPCell cell = new PdfPCell(phr);
328            cell.setHorizontalAlignment(horizontalAlignment);
329            if (!borderLine) {
330                cell.setBorderWidth(0);
331            }
332            cell.setVerticalAlignment(verticalAlignment);
333            return cell;
334        } 
335        
336        /**
337         * Created a cell with a specific font
338         * 
339         * @param value
340         * @param font
341         * @return
342         */
343        protected PdfPCell getAmountCell(BigDecimal value, Font font) {        
344            String amount = (value == null) ? ZERO_FOR_REPORT : formatAmount(value);        
345            return createCell(amount, font, Element.ALIGN_RIGHT, true);        
346        }
347        
348        /**
349         * Created a cell with a specific font and format
350         * 
351         * @param value
352         * @param font
353         * @param format
354         * @return
355         */
356        protected PdfPCell getAmountCell(BigDecimal value, Font font, String format) {        
357            String amount = (value == null) ? ZERO_FOR_REPORT : formatAmount(value, format);        
358            return createCell(amount, font, Element.ALIGN_RIGHT, true);        
359        }
360        
361        /** 
362         * Format the dollar amount - 19,2 decimal
363         * 
364         * @param amount
365         * @return
366         */
367        protected String formatAmount(BigDecimal amount) {                
368            NumberFormat formatter = new DecimalFormat("#,###,###,###,###,###,##0.00;(#,###,###,###,###,###,##0.00)");
369            return  formatter.format(amount.doubleValue());
370        }
371        
372        /**
373         * Format the dollar amount
374         * 
375         * @param amount
376         * @param format
377         * @return
378         */
379        protected String formatAmount(BigDecimal amount, String format) {        
380            NumberFormat formatter = new DecimalFormat(format + ";(" + format + ")");
381            return  formatter.format(amount.doubleValue());
382        }
383        
384        /**
385         * Converts a string to upper case
386         * 
387         * @param s
388         * @return
389         */
390        protected String convertToUpperCase(String s) {
391            if (s == null) {
392                return "";
393            } else {
394                return s.toUpperCase();
395            }
396        }
397    }