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.service.impl; 017 018 import java.util.HashMap; 019 import java.util.List; 020 import java.util.Map; 021 022 import org.apache.commons.lang.StringUtils; 023 import org.apache.ojb.broker.metadata.ClassDescriptor; 024 import org.kuali.kfs.integration.cab.CapitalAssetBuilderModuleService; 025 import org.kuali.kfs.integration.purap.CapitalAssetLocation; 026 import org.kuali.kfs.integration.purap.CapitalAssetSystem; 027 import org.kuali.kfs.module.cam.CamsKeyConstants; 028 import org.kuali.kfs.module.cam.CamsPropertyConstants; 029 import org.kuali.kfs.module.purap.PurapConstants; 030 import org.kuali.kfs.module.purap.PurapKeyConstants; 031 import org.kuali.kfs.module.purap.PurapParameterConstants; 032 import org.kuali.kfs.module.purap.PurapPropertyConstants; 033 import org.kuali.kfs.module.purap.businessobject.PurApItem; 034 import org.kuali.kfs.module.purap.businessobject.PurchasingCapitalAssetItem; 035 import org.kuali.kfs.module.purap.document.PurchasingDocument; 036 import org.kuali.kfs.module.purap.document.service.PurchasingDocumentSpecificService; 037 import org.kuali.kfs.module.purap.document.service.PurchasingService; 038 import org.kuali.kfs.module.purap.service.PurapAccountingService; 039 import org.kuali.kfs.sys.KFSPropertyConstants; 040 import org.kuali.kfs.sys.businessobject.Room; 041 import org.kuali.kfs.sys.context.SpringContext; 042 import org.kuali.kfs.sys.service.PostalCodeValidationService; 043 import org.kuali.kfs.sys.service.impl.KfsParameterConstants; 044 import org.kuali.kfs.vnd.businessobject.VendorDetail; 045 import org.kuali.rice.kns.service.BusinessObjectService; 046 import org.kuali.rice.kns.service.DataDictionaryService; 047 import org.kuali.rice.kns.service.ParameterService; 048 import org.kuali.rice.kns.service.SequenceAccessorService; 049 import org.kuali.rice.kns.service.impl.PersistenceServiceStructureImplBase; 050 import org.kuali.rice.kns.util.GlobalVariables; 051 import org.kuali.rice.kns.util.ObjectUtils; 052 import org.kuali.rice.kns.util.RiceKeyConstants; 053 import org.kuali.rice.kns.util.TypedArrayList; 054 import org.springframework.transaction.annotation.Transactional; 055 056 @Transactional 057 public class PurchasingServiceImpl extends PersistenceServiceStructureImplBase implements PurchasingService { 058 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurchasingServiceImpl.class); 059 060 private ParameterService parameterService; 061 private SequenceAccessorService sequenceAccessorService; 062 private PurapAccountingService purapAccountingService; 063 private CapitalAssetBuilderModuleService capitalAssetBuilderModuleService; 064 private PostalCodeValidationService postalCodeValidationService; 065 066 public void setPurapAccountingService(PurapAccountingService purapAccountingService) { 067 this.purapAccountingService = purapAccountingService; 068 } 069 070 public void setParameterService(ParameterService parameterService) { 071 this.parameterService = parameterService; 072 } 073 074 public void setSequenceAccessorService(SequenceAccessorService sequenceAccessorService) { 075 this.sequenceAccessorService = sequenceAccessorService; 076 } 077 078 public void setCapitalAssetBuilderModuleService(CapitalAssetBuilderModuleService capitalAssetBuilderModuleService) { 079 this.capitalAssetBuilderModuleService = capitalAssetBuilderModuleService; 080 } 081 082 public void setPostalCodeValidationService(PostalCodeValidationService postalCodeValidationService) { 083 this.postalCodeValidationService = postalCodeValidationService; 084 } 085 086 public void setupCapitalAssetItems(PurchasingDocument purDoc) { 087 088 List<PurchasingCapitalAssetItem> camsItemsList = purDoc.getPurchasingCapitalAssetItems(); 089 List<PurchasingCapitalAssetItem> newCamsItemsList = new TypedArrayList(purDoc.getPurchasingCapitalAssetItemClass()); 090 091 for (PurApItem purapItem : purDoc.getItems()) { 092 if (purapItem.getItemType().isLineItemIndicator() || PurapConstants.ItemTypeCodes.ITEM_TYPE_TRADE_IN_CODE.equals(purapItem.getItemTypeCode())) { 093 if (capitalAssetBuilderModuleService.doesItemNeedCapitalAsset(purapItem.getItemTypeCode(), purapItem.getSourceAccountingLines())) { 094 PurchasingCapitalAssetItem camsItem = getItemIfAlreadyInCamsItemsList(purapItem, camsItemsList); 095 // If either the camsItem is null or if its system is null and the document's system type is IND (this is 096 // the case when the user tries to switch from ONE system type to IND system type), we'll have to create 097 // the camsItem again along with its system to prevent the No collection found error. 098 if (ObjectUtils.isNull(camsItem) || (purDoc.getCapitalAssetSystemTypeCode() != null && purDoc.getCapitalAssetSystemTypeCode().equals(PurapConstants.CapitalAssetSystemTypes.INDIVIDUAL) && ObjectUtils.isNull(camsItem.getPurchasingCapitalAssetSystem()))) { 099 PurchasingCapitalAssetItem newCamsItem = createCamsItem(purDoc, purapItem); 100 newCamsItemsList.add(newCamsItem); 101 } 102 else { 103 camsItem.setPurchasingDocument(purDoc); 104 newCamsItemsList.add(camsItem); 105 } 106 } 107 else { 108 PurchasingCapitalAssetItem camsItem = getItemIfAlreadyInCamsItemsList(purapItem, camsItemsList); 109 if (camsItem != null && camsItem.isEmpty()) { 110 camsItemsList.remove(camsItem); 111 } 112 } 113 } 114 } 115 116 purDoc.setPurchasingCapitalAssetItems(newCamsItemsList); 117 118 if (purDoc.getPurchasingCapitalAssetItems().isEmpty()) { 119 purDoc.setCapitalAssetSystemStateCode(null); 120 purDoc.setCapitalAssetSystemTypeCode(null); 121 } 122 } 123 124 protected PurchasingCapitalAssetItem createCamsItem(PurchasingDocument purDoc, PurApItem purapItem) { 125 PurchasingDocumentSpecificService purchasingDocumentSpecificService = purDoc.getDocumentSpecificService(); 126 if (purapItem.getItemIdentifier() == null) { 127 ClassDescriptor cd = this.getClassDescriptor(purapItem.getClass()); 128 String sequenceName = cd.getFieldDescriptorByName(PurapPropertyConstants.ITEM_IDENTIFIER).getSequenceName(); 129 130 Integer itemIdentifier = sequenceAccessorService.getNextAvailableSequenceNumber(sequenceName, PurApItem.class).intValue(); 131 purapItem.setItemIdentifier(itemIdentifier); 132 } 133 PurchasingCapitalAssetItem camsItem = purchasingDocumentSpecificService.createCamsItem(purDoc, purapItem); 134 return camsItem; 135 } 136 137 138 protected PurchasingCapitalAssetItem getItemIfAlreadyInCamsItemsList(PurApItem item, List<PurchasingCapitalAssetItem> camsItemsList) { 139 for (PurchasingCapitalAssetItem camsItem : camsItemsList) { 140 if (camsItem.getItemIdentifier() != null && camsItem.getItemIdentifier().equals(item.getItemIdentifier())) { 141 return camsItem; 142 } 143 } 144 145 return null; 146 } 147 148 149 public void deleteCapitalAssetItems(PurchasingDocument purDoc, Integer itemIdentifier) { 150 // delete the corresponding CAMS items. 151 int index = 0; 152 for (PurchasingCapitalAssetItem camsItem : purDoc.getPurchasingCapitalAssetItems()) { 153 if (camsItem.getItemIdentifier().equals(itemIdentifier)) { 154 break; 155 } 156 index++; 157 } 158 purDoc.getPurchasingCapitalAssetItems().remove(index); 159 } 160 161 public void setupCapitalAssetSystem(PurchasingDocument purDoc) { 162 CapitalAssetSystem resultSystem = purDoc.getDocumentSpecificService().createCapitalAssetSystem(); 163 if (purDoc.getCapitalAssetSystemTypeCode() != null && (purDoc.getCapitalAssetSystemTypeCode().equals(PurapConstants.CapitalAssetTabStrings.ONE_SYSTEM) || purDoc.getCapitalAssetSystemTypeCode().equals(PurapConstants.CapitalAssetTabStrings.MULTIPLE_SYSTEMS))) { 164 if (purDoc.getPurchasingCapitalAssetSystems().size() == 0) { 165 purDoc.getPurchasingCapitalAssetSystems().add(resultSystem); 166 } 167 } 168 } 169 170 public boolean getDefaultUseTaxIndicatorValue(PurchasingDocument purDoc) { 171 172 purDoc.refreshReferenceObject("vendorDetail"); 173 VendorDetail vendor = purDoc.getVendorDetail(); 174 if (vendor != null) { 175 String vendorStateCode = vendor.getDefaultAddressStateCode(); 176 String billingStateCode = purDoc.getBillingStateCode(); 177 if (StringUtils.equals(vendorStateCode, billingStateCode) || (vendor.isTaxableIndicator())) { 178 return false; 179 } 180 } 181 else { 182 // don't set use tax if no vendor on req 183 return true; 184 } 185 186 return true; 187 } 188 189 public String getDefaultAssetTypeCodeNotThisFiscalYear() { 190 //FIXME (hjs) is this breaking modularization?? 191 return parameterService.getParameterValue(KfsParameterConstants.CAPITAL_ASSET_BUILDER_DOCUMENT.class, PurapParameterConstants.CapitalAsset.PURCHASING_DEFAULT_ASSET_TYPE_WHEN_NOT_THIS_FISCAL_YEAR); 192 } 193 194 public boolean checkCapitalAssetLocation(CapitalAssetLocation location) { 195 // if any of the date fields have a value AND one of them does not have a value... 196 if (ObjectUtils.isNotNull(location) && 197 (StringUtils.isEmpty(location.getCapitalAssetLine1Address()) || 198 StringUtils.isEmpty(location.getCapitalAssetCityName()) || 199 StringUtils.isEmpty(location.getCapitalAssetCountryCode()) )) { 200 String missingFields = ""; 201 if (StringUtils.isEmpty(location.getCapitalAssetLine1Address())) { 202 missingFields = "Address"; 203 addErrorToCapitalAssetLocation(PurapPropertyConstants.CAPITAL_ASSET_LOCATION_ADDRESS_LINE1,missingFields); 204 } 205 if (StringUtils.isEmpty(location.getCapitalAssetCityName())) { 206 missingFields = "City"; 207 addErrorToCapitalAssetLocation(PurapPropertyConstants.CAPITAL_ASSET_LOCATION_CITY,missingFields); 208 } 209 if (StringUtils.isEmpty(location.getCapitalAssetCountryCode())) { 210 missingFields = "Country"; 211 addErrorToCapitalAssetLocation(PurapPropertyConstants.CAPITAL_ASSET_LOCATION_COUNTRY,missingFields); 212 } 213 return false; 214 } 215 return true; 216 } 217 218 219 public boolean checkValidRoomNumber(CapitalAssetLocation location){ 220 boolean valid = true; 221 if (StringUtils.isNotBlank(location.getBuildingCode()) && StringUtils.isNotBlank(location.getBuildingRoomNumber())) { 222 Map objectKeys = new HashMap(); 223 objectKeys.put(CamsPropertyConstants.AssetGlobalDetail.CAMPUS_CODE, location.getCampusCode()); 224 objectKeys.put(CamsPropertyConstants.AssetGlobalDetail.BUILDING_CODE, location.getBuildingCode()); 225 objectKeys.put(CamsPropertyConstants.AssetGlobalDetail.BUILDING_ROOM_NUMBER, location.getBuildingRoomNumber()); 226 Room room = (Room) SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(Room.class, objectKeys); 227 228 if (ObjectUtils.isNull(room)) { 229 GlobalVariables.getMessageMap().addToErrorPath(PurapPropertyConstants.NEW_PURCHASING_CAPITAL_ASSET_LOCATION_LINE); 230 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.CAPITAL_ASSET_LOCATION_ROOM, CamsKeyConstants.AssetLocationGlobal.ERROR_INVALID_ROOM_NUMBER,location.getBuildingCode(),location.getBuildingRoomNumber(), location.getCampusCode()); 231 GlobalVariables.getMessageMap().removeFromErrorPath(PurapPropertyConstants.NEW_PURCHASING_CAPITAL_ASSET_LOCATION_LINE); 232 valid &= false; 233 } 234 else if (!room.isActive()) { 235 String label = getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(Room.class.getName()).getAttributeDefinition(KFSPropertyConstants.BUILDING_ROOM_NUMBER).getLabel(); 236 //GlobalVariables.getMessageMap().putError(PurapConstants.CAPITAL_ASSET_TAB_ERRORS, RiceKeyConstants.ERROR_INACTIVE, label); 237 GlobalVariables.getMessageMap().addToErrorPath(PurapPropertyConstants.NEW_PURCHASING_CAPITAL_ASSET_LOCATION_LINE); 238 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.CAPITAL_ASSET_LOCATION_ROOM, RiceKeyConstants.ERROR_INACTIVE, label); 239 GlobalVariables.getMessageMap().removeFromErrorPath(PurapPropertyConstants.NEW_PURCHASING_CAPITAL_ASSET_LOCATION_LINE); 240 valid &= false; 241 } 242 }else if (StringUtils.isBlank(location.getBuildingCode()) && StringUtils.isNotBlank(location.getBuildingRoomNumber())){ 243 Map objectKeys = new HashMap(); 244 objectKeys.put(CamsPropertyConstants.AssetGlobalDetail.CAMPUS_CODE, location.getCampusCode()); 245 objectKeys.put(CamsPropertyConstants.AssetGlobalDetail.BUILDING_ROOM_NUMBER, location.getBuildingRoomNumber()); 246 Room room = (Room) SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(Room.class, objectKeys); 247 248 if (ObjectUtils.isNull(room)) { 249 GlobalVariables.getMessageMap().addToErrorPath(PurapPropertyConstants.NEW_PURCHASING_CAPITAL_ASSET_LOCATION_LINE); 250 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.CAPITAL_ASSET_LOCATION_ROOM, CamsKeyConstants.AssetLocationGlobal.ERROR_INVALID_ROOM_NUMBER_FOR_CAMPUS,location.getBuildingRoomNumber(), location.getCampusCode()); 251 GlobalVariables.getMessageMap().removeFromErrorPath(PurapPropertyConstants.NEW_PURCHASING_CAPITAL_ASSET_LOCATION_LINE); 252 valid &= false; 253 } 254 else if (!room.isActive()) { 255 String label = getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(Room.class.getName()).getAttributeDefinition(KFSPropertyConstants.BUILDING_ROOM_NUMBER).getLabel(); 256 GlobalVariables.getMessageMap().addToErrorPath(PurapPropertyConstants.NEW_PURCHASING_CAPITAL_ASSET_LOCATION_LINE); 257 GlobalVariables.getMessageMap().putError(PurapPropertyConstants.CAPITAL_ASSET_LOCATION_ROOM, RiceKeyConstants.ERROR_INACTIVE, label); 258 GlobalVariables.getMessageMap().removeFromErrorPath(PurapPropertyConstants.NEW_PURCHASING_CAPITAL_ASSET_LOCATION_LINE); 259 //GlobalVariables.getMessageMap().putError(PurapConstants.CAPITAL_ASSET_TAB_ERRORS, RiceKeyConstants.ERROR_INACTIVE, label); 260 valid &= false; 261 } 262 } 263 return valid; 264 } 265 266 /** 267 * Gets the dataDictionaryService attribute. 268 * 269 * @return an implementation of the dataDictionaryService. 270 */ 271 public DataDictionaryService getDataDictionaryService() { 272 return SpringContext.getBean(DataDictionaryService.class); 273 } 274 275 public void addErrorToCapitalAssetLocation(String path, String field) { 276 277 GlobalVariables.getMessageMap().addToErrorPath(PurapPropertyConstants.NEW_PURCHASING_CAPITAL_ASSET_LOCATION_LINE); 278 GlobalVariables.getMessageMap().putError(path,PurapKeyConstants.ERROR_CAPITAL_ASSET_INCOMPLETE_ADDRESS,field); 279 GlobalVariables.getMessageMap().removeFromErrorPath(PurapPropertyConstants.NEW_PURCHASING_CAPITAL_ASSET_LOCATION_LINE); 280 } 281 282 283 }