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.purap.document.validation.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.module.purap.PurapKeyConstants;
023    import org.kuali.kfs.module.purap.PurapPropertyConstants;
024    import org.kuali.kfs.module.purap.businessobject.PurApItem;
025    import org.kuali.kfs.module.purap.businessobject.PurchasingItemBase;
026    import org.kuali.kfs.sys.KFSKeyConstants;
027    import org.kuali.kfs.sys.document.validation.GenericValidation;
028    import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
029    import org.kuali.kfs.vnd.businessobject.CommodityCode;
030    import org.kuali.rice.kns.service.BusinessObjectService;
031    import org.kuali.rice.kns.service.DataDictionaryService;
032    import org.kuali.rice.kns.util.GlobalVariables;
033    
034    public class PurchasingCommodityCodeValidation extends GenericValidation {
035        
036        private BusinessObjectService businessObjectService;
037        private DataDictionaryService dataDictionaryService;
038        private PurApItem itemForValidation;
039        
040        public boolean validate(AttributedDocumentEvent event) {
041            boolean valid = true;
042            GlobalVariables.getMessageMap().clearErrorPath();                
043            GlobalVariables.getMessageMap().addToErrorPath("document.item[" + (itemForValidation.getItemLineNumber() - 1) + "]");
044    
045            itemForValidation.refreshReferenceObject(PurapPropertyConstants.COMMODITY_CODE);
046            valid &= validateCommodityCodes(itemForValidation, commodityCodeIsRequired());
047            
048            GlobalVariables.getMessageMap().removeFromErrorPath("document.item[" + (itemForValidation.getItemLineNumber() - 1) + "]");
049    
050            return valid;
051    
052        }
053        
054        public PurApItem getItemForValidation() {
055            return itemForValidation;
056        }
057    
058        public void setItemForValidation(PurApItem itemForValidation) {
059            this.itemForValidation = itemForValidation;
060        }
061    
062        /**
063         * Validates whether the commodity code existed on the item, and if existed, whether the
064         * commodity code on the item existed in the database, and if so, whether the commodity 
065         * code is active. Display error if any of these 3 conditions are not met.
066         * 
067         * @param item  The PurApItem containing the commodity code to be validated.
068         * @return boolean false if the validation fails and true otherwise.
069         */
070        protected boolean validateCommodityCodes(PurApItem item, boolean commodityCodeRequired) {
071            boolean valid = true;
072            String identifierString = item.getItemIdentifierString();
073            PurchasingItemBase purItem = (PurchasingItemBase) item;
074            
075            //This validation is only needed if the commodityCodeRequired system parameter is true
076            if (commodityCodeRequired && StringUtils.isBlank(purItem.getPurchasingCommodityCode()) ) {
077                //This is the case where the commodity code is required but the item does not currently contain the commodity code.
078                valid = false;
079                String attributeLabel = dataDictionaryService.
080                                        getDataDictionary().getBusinessObjectEntry(CommodityCode.class.getName()).
081                                        getAttributeDefinition(PurapPropertyConstants.ITEM_COMMODITY_CODE).getLabel();
082                GlobalVariables.getMessageMap().putError(PurapPropertyConstants.ITEM_COMMODITY_CODE, KFSKeyConstants.ERROR_REQUIRED, attributeLabel + " in " + identifierString);
083            }
084            else if (StringUtils.isNotBlank(purItem.getPurchasingCommodityCode())) {
085                //Find out whether the commodity code has existed in the database
086                Map<String,String> fieldValues = new HashMap<String, String>();
087                fieldValues.put(PurapPropertyConstants.ITEM_COMMODITY_CODE, purItem.getPurchasingCommodityCode());
088                if (businessObjectService.countMatching(CommodityCode.class, fieldValues) != 1) {
089                    //This is the case where the commodity code on the item does not exist in the database.
090                    valid = false;
091                    GlobalVariables.getMessageMap().putError(PurapPropertyConstants.ITEM_COMMODITY_CODE, PurapKeyConstants.PUR_COMMODITY_CODE_INVALID,  " in " + identifierString);
092                }
093                else {
094                    valid &= validateThatCommodityCodeIsActive(item);
095                }
096            }
097            
098            return valid;
099        }
100    
101        protected boolean validateThatCommodityCodeIsActive(PurApItem item) {
102            if (!((PurchasingItemBase)item).getCommodityCode().isActive()) {
103                //This is the case where the commodity code on the item is not active.
104                GlobalVariables.getMessageMap().putError(PurapPropertyConstants.ITEM_COMMODITY_CODE, PurapKeyConstants.PUR_COMMODITY_CODE_INACTIVE, " in " + item.getItemIdentifierString());
105                return false;
106            }
107            return true;
108        }
109    
110        /**
111         * Predicate to do a parameter lookup and tell us whether a commodity code is required.
112         * Override in child classes. 
113         * 
114         * @return      True if a commodity code is required.
115         */
116        protected boolean commodityCodeIsRequired() {
117            return false;
118        }
119    
120        public BusinessObjectService getBusinessObjectService() {
121            return businessObjectService;
122        }
123    
124        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
125            this.businessObjectService = businessObjectService;
126        }
127    
128        public DataDictionaryService getDataDictionaryService() {
129            return dataDictionaryService;
130        }
131    
132        public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
133            this.dataDictionaryService = dataDictionaryService;
134        }
135    
136    }