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 }