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.ArrayList;
019 import java.util.Arrays;
020 import java.util.HashMap;
021 import java.util.List;
022 import java.util.Map;
023
024 import org.apache.commons.lang.StringUtils;
025 import org.kuali.kfs.coa.businessobject.Account;
026 import org.kuali.kfs.coa.businessobject.ObjectCode;
027 import org.kuali.kfs.coa.service.ObjectCodeService;
028 import org.kuali.kfs.module.cam.CamsConstants;
029 import org.kuali.kfs.module.cam.CamsPropertyConstants;
030 import org.kuali.kfs.module.cam.businessobject.Asset;
031 import org.kuali.kfs.module.cam.businessobject.AssetGlpeSourceDetail;
032 import org.kuali.kfs.module.cam.businessobject.AssetObjectCode;
033 import org.kuali.kfs.module.cam.businessobject.AssetPayment;
034 import org.kuali.kfs.module.cam.businessobject.AssetPaymentDetail;
035 import org.kuali.kfs.module.cam.businessobject.AssetRetirementGlobal;
036 import org.kuali.kfs.module.cam.businessobject.AssetRetirementGlobalDetail;
037 import org.kuali.kfs.module.cam.document.gl.CamsGeneralLedgerPendingEntrySourceBase;
038 import org.kuali.kfs.module.cam.document.service.AssetObjectCodeService;
039 import org.kuali.kfs.module.cam.document.service.AssetPaymentService;
040 import org.kuali.kfs.module.cam.document.service.AssetRetirementService;
041 import org.kuali.kfs.module.cam.document.service.AssetService;
042 import org.kuali.kfs.module.cam.util.ObjectValueUtils;
043 import org.kuali.kfs.sys.KFSConstants;
044 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
045 import org.kuali.kfs.sys.context.SpringContext;
046 import org.kuali.kfs.sys.document.authorization.FinancialSystemMaintenanceDocumentAuthorizerBase;
047 import org.kuali.kfs.sys.service.UniversityDateService;
048 import org.kuali.rice.kns.bo.PersistableBusinessObject;
049 import org.kuali.rice.kns.document.MaintenanceDocument;
050 import org.kuali.rice.kns.service.BusinessObjectService;
051 import org.kuali.rice.kns.service.DocumentHelperService;
052 import org.kuali.rice.kns.service.ParameterService;
053 import org.kuali.rice.kns.util.GlobalVariables;
054 import org.kuali.rice.kns.util.KualiDecimal;
055 import org.kuali.rice.kns.util.ObjectUtils;
056 import org.kuali.rice.kns.util.TypedArrayList;
057
058 public class AssetRetirementServiceImpl implements AssetRetirementService {
059
060 protected enum AmountCategory {
061
062 CAPITALIZATION {
063 void setParams(AssetGlpeSourceDetail postable, AssetPayment assetPayment, AssetObjectCode assetObjectCode) {
064 postable.setCapitalization(true);
065 ParameterService parameterService = SpringContext.getBean(ParameterService.class);
066 String lineDescription = parameterService.getParameterValue(AssetRetirementGlobal.class, CamsConstants.AssetRetirementGlobal.CAPITALIZATION_LINE_DESCRIPTION);
067 postable.setFinancialDocumentLineDescription(lineDescription);
068 postable.setAmount(assetPayment.getAccountChargeAmount());
069 postable.setFinancialObjectCode(assetObjectCode.getCapitalizationFinancialObjectCode());
070 postable.setObjectCode(assetObjectCode.getCapitalizationFinancialObject());
071 };
072 },
073 ACCUMMULATE_DEPRECIATION {
074 void setParams(AssetGlpeSourceDetail postable, AssetPayment assetPayment, AssetObjectCode assetObjectCode) {
075 postable.setAccumulatedDepreciation(true);
076 ParameterService parameterService = SpringContext.getBean(ParameterService.class);
077 String lineDescription = parameterService.getParameterValue(AssetRetirementGlobal.class, CamsConstants.AssetRetirementGlobal.ACCUMULATED_DEPRECIATION_LINE_DESCRIPTION);
078 postable.setFinancialDocumentLineDescription(lineDescription);
079 postable.setAmount(assetPayment.getAccumulatedPrimaryDepreciationAmount());
080 postable.setFinancialObjectCode(assetObjectCode.getAccumulatedDepreciationFinancialObjectCode());
081 postable.setObjectCode(assetObjectCode.getAccumulatedDepreciationFinancialObject());
082 };
083 },
084 OFFSET_AMOUNT {
085 void setParams(AssetGlpeSourceDetail postable, AssetPayment assetPayment, AssetObjectCode assetObjectCode) {
086 postable.setCapitalizationOffset(true);
087 ParameterService parameterService = SpringContext.getBean(ParameterService.class);
088 String lineDescription = parameterService.getParameterValue(AssetRetirementGlobal.class, CamsConstants.AssetRetirementGlobal.OFFSET_AMOUNT_LINE_DESCRIPTION);
089 postable.setFinancialDocumentLineDescription(lineDescription);
090
091 KualiDecimal accumlatedDepreciationAmount = (assetPayment.getAccumulatedPrimaryDepreciationAmount() == null ? new KualiDecimal(0) : assetPayment.getAccumulatedPrimaryDepreciationAmount());
092
093 postable.setAmount(assetPayment.getAccountChargeAmount().subtract(accumlatedDepreciationAmount));
094 postable.setFinancialObjectCode(SpringContext.getBean(ParameterService.class).getParameterValue(AssetRetirementGlobal.class, CamsConstants.Parameters.DEFAULT_GAIN_LOSS_DISPOSITION_OBJECT_CODE).trim());
095
096 Map pkMap = new HashMap();
097 UniversityDateService universityDateService = SpringContext.getBean(UniversityDateService.class);
098 String gainDispositionObjectCode = parameterService.getParameterValue(AssetRetirementGlobal.class, CamsConstants.Parameters.DEFAULT_GAIN_LOSS_DISPOSITION_OBJECT_CODE);
099
100 pkMap.put(KFSConstants.UNIVERSITY_FISCAL_YEAR_PROPERTY_NAME, universityDateService.getCurrentFiscalYear());
101 pkMap.put(KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME, assetPayment.getAsset().getOrganizationOwnerChartOfAccountsCode());
102 pkMap.put(KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, gainDispositionObjectCode);
103
104 ObjectCode offsetFinancialObject = (ObjectCode) SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(ObjectCode.class, pkMap);
105
106 postable.setObjectCode(offsetFinancialObject);
107 };
108 };
109
110 abstract void setParams(AssetGlpeSourceDetail postable, AssetPayment assetPayment, AssetObjectCode assetObjectCode);
111 }
112
113 private UniversityDateService universityDateService;
114 private AssetObjectCodeService assetObjectCodeService;
115 private BusinessObjectService businessObjectService;
116 private AssetPaymentService assetPaymentService;
117 private ParameterService parameterService;
118 private AssetService assetService;
119
120 public ParameterService getParameterService() {
121 return parameterService;
122 }
123
124 public void setParameterService(ParameterService parameterService) {
125 this.parameterService = parameterService;
126 }
127
128 public AssetService getAssetService() {
129 return assetService;
130 }
131
132 public void setAssetService(AssetService assetService) {
133 this.assetService = assetService;
134 }
135
136 public UniversityDateService getUniversityDateService() {
137 return universityDateService;
138 }
139
140 public void setUniversityDateService(UniversityDateService universityDateService) {
141 this.universityDateService = universityDateService;
142 }
143
144 public AssetObjectCodeService getAssetObjectCodeService() {
145 return assetObjectCodeService;
146 }
147
148 public void setAssetObjectCodeService(AssetObjectCodeService assetObjectCodeService) {
149 this.assetObjectCodeService = assetObjectCodeService;
150 }
151
152
153 public BusinessObjectService getBusinessObjectService() {
154 return businessObjectService;
155 }
156
157 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
158 this.businessObjectService = businessObjectService;
159 }
160
161 public AssetPaymentService getAssetPaymentService() {
162 return assetPaymentService;
163 }
164
165 public void setAssetPaymentService(AssetPaymentService assetPaymentService) {
166 this.assetPaymentService = assetPaymentService;
167 }
168
169 /**
170 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#isAssetRetiredBySoldOrAuction(org.kuali.kfs.module.cam.businessobject.AssetRetirementGlobal)
171 */
172 public boolean isAssetRetiredByAuction(AssetRetirementGlobal assetRetirementGlobal) {
173 return CamsConstants.AssetRetirementReasonCode.AUCTION.equalsIgnoreCase(assetRetirementGlobal.getRetirementReasonCode());
174 }
175
176 /**
177 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#isAssetRetiredBySold(org.kuali.kfs.module.cam.businessobject.AssetRetirementGlobal)
178 */
179 public boolean isAssetRetiredBySold(AssetRetirementGlobal assetRetirementGlobal) {
180 return CamsConstants.AssetRetirementReasonCode.SOLD.equalsIgnoreCase(assetRetirementGlobal.getRetirementReasonCode());
181 }
182
183 /**
184 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#isAssetRetiredByExternalTransferOrGift(org.kuali.kfs.module.cam.businessobject.AssetRetirementGlobal)
185 */
186 public boolean isAssetRetiredByExternalTransferOrGift(AssetRetirementGlobal assetRetirementGlobal) {
187 return CamsConstants.AssetRetirementReasonCode.EXTERNAL_TRANSFER.equalsIgnoreCase(assetRetirementGlobal.getRetirementReasonCode()) || CamsConstants.AssetRetirementReasonCode.GIFT.equalsIgnoreCase(assetRetirementGlobal.getRetirementReasonCode());
188 }
189
190 /**
191 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#isAssetRetiredByMerged(org.kuali.kfs.module.cam.businessobject.AssetRetirementGlobal)
192 */
193 public boolean isAssetRetiredByMerged(AssetRetirementGlobal assetRetirementGlobal) {
194 return CamsConstants.AssetRetirementReasonCode.MERGED.equalsIgnoreCase(assetRetirementGlobal.getRetirementReasonCode());
195 }
196
197 /**
198 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#isAssetRetiredByTheft(org.kuali.kfs.module.cam.businessobject.AssetRetirementGlobal)
199 */
200 public boolean isAssetRetiredByTheft(AssetRetirementGlobal assetRetirementGlobal) {
201 return CamsConstants.AssetRetirementReasonCode.THEFT.equalsIgnoreCase(assetRetirementGlobal.getRetirementReasonCode());
202 }
203
204 /**
205 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#getAssetRetirementReasonName(org.kuali.kfs.module.cam.businessobject.AssetRetirementGlobal)
206 */
207 public String getAssetRetirementReasonName(AssetRetirementGlobal assetRetirementGlobal) {
208 return assetRetirementGlobal.getRetirementReason() == null ? new String() : assetRetirementGlobal.getRetirementReason().getRetirementReasonName();
209 }
210
211 /**
212 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#generateOffsetPaymentsForEachSource(org.kuali.kfs.module.cam.businessobject.Asset,
213 * java.util.List, java.lang.String)
214 */
215 public void generateOffsetPaymentsForEachSource(Asset sourceAsset, List<PersistableBusinessObject> persistables, String currentDocumentNumber) {
216 List<AssetPayment> offsetPayments = new TypedArrayList(AssetPayment.class);
217 Integer maxSequenceNo = assetPaymentService.getMaxSequenceNumber(sourceAsset.getCapitalAssetNumber());
218
219 try {
220 for (AssetPayment sourcePayment : sourceAsset.getAssetPayments()) {
221 AssetPayment offsetPayment = new AssetPayment();
222 ObjectValueUtils.copySimpleProperties(sourcePayment, offsetPayment);
223 offsetPayment.setFinancialDocumentTypeCode(CamsConstants.PaymentDocumentTypeCodes.ASSET_RETIREMENT_MERGE);
224 offsetPayment.setDocumentNumber(currentDocumentNumber);
225 offsetPayment.setPaymentSequenceNumber(++maxSequenceNo);
226 assetPaymentService.adjustPaymentAmounts(offsetPayment, true, false);
227 offsetPayments.add(offsetPayment);
228 }
229 }
230 catch (Exception e) {
231 throw new RuntimeException("Error occured while creating offset payment in retirement", e);
232 }
233 persistables.addAll(offsetPayments);
234 }
235
236 /**
237 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#generateNewPaymentForTarget(org.kuali.kfs.module.cam.businessobject.Asset,
238 * org.kuali.kfs.module.cam.businessobject.Asset, java.util.List, java.lang.Integer, java.lang.String)
239 */
240 public Integer generateNewPaymentForTarget(Asset targetAsset, Asset sourceAsset, List<PersistableBusinessObject> persistables, Integer maxSequenceNo, String currentDocumentNumber) {
241 List<AssetPayment> newPayments = new TypedArrayList(AssetPayment.class);
242 try {
243 for (AssetPayment sourcePayment : sourceAsset.getAssetPayments()) {
244 AssetPayment newPayment = new AssetPayment();
245 ObjectValueUtils.copySimpleProperties(sourcePayment, newPayment);
246 newPayment.setCapitalAssetNumber(targetAsset.getCapitalAssetNumber());
247 newPayment.setFinancialDocumentTypeCode(CamsConstants.PaymentDocumentTypeCodes.ASSET_RETIREMENT_MERGE);
248 newPayment.setPaymentSequenceNumber(++maxSequenceNo);
249 newPayment.setDocumentNumber(currentDocumentNumber);
250 assetPaymentService.adjustPaymentAmounts(newPayment, false, false);
251 newPayments.add(newPayment);
252 }
253 }
254 catch (Exception e) {
255 throw new RuntimeException("Error occured while creating new payment in retirement", e);
256 }
257 persistables.addAll(newPayments);
258 return maxSequenceNo;
259 }
260
261
262 /**
263 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#isRetirementReasonCodeInGroup(java.lang.String,
264 * java.lang.String)
265 */
266 public boolean isRetirementReasonCodeInGroup(String reasonCodeGroup, String reasonCode) {
267 if (StringUtils.isBlank(reasonCodeGroup) || StringUtils.isBlank(reasonCode)) {
268 return false;
269 }
270 return Arrays.asList(reasonCodeGroup.split(";")).contains(reasonCode);
271 }
272
273 /**
274 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#isAllowedRetireMultipleAssets(java.lang.String)
275 */
276 public boolean isAllowedRetireMultipleAssets(MaintenanceDocument maintenanceDocument) {
277 FinancialSystemMaintenanceDocumentAuthorizerBase documentAuthorizer = (FinancialSystemMaintenanceDocumentAuthorizerBase) SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(maintenanceDocument);
278 boolean isAuthorized = documentAuthorizer.isAuthorized(maintenanceDocument, CamsConstants.CAM_MODULE_CODE,
279 CamsConstants.PermissionNames.RETIRE_MULTIPLE, GlobalVariables.getUserSession().getPerson().getPrincipalId());
280
281 return isAuthorized;
282 }
283
284 /**
285 * @see org.kuali.kfs.module.cam.document.service.AssetRetirementService#createGLPostables(org.kuali.kfs.module.cam.businessobject.AssetRetirementGlobal,
286 * org.kuali.module.cams.gl.CamsGlPosterBase)
287 */
288 public void createGLPostables(AssetRetirementGlobal assetRetirementGlobal, CamsGeneralLedgerPendingEntrySourceBase assetRetirementGlPoster) {
289
290 List<AssetRetirementGlobalDetail> assetRetirementGlobalDetails = assetRetirementGlobal.getAssetRetirementGlobalDetails();
291
292 for (AssetRetirementGlobalDetail assetRetirementGlobalDetail : assetRetirementGlobalDetails) {
293 Asset asset = assetRetirementGlobalDetail.getAsset();
294
295 for (AssetPayment assetPayment : asset.getAssetPayments()) {
296 if (!getAssetPaymentService().isPaymentFederalOwned(assetPayment) && !("Y".equals(assetPayment.getTransferPaymentCode()))) {
297 List<GeneralLedgerPendingEntrySourceDetail> postables = generateGlPostablesForOnePayment(assetRetirementGlobal.getDocumentNumber(), assetRetirementGlPoster, asset, assetPayment);
298 assetRetirementGlPoster.getPostables().addAll(postables);
299 }
300 }
301 }
302
303 }
304
305 /**
306 * Generate a collection of Postables for each payment.
307 *
308 * @param documentNumber
309 * @param assetRetirementGlPoster
310 * @param asset
311 * @param assetPayment
312 * @return
313 */
314 protected List<GeneralLedgerPendingEntrySourceDetail> generateGlPostablesForOnePayment(String documentNumber, CamsGeneralLedgerPendingEntrySourceBase assetRetirementGlPoster, Asset asset, AssetPayment assetPayment) {
315 List<GeneralLedgerPendingEntrySourceDetail> postables = new ArrayList<GeneralLedgerPendingEntrySourceDetail>();
316 Account plantAccount = getPlantFundAccount(asset, assetPayment);
317
318 if (ObjectUtils.isNotNull(plantAccount)) {
319 if (assetPaymentService.isPaymentEligibleForCapitalizationGLPosting(assetPayment)) {
320 createNewPostable(AmountCategory.CAPITALIZATION, asset, assetPayment, documentNumber, plantAccount, postables);
321 }
322
323 if (assetPaymentService.isPaymentEligibleForAccumDeprGLPosting(assetPayment)) {
324 createNewPostable(AmountCategory.ACCUMMULATE_DEPRECIATION, asset, assetPayment, documentNumber, plantAccount, postables);
325 }
326
327 if (assetPaymentService.isPaymentEligibleForOffsetGLPosting(assetPayment)) {
328 createNewPostable(AmountCategory.OFFSET_AMOUNT, asset, assetPayment, documentNumber, plantAccount, postables);
329 }
330 }
331 return postables;
332 }
333
334 /**
335 * This method creates one postable and sets the values.
336 *
337 * @param category
338 * @param asset
339 * @param assetPayment
340 * @param documentNumber
341 * @param plantAccount
342 * @return
343 */
344 protected void createNewPostable(AmountCategory category, Asset asset, AssetPayment assetPayment, String documentNumber, Account plantAccount, List<GeneralLedgerPendingEntrySourceDetail> postables) {
345 boolean success = true;
346 AssetGlpeSourceDetail postable = new AssetGlpeSourceDetail();
347
348 AssetObjectCode assetObjectCode = getAssetObjectCode(asset, assetPayment);
349 category.setParams(postable, assetPayment, assetObjectCode);
350
351 // Set Postable attributes which are common among Capitalized, Accumulated Depreciation and gain/loss disposition .
352 postable.setDocumentNumber(documentNumber);
353 postable.setAccount(plantAccount);
354 postable.setAccountNumber(plantAccount.getAccountNumber());
355 postable.setBalanceTypeCode(CamsConstants.Postable.GL_BALANCE_TYPE_CODE_AC);
356 postable.setChartOfAccountsCode(asset.getOrganizationOwnerChartOfAccountsCode());
357
358 postable.setPostingYear(universityDateService.getCurrentFiscalYear());
359 // Fields copied from payment
360 postable.setFinancialSubObjectCode(assetPayment.getFinancialSubObjectCode());
361 postable.setProjectCode(assetPayment.getProjectCode());
362 postable.setSubAccountNumber(assetPayment.getSubAccountNumber());
363 postable.setOrganizationReferenceId(assetPayment.getOrganizationReferenceId());
364 postables.add(postable);
365 }
366
367 protected AssetObjectCode getAssetObjectCode(Asset asset, AssetPayment assetPayment) {
368 ObjectCodeService objectCodeService = (ObjectCodeService) SpringContext.getBean(ObjectCodeService.class);
369 ObjectCode objectCode = objectCodeService.getByPrimaryIdForCurrentYear(assetPayment.getChartOfAccountsCode(), assetPayment.getFinancialObjectCode());
370
371 AssetObjectCode assetObjectCode = assetObjectCodeService.findAssetObjectCode(asset.getOrganizationOwnerChartOfAccountsCode(), objectCode.getFinancialObjectSubTypeCode());
372 return assetObjectCode;
373 }
374
375
376 /**
377 * Get the offset Object Code.
378 *
379 * @param asset
380 * @return
381 */
382 public ObjectCode getOffsetFinancialObject(String chartOfAccountsCode) {
383 Map pkMap = new HashMap();
384 UniversityDateService universityDateService = SpringContext.getBean(UniversityDateService.class);
385 ParameterService parameterService = SpringContext.getBean(ParameterService.class);
386 String gainDispositionObjectCode = parameterService.getParameterValue(AssetRetirementGlobal.class, CamsConstants.Parameters.DEFAULT_GAIN_LOSS_DISPOSITION_OBJECT_CODE);
387
388 pkMap.put(KFSConstants.UNIVERSITY_FISCAL_YEAR_PROPERTY_NAME, universityDateService.getCurrentFiscalYear());
389 pkMap.put(KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME, chartOfAccountsCode);
390 pkMap.put(KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME, gainDispositionObjectCode);
391
392 return (ObjectCode) SpringContext.getBean(BusinessObjectService.class).findByPrimaryKey(ObjectCode.class, pkMap);
393 }
394
395
396 /**
397 * Get the corresponding Plant Fund Account object based on the payment's financialObjectSubTypeCode.
398 *
399 * @param asset
400 * @param payment
401 * @return
402 */
403 protected Account getPlantFundAccount(Asset asset, AssetPayment payment) {
404 Account plantFundAccount = null;
405
406 payment.refreshReferenceObject(CamsPropertyConstants.AssetPayment.FINANCIAL_OBJECT);
407 asset.refreshReferenceObject(CamsPropertyConstants.Asset.ORGANIZATION_OWNER_ACCOUNT);
408
409 if (ObjectUtils.isNotNull(payment.getFinancialObject()) && ObjectUtils.isNotNull(asset.getOrganizationOwnerAccount())) {
410 ObjectCodeService objectCodeService = (ObjectCodeService) SpringContext.getBean(ObjectCodeService.class);
411 ObjectCode objectCode = objectCodeService.getByPrimaryIdForCurrentYear(payment.getChartOfAccountsCode(), payment.getFinancialObjectCode());
412
413 String financialObjectSubTypeCode = objectCode.getFinancialObjectSubTypeCode();
414
415 if (assetService.isAssetMovableCheckByPayment(financialObjectSubTypeCode)) {
416 plantFundAccount = asset.getOrganizationOwnerAccount().getOrganization().getOrganizationPlantAccount();
417 }
418 else {
419 plantFundAccount = asset.getOrganizationOwnerAccount().getOrganization().getCampusPlantAccount();
420 }
421 }
422
423 return plantFundAccount;
424 }
425
426 /**
427 * This method generates the calculatedTotal amount based on salePrice + handlingFeeAmount + preventiveMaintenanceAmount.
428 *
429 * @param salePrice
430 * @param handlingFeeAmount
431 * @param preventiveMaintenanceAmount
432 * @return
433 */
434 public String generateCalculatedTotal(String salePrice, String handlingFeeAmount, String preventiveMaintenanceAmount) {
435 KualiDecimal calculatedTotal = KualiDecimal.ZERO;
436
437 if (!salePrice.isEmpty()) {
438 KualiDecimal testAmount = toKualiDecimal(salePrice);
439 if(testAmount.isZero()){
440 return "Please enter Sale Price in 1,234,567.00 Format";
441 }
442 calculatedTotal = calculatedTotal.add(testAmount);
443 }
444 if (!handlingFeeAmount.isEmpty()) {
445 KualiDecimal testAmount = toKualiDecimal(handlingFeeAmount);
446 if(testAmount.isZero()){
447 return "Please enter Handling Fee Amount in 1,234,567.00 Format";
448 }
449 calculatedTotal = calculatedTotal.add(testAmount);
450 }
451 if (!preventiveMaintenanceAmount.isEmpty()) {
452 KualiDecimal testAmount = toKualiDecimal(preventiveMaintenanceAmount);
453 if(testAmount.isZero()){
454 return "Please enter Preventive Maintenance Amount in 1,234,567.00 Format";
455 }
456 calculatedTotal = calculatedTotal.add(testAmount);
457 }
458
459 return calculatedTotal.toString();
460 }
461
462 /**
463 * This method converts a String to a KualiDecimal via Double. Or else returns a Zero to invoke proper error message and to avoid breaking DWR call
464 *
465 * @param amount
466 * @return
467 */
468 protected KualiDecimal toKualiDecimal(String amount) {
469 KualiDecimal newAmount;
470 try{
471 newAmount = new KualiDecimal(java.lang.Double.parseDouble(amount));
472 }catch(NumberFormatException e){
473 return KualiDecimal.ZERO;
474 }
475 return newAmount;
476 }
477
478 }