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.ld.document.service.impl;
017    
018    import java.sql.Date;
019    
020    import org.apache.commons.lang.StringUtils;
021    import org.kuali.kfs.coa.businessobject.ObjectCode;
022    import org.kuali.kfs.coa.service.ObjectCodeService;
023    import org.kuali.kfs.fp.document.YearEndDocument;
024    import org.kuali.kfs.fp.document.service.YearEndPendingEntryService;
025    import org.kuali.kfs.module.ld.LaborConstants;
026    import org.kuali.kfs.module.ld.businessobject.BenefitsCalculation;
027    import org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine;
028    import org.kuali.kfs.module.ld.businessobject.LaborLedgerPendingEntry;
029    import org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument;
030    import org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService;
031    import org.kuali.kfs.module.ld.service.LaborBenefitsCalculationService;
032    import org.kuali.kfs.module.ld.util.DebitCreditUtil;
033    import org.kuali.kfs.sys.KFSConstants;
034    import org.kuali.kfs.sys.KFSPropertyConstants;
035    import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
036    import org.kuali.kfs.sys.service.HomeOriginationService;
037    import org.kuali.kfs.sys.service.OptionsService;
038    import org.kuali.rice.kns.bo.DocumentHeader;
039    import org.kuali.rice.kns.service.DataDictionaryService;
040    import org.kuali.rice.kns.service.DateTimeService;
041    import org.kuali.rice.kns.util.KualiDecimal;
042    
043    /**
044     * Default implementation of the LaborPendingEntryConverterService
045     */
046    public class LaborPendingEntryConverterServiceImpl implements LaborPendingEntryConverterService {
047        protected HomeOriginationService homeOriginationService;
048        protected LaborBenefitsCalculationService laborBenefitsCalculationService;
049        protected OptionsService optionsService;
050        protected ObjectCodeService objectCodeService;
051        protected DataDictionaryService dataDictionaryService;
052        protected DateTimeService dateTimeService;
053        protected YearEndPendingEntryService yearEndPendingEntryService;
054    
055        /**
056         * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getBenefitA21PendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, org.kuali.rice.kns.util.KualiDecimal, java.lang.String)
057         */
058        public LaborLedgerPendingEntry getBenefitA21PendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, KualiDecimal benefitAmount, String fringeBenefitObjectCode) {
059            LaborLedgerPendingEntry pendingEntry = getBenefitPendingEntry(document, accountingLine, sequenceHelper, benefitAmount, fringeBenefitObjectCode);
060    
061            pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_A21);
062            String debitCreditCode = DebitCreditUtil.getReverseDebitCreditCode(pendingEntry.getTransactionDebitCreditCode());
063            pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
064    
065            return pendingEntry;
066        }
067    
068        /**
069         * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getBenefitA21ReversalPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, org.kuali.rice.kns.util.KualiDecimal, java.lang.String)
070         */
071        public LaborLedgerPendingEntry getBenefitA21ReversalPendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, KualiDecimal benefitAmount, String fringeBenefitObjectCode) {
072            LaborLedgerPendingEntry pendingEntry = getBenefitA21PendingEntry(document, accountingLine, sequenceHelper, benefitAmount, fringeBenefitObjectCode);
073    
074            pendingEntry.setUniversityFiscalYear(accountingLine.getPayrollEndDateFiscalYear());
075            pendingEntry.setUniversityFiscalPeriodCode(accountingLine.getPayrollEndDateFiscalPeriodCode());
076    
077            String debitCreditCode = DebitCreditUtil.getReverseDebitCreditCode(pendingEntry.getTransactionDebitCreditCode());
078            pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
079    
080            return pendingEntry;
081        }
082    
083        /**
084         * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getBenefitClearingPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, java.lang.String, java.lang.String, java.lang.String, org.kuali.rice.kns.util.KualiDecimal)
085         */
086        public LaborLedgerPendingEntry getBenefitClearingPendingEntry(LaborLedgerPostingDocument document, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, String accountNumber, String chartOfAccountsCode, String benefitTypeCode, KualiDecimal clearingAmount) {
087            LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(document);
088    
089            pendingEntry.setChartOfAccountsCode(chartOfAccountsCode);
090            pendingEntry.setAccountNumber(accountNumber);
091            pendingEntry.setSubAccountNumber(KFSConstants.getDashSubAccountNumber());
092            pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL);
093    
094            Integer fiscalYear = getOptionsService().getCurrentYearOptions().getUniversityFiscalYear();
095            BenefitsCalculation benefitsCalculation = getLaborBenefitsCalculationService().getBenefitsCalculation(fiscalYear, chartOfAccountsCode, benefitTypeCode);
096            String objectCode = benefitsCalculation.getPositionFringeBenefitObjectCode();
097            pendingEntry.setFinancialObjectCode(objectCode);
098    
099            ObjectCode oc = getObjectCodeService().getByPrimaryId(fiscalYear, chartOfAccountsCode, objectCode);
100            pendingEntry.setFinancialObjectTypeCode(oc.getFinancialObjectTypeCode());
101    
102            pendingEntry.setFinancialSubObjectCode(KFSConstants.getDashFinancialSubObjectCode());
103            pendingEntry.setTransactionLedgerEntrySequenceNumber(getNextSequenceNumber(sequenceHelper));
104    
105            String debitCreditCode = DebitCreditUtil.getDebitCreditCode(clearingAmount, false);
106            pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
107            pendingEntry.setTransactionLedgerEntryAmount(clearingAmount.abs());
108    
109            pendingEntry.setProjectCode(KFSConstants.getDashProjectCode());
110            pendingEntry.setPositionNumber(LaborConstants.getDashPositionNumber());
111            pendingEntry.setEmplid(LaborConstants.getDashEmplId());
112            pendingEntry.setTransactionTotalHours(null);
113    
114            overrideEntryForYearEndIfNecessary(document, pendingEntry);
115    
116            return pendingEntry;
117        }
118        
119        /**
120         * Updates the given LLPE for year end documents
121         * @param document the document to check if it is YearEnd
122         * @param pendingEntry the pending entry to update
123         */
124        protected void overrideEntryForYearEndIfNecessary(LaborLedgerPostingDocument document, LaborLedgerPendingEntry pendingEntry) {
125            // year end document should post to previous fiscal year and final period
126            if (document instanceof YearEndDocument) {
127                pendingEntry.setUniversityFiscalYear(getYearEndPendingEntryService().getPreviousFiscalYear());
128                pendingEntry.setUniversityFiscalPeriodCode(getYearEndPendingEntryService().getFinalAccountingPeriod());
129            }
130        }
131    
132        /**
133         * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getBenefitPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, org.kuali.rice.kns.util.KualiDecimal, java.lang.String)
134         */
135        public LaborLedgerPendingEntry getBenefitPendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, KualiDecimal benefitAmount, String fringeBenefitObjectCode) {
136            LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(document, accountingLine);
137    
138            // if account doesn't accept fringe charges, use reports to account
139            if (!accountingLine.getAccount().isAccountsFringesBnftIndicator()) {
140                pendingEntry.setChartOfAccountsCode(accountingLine.getAccount().getReportsToChartOfAccountsCode());
141                pendingEntry.setAccountNumber(accountingLine.getAccount().getReportsToAccountNumber());
142            }
143    
144            pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL);
145            pendingEntry.setFinancialObjectCode(pickValue(fringeBenefitObjectCode, KFSConstants.getDashFinancialObjectCode()));
146    
147            ObjectCode fringeObjectCode = getObjectCodeService().getByPrimaryId(accountingLine.getPayrollEndDateFiscalYear(), accountingLine.getChartOfAccountsCode(), fringeBenefitObjectCode);
148            pendingEntry.setFinancialObjectTypeCode(fringeObjectCode.getFinancialObjectTypeCode());
149    
150            pendingEntry.setFinancialSubObjectCode(KFSConstants.getDashFinancialSubObjectCode());
151            pendingEntry.setTransactionLedgerEntryAmount(benefitAmount.abs());
152            pendingEntry.setPositionNumber(LaborConstants.getDashPositionNumber());
153            pendingEntry.setEmplid(LaborConstants.getDashEmplId());
154            pendingEntry.setTransactionLedgerEntrySequenceNumber(getNextSequenceNumber(sequenceHelper));
155    
156            // year end document should post to previous fiscal year and final period
157            overrideEntryForYearEndIfNecessary(document, pendingEntry);
158    
159            return pendingEntry;
160        }
161    
162        /**
163         * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getDefaultPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine)
164         */
165        public LaborLedgerPendingEntry getDefaultPendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine) {
166            LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(document);
167    
168            pendingEntry.setChartOfAccountsCode(accountingLine.getChartOfAccountsCode());
169            pendingEntry.setAccountNumber(accountingLine.getAccountNumber());
170            pendingEntry.setFinancialObjectCode(accountingLine.getFinancialObjectCode());
171    
172            String subAccountNumber = pickValue(accountingLine.getSubAccountNumber(), KFSConstants.getDashSubAccountNumber());
173            pendingEntry.setSubAccountNumber(subAccountNumber);
174    
175            String subObjectCode = pickValue(accountingLine.getFinancialSubObjectCode(), KFSConstants.getDashFinancialSubObjectCode());
176            pendingEntry.setFinancialSubObjectCode(subObjectCode);
177    
178            String projectCode = pickValue(accountingLine.getProjectCode(), KFSConstants.getDashProjectCode());
179            pendingEntry.setProjectCode(projectCode);
180    
181            accountingLine.refreshReferenceObject(KFSPropertyConstants.OBJECT_CODE);
182            String objectTypeCode = accountingLine.getObjectCode().getFinancialObjectTypeCode();
183            pendingEntry.setFinancialObjectTypeCode(objectTypeCode);
184    
185            KualiDecimal transactionAmount = accountingLine.getAmount();
186            String debitCreditCode = DebitCreditUtil.getDebitCreditCodeForExpenseDocument(accountingLine);
187            pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
188            pendingEntry.setTransactionLedgerEntryAmount(transactionAmount.abs());
189    
190            pendingEntry.setPositionNumber(accountingLine.getPositionNumber());
191            pendingEntry.setEmplid(accountingLine.getEmplid());
192            pendingEntry.setPayrollEndDateFiscalYear(accountingLine.getPayrollEndDateFiscalYear());
193            pendingEntry.setPayrollEndDateFiscalPeriodCode(accountingLine.getPayrollEndDateFiscalPeriodCode());
194            pendingEntry.setTransactionTotalHours(accountingLine.getPayrollTotalHours());
195            pendingEntry.setOrganizationReferenceId(accountingLine.getOrganizationReferenceId());
196    
197            return pendingEntry;
198        }
199    
200        /**
201         * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getDefaultPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument)
202         */
203        public LaborLedgerPendingEntry getDefaultPendingEntry(LaborLedgerPostingDocument document) {
204            LaborLedgerPendingEntry pendingEntry = getSimpleDefaultPendingEntry();
205            DocumentHeader documentHeader = document.getDocumentHeader();
206    
207            String documentTypeCode = getDataDictionaryService().getDocumentTypeNameByClass(document.getClass());
208            pendingEntry.setFinancialDocumentTypeCode(documentTypeCode);
209    
210            pendingEntry.setDocumentNumber(documentHeader.getDocumentNumber());
211            pendingEntry.setTransactionLedgerEntryDescription(documentHeader.getDocumentDescription());
212            pendingEntry.setOrganizationDocumentNumber(documentHeader.getOrganizationDocumentNumber());
213    
214            return pendingEntry;
215        }
216    
217        /**
218         * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getExpenseA21PendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper)
219         */
220        public LaborLedgerPendingEntry getExpenseA21PendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
221            LaborLedgerPendingEntry pendingEntry = getExpensePendingEntry(document, accountingLine, sequenceHelper);
222    
223            pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_A21);
224            String debitCreditCode = DebitCreditUtil.getReverseDebitCreditCode(pendingEntry.getTransactionDebitCreditCode());
225            pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
226    
227            return pendingEntry;
228        }
229    
230        /**
231         * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getExpenseA21ReversalPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper)
232         */
233        public LaborLedgerPendingEntry getExpenseA21ReversalPendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
234            LaborLedgerPendingEntry pendingEntry = getExpenseA21PendingEntry(document, accountingLine, sequenceHelper);
235    
236            pendingEntry.setUniversityFiscalYear(accountingLine.getPayrollEndDateFiscalYear());
237            pendingEntry.setUniversityFiscalPeriodCode(accountingLine.getPayrollEndDateFiscalPeriodCode());
238    
239            String debitCreditCode = DebitCreditUtil.getReverseDebitCreditCode(pendingEntry.getTransactionDebitCreditCode());
240            pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
241    
242            return pendingEntry;
243        }
244    
245        /**
246         * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getExpensePendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper)
247         */
248        public LaborLedgerPendingEntry getExpensePendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
249            LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(document, accountingLine);
250    
251            pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL);
252            pendingEntry.setTransactionLedgerEntrySequenceNumber(getNextSequenceNumber(sequenceHelper));
253    
254            // year end document should post to previous fiscal year and final period
255            overrideEntryForYearEndIfNecessary(document, pendingEntry);
256    
257            return pendingEntry;
258        }
259    
260        /**
261         * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getSimpleDefaultPendingEntry()
262         */
263        public LaborLedgerPendingEntry getSimpleDefaultPendingEntry() {
264            LaborLedgerPendingEntry pendingEntry = new LaborLedgerPendingEntry();
265    
266            pendingEntry.setUniversityFiscalYear(null);
267            pendingEntry.setUniversityFiscalPeriodCode(null);
268    
269            String originationCode = getHomeOriginationService().getHomeOrigination().getFinSystemHomeOriginationCode();
270            pendingEntry.setFinancialSystemOriginationCode(originationCode);
271    
272            Date transactionDate = getDateTimeService().getCurrentSqlDate();
273            pendingEntry.setTransactionDate(transactionDate);
274    
275            pendingEntry.setFinancialDocumentReversalDate(null);
276            pendingEntry.setReferenceFinancialSystemOriginationCode(null);
277            pendingEntry.setReferenceFinancialDocumentNumber(null);
278            pendingEntry.setReferenceFinancialDocumentTypeCode(null);
279    
280            return pendingEntry;
281        }
282        
283        /**
284         * Pick one from target and backup values based on the availability of target value
285         * 
286         * @param targetValue the given target value
287         * @param backupValue the backup value of the target value
288         * @return target value if it is not null; otherwise, return its backup
289         */
290        protected String pickValue(String targetValue, String backupValue) {
291            return StringUtils.isNotBlank(targetValue) ? targetValue : backupValue;
292        }
293    
294        /**
295         * This method gets the next sequence number and increments.
296         * 
297         * @param sequenceHelper the given sequence helper
298         * @return the next sequence number and increments
299         */
300        protected Integer getNextSequenceNumber(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
301            Integer nextSequenceNumber = sequenceHelper.getSequenceCounter();
302            sequenceHelper.increment();
303    
304            return nextSequenceNumber;
305        }
306    
307        public HomeOriginationService getHomeOriginationService() {
308            return homeOriginationService;
309        }
310    
311        public void setHomeOriginationService(HomeOriginationService homeOriginationService) {
312            this.homeOriginationService = homeOriginationService;
313        }
314    
315        public LaborBenefitsCalculationService getLaborBenefitsCalculationService() {
316            return laborBenefitsCalculationService;
317        }
318    
319        public void setLaborBenefitsCalculationService(LaborBenefitsCalculationService laborBenefitsCalculationService) {
320            this.laborBenefitsCalculationService = laborBenefitsCalculationService;
321        }
322    
323        public OptionsService getOptionsService() {
324            return optionsService;
325        }
326    
327        public void setOptionsService(OptionsService optionsService) {
328            this.optionsService = optionsService;
329        }
330    
331        public ObjectCodeService getObjectCodeService() {
332            return objectCodeService;
333        }
334    
335        public void setObjectCodeService(ObjectCodeService objectCodeService) {
336            this.objectCodeService = objectCodeService;
337        }
338    
339        public DataDictionaryService getDataDictionaryService() {
340            return dataDictionaryService;
341        }
342    
343        public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
344            this.dataDictionaryService = dataDictionaryService;
345        }
346    
347        public DateTimeService getDateTimeService() {
348            return dateTimeService;
349        }
350    
351        public void setDateTimeService(DateTimeService dateTimeService) {
352            this.dateTimeService = dateTimeService;
353        }
354    
355        public YearEndPendingEntryService getYearEndPendingEntryService() {
356            return yearEndPendingEntryService;
357        }
358    
359        public void setYearEndPendingEntryService(YearEndPendingEntryService yearEndPendingEntryService) {
360            this.yearEndPendingEntryService = yearEndPendingEntryService;
361        }
362    
363    }