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.service.impl;
017    
018    import java.util.ArrayList;
019    import java.util.Arrays;
020    import java.util.Collection;
021    import java.util.HashMap;
022    import java.util.List;
023    import java.util.Map;
024    import java.util.Set;
025    
026    import org.apache.commons.lang.StringUtils;
027    import org.kuali.kfs.coa.businessobject.ObjectCode;
028    import org.kuali.kfs.integration.ld.LaborLedgerBalance;
029    import org.kuali.kfs.integration.ld.LaborLedgerExpenseTransferAccountingLine;
030    import org.kuali.kfs.integration.ld.LaborLedgerObject;
031    import org.kuali.kfs.integration.ld.LaborLedgerPositionObjectBenefit;
032    import org.kuali.kfs.integration.ld.LaborLedgerPositionObjectGroup;
033    import org.kuali.kfs.integration.ld.LaborModuleService;
034    import org.kuali.kfs.module.ld.LaborPropertyConstants;
035    import org.kuali.kfs.module.ld.businessobject.LaborLedgerPendingEntry;
036    import org.kuali.kfs.module.ld.businessobject.LedgerBalance;
037    import org.kuali.kfs.module.ld.document.SalaryExpenseTransferDocument;
038    import org.kuali.kfs.module.ld.service.LaborBenefitsCalculationService;
039    import org.kuali.kfs.module.ld.service.LaborLedgerBalanceService;
040    import org.kuali.kfs.module.ld.service.LaborLedgerEntryService;
041    import org.kuali.kfs.module.ld.service.LaborLedgerPendingEntryService;
042    import org.kuali.kfs.module.ld.service.LaborOriginEntryService;
043    import org.kuali.kfs.sys.KFSConstants;
044    import org.kuali.kfs.sys.KFSPropertyConstants;
045    import org.kuali.kfs.sys.context.SpringContext;
046    import org.kuali.kfs.sys.service.UniversityDateService;
047    import org.kuali.rice.kew.exception.WorkflowException;
048    import org.kuali.rice.kns.bo.DocumentHeader;
049    import org.kuali.rice.kns.rule.event.SaveDocumentEvent;
050    import org.kuali.rice.kns.service.BusinessObjectService;
051    import org.kuali.rice.kns.service.DataDictionaryService;
052    import org.kuali.rice.kns.service.DocumentService;
053    import org.kuali.rice.kns.service.KualiModuleService;
054    import org.kuali.rice.kns.util.GlobalVariables;
055    import org.kuali.rice.kns.util.KualiDecimal;
056    import org.kuali.rice.kns.workflow.service.WorkflowDocumentService;
057    import org.springframework.transaction.annotation.Transactional;
058    
059    /**
060     * This implements the service methods that may be used by outside of labor module
061     */
062    @Transactional
063    public class LaborModuleServiceImpl implements LaborModuleService {
064        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LaborModuleServiceImpl.class);
065    
066        /**
067         * @see org.kuali.kfs.integration.ld.LaborModuleService#calculateFringeBenefitFromLaborObject(org.kuali.kfs.integration.ld.LaborLedgerObject,
068         *      org.kuali.rice.kns.util.KualiDecimal)
069         */
070        public KualiDecimal calculateFringeBenefitFromLaborObject(LaborLedgerObject laborLedgerObject, KualiDecimal salaryAmount) {
071            return getLaborBenefitsCalculationService().calculateFringeBenefit(laborLedgerObject, salaryAmount);
072        }
073    
074        /**
075         * @see org.kuali.kfs.integration.ld.LaborModuleService#calculateFringeBenefit(java.lang.Integer, java.lang.String,
076         *      java.lang.String, org.kuali.rice.kns.util.KualiDecimal)
077         */
078        public KualiDecimal calculateFringeBenefit(Integer fiscalYear, String chartCode, String objectCode, KualiDecimal salaryAmount) {
079            return getLaborBenefitsCalculationService().calculateFringeBenefit(fiscalYear, chartCode, objectCode, salaryAmount);
080        }
081    
082        /**
083         * @see org.kuali.kfs.integration.ld.LaborModuleService#createAndBlankApproveSalaryExpenseTransferDocument(java.lang.String,
084         *      java.lang.String, java.lang.String, java.util.List, java.util.List, java.util.List)
085         */
086        public void createAndBlankApproveSalaryExpenseTransferDocument(String documentDescription, String explanation, String annotation, List<String> adHocRecipients, List<LaborLedgerExpenseTransferAccountingLine> sourceAccountingLines, List<LaborLedgerExpenseTransferAccountingLine> targetAccountingLines) throws WorkflowException {
087            LOG.info("createSalaryExpenseTransferDocument() start");
088    
089            if (sourceAccountingLines == null || sourceAccountingLines.isEmpty()) {
090                LOG.info("Cannot create a salary expense document when the given source accounting line is empty.");
091                return;
092            }
093    
094            if (targetAccountingLines == null || targetAccountingLines.isEmpty()) {
095                LOG.info("Cannot create a salary expense document when the given target accounting line is empty.");
096                return;
097            }
098    
099            WorkflowDocumentService workflowDocumentService = SpringContext.getBean(WorkflowDocumentService.class);
100            SalaryExpenseTransferDocument document = (SalaryExpenseTransferDocument) getDocumentService().getNewDocument(SalaryExpenseTransferDocument.class);
101    
102            document.setEmplid(sourceAccountingLines.get(0).getEmplid());
103            document.setSourceAccountingLines(sourceAccountingLines);
104            document.setTargetAccountingLines(targetAccountingLines);
105    
106            DocumentHeader documentHeader = document.getDocumentHeader();
107            documentHeader.setDocumentDescription(documentDescription);
108            documentHeader.setExplanation(explanation);
109    
110            document.prepareForSave(new SaveDocumentEvent(document));
111            document.populateDocumentForRouting();
112    
113            String documentTitle = document.getDocumentTitle();
114            if (StringUtils.isNotBlank(documentTitle)) {
115                document.getDocumentHeader().getWorkflowDocument().setTitle(documentTitle);
116            }
117    
118            String organizationDocumentNumber = document.getDocumentHeader().getOrganizationDocumentNumber();
119            if (StringUtils.isNotBlank(organizationDocumentNumber)) {
120                document.getDocumentHeader().getWorkflowDocument().setAppDocId(organizationDocumentNumber);
121            }
122    
123            this.getBusinessObjectService().save(document);
124    
125            workflowDocumentService.blanketApprove(document.getDocumentHeader().getWorkflowDocument(), annotation, adHocRecipients);
126            GlobalVariables.getUserSession().setWorkflowDocument(document.getDocumentHeader().getWorkflowDocument());
127        }
128    
129        /**
130         * @see org.kuali.kfs.integration.ld.LaborModuleService#countPendingSalaryExpenseTransfer(java.lang.String)
131         */
132        public int countPendingSalaryExpenseTransfer(String emplid) {
133            Map<String, Object> positiveFieldValues = new HashMap<String, Object>();
134            positiveFieldValues.put(KFSPropertyConstants.EMPLID, emplid);
135            positiveFieldValues.put(KFSPropertyConstants.FINANCIAL_DOCUMENT_TYPE_CODE, KFSConstants.FinancialDocumentTypeCodes.SALARY_EXPENSE_TRANSFER);
136    
137            List<String> approvedCodes = Arrays.asList(KFSConstants.PENDING_ENTRY_APPROVED_STATUS_CODE.APPROVED, KFSConstants.PENDING_ENTRY_APPROVED_STATUS_CODE.PROCESSED);
138            Map<String, Object> negativeFieldValues = new HashMap<String, Object>();
139            negativeFieldValues.put(KFSPropertyConstants.FINANCIAL_DOCUMENT_APPROVED_CODE, approvedCodes);
140    
141            return getBusinessObjectService().countMatching(LaborLedgerPendingEntry.class, positiveFieldValues, negativeFieldValues);
142        }
143    
144        /**
145         * @see org.kuali.kfs.integration.ld.LaborModuleService#findEmployeesWithPayType(java.util.Map, java.util.List, java.util.Map)
146         */
147        public List<String> findEmployeesWithPayType(Map<Integer, Set<String>> payPeriods, List<String> balanceTypes, Map<String, Set<String>> earnCodePayGroupMap) {
148            return getLaborLedgerEntryService().findEmployeesWithPayType(payPeriods, balanceTypes, earnCodePayGroupMap);
149        }
150    
151        /**
152         * @see org.kuali.kfs.integration.ld.LaborModuleService#isEmployeeWithPayType(java.lang.String, java.util.Map, java.util.List,
153         *      java.util.Map)
154         */
155        public boolean isEmployeeWithPayType(String emplid, Map<Integer, Set<String>> payPeriods, List<String> balanceTypes, Map<String, Set<String>> earnCodePayGroupMap) {
156            return getLaborLedgerEntryService().isEmployeeWithPayType(emplid, payPeriods, balanceTypes, earnCodePayGroupMap);
157        }
158    
159        /**
160         * @see org.kuali.kfs.integration.ld.LaborModuleService#findLedgerBalances(java.util.Map, java.util.Map, java.util.Set,
161         *      java.util.List, java.util.List)
162         */
163        public Collection<LaborLedgerBalance> findLedgerBalances(Map<String, List<String>> fieldValues, Map<String, List<String>> excludedFieldValues, Set<Integer> fiscalYears, List<String> balanceTypes, List<String> positionObjectGroupCodes) {
164            Collection<LaborLedgerBalance> LaborLedgerBalances = new ArrayList<LaborLedgerBalance>();
165    
166            Collection<LedgerBalance> ledgerBalances = getLaborLedgerBalanceService().findLedgerBalances(fieldValues, excludedFieldValues, fiscalYears, balanceTypes, positionObjectGroupCodes);
167            for (LedgerBalance balance : ledgerBalances) {
168                LaborLedgerBalances.add(balance);
169            }
170            return LaborLedgerBalances;
171        }
172    
173        public LaborLedgerPositionObjectGroup getLaborLedgerPositionObjectGroup(String positionObjectGroupCode) {
174            Map<String, Object> primaryKeys = new HashMap<String, Object>();
175            primaryKeys.put(LaborPropertyConstants.POSITION_OBJECT_GROUP_CODE, positionObjectGroupCode);
176    
177            return getKualiModuleService().getResponsibleModuleService(LaborLedgerPositionObjectGroup.class).getExternalizableBusinessObject(LaborLedgerPositionObjectGroup.class, primaryKeys);
178        }
179    
180        /**
181         * @see org.kuali.kfs.integration.service.LaborModuleService#doesLaborLedgerPositionObjectGroupExist(java.lang.String)
182         */
183        public boolean doesLaborLedgerPositionObjectGroupExist(String positionObjectGroupCode) {
184            return this.getLaborLedgerPositionObjectGroup(positionObjectGroupCode) != null;
185        }
186    
187        /**
188         * @see org.kuali.kfs.integration.ld.LaborModuleService#retrieveLaborLedgerObject(java.lang.Integer, java.lang.String,
189         *      java.lang.String)
190         */
191        public LaborLedgerObject retrieveLaborLedgerObject(Integer fiscalYear, String chartOfAccountsCode, String objectCode) {
192            Map<String, Object> searchCriteria = new HashMap<String, Object>();
193            searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, fiscalYear);
194            searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
195            searchCriteria.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, objectCode);
196    
197            return getKualiModuleService().getResponsibleModuleService(LaborLedgerObject.class).getExternalizableBusinessObject(LaborLedgerObject.class, searchCriteria);
198        }
199    
200        /**
201         * @see org.kuali.kfs.integration.ld.LaborModuleService#retrieveLaborLedgerObject(org.kuali.kfs.coa.businessobject.ObjectCode)
202         */
203        public LaborLedgerObject retrieveLaborLedgerObject(ObjectCode financialObject) {
204            if (financialObject == null) {
205                throw new IllegalArgumentException("The given financial object cannot be null.");
206            }
207    
208            Integer fiscalYear = financialObject.getUniversityFiscalYear();
209            String chartOfAccountsCode = financialObject.getChartOfAccountsCode();
210            String financialObjectCode = financialObject.getFinancialObjectCode();
211    
212            return this.retrieveLaborLedgerObject(fiscalYear, chartOfAccountsCode, financialObjectCode);
213        }
214    
215        /**
216         * @see org.kuali.kfs.integration.ld.LaborModuleService#hasPendingLaborLedgerEntry(java.lang.String, java.lang.String)
217         */
218        public boolean hasPendingLaborLedgerEntry(String chartOfAccountsCode, String accountNumber) {
219            return getLaborLedgerPendingEntryService().hasPendingLaborLedgerEntry(chartOfAccountsCode, accountNumber);
220        }
221    
222        /**
223         * @see org.kuali.kfs.integration.ld.LaborModuleService#retrieveLaborPositionObjectBenefits(java.lang.Integer, java.lang.String,
224         *      java.lang.String)
225         */
226        public List<LaborLedgerPositionObjectBenefit> retrieveLaborPositionObjectBenefits(Integer fiscalYear, String chartOfAccountsCode, String objectCode) {
227            Map<String, Object> searchCriteria = new HashMap<String, Object>();
228    
229            searchCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, fiscalYear);
230            searchCriteria.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
231            searchCriteria.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, objectCode);
232    
233            return getKualiModuleService().getResponsibleModuleService(LaborLedgerPositionObjectBenefit.class).getExternalizableBusinessObjectsList(LaborLedgerPositionObjectBenefit.class, searchCriteria);
234        }
235    
236        /**
237         * @see org.kuali.kfs.integration.ld.LaborModuleService#hasFringeBenefitProducingObjectCodes(java.lang.Integer,
238         *      java.lang.String, java.lang.String)
239         */
240        public boolean hasFringeBenefitProducingObjectCodes(Integer fiscalYear, String chartOfAccountsCode, String financialObjectCode) {
241            List<LaborLedgerPositionObjectBenefit> objectBenefits = this.retrieveLaborPositionObjectBenefits(fiscalYear, chartOfAccountsCode, financialObjectCode);
242            return (objectBenefits != null && !objectBenefits.isEmpty());
243        }
244    
245        /**
246         * @see org.kuali.kfs.integration.ld.LaborModuleService#getLaborOriginEntryGroupCount(java.lang.Integer)
247         */
248    //    public Integer getLaborOriginEntryGroupCount(Integer groupId) {
249    //        return getLaborOriginEntryService().getGroupCount(groupId);
250    //    }
251    
252        /**
253         * Gets the laborBenefitsCalculationService attribute.
254         * 
255         * @return an implementation of the laborBenefitsCalculationService.
256         */
257        public LaborBenefitsCalculationService getLaborBenefitsCalculationService() {
258            return SpringContext.getBean(LaborBenefitsCalculationService.class);
259        }
260    
261        /**
262         * Gets the laborLedgerEntryService attribute.
263         * 
264         * @return an implementation of the laborLedgerEntryService.
265         */
266        public LaborLedgerEntryService getLaborLedgerEntryService() {
267            return SpringContext.getBean(LaborLedgerEntryService.class);
268        }
269    
270        /**
271         * Gets the laborLedgerBalanceService attribute.
272         * 
273         * @return an implementation of the laborLedgerBalanceService.
274         */
275        public LaborLedgerBalanceService getLaborLedgerBalanceService() {
276            return SpringContext.getBean(LaborLedgerBalanceService.class);
277        }
278    
279        /**
280         * Gets the documentService attribute.
281         * 
282         * @return an implementation of the documentService.
283         */
284        public DocumentService getDocumentService() {
285            return SpringContext.getBean(DocumentService.class);
286        }
287    
288        /**
289         * Gets the dataDictionaryService attribute.
290         * 
291         * @return an implementation of the dataDictionaryService.
292         */
293        public DataDictionaryService getDataDictionaryService() {
294            return SpringContext.getBean(DataDictionaryService.class);
295        }
296    
297        /**
298         * Gets the universityDateService attribute.
299         * 
300         * @return an implementation of the universityDateService.
301         */
302        public UniversityDateService getUniversityDateService() {
303            return SpringContext.getBean(UniversityDateService.class);
304        }
305    
306        /**
307         * Gets the businessObjectService attribute.
308         * 
309         * @return an implementation of the businessObjectService.
310         */
311        public BusinessObjectService getBusinessObjectService() {
312            return SpringContext.getBean(BusinessObjectService.class);
313        }
314    
315        /**
316         * Gets the laborLedgerPendingEntryService
317         * 
318         * @return an implementation of the LaborLedgerPendingEntryService
319         */
320        public LaborLedgerPendingEntryService getLaborLedgerPendingEntryService() {
321            return SpringContext.getBean(LaborLedgerPendingEntryService.class);
322        }
323    
324        /**
325         * Returns an instance of the LaborOriginEntryService, for use by services in the module
326         * 
327         * @return an instance of an implementation of the LaborOriginEntryService
328         */
329        public LaborOriginEntryService getLaborOriginEntryService() {
330            return SpringContext.getBean(LaborOriginEntryService.class);
331        }
332    
333        /**
334         * Gets the KualiModuleService attribute value.
335         * 
336         * @return an implementation of the KualiModuleService.
337         */
338        public KualiModuleService getKualiModuleService() {
339            return SpringContext.getBean(KualiModuleService.class);
340        }
341    }