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.cam.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.kuali.kfs.module.cam.CamsConstants; 024 import org.kuali.kfs.module.cam.CamsKeyConstants; 025 import org.kuali.kfs.module.cam.CamsPropertyConstants.AssetTransferDocument; 026 import org.kuali.kfs.module.cam.businessobject.Asset; 027 import org.kuali.kfs.module.cam.businessobject.AssetLocation; 028 import org.kuali.kfs.module.cam.businessobject.AssetType; 029 import org.kuali.kfs.module.cam.document.service.AssetLocationService; 030 import org.kuali.kfs.sys.KFSConstants; 031 import org.kuali.kfs.sys.KFSPropertyConstants; 032 import org.kuali.kfs.sys.context.SpringContext; 033 import org.kuali.rice.kns.bo.BusinessObject; 034 import org.kuali.rice.kns.bo.State; 035 import org.kuali.rice.kns.datadictionary.DataDictionaryEntryBase; 036 import org.kuali.rice.kns.document.DocumentBase; 037 import org.kuali.rice.kns.service.BusinessObjectService; 038 import org.kuali.rice.kns.service.DataDictionaryService; 039 import org.kuali.rice.kns.service.StateService; 040 import org.kuali.rice.kns.util.GlobalVariables; 041 import org.kuali.rice.kns.util.ObjectUtils; 042 043 public class AssetLocationServiceImpl implements AssetLocationService { 044 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AssetLocationService.class); 045 046 private BusinessObjectService businessObjectService; 047 private DataDictionaryService DataDictionaryService; 048 049 /** 050 * @see org.kuali.kfs.module.cam.document.service.AssetLocationService#setOffCampusLocation(org.kuali.kfs.module.cam.businessobject.Asset) 051 */ 052 public void setOffCampusLocation(Asset asset) { 053 List<AssetLocation> assetLocations = asset.getAssetLocations(); 054 AssetLocation offCampusLocation = null; 055 056 for (AssetLocation location : assetLocations) { 057 if (CamsConstants.AssetLocationTypeCode.OFF_CAMPUS.equalsIgnoreCase(location.getAssetLocationTypeCode())) { 058 // We need a new instance for asset location. Otherwise, if we copy it from the assetLocations collection, it could 059 // have newBO and oldBO pointing to the same AssetLocation instance which is bad. 060 offCampusLocation = new AssetLocation(location); 061 break; 062 } 063 } 064 065 if (ObjectUtils.isNull(offCampusLocation)) { 066 offCampusLocation = new AssetLocation(asset.getCapitalAssetNumber()); 067 offCampusLocation.setAssetLocationTypeCode(CamsConstants.AssetLocationTypeCode.OFF_CAMPUS); 068 } 069 asset.setOffCampusLocation(offCampusLocation); 070 } 071 072 /** 073 * update existing offCampusLocation 074 * 075 * @see org.kuali.kfs.module.cam.document.service.AssetLocationService#updateOffCampusLocation(org.kuali.kfs.module.cam.businessobject.Asset) 076 */ 077 public void updateOffCampusLocation(Asset asset) { 078 AssetLocation offLocation = asset.getOffCampusLocation(); 079 boolean isOffCampusEmpty = isOffCampusLocationEmpty(offLocation); 080 AssetLocation removableOffCampusLocation = null; 081 082 for (AssetLocation location : asset.getAssetLocations()) { 083 if (CamsConstants.AssetLocationTypeCode.OFF_CAMPUS.equalsIgnoreCase(location.getAssetLocationTypeCode())) { 084 if (isOffCampusEmpty) { 085 removableOffCampusLocation = location; 086 } 087 else { 088 location.setAssetLocationCityName(offLocation.getAssetLocationCityName()); 089 location.setAssetLocationContactIdentifier(offLocation.getAssetLocationContactIdentifier()); 090 location.setAssetLocationContactName(offLocation.getAssetLocationContactName()); 091 location.setAssetLocationCountryCode(offLocation.getAssetLocationCountryCode()); 092 location.setAssetLocationInstitutionName(offLocation.getAssetLocationInstitutionName()); 093 location.setAssetLocationPhoneNumber(offLocation.getAssetLocationPhoneNumber()); 094 location.setAssetLocationStateCode(offLocation.getAssetLocationStateCode()); 095 location.setAssetLocationStreetAddress(offLocation.getAssetLocationStreetAddress()); 096 location.setAssetLocationZipCode(offLocation.getAssetLocationZipCode()); 097 return; 098 } 099 } 100 } 101 102 if (removableOffCampusLocation != null) { 103 asset.getAssetLocations().remove(removableOffCampusLocation); 104 } 105 else if (!isOffCampusEmpty) { // add the check for off-campus empty 106 // new offCampusLocation, add it into assetLocation List 107 asset.getAssetLocations().add(offLocation); 108 } 109 110 } 111 112 /** 113 * @see org.kuali.kfs.module.cam.document.service.AssetLocationService#isOffCampusLocationExists(org.kuali.kfs.module.cam.businessobject.AssetLocation) 114 */ 115 public boolean isOffCampusLocationExists(AssetLocation offCampusLocation) { 116 if (ObjectUtils.isNotNull(offCampusLocation)) { 117 if (CamsConstants.AssetLocationTypeCode.OFF_CAMPUS.equalsIgnoreCase(offCampusLocation.getAssetLocationTypeCode())) { 118 return true; 119 } 120 } 121 return false; 122 } 123 124 /** 125 * @see org.kuali.kfs.module.cam.document.service.AssetLocationService#isOffCampusLocationEmpty(org.kuali.kfs.module.cam.businessobject.AssetLocation) 126 */ 127 public boolean isOffCampusLocationEmpty(AssetLocation offCampusLocation) { 128 if (ObjectUtils.isNotNull(offCampusLocation)) { 129 if (StringUtils.isNotBlank(offCampusLocation.getAssetLocationCityName()) || StringUtils.isNotBlank(offCampusLocation.getAssetLocationContactIdentifier()) || StringUtils.isNotBlank(offCampusLocation.getAssetLocationContactName()) || StringUtils.isNotBlank(offCampusLocation.getAssetLocationCountryCode()) || StringUtils.isNotBlank(offCampusLocation.getAssetLocationInstitutionName()) || StringUtils.isNotBlank(offCampusLocation.getAssetLocationPhoneNumber()) || StringUtils.isNotBlank(offCampusLocation.getAssetLocationStateCode()) || StringUtils.isNotBlank(offCampusLocation.getAssetLocationStreetAddress()) || StringUtils.isNotBlank(offCampusLocation.getAssetLocationZipCode())) { 130 return false; 131 } 132 } 133 return true; 134 } 135 136 /** 137 * @see org.kuali.kfs.module.cam.document.service.AssetLocationService#validateLocation(java.lang.Object, 138 * org.kuali.kfs.module.cam.businessobject.Asset, java.util.Map) 139 */ 140 public boolean validateLocation(Map<LocationField, String> fieldMap, BusinessObject businessObject, boolean isCapital, AssetType assetType) { 141 String campusCode = readPropertyValue(businessObject, fieldMap, LocationField.CAMPUS_CODE); 142 String buildingCode = readPropertyValue(businessObject, fieldMap, LocationField.BUILDING_CODE); 143 String roomNumber = readPropertyValue(businessObject, fieldMap, LocationField.ROOM_NUMBER); 144 String subRoomNumber = readPropertyValue(businessObject, fieldMap, LocationField.SUB_ROOM_NUMBER); 145 String contactName = readPropertyValue(businessObject, fieldMap, LocationField.CONTACT_NAME); 146 String streetAddress = readPropertyValue(businessObject, fieldMap, LocationField.STREET_ADDRESS); 147 String cityName = readPropertyValue(businessObject, fieldMap, LocationField.CITY_NAME); 148 String stateCode = readPropertyValue(businessObject, fieldMap, LocationField.STATE_CODE); 149 String zipCode = readPropertyValue(businessObject, fieldMap, LocationField.ZIP_CODE); 150 String countryCode = readPropertyValue(businessObject, fieldMap, LocationField.COUNTRY_CODE); 151 152 // businessObject parameter could be BusinessObjectEntry or TransactionalDocumentEntry 153 DataDictionaryService ddService = this.getDataDictionaryService(); 154 DataDictionaryEntryBase ddEntry = null; 155 if (DocumentBase.class.isAssignableFrom(businessObject.getClass())) { 156 String docTypeName = ddService.getDocumentTypeNameByClass(businessObject.getClass()); 157 ddEntry = ddService.getDataDictionary().getDocumentEntry(docTypeName); 158 } 159 else { 160 ddEntry = this.getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(businessObject.getClass().getName()); 161 } 162 163 boolean onCampus = StringUtils.isNotBlank(buildingCode) || StringUtils.isNotBlank(roomNumber) || StringUtils.isNotBlank(subRoomNumber); 164 boolean offCampus = StringUtils.isNotBlank(contactName) || StringUtils.isNotBlank(streetAddress) || StringUtils.isNotBlank(cityName) || StringUtils.isNotBlank(stateCode) || StringUtils.isNotBlank(zipCode) || StringUtils.isNotBlank(countryCode); 165 166 boolean valid = true; 167 if (onCampus && offCampus) { 168 putError(fieldMap, LocationField.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_CHOOSE_LOCATION_INFO); 169 valid &= false; 170 } 171 else { 172 if (isCapital) { 173 valid &= validateCapitalAssetLocation(assetType, fieldMap, campusCode, buildingCode, roomNumber, subRoomNumber, contactName, streetAddress, cityName, stateCode, zipCode, countryCode, onCampus, offCampus, ddEntry); 174 } 175 else { 176 valid &= validateNonCapitalAssetLocation(fieldMap, contactName, streetAddress, cityName, stateCode, zipCode, countryCode, onCampus, offCampus); 177 } 178 } 179 return valid; 180 } 181 182 183 protected boolean validateCapitalAssetLocation(AssetType assetType, Map<LocationField, String> fieldMap, String campusCode, String buildingCode, String roomNumber, String subRoomNumber, String contactName, String streetAddress, String cityName, String stateCode, String zipCode, String countryCode, boolean onCampus, boolean offCampus, DataDictionaryEntryBase businessObjectEntry) { 184 boolean valid = true; 185 if (ObjectUtils.isNull(assetType)) { 186 GlobalVariables.getMessageMap().putErrorForSectionId(CamsConstants.LOCATION_INFORMATION_SECTION_ID, CamsKeyConstants.AssetLocation.ERROR_CHOOSE_ASSET_TYPE); 187 valid &= false; 188 } 189 else { 190 String label; 191 if (assetType.isRequiredBuildingIndicator() && offCampus) { 192 // off campus information not allowed 193 if (StringUtils.isNotBlank(contactName)) { 194 label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.CONTACT_NAME)).getLabel(); 195 putError(fieldMap, LocationField.CONTACT_NAME, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); 196 valid &= false; 197 } 198 if (StringUtils.isNotBlank(streetAddress)) { 199 label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.STREET_ADDRESS)).getLabel(); 200 putError(fieldMap, LocationField.STREET_ADDRESS, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); 201 valid &= false; 202 } 203 204 if (StringUtils.isNotBlank(cityName)) { 205 label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.CITY_NAME)).getLabel(); 206 putError(fieldMap, LocationField.CITY_NAME, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); 207 valid &= false; 208 } 209 210 if (StringUtils.isNotBlank(stateCode)) { 211 label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.STATE_CODE)).getLabel(); 212 putError(fieldMap, LocationField.STATE_CODE, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); 213 valid &= false; 214 } 215 216 if (StringUtils.isNotBlank(zipCode)) { 217 label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.ZIP_CODE)).getLabel(); 218 putError(fieldMap, LocationField.ZIP_CODE, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); 219 valid &= false; 220 } 221 222 if (StringUtils.isNotBlank(countryCode)) { 223 label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.COUNTRY_CODE)).getLabel(); 224 putError(fieldMap, LocationField.COUNTRY_CODE, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); 225 valid &= false; 226 } 227 } 228 else if (!assetType.isMovingIndicator() && !assetType.isRequiredBuildingIndicator() && onCampus) { 229 // land information cannot have on-campus 230 if (StringUtils.isNotBlank(buildingCode)) { 231 label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.BUILDING_CODE)).getLabel(); 232 putError(fieldMap, LocationField.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); 233 valid &= false; 234 } 235 236 if (StringUtils.isNotBlank(roomNumber)) { 237 label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.ROOM_NUMBER)).getLabel(); 238 putError(fieldMap, LocationField.ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); 239 valid &= false; 240 } 241 242 if (StringUtils.isNotBlank(subRoomNumber)) { 243 label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.SUB_ROOM_NUMBER)).getLabel(); 244 putError(fieldMap, LocationField.SUB_ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); 245 valid &= false; 246 } 247 } 248 else if (onCampus) { 249 valid = validateOnCampusLocation(fieldMap, assetType, campusCode, buildingCode, roomNumber, subRoomNumber); 250 } 251 else if (offCampus) { 252 valid = validateOffCampusLocation(fieldMap, contactName, streetAddress, cityName, stateCode, zipCode, countryCode); 253 } 254 else if (assetType.isMovingIndicator() || assetType.isRequiredBuildingIndicator()) { 255 putError(fieldMap, LocationField.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_LOCATION_INFO_REQUIRED); 256 valid &= false; 257 } 258 } 259 return valid; 260 } 261 262 protected boolean validateNonCapitalAssetLocation(Map<LocationField, String> fieldMap, String contactName, String streetAddress, String cityName, String stateCode, String zipCode, String countryCode, boolean onCampus, boolean offCampus) { 263 boolean valid = true; 264 if (offCampus) { 265 valid = validateOffCampusLocation(fieldMap, contactName, streetAddress, cityName, stateCode, zipCode, countryCode); 266 } 267 return valid; 268 } 269 270 271 /** 272 * Convenience method to append the path prefix 273 */ 274 protected void putError(Map<LocationField, String> fieldMap, LocationField field, String errorKey, String... errorParameters) { 275 GlobalVariables.getMessageMap().putError(fieldMap.get(field), errorKey, errorParameters); 276 } 277 278 protected boolean validateOnCampusLocation(Map<LocationField, String> fieldMap, AssetType assetType, String campusCode, String buildingCode, String buildingRoomNumber, String subRoomNumber) { 279 boolean valid = true; 280 if (assetType.isMovingIndicator()) { 281 if (StringUtils.isBlank(buildingCode)) { 282 putError(fieldMap, LocationField.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_ONCAMPUS_BUILDING_CODE_REQUIRED, assetType.getCapitalAssetTypeDescription()); 283 valid &= false; 284 } 285 if (StringUtils.isBlank(buildingRoomNumber)) { 286 putError(fieldMap, LocationField.ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_ONCAMPUS_BUILDING_ROOM_NUMBER_REQUIRED, assetType.getCapitalAssetTypeDescription()); 287 valid &= false; 288 } 289 } 290 if (assetType.isRequiredBuildingIndicator()) { 291 if (StringUtils.isBlank(buildingCode)) { 292 putError(fieldMap, LocationField.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_ONCAMPUS_BUILDING_CODE_REQUIRED, assetType.getCapitalAssetTypeDescription()); 293 valid &= false; 294 } 295 if (StringUtils.isNotBlank(buildingRoomNumber)) { 296 putError(fieldMap, LocationField.ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_ONCAMPUS_BUILDING_ROOM_NUMBER_NOT_PERMITTED, assetType.getCapitalAssetTypeDescription()); 297 valid &= false; 298 } 299 if (StringUtils.isNotBlank(subRoomNumber)) { 300 putError(fieldMap, LocationField.SUB_ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_ONCAMPUS_SUB_ROOM_NUMBER_NOT_PERMITTED, assetType.getCapitalAssetTypeDescription()); 301 valid &= false; 302 } 303 } 304 return valid; 305 } 306 307 protected boolean validateOffCampusLocation(Map<LocationField, String> fieldMap, String contactName, String streetAddress, String cityName, String stateCode, String zipCode, String countryCode) { 308 boolean valid = true; 309 boolean isCountryUS = false; 310 if (isBlank(fieldMap, LocationField.COUNTRY_CODE, countryCode)) { 311 putError(fieldMap, LocationField.COUNTRY_CODE, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_COUNTRY_REQUIRED); 312 valid &= false; 313 } 314 else { 315 isCountryUS = countryCode.equals(KFSConstants.COUNTRY_CODE_UNITED_STATES); 316 } 317 318 if (isBlank(fieldMap, LocationField.CONTACT_NAME, contactName)) { 319 putError(fieldMap, LocationField.CONTACT_NAME, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_CONTACT_REQUIRED); 320 valid &= false; 321 } 322 323 if (isBlank(fieldMap, LocationField.STREET_ADDRESS, streetAddress)) { 324 putError(fieldMap, LocationField.STREET_ADDRESS, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_ADDRESS_REQUIRED); 325 valid &= false; 326 } 327 if (isBlank(fieldMap, LocationField.CITY_NAME, cityName)) { 328 putError(fieldMap, LocationField.CITY_NAME, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_CITY_REQUIRED); 329 valid &= false; 330 } 331 332 333 if (isCountryUS) { 334 if (isBlank(fieldMap, LocationField.STATE_CODE, stateCode)) { 335 putError(fieldMap, LocationField.STATE_CODE, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_STATE_REQUIRED); 336 valid &= false; 337 } 338 if (isBlank(fieldMap, LocationField.ZIP_CODE, zipCode)) { 339 putError(fieldMap, LocationField.ZIP_CODE, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_ZIP_REQUIRED); 340 valid &= false; 341 } 342 if (!isBlank(fieldMap, LocationField.STATE_CODE, stateCode)) { 343 Map assetLocationMap = new HashMap(); 344 assetLocationMap.put(KFSPropertyConstants.POSTAL_STATE_CODE, stateCode); 345 State locationState = SpringContext.getBean(StateService.class).getByPrimaryId(stateCode); 346 if (ObjectUtils.isNull(locationState)) { 347 putError(fieldMap, LocationField.STATE_CODE, CamsKeyConstants.AssetLocation.ERROR_INVALID_OFF_CAMPUS_STATE, stateCode); 348 valid &= false; 349 } 350 } 351 } 352 353 return valid; 354 } 355 356 protected boolean isBlank(Map<LocationField, String> fieldMap, LocationField field, String countryCode) { 357 return fieldMap.get(field) != null && StringUtils.isBlank(countryCode); 358 } 359 360 protected String readPropertyValue(BusinessObject currObject, Map<LocationField, String> fieldMap, LocationField field) { 361 String stringValue = null; 362 try { 363 String propertyName = fieldMap.get(field); 364 if (propertyName != null) { 365 stringValue = (String) ObjectUtils.getNestedValue(currObject, propertyName); 366 } 367 } 368 catch (Exception e) { 369 throw new RuntimeException(e); 370 } 371 return stringValue; 372 } 373 374 public BusinessObjectService getBusinessObjectService() { 375 return businessObjectService; 376 } 377 378 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 379 this.businessObjectService = businessObjectService; 380 } 381 382 public DataDictionaryService getDataDictionaryService() { 383 return DataDictionaryService; 384 } 385 386 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) { 387 DataDictionaryService = dataDictionaryService; 388 } 389 390 }