001/*
002 * Copyright 2008 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 */
016package org.kuali.ole.module.purap.document.validation.impl;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.ole.integration.cab.CapitalAssetBuilderModuleService;
020import org.kuali.ole.integration.purap.CapitalAssetLocation;
021import org.kuali.ole.integration.purap.CapitalAssetSystem;
022import org.kuali.ole.module.purap.PurapConstants;
023import org.kuali.ole.module.purap.PurapKeyConstants;
024import org.kuali.ole.module.purap.PurapPropertyConstants;
025import org.kuali.ole.module.purap.businessobject.PurchasingCapitalAssetItem;
026import org.kuali.ole.module.purap.businessobject.RequisitionCapitalAssetSystem;
027import org.kuali.ole.module.purap.document.PurchasingDocument;
028import org.kuali.ole.module.purap.document.service.PurchasingService;
029import org.kuali.ole.sys.context.SpringContext;
030import org.kuali.ole.sys.document.validation.GenericValidation;
031import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
032import org.kuali.rice.core.api.util.RiceKeyConstants;
033import org.kuali.rice.kns.service.DataDictionaryService;
034import org.kuali.rice.krad.util.GlobalVariables;
035import org.kuali.rice.krad.util.ObjectUtils;
036
037public class PurchasingCapitalAssetValidation extends GenericValidation {
038    CapitalAssetBuilderModuleService capitalAssetBuilderModuleService;
039    PurchasingService purchasingService;
040    protected static String ERROR_PATH_PREFIX_FOR_IND_SYSTEM = "document.purchasingCapitalAssetItems[";
041    protected static String ERROR_PATH_SUFFIX_FOR_IND_SYSTEM = "].purchasingCapitalAssetSystem";
042    protected static String ERROR_PATH_PREFIX_FOR_ONE_SYSTEM = "document.purchasingCapitalAssetSystems[0]";
043
044    public boolean validate(AttributedDocumentEvent event) {
045        GlobalVariables.getMessageMap().clearErrorPath();
046        boolean valid = true;
047        PurchasingDocument purchasingDocument = (PurchasingDocument) event.getDocument();
048
049        boolean requiredByObjectSubType = !capitalAssetBuilderModuleService.validatePurchasingObjectSubType(purchasingDocument);
050        boolean requiredByChart = !capitalAssetBuilderModuleService.validateAllFieldRequirementsByChart(purchasingDocument);
051        boolean capitalAssetRequired = requiredByObjectSubType && requiredByChart;
052
053        if (capitalAssetRequired) {
054            // if capital asset required, check to see if the capital asset data are setup 
055            String typeCode = purchasingDocument.getCapitalAssetSystemTypeCode();
056            if (StringUtils.isBlank(typeCode) || StringUtils.isBlank(purchasingDocument.getCapitalAssetSystemStateCode()) ||
057                    purchasingDocument.getPurchasingCapitalAssetSystems() == null || purchasingDocument.getPurchasingCapitalAssetItems() == null) {
058                valid = false;
059            } else if ((typeCode.equals(PurapConstants.CapitalAssetTabStrings.ONE_SYSTEM) || typeCode.equals(PurapConstants.CapitalAssetTabStrings.MULTIPLE_SYSTEMS)) &&
060                    purchasingDocument.getPurchasingCapitalAssetSystems().size() == 0) {
061                valid = false;
062            }
063            /* TODO
064             * either complete the following with checking that capital asset items are correctly setup, or replace this whole part (and above)
065             * with checking on a flag that indicates whether select/update capital asset has been done since last item changes 
066             */
067            else if (purchasingDocument.getPurchasingCapitalAssetItems().isEmpty()) {
068                valid = false;
069            }
070
071            if (!valid) {
072                GlobalVariables.getMessageMap().putError("newPurchasingItemCapitalAssetLine", PurapKeyConstants.ERROR_CAPITAL_ASSET_REQD_FOR_PUR_OBJ_SUB_TYPE);
073                return valid;
074            }
075        } else {
076            // if capital asset not required, reset system type and state code in case they are filled in
077            // if capital asset items are empty, then set sytem type code and system state code to null
078            // fix to jira KFSMI-5146
079            if (purchasingDocument.getPurchasingCapitalAssetItems().isEmpty()) {
080                purchasingDocument.setCapitalAssetSystemTypeCode(null);
081                purchasingDocument.setCapitalAssetSystemStateCode(null);
082            }
083        }
084
085        // We only need to do capital asset validations if the capital asset system type is not blank.
086        if (StringUtils.isNotBlank(purchasingDocument.getCapitalAssetSystemTypeCode())) {
087            valid &= capitalAssetBuilderModuleService.validatePurchasingData(purchasingDocument);
088
089            // FIXME hjs move this to cab module service
090            // validate complete location addresses
091            if (purchasingDocument.getCapitalAssetSystemTypeCode().equals(PurapConstants.CapitalAssetSystemTypes.INDIVIDUAL)) {
092                for (CapitalAssetSystem system : purchasingDocument.getPurchasingCapitalAssetSystems()) {
093                    for (CapitalAssetLocation location : system.getCapitalAssetLocations()) {
094                        valid &= purchasingService.checkCapitalAssetLocation(location);
095                    }
096                }
097            } else if (purchasingDocument.getCapitalAssetSystemTypeCode().equals(PurapConstants.CapitalAssetSystemTypes.ONE_SYSTEM)) {
098                CapitalAssetSystem system = purchasingDocument.getPurchasingCapitalAssetSystems().get(0);
099                for (CapitalAssetLocation location : system.getCapitalAssetLocations()) {
100                    valid &= purchasingService.checkCapitalAssetLocation(location);
101                }
102            }
103
104            // Validate asset type code if entered by user.
105            valid &= validateAssetTypeExistence(purchasingDocument);
106        }
107
108
109        return valid;
110    }
111
112    /**
113     * Validate user input asset type code.
114     *
115     * @param purchasingDocument
116     * @return
117     */
118    protected boolean validateAssetTypeExistence(PurchasingDocument purchasingDocument) {
119        boolean valid = true;
120        // validate for Individual system
121        if (purchasingDocument.getCapitalAssetSystemTypeCode().equals(PurapConstants.CapitalAssetSystemTypes.INDIVIDUAL)) {
122            int i = 0;
123            for (PurchasingCapitalAssetItem capitalAssetItem : purchasingDocument.getPurchasingCapitalAssetItems()) {
124                if (ObjectUtils.isNotNull(capitalAssetItem) && ObjectUtils.isNotNull(capitalAssetItem.getPurchasingCapitalAssetSystem())) {
125                    String assetTypeCode = capitalAssetItem.getPurchasingCapitalAssetSystem().getCapitalAssetTypeCode();
126                    if (StringUtils.isNotBlank(assetTypeCode) && !capitalAssetBuilderModuleService.isAssetTypeExisting(assetTypeCode)) {
127                        valid = false;
128                        String errorPath = ERROR_PATH_PREFIX_FOR_IND_SYSTEM + new Integer(i).toString() + ERROR_PATH_SUFFIX_FOR_IND_SYSTEM;
129                        addAssetTypeErrorWithFullErrorPath(errorPath);
130                    }
131                }
132                i++;
133            }
134        } else if (purchasingDocument.getCapitalAssetSystemTypeCode().equals(PurapConstants.CapitalAssetSystemTypes.ONE_SYSTEM)) {
135            // validate for One system
136            if (ObjectUtils.isNotNull(purchasingDocument.getPurchasingCapitalAssetSystems())) {
137                CapitalAssetSystem system = purchasingDocument.getPurchasingCapitalAssetSystems().get(0);
138                if (ObjectUtils.isNotNull(system) && StringUtils.isNotBlank(system.getCapitalAssetTypeCode()) && !capitalAssetBuilderModuleService.isAssetTypeExisting(system.getCapitalAssetTypeCode())) {
139                    valid = false;
140                    String errorPath = ERROR_PATH_PREFIX_FOR_ONE_SYSTEM;
141                    addAssetTypeErrorWithFullErrorPath(errorPath);
142                }
143            }
144        }
145        // Validate for Multiple system is ignored since currently it's not supported to enter. 
146        return valid;
147    }
148
149    /**
150     * Add asset type error to the global message map.
151     *
152     * @param errorPath
153     */
154    protected void addAssetTypeErrorWithFullErrorPath(String errorPath) {
155        GlobalVariables.getMessageMap().addToErrorPath(errorPath);
156        String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(RequisitionCapitalAssetSystem.class.getName()).getAttributeDefinition(PurapPropertyConstants.CAPITAL_ASSET_TYPE_CODE).getLabel();
157        GlobalVariables.getMessageMap().putError(PurapPropertyConstants.CAPITAL_ASSET_TYPE_CODE, RiceKeyConstants.ERROR_EXISTENCE, label);
158        GlobalVariables.getMessageMap().removeFromErrorPath(errorPath);
159    }
160
161    public CapitalAssetBuilderModuleService getCapitalAssetBuilderModuleService() {
162        return capitalAssetBuilderModuleService;
163    }
164
165    public void setCapitalAssetBuilderModuleService(CapitalAssetBuilderModuleService capitalAssetBuilderModuleService) {
166        this.capitalAssetBuilderModuleService = capitalAssetBuilderModuleService;
167    }
168
169    public PurchasingService getPurchasingService() {
170        return purchasingService;
171    }
172
173    public void setPurchasingService(PurchasingService purchasingService) {
174        this.purchasingService = purchasingService;
175    }
176
177}