/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.cam.document.service.impl; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.module.cam.CamsConstants; import org.kuali.kfs.module.cam.CamsKeyConstants; import org.kuali.kfs.module.cam.businessobject.Asset; import org.kuali.kfs.module.cam.businessobject.AssetLocation; import org.kuali.kfs.module.cam.businessobject.AssetType; import org.kuali.kfs.module.cam.document.service.AssetLocationService; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.rice.kns.service.DataDictionaryService; import org.kuali.rice.krad.bo.BusinessObject; import org.kuali.rice.krad.datadictionary.DataDictionaryEntryBase; import org.kuali.rice.krad.document.DocumentBase; import org.kuali.rice.krad.service.BusinessObjectService; import org.kuali.rice.krad.util.GlobalVariables; import org.kuali.rice.krad.util.ObjectUtils; import org.kuali.rice.location.api.state.State; import org.kuali.rice.location.api.state.StateService; public class AssetLocationServiceImpl implements AssetLocationService { private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AssetLocationService.class); private BusinessObjectService businessObjectService; private DataDictionaryService DataDictionaryService; /** * @see org.kuali.kfs.module.cam.document.service.AssetLocationService#setOffCampusLocation(org.kuali.kfs.module.cam.businessobject.Asset) */ public void setOffCampusLocation(Asset asset) { List<AssetLocation> assetLocations = asset.getAssetLocations(); AssetLocation offCampusLocation = null; for (AssetLocation location : assetLocations) { if (CamsConstants.AssetLocationTypeCode.OFF_CAMPUS.equalsIgnoreCase(location.getAssetLocationTypeCode())) { // We need a new instance for asset location. Otherwise, if we copy it from the assetLocations collection, it could // have newBO and oldBO pointing to the same AssetLocation instance which is bad. offCampusLocation = new AssetLocation(location); break; } } if (ObjectUtils.isNull(offCampusLocation)) { offCampusLocation = new AssetLocation(asset.getCapitalAssetNumber()); offCampusLocation.setAssetLocationTypeCode(CamsConstants.AssetLocationTypeCode.OFF_CAMPUS); } asset.setOffCampusLocation(offCampusLocation); } /** * update existing offCampusLocation * * @see org.kuali.kfs.module.cam.document.service.AssetLocationService#updateOffCampusLocation(org.kuali.kfs.module.cam.businessobject.Asset) */ public void updateOffCampusLocation(Asset asset) { AssetLocation offLocation = asset.getOffCampusLocation(); boolean isOffCampusEmpty = isOffCampusLocationEmpty(offLocation); AssetLocation removableOffCampusLocation = null; for (AssetLocation location : asset.getAssetLocations()) { if (CamsConstants.AssetLocationTypeCode.OFF_CAMPUS.equalsIgnoreCase(location.getAssetLocationTypeCode())) { if (isOffCampusEmpty) { removableOffCampusLocation = location; } else { location.setAssetLocationCityName(offLocation.getAssetLocationCityName()); location.setAssetLocationContactIdentifier(offLocation.getAssetLocationContactIdentifier()); location.setAssetLocationContactName(offLocation.getAssetLocationContactName()); location.setAssetLocationCountryCode(offLocation.getAssetLocationCountryCode()); location.setAssetLocationInstitutionName(offLocation.getAssetLocationInstitutionName()); location.setAssetLocationPhoneNumber(offLocation.getAssetLocationPhoneNumber()); location.setAssetLocationStateCode(offLocation.getAssetLocationStateCode()); location.setAssetLocationStreetAddress(offLocation.getAssetLocationStreetAddress()); location.setAssetLocationZipCode(offLocation.getAssetLocationZipCode()); return; } } } if (removableOffCampusLocation != null) { asset.getAssetLocations().remove(removableOffCampusLocation); } else if (!isOffCampusEmpty) { // add the check for off-campus empty // new offCampusLocation, add it into assetLocation List asset.getAssetLocations().add(offLocation); } } /** * @see org.kuali.kfs.module.cam.document.service.AssetLocationService#isOffCampusLocationExists(org.kuali.kfs.module.cam.businessobject.AssetLocation) */ public boolean isOffCampusLocationExists(AssetLocation offCampusLocation) { if (ObjectUtils.isNotNull(offCampusLocation)) { if (CamsConstants.AssetLocationTypeCode.OFF_CAMPUS.equalsIgnoreCase(offCampusLocation.getAssetLocationTypeCode())) { return true; } } return false; } /** * @see org.kuali.kfs.module.cam.document.service.AssetLocationService#isOffCampusLocationEmpty(org.kuali.kfs.module.cam.businessobject.AssetLocation) */ public boolean isOffCampusLocationEmpty(AssetLocation offCampusLocation) { if (ObjectUtils.isNotNull(offCampusLocation)) { 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())) { return false; } } return true; } /** * @see org.kuali.kfs.module.cam.document.service.AssetLocationService#validateLocation(java.lang.Object, * org.kuali.kfs.module.cam.businessobject.Asset, java.util.Map) */ public boolean validateLocation(Map<LocationField, String> fieldMap, BusinessObject businessObject, boolean isCapital, AssetType assetType) { String campusCode = readPropertyValue(businessObject, fieldMap, LocationField.CAMPUS_CODE); String buildingCode = readPropertyValue(businessObject, fieldMap, LocationField.BUILDING_CODE); String roomNumber = readPropertyValue(businessObject, fieldMap, LocationField.ROOM_NUMBER); String subRoomNumber = readPropertyValue(businessObject, fieldMap, LocationField.SUB_ROOM_NUMBER); String contactName = readPropertyValue(businessObject, fieldMap, LocationField.CONTACT_NAME); String streetAddress = readPropertyValue(businessObject, fieldMap, LocationField.STREET_ADDRESS); String cityName = readPropertyValue(businessObject, fieldMap, LocationField.CITY_NAME); String stateCode = readPropertyValue(businessObject, fieldMap, LocationField.STATE_CODE); String zipCode = readPropertyValue(businessObject, fieldMap, LocationField.ZIP_CODE); String countryCode = readPropertyValue(businessObject, fieldMap, LocationField.COUNTRY_CODE); // businessObject parameter could be BusinessObjectEntry or TransactionalDocumentEntry DataDictionaryService ddService = this.getDataDictionaryService(); DataDictionaryEntryBase ddEntry = null; if (DocumentBase.class.isAssignableFrom(businessObject.getClass())) { String docTypeName = ddService.getDocumentTypeNameByClass(businessObject.getClass()); ddEntry = ddService.getDataDictionary().getDocumentEntry(docTypeName); } else { ddEntry = this.getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(businessObject.getClass().getName()); } boolean onCampus = StringUtils.isNotBlank(buildingCode) || StringUtils.isNotBlank(roomNumber) || StringUtils.isNotBlank(subRoomNumber); boolean offCampus = StringUtils.isNotBlank(contactName) || StringUtils.isNotBlank(streetAddress) || StringUtils.isNotBlank(cityName) || StringUtils.isNotBlank(stateCode) || StringUtils.isNotBlank(zipCode) || StringUtils.isNotBlank(countryCode); boolean valid = true; if (onCampus && offCampus) { putError(fieldMap, LocationField.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_CHOOSE_LOCATION_INFO); valid &= false; } else { if (isCapital) { valid &= validateCapitalAssetLocation(assetType, fieldMap, campusCode, buildingCode, roomNumber, subRoomNumber, contactName, streetAddress, cityName, stateCode, zipCode, countryCode, onCampus, offCampus, ddEntry); } else { valid &= validateNonCapitalAssetLocation(fieldMap, contactName, streetAddress, cityName, stateCode, zipCode, countryCode, onCampus, offCampus); } } return valid; } 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) { boolean valid = true; if (ObjectUtils.isNull(assetType)) { GlobalVariables.getMessageMap().putErrorForSectionId(CamsConstants.LOCATION_INFORMATION_SECTION_ID, CamsKeyConstants.AssetLocation.ERROR_CHOOSE_ASSET_TYPE); valid &= false; } else { String label; if (assetType.isRequiredBuildingIndicator() && offCampus) { // off campus information not allowed if (StringUtils.isNotBlank(contactName)) { label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.CONTACT_NAME)).getLabel(); putError(fieldMap, LocationField.CONTACT_NAME, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); valid &= false; } if (StringUtils.isNotBlank(streetAddress)) { label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.STREET_ADDRESS)).getLabel(); putError(fieldMap, LocationField.STREET_ADDRESS, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); valid &= false; } if (StringUtils.isNotBlank(cityName)) { label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.CITY_NAME)).getLabel(); putError(fieldMap, LocationField.CITY_NAME, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); valid &= false; } if (StringUtils.isNotBlank(stateCode)) { label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.STATE_CODE)).getLabel(); putError(fieldMap, LocationField.STATE_CODE, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); valid &= false; } if (StringUtils.isNotBlank(zipCode)) { label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.ZIP_CODE)).getLabel(); putError(fieldMap, LocationField.ZIP_CODE, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); valid &= false; } if (StringUtils.isNotBlank(countryCode)) { label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.COUNTRY_CODE)).getLabel(); putError(fieldMap, LocationField.COUNTRY_CODE, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); valid &= false; } } else if (!assetType.isMovingIndicator() && !assetType.isRequiredBuildingIndicator() && onCampus) { // land information cannot have on-campus if (StringUtils.isNotBlank(buildingCode)) { label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.BUILDING_CODE)).getLabel(); putError(fieldMap, LocationField.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); valid &= false; } if (StringUtils.isNotBlank(roomNumber)) { label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.ROOM_NUMBER)).getLabel(); putError(fieldMap, LocationField.ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); valid &= false; } if (StringUtils.isNotBlank(subRoomNumber)) { label = businessObjectEntry.getAttributeDefinition(fieldMap.get(LocationField.SUB_ROOM_NUMBER)).getLabel(); putError(fieldMap, LocationField.SUB_ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_LOCATION_NOT_PERMITTED_ASSET_TYPE, new String[] { label, assetType.getCapitalAssetTypeDescription() }); valid &= false; } } else if (onCampus) { valid = validateOnCampusLocation(fieldMap, assetType, campusCode, buildingCode, roomNumber, subRoomNumber); } else if (offCampus) { valid = validateOffCampusLocation(fieldMap, contactName, streetAddress, cityName, stateCode, zipCode, countryCode); } else if (assetType.isMovingIndicator() || assetType.isRequiredBuildingIndicator()) { putError(fieldMap, LocationField.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_LOCATION_INFO_REQUIRED); valid &= false; } } return valid; } protected boolean validateNonCapitalAssetLocation(Map<LocationField, String> fieldMap, String contactName, String streetAddress, String cityName, String stateCode, String zipCode, String countryCode, boolean onCampus, boolean offCampus) { boolean valid = true; if (offCampus) { valid = validateOffCampusLocation(fieldMap, contactName, streetAddress, cityName, stateCode, zipCode, countryCode); } return valid; } /** * Convenience method to append the path prefix */ protected void putError(Map<LocationField, String> fieldMap, LocationField field, String errorKey, String... errorParameters) { GlobalVariables.getMessageMap().putError(fieldMap.get(field), errorKey, errorParameters); } protected boolean validateOnCampusLocation(Map<LocationField, String> fieldMap, AssetType assetType, String campusCode, String buildingCode, String buildingRoomNumber, String subRoomNumber) { boolean valid = true; if (assetType.isMovingIndicator()) { if (StringUtils.isBlank(buildingCode)) { putError(fieldMap, LocationField.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_ONCAMPUS_BUILDING_CODE_REQUIRED, assetType.getCapitalAssetTypeDescription()); valid &= false; } if (StringUtils.isBlank(buildingRoomNumber)) { putError(fieldMap, LocationField.ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_ONCAMPUS_BUILDING_ROOM_NUMBER_REQUIRED, assetType.getCapitalAssetTypeDescription()); valid &= false; } } if (assetType.isRequiredBuildingIndicator()) { if (StringUtils.isBlank(buildingCode)) { putError(fieldMap, LocationField.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_ONCAMPUS_BUILDING_CODE_REQUIRED, assetType.getCapitalAssetTypeDescription()); valid &= false; } if (StringUtils.isNotBlank(buildingRoomNumber)) { putError(fieldMap, LocationField.ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_ONCAMPUS_BUILDING_ROOM_NUMBER_NOT_PERMITTED, assetType.getCapitalAssetTypeDescription()); valid &= false; } if (StringUtils.isNotBlank(subRoomNumber)) { putError(fieldMap, LocationField.SUB_ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_ONCAMPUS_SUB_ROOM_NUMBER_NOT_PERMITTED, assetType.getCapitalAssetTypeDescription()); valid &= false; } } return valid; } protected boolean validateOffCampusLocation(Map<LocationField, String> fieldMap, String contactName, String streetAddress, String cityName, String stateCode, String zipCode, String countryCode) { boolean valid = true; boolean isCountryUS = false; if (isBlank(fieldMap, LocationField.COUNTRY_CODE, countryCode)) { putError(fieldMap, LocationField.COUNTRY_CODE, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_COUNTRY_REQUIRED); valid &= false; } else { isCountryUS = countryCode.equals(KFSConstants.COUNTRY_CODE_UNITED_STATES); } if (isBlank(fieldMap, LocationField.CONTACT_NAME, contactName)) { putError(fieldMap, LocationField.CONTACT_NAME, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_CONTACT_REQUIRED); valid &= false; } if (isBlank(fieldMap, LocationField.STREET_ADDRESS, streetAddress)) { putError(fieldMap, LocationField.STREET_ADDRESS, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_ADDRESS_REQUIRED); valid &= false; } if (isBlank(fieldMap, LocationField.CITY_NAME, cityName)) { putError(fieldMap, LocationField.CITY_NAME, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_CITY_REQUIRED); valid &= false; } if (isCountryUS) { if (isBlank(fieldMap, LocationField.STATE_CODE, stateCode)) { putError(fieldMap, LocationField.STATE_CODE, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_STATE_REQUIRED); valid &= false; } if (isBlank(fieldMap, LocationField.ZIP_CODE, zipCode)) { putError(fieldMap, LocationField.ZIP_CODE, CamsKeyConstants.AssetLocation.ERROR_OFFCAMPUS_ZIP_REQUIRED); valid &= false; } if (!isBlank(fieldMap, LocationField.STATE_CODE, stateCode)) { Map assetLocationMap = new HashMap(); assetLocationMap.put(KFSPropertyConstants.POSTAL_STATE_CODE, stateCode); State locationState = SpringContext.getBean(StateService.class).getState(countryCode, stateCode); if (ObjectUtils.isNull(locationState)) { putError(fieldMap, LocationField.STATE_CODE, CamsKeyConstants.AssetLocation.ERROR_INVALID_OFF_CAMPUS_STATE, stateCode); valid &= false; } } } return valid; } protected boolean isBlank(Map<LocationField, String> fieldMap, LocationField field, String countryCode) { return fieldMap.get(field) != null && StringUtils.isBlank(countryCode); } protected String readPropertyValue(BusinessObject currObject, Map<LocationField, String> fieldMap, LocationField field) { String stringValue = null; try { String propertyName = fieldMap.get(field); if (propertyName != null) { stringValue = (String) ObjectUtils.getNestedValue(currObject, propertyName); } } catch (Exception e) { throw new RuntimeException(e); } return stringValue; } public BusinessObjectService getBusinessObjectService() { return businessObjectService; } public void setBusinessObjectService(BusinessObjectService businessObjectService) { this.businessObjectService = businessObjectService; } public DataDictionaryService getDataDictionaryService() { return DataDictionaryService; } public void setDataDictionaryService(DataDictionaryService dataDictionaryService) { DataDictionaryService = dataDictionaryService; } }