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.cab.batch;
017    
018    import java.sql.Timestamp;
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.Date;
022    import java.util.HashSet;
023    import java.util.List;
024    
025    import org.apache.log4j.Logger;
026    import org.kuali.kfs.gl.businessobject.Entry;
027    import org.kuali.kfs.module.cab.batch.service.BatchExtractReportService;
028    import org.kuali.kfs.module.cab.batch.service.BatchExtractService;
029    import org.kuali.kfs.module.cab.businessobject.PurchasingAccountsPayableDocument;
030    import org.kuali.kfs.sys.batch.AbstractStep;
031    import org.kuali.rice.kns.service.DateTimeService;
032    
033    public class ExtractStep extends AbstractStep {
034        private static final Logger LOG = Logger.getLogger(ExtractStep.class);
035        private BatchExtractService batchExtractService;
036        private DateTimeService dateTimeService;
037        private BatchExtractReportService batchExtractReportService;
038    
039        /**
040         * CAB Extract Steps
041         * <li>Find all GL transactions created after last extract time matching CAB filter parameters</li>
042         * <li>For each GL line perform the following steps</li>
043         * <li>Check GL lines belongs to a PO or Not</li>
044         * <li>If not PO related, then check for duplicate in CB_GL_ENTRY_T, if not duplicate insert into CB_GL_ENTRY_T</li>
045         * <li>If PO related, check against PURAP Account Line Revision History for respective PREQ or CM document</li>
046         * <li>If sum of amounts matches grouped by fields "univ_fiscal_yr, fin_coa_cd, account_nbr, sub_acct_nbr, fin_object_cd,
047         * fin_sub_obj_cd, univ_fiscal_prd_cd, fdoc_nbr, fdoc_ref_nbr" then it is a valid one, else ignore the GL lines for the document
048         * and write to the reconciliation report </li>
049         * <li>If CB_PUR_DOC entry doesn't exist, insert new record else update active indicator</li>
050         * <li>Insert into CB_PUR_ITM_AST_T when record not exists or inactive, if active exact match found then skip</li>
051         * <li>Insert one/multiple entries into CB_PUR_LN_AST_ACCT_T, amount should match exact from account line history</li>
052         * 
053         * @see org.kuali.kfs.batch.Step#execute(java.lang.String, java.util.Date)
054         */
055        public boolean execute(String jobName, Date jobRunDate) throws InterruptedException {
056            ExtractProcessLog processLog = new ExtractProcessLog();
057            try {
058                Timestamp startTs = dateTimeService.getCurrentTimestamp();
059                LOG.info("CAB extract started at " + startTs);
060                processLog.setStartTime(startTs);
061                Collection<Entry> elgibleGLEntries = batchExtractService.findElgibleGLEntries(processLog);
062    
063                if (elgibleGLEntries != null && !elgibleGLEntries.isEmpty()) {
064                    List<Entry> fpLines = new ArrayList<Entry>();
065                    List<Entry> purapLines = new ArrayList<Entry>();
066                    // Separate PO lines
067                    batchExtractService.separatePOLines(fpLines, purapLines, elgibleGLEntries);
068                    // Save the Non-PO lines
069                    batchExtractService.saveFPLines(fpLines, processLog);
070                    // Save the PO lines
071                    HashSet<PurchasingAccountsPayableDocument> purApDocuments = batchExtractService.savePOLines(purapLines, processLog);
072    
073                    // call allocate additional charges( not including trade-in lines) during batch. if comment out this line, CAB users
074                    // will see them on the screen and they will have to manually allocate the additional charge lines.
075                    batchExtractService.allocateAdditionalCharges(purApDocuments);
076    
077                    // Set the log values
078                    processLog.setTotalGlCount(elgibleGLEntries.size());
079                    processLog.setNonPurApGlCount(fpLines.size());
080                    processLog.setPurApGlCount(purapLines.size());
081                    // Update the last extract time stamp
082                    batchExtractService.updateLastExtractTime(startTs);
083                    LOG.info("CAB batch finished at " + dateTimeService.getCurrentTimestamp());
084                    processLog.setFinishTime(dateTimeService.getCurrentTimestamp());
085                    processLog.setSuccess(true);
086                }
087                else {
088                    LOG.warn("****** No records processed during CAB Extract *******");
089                    processLog.setSuccess(false);
090                    processLog.setErrorMessage("No GL records were found for CAB processing.");
091                }
092                processLog.setFinishTime(dateTimeService.getCurrentTimestamp());
093            }
094            catch (Throwable e) {
095                processLog.setSuccess(false);
096                processLog.setErrorMessage("Unexpected error occured while performing CAB Extract. " + e.toString());
097                LOG.error("Unexpected error occured while performing CAB Extract.", e);
098                new RuntimeException(e);
099            }
100            finally {
101                batchExtractReportService.generateStatusReportPDF(processLog);
102                // create mismatch report if necessary
103                if (processLog.getMismatchedGLEntries() != null && !processLog.getMismatchedGLEntries().isEmpty()) {
104                    batchExtractReportService.generateMismatchReportPDF(processLog);
105                }
106                LOG.info("Batch status report is generated successfully.");
107            }
108            return true;
109        }
110    
111        /**
112         * Gets the batchExtractService attribute.
113         * 
114         * @return Returns the batchExtractService.
115         */
116        public BatchExtractService getBatchExtractService() {
117            return batchExtractService;
118        }
119    
120        /**
121         * Sets the batchExtractService attribute value.
122         * 
123         * @param batchExtractService The batchExtractService to set.
124         */
125        public void setBatchExtractService(BatchExtractService batchExtractService) {
126            this.batchExtractService = batchExtractService;
127        }
128    
129        /**
130         * Gets the dateTimeService attribute.
131         * 
132         * @return Returns the dateTimeService.
133         */
134        public DateTimeService getDateTimeService() {
135            return dateTimeService;
136        }
137    
138        /**
139         * Sets the dateTimeService attribute value.
140         * 
141         * @param dateTimeService The dateTimeService to set.
142         */
143        public void setDateTimeService(DateTimeService dateTimeService) {
144            this.dateTimeService = dateTimeService;
145        }
146    
147        /**
148         * Gets the batchExtractReportService attribute.
149         * 
150         * @return Returns the batchExtractReportService.
151         */
152        public BatchExtractReportService getBatchExtractReportService() {
153            return batchExtractReportService;
154        }
155    
156        /**
157         * Sets the batchExtractReportService attribute value.
158         * 
159         * @param batchExtractReportService The batchExtractReportService to set.
160         */
161        public void setBatchExtractReportService(BatchExtractReportService batchExtractReportService) {
162            this.batchExtractReportService = batchExtractReportService;
163        }
164    
165    
166    }