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.fp.service.impl;
017    
018    import java.util.HashMap;
019    import java.util.Map;
020    
021    import org.apache.commons.lang.StringUtils;
022    import org.kuali.kfs.fp.businessobject.CashDrawer;
023    import org.kuali.kfs.fp.service.CashDrawerService;
024    import org.kuali.kfs.sys.KFSConstants;
025    import org.kuali.rice.kns.service.BusinessObjectService;
026    import org.kuali.rice.kns.util.KualiDecimal;
027    import org.springframework.transaction.annotation.Transactional;
028    
029    
030    /**
031     * This is the default implementation of the CashDrawerService interface.
032     */
033    @Transactional
034    public class CashDrawerServiceImpl implements CashDrawerService {
035        private BusinessObjectService businessObjectService;
036        private static final String CAMPUS_CODE_PROPERTY = "campusCode";
037    
038    
039        /**
040         * Retrieves the CashDrawer associated with the campus code provided and sets the state of the drawer to closed.
041         * 
042         * @param campusCode The code of the campus associated with the cash drawer being retrieved.
043         * @see org.kuali.kfs.fp.service.CashDrawerService#closeCashDrawer(java.lang.String)
044         */
045        public void closeCashDrawer(String campusCode) {
046            CashDrawer drawer = getByCampusCode(campusCode);
047            this.closeCashDrawer(drawer);
048        }
049        
050        /**
051         * Sets the status of the drawer provided to closed and saves the new state.
052         * 
053         * @param drawer The instance of the cash drawer to be closed.
054         * @see org.kuali.kfs.fp.service.CashDrawerService#closeCashDrawer(org.kuali.kfs.fp.businessobject.CashDrawer)
055         */
056        public void closeCashDrawer(CashDrawer drawer) {
057            drawer.setStatusCode(KFSConstants.CashDrawerConstants.STATUS_CLOSED);
058            drawer.setReferenceFinancialDocumentNumber(null);
059    
060            save(drawer);
061        }
062    
063        /**
064         * Retrieves an instance of a cash drawer based on the parameters provided and sets the status of the drawer to open, 
065         * persists the state change and then returns an instance of the drawer in it's new state.
066         * 
067         * @param campusCode The campus code associated with the cash drawer we wish to retrieve and open.
068         * @param documentId The id of the reference document linked to the drawer.
069         * @return  A new instance of the cash drawer in open status.
070         * 
071         * @see org.kuali.kfs.fp.service.CashDrawerService#openCashDrawer(java.lang.String, java.lang.String)
072         */
073        public CashDrawer openCashDrawer(String campusCode, String documentId) {
074            if (StringUtils.isBlank(documentId)) {
075                throw new IllegalArgumentException("invalid (blank) documentId");
076            }
077    
078            CashDrawer drawer = getByCampusCode(campusCode);
079            return this.openCashDrawer(drawer, documentId);
080        }
081        
082        /**
083         * Sets the status of the cash drawer provided to open, persists this new state and returns the drawer.
084         * 
085         * @param drawer An instance of the drawer being opened.
086         * @param documentId The id of the reference document linked to the drawer.
087         * @return An instance of the cash drawer with a status of open.
088         * 
089         * @see org.kuali.kfs.fp.service.CashDrawerService#openCashDrawer(org.kuali.kfs.fp.businessobject.CashDrawer, java.lang.String)
090         */
091        public CashDrawer openCashDrawer(CashDrawer drawer, String documentId) {
092            if (StringUtils.isBlank(documentId)) {
093                throw new IllegalArgumentException("invalid (blank) documentId");
094            }
095    
096            drawer.setStatusCode(KFSConstants.CashDrawerConstants.STATUS_OPEN);
097            drawer.setReferenceFinancialDocumentNumber(documentId);
098    
099            save(drawer);
100            return drawer;
101        }
102    
103        /**
104         * Retrieves a cash drawer using the campus code provided, updates the state to locked, then persists this state change.
105         * 
106         * @param campusCode The campus code associated with the cash drawer.
107         * @param documentId The reference document id to be set to the cash drawer.
108         * 
109         * @see org.kuali.kfs.fp.service.CashDrawerService#lockCashDrawer(java.lang.String,java.lang.String)
110         */
111        public void lockCashDrawer(String campusCode, String documentId) {
112            if (StringUtils.isBlank(documentId)) {
113                throw new IllegalArgumentException("invalid (blank) documentId");
114            }
115    
116            CashDrawer drawer = getByCampusCode(campusCode);
117            this.lockCashDrawer(drawer, documentId);
118        }
119        
120        /**
121         * Sets the state of the cash drawer provided to locked and persists this new state.
122         * 
123         * @param drawer The cash drawer to be locked.
124         * @param documentId The reference document id to be set to the cash drawer.
125         * 
126         * @see org.kuali.kfs.fp.service.CashDrawerService#lockCashDrawer(org.kuali.kfs.fp.businessobject.CashDrawer, java.lang.String)
127         */
128        public void lockCashDrawer(CashDrawer drawer, String documentId) {
129            if (StringUtils.isBlank(documentId)) {
130                throw new IllegalArgumentException("invalid (blank) documentId");
131            }
132            
133            if (!StringUtils.equals(KFSConstants.CashDrawerConstants.STATUS_OPEN, drawer.getStatusCode())) {
134                throw new IllegalStateException("CashDrawer '" + drawer.getCampusCode() + "' cannot be locked because it is not open");
135            }
136            if (!StringUtils.equals(documentId, drawer.getReferenceFinancialDocumentNumber())) {
137                throw new IllegalStateException("CashDrawer '" + drawer.getCampusCode() + "' cannot be locked because it was opened by document " + drawer.getReferenceFinancialDocumentNumber());
138            }
139    
140            drawer.setStatusCode(KFSConstants.CashDrawerConstants.STATUS_LOCKED);
141            drawer.setReferenceFinancialDocumentNumber(documentId);
142    
143            save(drawer);
144        }
145    
146        /**
147         * Retrieves a cash drawer using the campus code provided, updates the state to open, then persists this state change.
148         * 
149         * @param campusCode The campus code associated with the cash drawer.
150         * @param documentId The reference document id to be set to the cash drawer.
151         * 
152         * @see org.kuali.kfs.fp.service.CashDrawerService#unlockCashDrawer(java.lang.String,java.lang.String)
153         */
154        public void unlockCashDrawer(String campusCode, String documentId) {
155            if (StringUtils.isBlank(documentId)) {
156                throw new IllegalArgumentException("invalid (blank) documentId");
157            }
158    
159            CashDrawer drawer = getByCampusCode(campusCode);
160            this.unlockCashDrawer(drawer, documentId);
161        }
162    
163        /**
164         * Sets the state of the cash drawer provided to open and persists this new state.
165         * 
166         * @param drawer The cash drawer to be unlocked.
167         * @param documentId The reference document id to be set to the cash drawer.
168         * 
169         * @see org.kuali.kfs.fp.service.CashDrawerService#unlockCashDrawer(org.kuali.kfs.fp.businessobject.CashDrawer, java.lang.String)
170         */
171        public void unlockCashDrawer(CashDrawer drawer, String documentId) {
172            if (StringUtils.isBlank(documentId)) {
173                throw new IllegalArgumentException("invalid (blank) documentId");
174            }
175    
176            if (!StringUtils.equals(KFSConstants.CashDrawerConstants.STATUS_LOCKED, drawer.getStatusCode())) {
177                throw new IllegalStateException("CashDrawer '" + drawer.getCampusCode() + "' cannot be unlocked because it is not locked");
178            }
179            if (!StringUtils.equals(documentId, drawer.getReferenceFinancialDocumentNumber())) {
180                throw new IllegalStateException("CashDrawer '" + drawer.getCampusCode() + "' cannot be unlocked because it was locked by document " + drawer.getReferenceFinancialDocumentNumber());
181            }
182    
183            drawer.setStatusCode(KFSConstants.CashDrawerConstants.STATUS_OPEN);
184            drawer.setReferenceFinancialDocumentNumber(documentId);
185    
186            save(drawer);
187        }
188    
189        /**
190         * This method retrieves a cash drawer instance using the campus code provided as a search parameter.  If no drawer can
191         * be found for the campus provided and the autocreate flag is set to true, then a new instance of a cash drawer will
192         * be generated and returned.  If the autocreate flag is false, then a null value will be returned.
193         * 
194         * NOTE: The new instance created if autocreate is set to true is an unpersisted instance.
195         * 
196         * @param campusCode The campus code used to retrieve the cash drawer.
197         * @return An instance of a cash drawer matching the value provided.
198         * 
199         * @see org.kuali.kfs.fp.service.CashDrawerService#findByCampusCode(java.lang.String)
200         */
201        public CashDrawer getByCampusCode(String campusCode) {
202            if (StringUtils.isBlank(campusCode)) {
203                throw new IllegalArgumentException("invalid (blank) campusCode");
204            }
205    
206            return (CashDrawer)businessObjectService.findByPrimaryKey(CashDrawer.class, buildPrimaryKeyMap(campusCode));
207        }
208    
209    
210        /**
211         * Persists the given CashDrawer instance.
212         * 
213         * @param cashDrawer The cash drawer to be persisted.
214         */
215        protected void save(CashDrawer cashDrawer) {
216            if (cashDrawer == null) {
217                throw new IllegalArgumentException("invalid (null) cashDrawer");
218            }
219    
220            businessObjectService.save(cashDrawer);
221        }
222    
223        /**
224         * This method creates a primary key map by adding the associated campus code to a new map instance and returning 
225         * this map new instance.
226         * 
227         * @param campusCode The campus code to be added to the map.
228         * @return Map suitable for use with primaryKey-related OJB methods
229         */
230        protected Map buildPrimaryKeyMap(String campusCode) {
231            Map keyMap = new HashMap();
232            keyMap.put(CAMPUS_CODE_PROPERTY, campusCode);
233            return keyMap;
234        }
235    
236        /**
237         * This method calculates the total of all the coins in the cash drawer.  This is accomplished by totaling the values from
238         * each of the *CentAmount() methods (ie. getFinancialDocumentHundredCentAmount()) from the drawer and returning the resulting 
239         * value.
240         * 
241         * @param drawer The drawer being totaled.
242         * @return The sum of all the coin amounts in the drawer.
243         * 
244         * @see org.kuali.kfs.fp.service.CashDrawerService#getCoinTotal(org.kuali.kfs.fp.businessobject.CashDrawer)
245         */
246        public KualiDecimal getCoinTotal(CashDrawer drawer) {
247            KualiDecimal sum = new KualiDecimal(0.0);
248            if (drawer != null) {
249                if (drawer.getFinancialDocumentHundredCentAmount() != null) {
250                    sum.add(drawer.getFinancialDocumentHundredCentAmount());
251                }
252                if (drawer.getFinancialDocumentFiftyCentAmount() != null) {
253                    sum.add(drawer.getFinancialDocumentFiftyCentAmount());
254                }
255                if (drawer.getFinancialDocumentTwentyFiveCentAmount() != null) {
256                    sum.add(drawer.getFinancialDocumentTwentyFiveCentAmount());
257                }
258                if (drawer.getFinancialDocumentTenCentAmount() != null) {
259                    sum.add(drawer.getFinancialDocumentTenCentAmount());
260                }
261                if (drawer.getFinancialDocumentFiveCentAmount() != null) {
262                    sum.add(drawer.getFinancialDocumentFiveCentAmount());
263                }
264                if (drawer.getFinancialDocumentOneCentAmount() != null) {
265                    sum.add(drawer.getFinancialDocumentOneCentAmount());
266                }
267                if (drawer.getFinancialDocumentOtherCentAmount() != null) {
268                    sum.add(drawer.getFinancialDocumentOtherCentAmount());
269                }
270            }
271            return sum;
272        }
273    
274        /**
275         * This method calculates the total of all the currency in the cash drawer.  This is accomplished by totaling the values from
276         * each of the *DollarAmount() methods (ie. getFinancialDocumentHundredDollarAmount()) from the drawer and returning the resulting 
277         * value.
278         * 
279         * @param drawer The drawer being totaled.
280         * @return The sum of all the currency amounts in the drawer.
281         * 
282         * @see org.kuali.kfs.fp.service.CashDrawerService#getCurrencyTotal(org.kuali.kfs.fp.businessobject.CashDrawer)
283         */
284        public KualiDecimal getCurrencyTotal(CashDrawer drawer) {
285            KualiDecimal sum = new KualiDecimal(0.0);
286            if (drawer != null) {
287                if (drawer.getFinancialDocumentHundredDollarAmount() != null) {
288                    sum.add(drawer.getFinancialDocumentHundredDollarAmount());
289                }
290                if (drawer.getFinancialDocumentFiftyDollarAmount() != null) {
291                    sum.add(drawer.getFinancialDocumentFiftyDollarAmount());
292                }
293                if (drawer.getFinancialDocumentTwentyDollarAmount() != null) {
294                    sum.add(drawer.getFinancialDocumentTwentyDollarAmount());
295                }
296                if (drawer.getFinancialDocumentTenDollarAmount() != null) {
297                    sum.add(drawer.getFinancialDocumentTenDollarAmount());
298                }
299                if (drawer.getFinancialDocumentFiveDollarAmount() != null) {
300                    sum.add(drawer.getFinancialDocumentFiveDollarAmount());
301                }
302                if (drawer.getFinancialDocumentTwoDollarAmount() != null) {
303                    sum.add(drawer.getFinancialDocumentTwoDollarAmount());
304                }
305                if (drawer.getFinancialDocumentOneDollarAmount() != null) {
306                    sum.add(drawer.getFinancialDocumentOneDollarAmount());
307                }
308                if (drawer.getFinancialDocumentOtherDollarAmount() != null) {
309                    sum.add(drawer.getFinancialDocumentOtherDollarAmount());
310                }
311            }
312            return sum;
313        }
314    
315        // Spring injection
316        /**
317         * Gets the businessObjectService attribute value.
318         * 
319         * @return The current value of businessObjectService.
320         */
321        public BusinessObjectService getBusinessObjectService() {
322            return businessObjectService;
323        }
324    
325        /**
326         * Sets the businessObjectService attribute value.
327         * 
328         * @param businessObjectService The businessObjectService to set.
329         */
330        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
331            this.businessObjectService = businessObjectService;
332        }
333    }