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.pdp.batch.service.impl;
017    
018    import java.io.FileOutputStream;
019    import java.text.DecimalFormat;
020    import java.text.MessageFormat;
021    import java.text.SimpleDateFormat;
022    import java.util.Collection;
023    import java.util.Date;
024    import java.util.Iterator;
025    import java.util.List;
026    
027    import org.kuali.kfs.gl.report.TransactionReport.PageHelper;
028    import org.kuali.kfs.pdp.PdpKeyConstants;
029    import org.kuali.kfs.pdp.batch.service.DailyReportService;
030    import org.kuali.kfs.pdp.businessobject.DailyReport;
031    import org.kuali.kfs.pdp.dataaccess.PaymentDetailDao;
032    import org.kuali.kfs.pdp.service.PaymentGroupService;
033    import org.kuali.rice.kns.service.DateTimeService;
034    import org.kuali.rice.kns.service.KualiConfigurationService;
035    import org.springframework.transaction.annotation.Transactional;
036    
037    import com.lowagie.text.Document;
038    import com.lowagie.text.DocumentException;
039    import com.lowagie.text.Element;
040    import com.lowagie.text.Font;
041    import com.lowagie.text.FontFactory;
042    import com.lowagie.text.PageSize;
043    import com.lowagie.text.Phrase;
044    import com.lowagie.text.Rectangle;
045    import com.lowagie.text.pdf.PdfPCell;
046    import com.lowagie.text.pdf.PdfPTable;
047    import com.lowagie.text.pdf.PdfWriter;
048    
049    @Transactional
050    public class DailyReportServiceImpl implements DailyReportService {
051        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DailyReportServiceImpl.class);
052    
053        private PaymentDetailDao paymentDetailDao;
054        private DateTimeService dateTimeService;
055        private String directoryName;
056        private PaymentGroupService paymentGroupService;
057        private KualiConfigurationService kualiConfigurationService;
058        
059        private Font headerFont;
060        private Font textFont;
061    
062        public DailyReportServiceImpl() {
063            headerFont = FontFactory.getFont(FontFactory.COURIER, 8, Font.BOLD);
064            textFont = FontFactory.getFont(FontFactory.COURIER, 8, Font.NORMAL);
065        }
066    
067        protected List<DailyReport> getData() {
068            LOG.debug("getData() started");
069    
070            return paymentDetailDao.getDailyReportData();
071        }
072    
073        public void runReport() {
074            LOG.debug("runReport() started");
075    
076            Collection<DailyReport> data = getData();
077            Date today = dateTimeService.getCurrentDate();
078            SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
079            
080            String reportFilePrefix = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.DAILY_REPORT_SERVICE_FILE_PREFIX);
081            reportFilePrefix = MessageFormat.format(reportFilePrefix, new Object[]{ null });
082            
083            String reportTitle = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.DAILY_REPORT_SERVICE_REPORT_TITLE);
084            reportTitle = MessageFormat.format(reportTitle, new Object[]{ sdf.format(today) });
085            
086            Document document = openPdfWriter(directoryName, reportFilePrefix, dateTimeService.getCurrentDate(), reportTitle);
087    
088            try {
089                float[] summaryWidths = { 20, 20, 20, 20, 20 };
090                PdfPTable dataTable = new PdfPTable(summaryWidths);
091                dataTable.setWidthPercentage(100);
092                dataTable.setHeaderRows(1);
093                addHeader(dataTable);
094    
095                boolean rows = false;
096                DailyReport sortTotal = new DailyReport();
097                DailyReport total = new DailyReport();
098                DailyReport dr = new DailyReport();
099                
100                String totalForSubtitle = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.DAILY_REPORT_SERVICE_TOTAL_FOR_SUBTITLE);
101                
102                String totalSubtitle = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.DAILY_REPORT_SERVICE_TOTAL_SUBTITLE);
103                totalSubtitle = MessageFormat.format(totalSubtitle, new Object[]{ null });
104                
105                
106                for (Iterator iter = data.iterator(); iter.hasNext();) {
107                    dr = (DailyReport) iter.next();
108    
109                    if ( ! rows ) {
110                        rows = true;
111                        sortTotal = new DailyReport(dr);
112                        sortTotal.addRow(dr);
113                        addRow(dataTable, dr, false, this.paymentGroupService.getSortGroupName(this.paymentGroupService.getSortGroupId(dr.getPaymentGroup())));
114                    } else if (this.paymentGroupService.getSortGroupId(sortTotal.getPaymentGroup()) != (this.paymentGroupService.getSortGroupId(dr.getPaymentGroup()))) {
115                        String newTotalForSubtitle = MessageFormat.format(totalForSubtitle, new Object[]{ this.paymentGroupService.getSortGroupName(this.paymentGroupService.getSortGroupId(sortTotal.getPaymentGroup())) });
116                       
117                        addRow(dataTable, sortTotal, true, newTotalForSubtitle );
118                        sortTotal = new DailyReport(dr);
119                        sortTotal.addRow(dr);
120                        addRow(dataTable, dr, false, this.paymentGroupService.getSortGroupName(this.paymentGroupService.getSortGroupId(dr.getPaymentGroup())));
121                    } else {
122                        sortTotal.addRow(dr);
123                        addRow(dataTable, dr, false,"");
124                    }
125    
126                    total.addRow(dr);
127                }
128    
129                if (rows) {
130                    String newTotalForSubtitle = MessageFormat.format(totalForSubtitle, new Object[]{ this.paymentGroupService.getSortGroupName(this.paymentGroupService.getSortGroupId(sortTotal.getPaymentGroup())) });
131                    
132                    addRow(dataTable, sortTotal, true, newTotalForSubtitle);
133                }
134                addRow(dataTable, total, true, totalSubtitle);
135    
136                document.add(dataTable);
137            }
138            catch (DocumentException d) {
139                throw new RuntimeException(d);
140            }
141            document.close();
142        }
143    
144        protected void addHeader(PdfPTable dataTable) {
145            String sortOrderSubtitle = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.DAILY_REPORT_SERVICE_SORT_ORDER_SUBTITLE);
146            sortOrderSubtitle = MessageFormat.format(sortOrderSubtitle, new Object[]{ null });
147            
148            PdfPCell cell = new PdfPCell(new Phrase(sortOrderSubtitle, headerFont));
149            dataTable.addCell(cell);
150            
151            String customerSubtitle = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.DAILY_REPORT_SERVICE_CUSTOMER_SUBTITLE);
152            customerSubtitle = MessageFormat.format(customerSubtitle, new Object[]{ null });
153            
154            cell = new PdfPCell(new Phrase(customerSubtitle, headerFont));
155            dataTable.addCell(cell);
156    
157            String amountOfPaymentsSubtitle = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.DAILY_REPORT_SERVICE_AMOUNT_OF_PAYMENTS_SUBTITLE);
158            amountOfPaymentsSubtitle = MessageFormat.format(amountOfPaymentsSubtitle, new Object[]{ null });
159            
160            cell = new PdfPCell(new Phrase(amountOfPaymentsSubtitle, headerFont));
161            cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
162            dataTable.addCell(cell);
163            
164            String numberOfPaymentRecordsSubtitle = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.DAILY_REPORT_SERVICE_NUMBER_OF_PAYMENT_RECORDS_SUBTITLE);
165            numberOfPaymentRecordsSubtitle = MessageFormat.format(numberOfPaymentRecordsSubtitle, new Object[]{ null });
166            
167            cell = new PdfPCell(new Phrase(numberOfPaymentRecordsSubtitle, headerFont));
168            cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
169            dataTable.addCell(cell);
170            
171            String numberOfPayeesSubtitle = this.kualiConfigurationService.getPropertyString(PdpKeyConstants.DAILY_REPORT_SERVICE_NUMBER_OF_PAYEES_SUBTITLE);
172            numberOfPayeesSubtitle= MessageFormat.format(numberOfPayeesSubtitle, new Object[]{ null });
173            
174            cell = new PdfPCell(new Phrase(numberOfPayeesSubtitle, headerFont));
175            cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
176            dataTable.addCell(cell);
177        }
178    
179        protected void addRow(PdfPTable dataTable, DailyReport dr, boolean bold) {
180            addRow(dataTable,dr,bold, this.paymentGroupService.getSortGroupName(this.paymentGroupService.getSortGroupId(dr.getPaymentGroup())));
181        }
182    
183        protected void addRow(PdfPTable dataTable, DailyReport dr, boolean bold,String name) {
184            DecimalFormat af = new DecimalFormat("###,###,##0.00");
185            DecimalFormat nf = new DecimalFormat("###,##0");
186    
187            Font f = null;
188            if (bold) {
189                f = headerFont;
190    
191                for (int i = 0; i < 5; i++) {
192                    PdfPCell cell = new PdfPCell(new Phrase(" ", f));
193                    cell.setBorder(Rectangle.NO_BORDER);
194                    dataTable.addCell(cell);
195                }
196            }
197            else {
198                f = textFont;
199            }
200    
201            PdfPCell cell = new PdfPCell(new Phrase(name, f));
202            cell.setBorder(Rectangle.NO_BORDER);
203            dataTable.addCell(cell);
204    
205            if ( ! bold ) {
206                cell = new PdfPCell(new Phrase(dr.getCustomer(), f));
207            } else {
208                cell = new PdfPCell(new Phrase("", f));
209            }
210            cell.setBorder(Rectangle.NO_BORDER);
211            dataTable.addCell(cell);
212    
213            cell = new PdfPCell(new Phrase(af.format(dr.getAmount()), f));
214            cell.setBorder(Rectangle.NO_BORDER);
215            cell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT);
216            dataTable.addCell(cell);
217    
218            cell = new PdfPCell(new Phrase(nf.format(dr.getPayments()), f));
219            cell.setBorder(Rectangle.NO_BORDER);
220            cell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT);
221            dataTable.addCell(cell);
222    
223            cell = new PdfPCell(new Phrase(nf.format(dr.getPayees()), f));
224            cell.setBorder(Rectangle.NO_BORDER);
225            cell.setHorizontalAlignment(PdfPCell.ALIGN_RIGHT);
226            dataTable.addCell(cell);
227    
228            if (bold) {
229                for (int i = 0; i < 5; i++) {
230                    PdfPCell cell2 = new PdfPCell(new Phrase(" ", f));
231                    cell2.setBorder(Rectangle.NO_BORDER);
232                    dataTable.addCell(cell2);
233                }
234            }
235        }
236    
237        protected Document openPdfWriter(String destinationDirectory, String fileprefix, Date runDate, String title) {
238            try {
239                Document document = new Document(PageSize.A4.rotate());
240    
241                PageHelper helper = new PageHelper();
242                helper.runDate = runDate;
243                helper.headerFont = headerFont;
244                helper.title = title;
245    
246                String filename = destinationDirectory + "/" + fileprefix + "_";
247                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
248                filename = filename + sdf.format(runDate);
249                filename = filename + ".pdf";
250                PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
251                writer.setPageEvent(helper);
252    
253                document.open();
254    
255                return document;
256            }
257            catch (Exception e) {
258                LOG.error("openPdfWriter() Exception caught trying to create new PDF document", e);
259                if (e instanceof RuntimeException) {
260                    throw (RuntimeException) e;
261                }
262                else {
263                    throw new RuntimeException(e);
264                }
265            }
266        }
267    
268        public void setDirectoryName(String d) {
269            directoryName = d;
270        }
271    
272        public void setDateTimeService(DateTimeService dts) {
273            dateTimeService = dts;
274        }
275    
276        public void setPaymentDetailDao(PaymentDetailDao pdd) {
277            paymentDetailDao = pdd;
278        }
279        
280        /**
281         * 
282         * @see org.kuali.kfs.pdp.batch.service.DailyReportService#setPaymentGroupService(org.kuali.kfs.pdp.service.PaymentGroupService)
283         */
284        public void setPaymentGroupService(PaymentGroupService paymentGroupService) {
285            this.paymentGroupService = paymentGroupService;
286        }
287    
288        public void setKualiConfigurationService(KualiConfigurationService kualiConfigurationService) {
289            this.kualiConfigurationService = kualiConfigurationService;
290        }
291    }