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.util;
017    
018    import java.util.ArrayList;
019    import java.util.List;
020    
021    import org.kuali.kfs.module.ld.LaborConstants;
022    import org.kuali.kfs.module.ld.businessobject.LaborOriginEntry;
023    import org.kuali.kfs.sys.KFSConstants;
024    import org.kuali.kfs.sys.KFSPropertyConstants;
025    import org.kuali.kfs.sys.ObjectUtil;
026    import org.kuali.rice.kns.util.KualiDecimal;
027    import org.kuali.rice.kns.util.ObjectUtils;
028    
029    /**
030     * This class is a working unit of labor origin entry. It is formed by a group of slimilar labor origin entries. If any two entries
031     * have the same values for the given fields, then they are similar and can be grouped.
032     */
033    public class LaborLedgerUnitOfWork {
034        private LaborOriginEntry workingEntry;
035        private List<String> keyFields;
036        private int numOfMember;
037    
038        /**
039         * Constructs a LaborLedgerUnitOfWork.java.
040         */
041        public LaborLedgerUnitOfWork() {
042            this(null);
043        }
044    
045        /**
046         * Constructs a LaborLedgerUnitOfWork.java.
047         * 
048         * @param laborOriginEntry the given origin entry
049         */
050        public LaborLedgerUnitOfWork(LaborOriginEntry laborOriginEntry) {
051            this.resetLaborLedgerUnitOfWork(laborOriginEntry);
052        }
053    
054        /**
055         * Intialize the default key fields of the labor ledger unit of work with the given origin entry
056         * 
057         * @param laborOriginEntry the given origin entry
058         */
059        public void resetLaborLedgerUnitOfWork(LaborOriginEntry laborOriginEntry) {
060            this.resetLaborLedgerUnitOfWork(laborOriginEntry, null);
061        }
062    
063        /**
064         * Intialize the specified key fields of the labor ledger unit of work with the given origin entry
065         * 
066         * @param laborOriginEntry the given origin entry
067         * @param keyFields the keys to which values will be assigned
068         */
069        public void resetLaborLedgerUnitOfWork(LaborOriginEntry laborOriginEntry, List<String> keyFields) {
070            this.workingEntry = new LaborOriginEntry();
071            this.setKeyFields(keyFields);
072    
073            if (laborOriginEntry != null) {
074                ObjectUtil.buildObject(workingEntry, laborOriginEntry, this.getKeyFields());
075    
076                boolean creditIndicator = KFSConstants.GL_CREDIT_CODE.equals(laborOriginEntry.getTransactionDebitCreditCode());
077                KualiDecimal entryAmount = laborOriginEntry.getTransactionLedgerEntryAmount();
078                KualiDecimal unitAmount = creditIndicator ? entryAmount.negated() : entryAmount;
079    
080                workingEntry.setTransactionLedgerEntryAmount(unitAmount);
081                workingEntry.setTransactionDebitCreditCode(laborOriginEntry.getTransactionDebitCreditCode());
082                numOfMember = 1;
083            }
084        }
085    
086        /**
087         * add the given origin entry as a member of the working unit
088         * 
089         * @param laborOriginEntry the given origin entry
090         * @return true if the given origin entry is successfully added into the current unit of work; otherwise, false
091         */
092        public boolean addEntryIntoUnit(LaborOriginEntry laborOriginEntry) {
093            if (this.hasSameKey(laborOriginEntry)) {
094                KualiDecimal unitAmount = workingEntry.getTransactionLedgerEntryAmount();
095                KualiDecimal entryAmount = laborOriginEntry.getTransactionLedgerEntryAmount();
096    
097                // if the input entry has a "credit" code , then subtract its amount from the unit total amount
098                boolean creditIndicator = KFSConstants.GL_CREDIT_CODE.equals(laborOriginEntry.getTransactionDebitCreditCode());
099                unitAmount = creditIndicator ? unitAmount.subtract(entryAmount) : unitAmount.add(entryAmount);
100    
101                workingEntry.setTransactionLedgerEntryAmount(unitAmount);
102                numOfMember++;
103    
104                return true;
105            }
106            return false;
107        }
108    
109        /**
110         * Determine if the given origin entry belongs to the current unit of work
111         * 
112         * @param laborOriginEntry the given origin entry
113         * @return true if the given origin entry belongs to the current unit of work; otherwise, false
114         */
115        public boolean canContain(LaborOriginEntry laborOriginEntry) {
116            return this.hasSameKey(laborOriginEntry);
117        }
118    
119        /**
120         * Determine if the given origin entry has the same key as the current unit of work
121         * 
122         * @param laborOriginEntry the given origin entry
123         * @return true if the given origin entry has the same key as the current unit of work; otherwise, false
124         */
125        public boolean hasSameKey(LaborOriginEntry laborOriginEntry) {
126            if(ObjectUtils.isNull(laborOriginEntry)) {
127                return false;
128            }
129            
130            return ObjectUtil.equals(workingEntry, laborOriginEntry, this.getKeyFields());
131        }
132    
133        /**
134         * @see java.lang.Object#toString()
135         */
136        @Override
137        public String toString() {
138            List<String> printablekeyFields = new ArrayList<String>(this.getKeyFields());
139            printablekeyFields.add(KFSPropertyConstants.TRANSACTION_LEDGER_ENTRY_AMOUNT);
140            return ObjectUtil.buildPropertyMap(workingEntry, printablekeyFields).toString();
141        }
142    
143        /**
144         * Gets the workingEntry attribute.
145         * 
146         * @return Returns the workingEntry.
147         */
148        public LaborOriginEntry getWorkingEntry() {
149            return this.workingEntry;
150        }
151    
152        /**
153         * Sets the workingEntry attribute value.
154         * 
155         * @param workingEntry The workingEntry to set.
156         */
157        public void setWorkingEntry(LaborOriginEntry workingEntry) {
158            this.workingEntry = workingEntry;
159        }
160    
161        /**
162         * Gets the keyFields attribute.
163         * 
164         * @return Returns the keyFields.
165         */
166        public List<String> getKeyFields() {
167            return keyFields;
168        }
169    
170        /**
171         * Sets the keyFields attribute value.
172         * 
173         * @param keyFields The keyFields to set.
174         */
175        public void setKeyFields(List<String> keyFields) {
176            this.keyFields = (keyFields != null) ? keyFields : this.getDefaultKeyFields();
177        }
178    
179        /**
180         * Gets the numOfMember attribute.
181         * 
182         * @return Returns the numOfMember.
183         */
184        public int getNumOfMember() {
185            return numOfMember;
186        }
187    
188        /**
189         * Sets the numOfMember attribute value.
190         * 
191         * @param numOfMember The numOfMember to set.
192         */
193        public void setNumOfMember(int numOfMember) {
194            this.numOfMember = numOfMember;
195        }
196    
197        /**
198         * Get the default key fields as a list
199         */
200        protected List<String> getDefaultKeyFields() {
201            List<String> defaultKeyFields = new ArrayList<String>(LaborConstants.consolidationAttributesOfOriginEntry());
202            defaultKeyFields.remove(KFSPropertyConstants.TRANSACTION_LEDGER_ENTRY_AMOUNT);
203            defaultKeyFields.remove(KFSPropertyConstants.TRANSACTION_DEBIT_CREDIT_CODE);
204    
205            return defaultKeyFields;
206        }
207    }