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.math.BigDecimal;
019    import java.util.HashMap;
020    import java.util.Map;
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.kuali.kfs.integration.cab.CapitalAssetBuilderModuleService;
024    import org.kuali.kfs.module.purap.PurapConstants;
025    import org.kuali.kfs.module.purap.PurapKeyConstants;
026    import org.kuali.kfs.module.purap.PurapPropertyConstants;
027    import org.kuali.kfs.module.purap.PurapConstants.ItemFields;
028    import org.kuali.kfs.module.purap.PurapConstants.ItemTypeCodes;
029    import org.kuali.kfs.module.purap.businessobject.PurApItem;
030    import org.kuali.kfs.module.purap.businessobject.PurchasingItemBase;
031    import org.kuali.kfs.module.purap.document.PurchasingDocument;
032    import org.kuali.kfs.sys.KFSKeyConstants;
033    import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
034    import org.kuali.kfs.vnd.businessobject.CommodityCode;
035    import org.kuali.rice.kns.service.BusinessObjectService;
036    import org.kuali.rice.kns.service.DataDictionaryService;
037    import org.kuali.rice.kns.util.GlobalVariables;
038    import org.kuali.rice.kns.util.ObjectUtils;
039    
040    public class PurchasingNewIndividualItemValidation extends PurchasingAccountsPayableNewIndividualItemValidation {
041    
042        private BusinessObjectService businessObjectService;
043        private CapitalAssetBuilderModuleService capitalAssetBuilderModuleService;
044        private PurchasingUnitOfMeasureValidation unitOfMeasureValidation;
045        private PurchasingItemUnitPriceValidation itemUnitPriceValidation;
046        private PurchasingItemDescriptionValidation itemDescriptionValidation;
047        private PurchasingItemQuantityValidation itemQuantityValidation;
048        private PurchasingBelowTheLineItemNoUnitCostValidation belowTheLineItemNoUnitCostValidation;
049        
050        public boolean validate(AttributedDocumentEvent event) {
051            boolean valid = true;
052            valid &= super.validate(event);
053            String recurringPaymentTypeCode = ((PurchasingDocument)event.getDocument()).getRecurringPaymentTypeCode(); 
054            //Capital asset validations are only done on line items (not additional charge items).
055            if (!getItemForValidation().getItemType().isAdditionalChargeIndicator()) {
056                valid &= capitalAssetBuilderModuleService.validateItemCapitalAssetWithErrors(recurringPaymentTypeCode, getItemForValidation(), false);
057            }
058            unitOfMeasureValidation.setItemForValidation(getItemForValidation());
059            valid &= unitOfMeasureValidation.validate(event);
060            
061            if (getItemForValidation().getItemType().isLineItemIndicator()) {
062                itemUnitPriceValidation.setItemForValidation(getItemForValidation());
063                valid &= itemUnitPriceValidation.validate(event);  
064                
065                itemDescriptionValidation.setItemForValidation(getItemForValidation());
066                valid &= itemDescriptionValidation.validate(event);
067                            
068                itemQuantityValidation.setItemForValidation(getItemForValidation());
069                valid &= itemQuantityValidation.validate(event);
070    
071                valid &= validateCommodityCodes(getItemForValidation(), commodityCodeIsRequired());      
072            }
073            else {
074                // No accounts can be entered on below-the-line items that have no unit cost.
075                belowTheLineItemNoUnitCostValidation.setItemForValidation(getItemForValidation());
076                valid &= belowTheLineItemNoUnitCostValidation.validate(event);                        
077            }
078            return valid;
079        }
080        
081        protected boolean commodityCodeIsRequired() {
082            return false;
083        }
084        
085        /**
086         * Validates that the document contains at least one item.
087         * 
088         * @param purDocument the purchasing document to be validated
089         * @return boolean false if the document does not contain at least one item.
090         */
091        public boolean validateContainsAtLeastOneItem(PurchasingDocument purDocument) {
092            boolean valid = false;
093            for (PurApItem item : purDocument.getItems()) {
094                if (!((PurchasingItemBase) item).isEmpty() && item.getItemType().isLineItemIndicator()) {
095    
096                    return true;
097                }
098            }
099            String documentType = getDocumentTypeLabel(purDocument.getDocumentHeader().getWorkflowDocument().getDocumentType());
100    
101            if (!valid) {
102                GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_REQUIRED, documentType);
103            }
104    
105            return valid;
106        }
107            
108        /**
109         * Validates whether the commodity code existed on the item, and if existed, whether the
110         * commodity code on the item existed in the database, and if so, whether the commodity 
111         * code is active. Display error if any of these 3 conditions are not met.
112         * 
113         * @param item  The PurApItem containing the commodity code to be validated.
114         * @return boolean false if the validation fails and true otherwise.
115         */
116        protected boolean validateCommodityCodes(PurApItem item, boolean commodityCodeRequired) {
117            boolean valid = true;
118            String identifierString = item.getItemIdentifierString();
119            PurchasingItemBase purItem = (PurchasingItemBase) item;
120            
121            //This validation is only needed if the commodityCodeRequired system parameter is true
122            if (commodityCodeRequired && StringUtils.isBlank(purItem.getPurchasingCommodityCode()) ) {
123                //This is the case where the commodity code is required but the item does not currently contain the commodity code.
124                valid = false;
125                String attributeLabel = getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(CommodityCode.class.getName()).
126                                        getAttributeDefinition(PurapPropertyConstants.ITEM_COMMODITY_CODE).getLabel();
127                GlobalVariables.getMessageMap().putError(PurapPropertyConstants.ITEM_COMMODITY_CODE, KFSKeyConstants.ERROR_REQUIRED, attributeLabel + " in " + identifierString);
128            }
129            else if (StringUtils.isNotBlank(purItem.getPurchasingCommodityCode())) {
130                //Find out whether the commodity code has existed in the database
131                Map<String,String> fieldValues = new HashMap<String, String>();
132                fieldValues.put(PurapPropertyConstants.ITEM_COMMODITY_CODE, purItem.getPurchasingCommodityCode());
133                if (businessObjectService.countMatching(CommodityCode.class, fieldValues) != 1) {
134                    //This is the case where the commodity code on the item does not exist in the database.
135                    valid = false;
136                    GlobalVariables.getMessageMap().putError(PurapPropertyConstants.ITEM_COMMODITY_CODE, PurapKeyConstants.PUR_COMMODITY_CODE_INVALID,  " in " + identifierString);
137                }
138                else {
139                    valid &= validateThatCommodityCodeIsActive(item);
140                }
141            }
142            
143            return valid;
144        }
145        
146        protected boolean validateThatCommodityCodeIsActive(PurApItem item) {
147            item.refreshReferenceObject(PurapPropertyConstants.COMMODITY_CODE);
148            if (!((PurchasingItemBase)item).getCommodityCode().isActive()) {
149                //This is the case where the commodity code on the item is not active.
150                GlobalVariables.getMessageMap().putError(PurapPropertyConstants.ITEM_COMMODITY_CODE, PurapKeyConstants.PUR_COMMODITY_CODE_INACTIVE, " in " + item.getItemIdentifierString());
151                return false;
152            }
153            return true;
154        }
155    
156        public BusinessObjectService getBusinessObjectService() {
157            return businessObjectService;
158        }
159    
160        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
161            this.businessObjectService = businessObjectService;
162        }
163    
164        public CapitalAssetBuilderModuleService getCapitalAssetBuilderModuleService() {
165            return capitalAssetBuilderModuleService;
166        }
167    
168        public void setCapitalAssetBuilderModuleService(CapitalAssetBuilderModuleService capitalAssetBuilderModuleService) {
169            this.capitalAssetBuilderModuleService = capitalAssetBuilderModuleService;
170        }
171    
172        public PurchasingUnitOfMeasureValidation getUnitOfMeasureValidation() {
173            return unitOfMeasureValidation;
174        }
175    
176        public void setUnitOfMeasureValidation(PurchasingUnitOfMeasureValidation unitOfMeasureValidation) {
177            this.unitOfMeasureValidation = unitOfMeasureValidation;
178        }
179    
180        public PurchasingItemUnitPriceValidation getItemUnitPriceValidation() {
181            return itemUnitPriceValidation;
182        }
183    
184        public void setItemUnitPriceValidation(PurchasingItemUnitPriceValidation itemUnitPriceValidation) {
185            this.itemUnitPriceValidation = itemUnitPriceValidation;
186        }
187    
188        public PurchasingItemDescriptionValidation getItemDescriptionValidation() {
189            return itemDescriptionValidation;
190        }
191    
192        public void setItemDescriptionValidation(PurchasingItemDescriptionValidation itemDescriptionValidation) {
193            this.itemDescriptionValidation = itemDescriptionValidation;
194        }
195    
196        public PurchasingItemQuantityValidation getItemQuantityValidation() {
197            return itemQuantityValidation;
198        }
199    
200        public void setItemQuantityValidation(PurchasingItemQuantityValidation itemQuantityValidation) {
201            this.itemQuantityValidation = itemQuantityValidation;
202        }
203    
204        public PurchasingBelowTheLineItemNoUnitCostValidation getBelowTheLineItemNoUnitCostValidation() {
205            return belowTheLineItemNoUnitCostValidation;
206        }
207    
208        public void setBelowTheLineItemNoUnitCostValidation(PurchasingBelowTheLineItemNoUnitCostValidation belowTheLineItemNoUnitCostValidation) {
209            this.belowTheLineItemNoUnitCostValidation = belowTheLineItemNoUnitCostValidation;
210        }
211        
212    
213    }