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;
017    
018    import java.util.HashMap;
019    import java.util.List;
020    import java.util.Map;
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.kuali.kfs.integration.ld.LaborLedgerPendingEntryForSearching;
024    import org.kuali.kfs.module.ld.businessobject.ExpenseTransferSourceAccountingLine;
025    import org.kuali.kfs.module.ld.businessobject.ExpenseTransferTargetAccountingLine;
026    import org.kuali.kfs.sys.KFSConstants;
027    import org.kuali.kfs.sys.businessobject.AccountingLine;
028    import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
029    import org.kuali.kfs.sys.context.SpringContext;
030    import org.kuali.kfs.sys.document.AmountTotaling;
031    import org.kuali.kfs.sys.document.Correctable;
032    import org.kuali.kfs.sys.document.validation.event.AccountingDocumentSaveWithNoLedgerEntryGenerationEvent;
033    import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService;
034    import org.kuali.rice.kim.bo.Person;
035    import org.kuali.rice.kim.service.PersonService;
036    import org.kuali.rice.kns.document.Copyable;
037    import org.kuali.rice.kns.exception.ValidationException;
038    import org.kuali.rice.kns.rule.event.KualiDocumentEvent;
039    import org.kuali.rice.kns.util.KualiDecimal;
040    
041    /**
042     * Labor Base class for Expense Transfer Documents
043     */
044    public abstract class LaborExpenseTransferDocumentBase extends LaborLedgerPostingDocumentBase implements AmountTotaling, Copyable, Correctable, LaborExpenseTransferDocument {
045        protected static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory.getLog(LaborExpenseTransferDocumentBase.class);
046        protected String emplid;
047        protected Person user;
048    
049        /**
050         * Constructor
051         */
052    
053        public LaborExpenseTransferDocumentBase() {
054            super();
055        }
056    
057        /**
058         * Determine whether target accouting lines have the same amounts as source accounting lines for each object code
059         * 
060         * @return true if target accouting lines have the same amounts as source accounting lines for each object code; otherwise,
061         *         false
062         */
063        public Map<String, KualiDecimal> getUnbalancedObjectCodes() {
064            Map<String, KualiDecimal> amountsFromSourceLine = summerizeByObjectCode(getSourceAccountingLines());
065            Map<String, KualiDecimal> amountsFromTargetLine = summerizeByObjectCode(getTargetAccountingLines());
066    
067            Map<String, KualiDecimal> unbalancedAmounts = new HashMap<String, KualiDecimal>();
068            for (String objectCode : amountsFromSourceLine.keySet()) {
069                KualiDecimal sourceAmount = amountsFromSourceLine.get(objectCode);
070    
071                if (!amountsFromTargetLine.containsKey(objectCode)) {
072                    unbalancedAmounts.put(objectCode, sourceAmount.negated());
073                }
074                else {
075                    KualiDecimal targetAmount = amountsFromTargetLine.get(objectCode);
076                    KualiDecimal amountDifference = targetAmount.subtract(sourceAmount);
077                    if (amountDifference.isNonZero()) {
078                        unbalancedAmounts.put(objectCode, amountDifference);
079                    }
080                }
081            }
082    
083            for (String objectCode : amountsFromTargetLine.keySet()) {
084                if (!amountsFromSourceLine.containsKey(objectCode)) {
085                    KualiDecimal targetAmount = amountsFromTargetLine.get(objectCode);
086                    unbalancedAmounts.put(objectCode, targetAmount);
087                }
088            }
089    
090            return unbalancedAmounts;
091        }
092    
093        /**
094         * summerize the amounts of accounting lines by object codes
095         * 
096         * @param accountingLines the given accounting line list
097         * @return the summerized amounts by object codes
098         */
099        protected Map<String, KualiDecimal> summerizeByObjectCode(List accountingLines) {
100            Map<String, KualiDecimal> amountByObjectCode = new HashMap<String, KualiDecimal>();
101    
102            for (Object accountingLine : accountingLines) {
103                AccountingLine line = (AccountingLine) accountingLine;
104                String objectCode = line.getFinancialObjectCode();
105                KualiDecimal amount = line.getAmount();
106    
107                if (amountByObjectCode.containsKey(objectCode)) {
108                    amount = amount.add(amountByObjectCode.get(objectCode));
109                }
110                amountByObjectCode.put(objectCode, amount);
111            }
112    
113            return amountByObjectCode;
114        }
115    
116        /**
117         * Gets the emplid
118         * 
119         * @return Returns the emplid.
120         * @see org.kuali.kfs.module.ld.document.LaborExpenseTransferDocument#getEmplid()
121         */
122        public String getEmplid() {
123            return emplid;
124        }
125    
126        /**
127         * Sets the emplid
128         * 
129         * @see org.kuali.kfs.module.ld.document.LaborExpenseTransferDocument#setEmplid(String)
130         * @param emplid
131         */
132        public void setEmplid(String emplid) {
133            this.emplid = emplid;
134        }
135        
136        /**
137         * Gets the user attribute. 
138         * @return Returns the user.
139         */
140        public Person getUser() {
141            if(user == null || !StringUtils.equals(user.getEmployeeId(), emplid)) {
142                this.user = SpringContext.getBean(PersonService.class).getPersonByEmployeeId(emplid);
143            }
144            
145            return user;
146        }
147    
148        /**
149         * Sets the user attribute value.
150         * @param user The user to set.
151         */
152        public void setUser(Person user) {
153            this.user = user;
154        }    
155    
156        /**
157         * Overrides the base implementation to return "From".
158         * 
159         * @see org.kuali.rice.kns.document.AccountingDocument#getSourceAccountingLinesSectionTitle()
160         */
161        public String getSourceAccountingLinesSectionTitle() {
162            return KFSConstants.FROM;
163        }
164    
165        /**
166         * Overrides the base implementation to return "To".
167         * 
168         * @see org.kuali.rice.kns.document.AccountingDocument#getTargetAccountingLinesSectionTitle()
169         */
170        public String getTargetAccountingLinesSectionTitle() {
171            return KFSConstants.TO;
172        }
173    
174        /**
175         * @return Returns the ExpenseTransferSourceAccountingLine
176         * @see org.kuali.kfs.sys.document.AccountingDocumentBase#getSourceAccountingLineClass()
177         */
178        public Class getSourceAccountingLineClass() {
179            return ExpenseTransferSourceAccountingLine.class;
180        }
181    
182        /**
183         * @return Returns the ExpenseTransferTargetAccountingLine
184         * @see org.kuali.kfs.sys.document.AccountingDocumentBase#getTargetAccountingLineClass()
185         */
186        public Class getTargetAccountingLineClass() {
187            return ExpenseTransferTargetAccountingLine.class;
188        }
189        
190    }