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.validation.impl;
017
018 import java.util.ArrayList;
019 import java.util.HashMap;
020 import java.util.List;
021 import java.util.Map;
022
023 import org.apache.commons.lang.StringUtils;
024 import org.kuali.kfs.coa.businessobject.Account;
025 import org.kuali.kfs.coa.businessobject.ObjectCode;
026 import org.kuali.kfs.coa.businessobject.OffsetDefinition;
027 import org.kuali.kfs.coa.businessobject.Organization;
028 import org.kuali.kfs.coa.service.ObjectCodeService;
029 import org.kuali.kfs.coa.service.OffsetDefinitionService;
030 import org.kuali.kfs.fp.document.TransferOfFundsDocument;
031 import org.kuali.kfs.module.cam.CamsConstants;
032 import org.kuali.kfs.module.cam.CamsKeyConstants;
033 import org.kuali.kfs.module.cam.CamsPropertyConstants;
034 import org.kuali.kfs.module.cam.businessobject.Asset;
035 import org.kuali.kfs.module.cam.businessobject.AssetGlobal;
036 import org.kuali.kfs.module.cam.businessobject.AssetObjectCode;
037 import org.kuali.kfs.module.cam.businessobject.AssetPayment;
038 import org.kuali.kfs.module.cam.document.AssetTransferDocument;
039 import org.kuali.kfs.module.cam.document.service.AssetLocationService;
040 import org.kuali.kfs.module.cam.document.service.AssetObjectCodeService;
041 import org.kuali.kfs.module.cam.document.service.AssetPaymentService;
042 import org.kuali.kfs.module.cam.document.service.AssetService;
043 import org.kuali.kfs.module.cam.document.service.AssetTransferService;
044 import org.kuali.kfs.module.cam.document.service.AssetLocationService.LocationField;
045 import org.kuali.kfs.module.cam.service.AssetLockService;
046 import org.kuali.kfs.sys.KFSConstants;
047 import org.kuali.kfs.sys.context.SpringContext;
048 import org.kuali.kfs.sys.document.authorization.FinancialSystemTransactionalDocumentAuthorizerBase;
049 import org.kuali.kfs.sys.document.validation.impl.GeneralLedgerPostingDocumentRuleBase;
050 import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService;
051 import org.kuali.kfs.sys.service.UniversityDateService;
052 import org.kuali.rice.kim.bo.Person;
053 import org.kuali.rice.kim.service.PersonService;
054 import org.kuali.rice.kns.document.Document;
055 import org.kuali.rice.kns.exception.ValidationException;
056 import org.kuali.rice.kns.service.DocumentHelperService;
057 import org.kuali.rice.kns.service.ParameterService;
058 import org.kuali.rice.kns.util.GlobalVariables;
059 import org.kuali.rice.kns.util.ObjectUtils;
060 import org.kuali.rice.kns.util.TypedArrayList;
061
062 public class AssetTransferDocumentRule extends GeneralLedgerPostingDocumentRuleBase {
063 protected static final Map<LocationField, String> LOCATION_FIELD_MAP = new HashMap<LocationField, String>();
064 static {
065 LOCATION_FIELD_MAP.put(LocationField.CAMPUS_CODE, CamsPropertyConstants.AssetTransferDocument.CAMPUS_CODE);
066 LOCATION_FIELD_MAP.put(LocationField.BUILDING_CODE, CamsPropertyConstants.AssetTransferDocument.BUILDING_CODE);
067 LOCATION_FIELD_MAP.put(LocationField.ROOM_NUMBER, CamsPropertyConstants.AssetTransferDocument.BUILDING_ROOM_NUMBER);
068 LOCATION_FIELD_MAP.put(LocationField.SUB_ROOM_NUMBER, CamsPropertyConstants.AssetTransferDocument.BUILDING_SUB_ROOM_NUMBER);
069 LOCATION_FIELD_MAP.put(LocationField.STREET_ADDRESS, CamsPropertyConstants.AssetTransferDocument.OFF_CAMPUS_ADDRESS);
070 LOCATION_FIELD_MAP.put(LocationField.CITY_NAME, CamsPropertyConstants.AssetTransferDocument.OFF_CAMPUS_CITY);
071 LOCATION_FIELD_MAP.put(LocationField.STATE_CODE, CamsPropertyConstants.AssetTransferDocument.OFF_CAMPUS_STATE_CODE);
072 LOCATION_FIELD_MAP.put(LocationField.ZIP_CODE, CamsPropertyConstants.AssetTransferDocument.OFF_CAMPUS_ZIP);
073 LOCATION_FIELD_MAP.put(LocationField.COUNTRY_CODE, CamsPropertyConstants.AssetGlobalDetail.OFF_CAMPUS_COUNTRY_CODE);
074 LOCATION_FIELD_MAP.put(LocationField.CONTACT_NAME, CamsPropertyConstants.AssetTransferDocument.OFF_CAMPUS_CONTACT_NAME);
075 }
076
077 protected UniversityDateService universityDateService;
078 protected AssetPaymentService assetPaymentService;
079 protected AssetService assetService;
080 protected ObjectCodeService objectCodeService;
081 protected AssetLockService assetLockService;
082
083 /**
084 * @see org.kuali.rice.kns.rules.DocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.kns.document.Document)
085 */
086 @Override
087 protected boolean processCustomSaveDocumentBusinessRules(Document document) {
088 AssetTransferDocument assetTransferDocument = (AssetTransferDocument) document;
089 Asset asset = assetTransferDocument.getAsset();
090 boolean valid = checkReferencesExist(assetTransferDocument);
091 assetTransferDocument.clearGlPostables();
092 if (valid && (valid &= validateAssetObjectCodeDefn(assetTransferDocument, asset))) {
093 SpringContext.getBean(AssetTransferService.class).createGLPostables(assetTransferDocument);
094 if (!SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(assetTransferDocument)) {
095 throw new ValidationException("General Ledger GLPE generation failed");
096 }
097 }
098
099 return valid;
100 }
101
102 /**
103 * Retrieve asset number need to be locked.
104 *
105 * @param document
106 * @return
107 */
108 protected List<Long> retrieveAssetNumberForLocking(Document document) {
109 AssetTransferDocument assetTransferDocument = (AssetTransferDocument) document;
110 List<Long> assetNumbers = new ArrayList<Long>();
111 if (assetTransferDocument.getAsset().getCapitalAssetNumber() != null) {
112 assetNumbers.add(assetTransferDocument.getAsset().getCapitalAssetNumber());
113 }
114 return assetNumbers;
115 }
116
117 protected boolean validateAssetObjectCodeDefn(AssetTransferDocument assetTransferDocument, Asset asset) {
118
119 if ( !isNonCapitalAsset(asset) && StringUtils.isNotBlank(assetTransferDocument.getOrganizationOwnerChartOfAccountsCode()) && StringUtils.isNotBlank(assetTransferDocument.getOrganizationOwnerAccountNumber())) {
120 boolean valid = true;
121 List<AssetPayment> assetPayments = asset.getAssetPayments();
122 ObjectCodeService objectCodeService = (ObjectCodeService) SpringContext.getBean(ObjectCodeService.class);
123 for (AssetPayment assetPayment : assetPayments) {
124 if (SpringContext.getBean(AssetPaymentService.class).isPaymentEligibleForGLPosting(assetPayment) && !assetPayment.getAccountChargeAmount().isZero()) {
125 // validate for transfer source
126
127 ObjectCode objectCode = objectCodeService.getByPrimaryIdForCurrentYear(assetPayment.getChartOfAccountsCode(), assetPayment.getFinancialObjectCode());
128
129 AssetObjectCode originAssetObjectCode = SpringContext.getBean(AssetObjectCodeService.class).findAssetObjectCode(asset.getOrganizationOwnerChartOfAccountsCode(), objectCode.getFinancialObjectSubTypeCode());
130 if (valid &= validateAssetObjectCode(originAssetObjectCode, asset.getOrganizationOwnerChartOfAccountsCode(), objectCode.getFinancialObjectSubTypeCode())) {
131 // validate object codes used to generate Capitalization/Accumulated Depreciation/Offset GL Postings.
132 valid &= validateFinancialObjectCodes(asset, assetPayment, originAssetObjectCode);
133 }
134 // validate for transfer target
135 AssetObjectCode targetAssetObjectCode = SpringContext.getBean(AssetObjectCodeService.class).findAssetObjectCode(assetTransferDocument.getOrganizationOwnerChartOfAccountsCode(), objectCode.getFinancialObjectSubTypeCode());
136 if (valid &= validateAssetObjectCode(targetAssetObjectCode, assetTransferDocument.getOrganizationOwnerChartOfAccountsCode(), objectCode.getFinancialObjectSubTypeCode())) {
137 // validate object codes used to generate Capitalization/Accumulated Depreciation/Offset GL Postings.
138 valid &= validateFinancialObjectCodes(asset, assetPayment, targetAssetObjectCode);
139 }
140 }
141 }
142 return valid;
143 }
144 else {
145 return true;
146 }
147
148 }
149
150 /**
151 * Asset Object Code must exist as an active status.
152 *
153 * @param asset
154 * @param assetPayment
155 * @return
156 */
157 protected boolean validateAssetObjectCode(AssetObjectCode assetObjectCode, String chartOfAccountsCode, String finObjectSubTypeCode) {
158 boolean valid = true;
159 if (ObjectUtils.isNull(assetObjectCode)) {
160 putError(CamsConstants.DOCUMENT_NUMBER_PATH, CamsKeyConstants.GLPosting.ERROR_ASSET_OBJECT_CODE_NOT_FOUND, new String[] { chartOfAccountsCode, finObjectSubTypeCode });
161 valid &= false;
162 }// check Asset Object Code active
163 else if (!assetObjectCode.isActive()) {
164 putError(CamsConstants.DOCUMENT_NUMBER_PATH, CamsKeyConstants.GLPosting.ERROR_ASSET_OBJECT_CODE_INACTIVE, new String[] { chartOfAccountsCode, finObjectSubTypeCode });
165 valid = false;
166 }
167
168 return valid;
169 }
170
171 /**
172 * Check Financial Object Code for GLPE.
173 *
174 * @param asset
175 * @param assetPayment
176 * @return
177 */
178 protected boolean validateFinancialObjectCodes(Asset asset, AssetPayment assetPayment, AssetObjectCode assetObjectCode) {
179 AssetPaymentService assetPaymentService = getAssetPaymentService();
180 boolean valid = true;
181
182 if (assetPaymentService.isPaymentEligibleForCapitalizationGLPosting(assetPayment)) {
183 // check for capitalization financial object code existing.
184 assetObjectCode.refreshReferenceObject(CamsPropertyConstants.AssetObjectCode.CAPITALIZATION_FINANCIAL_OBJECT);
185 valid &= validateFinObjectCodeForGLPosting(asset.getOrganizationOwnerChartOfAccountsCode(), assetObjectCode.getCapitalizationFinancialObjectCode(), assetObjectCode.getCapitalizationFinancialObject(), CamsConstants.GLPostingObjectCodeType.CAPITALIZATION);
186 }
187 if (assetPaymentService.isPaymentEligibleForAccumDeprGLPosting(assetPayment)) {
188 // check for accumulate depreciation financial Object Code existing
189 assetObjectCode.refreshReferenceObject(CamsPropertyConstants.AssetObjectCode.ACCUMULATED_DEPRECIATION_FINANCIAL_OBJECT);
190 valid &= validateFinObjectCodeForGLPosting(asset.getOrganizationOwnerChartOfAccountsCode(), assetObjectCode.getAccumulatedDepreciationFinancialObjectCode(), assetObjectCode.getAccumulatedDepreciationFinancialObject(), CamsConstants.GLPostingObjectCodeType.ACCUMMULATE_DEPRECIATION);
191 }
192 if (assetPaymentService.isPaymentEligibleForOffsetGLPosting(assetPayment)) {
193 // check for offset financial object code existing.
194 OffsetDefinition offsetDefinition = SpringContext.getBean(OffsetDefinitionService.class).getByPrimaryId(getUniversityDateService().getCurrentFiscalYear(), assetObjectCode.getChartOfAccountsCode(), CamsConstants.AssetTransfer.DOCUMENT_TYPE_CODE, CamsConstants.Postable.GL_BALANCE_TYPE_CODE_AC);
195 valid &= validateFinObjectCodeForGLPosting(asset.getOrganizationOwnerChartOfAccountsCode(), offsetDefinition.getFinancialObjectCode(), offsetDefinition.getFinancialObject(), CamsConstants.GLPostingObjectCodeType.OFFSET_AMOUNT);
196 }
197 return valid;
198 }
199
200 /**
201 * check existence and active status for given financial Object Code BO.
202 *
203 * @param chartCode
204 * @param finObjectCode
205 * @param finObject
206 * @return
207 */
208 protected boolean validateFinObjectCodeForGLPosting(String chartOfAccountsCode, String finObjectCode, ObjectCode finObject, String glPostingType) {
209 boolean valid = true;
210 // not defined in Asset Object Code table
211 if (StringUtils.isBlank(finObjectCode)) {
212 putError(CamsConstants.DOCUMENT_NUMBER_PATH, CamsKeyConstants.GLPosting.ERROR_OBJECT_CODE_FROM_ASSET_OBJECT_CODE_NOT_FOUND, new String[] { glPostingType, chartOfAccountsCode });
213 valid = false;
214 }
215 // check Object Code existing
216 else if (ObjectUtils.isNull(finObject)) {
217 putError(CamsConstants.DOCUMENT_NUMBER_PATH, CamsKeyConstants.GLPosting.ERROR_OBJECT_CODE_FROM_ASSET_OBJECT_CODE_INVALID, new String[] { glPostingType, finObjectCode, chartOfAccountsCode });
218 valid = false;
219 }
220 // check Object Code active
221 else if (!finObject.isActive()) {
222 putError(CamsConstants.DOCUMENT_NUMBER_PATH, CamsKeyConstants.GLPosting.ERROR_OBJECT_CODE_FROM_ASSET_OBJECT_CODE_INACTIVE, new String[] { glPostingType, finObjectCode, chartOfAccountsCode });
223 valid = false;
224 }
225 return valid;
226 }
227
228 /**
229 * @see org.kuali.rice.kns.rules.DocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.Document)
230 */
231 @Override
232 protected boolean processCustomRouteDocumentBusinessRules(Document document) {
233 if (!super.processCustomRouteDocumentBusinessRules(document) || GlobalVariables.getMessageMap().hasErrors())
234 return false;
235
236 Asset asset = ((AssetTransferDocument)document).getAsset();
237 boolean valid = true;
238 if (SpringContext.getBean(AssetService.class).isAssetRetired(asset)) {
239 valid &= false;
240 GlobalVariables.getMessageMap().putError(CamsConstants.DOC_HEADER_PATH, CamsKeyConstants.Transfer.ERROR_ASSET_RETIRED_NOTRANSFER, asset.getCapitalAssetNumber().toString(), asset.getRetirementReason().getRetirementReasonName());
241 }
242
243 if (valid) {
244 valid &= applyRules(document);
245 }
246
247 // only generate error message if asset is locked by other document without stop saving
248 valid &= !this.getAssetLockService().isAssetLocked(retrieveAssetNumberForLocking(document), CamsConstants.DocumentTypeName.ASSET_TRANSFER, document.getDocumentNumber());
249
250 return valid;
251 }
252
253 /**
254 * This method applies business rules
255 *
256 * @param document Transfer Document
257 * @return true if all rules are pass
258 */
259 protected boolean applyRules(Document document) {
260 boolean valid = true;
261 // check if selected account has plant fund accounts
262 AssetTransferDocument assetTransferDocument = (AssetTransferDocument) document;
263
264 // validate if asset status = N or D
265 String inventoryStatusCode = assetTransferDocument.getAsset().getInventoryStatus().getInventoryStatusCode();
266 if (inventoryStatusCode != null && !(StringUtils.equalsIgnoreCase(inventoryStatusCode, CamsConstants.InventoryStatusCode.NON_CAPITAL_ASSET_ACTIVE) || StringUtils.equalsIgnoreCase(inventoryStatusCode, CamsConstants.InventoryStatusCode.NON_CAPITAL_ASSET_ACTIVE_2003))) {
267 valid &= validateOwnerAccount(assetTransferDocument);
268 }
269
270 // validate if location info is available, campus or off-campus
271 valid &= validateLocation(assetTransferDocument);
272 if (assetTransferDocument.isInterdepartmentalSalesIndicator()) {
273 if (StringUtils.isBlank(assetTransferDocument.getTransferOfFundsFinancialDocumentNumber())) {
274 putError(CamsPropertyConstants.AssetTransferDocument.TRANSFER_FUND_FINANCIAL_DOC_NUM, CamsKeyConstants.Transfer.ERROR_TRFR_FDOC_REQUIRED);
275 valid &= false;
276 }
277 }
278
279 valid &= validatePaymentObjectCodes(assetTransferDocument);
280
281 return valid;
282 }
283
284
285 /**
286 * This method validates location information provided by the user
287 *
288 * @param assetTransferDocument Transfer Document
289 * @return true is location information is valid for the asset type
290 */
291 protected boolean validateLocation(AssetTransferDocument assetTransferDocument) {
292 GlobalVariables.getMessageMap().addToErrorPath(CamsConstants.DOCUMENT_PATH);
293 Asset asset = assetTransferDocument.getAsset();
294 asset.refreshReferenceObject(CamsPropertyConstants.Asset.CAPITAL_ASSET_TYPE);
295 boolean isCapitalAsset = this.getAssetService().isCapitalAsset(asset);
296 boolean valid = SpringContext.getBean(AssetLocationService.class).validateLocation(LOCATION_FIELD_MAP, assetTransferDocument, isCapitalAsset, asset.getCapitalAssetType());
297 GlobalVariables.getMessageMap().removeFromErrorPath(CamsConstants.DOCUMENT_PATH);
298 return valid;
299 }
300
301
302 /**
303 * This method checks if reference objects exist in the database or not
304 *
305 * @param assetTransferDocument Transfer document
306 * @return true if all objects exists in db
307 */
308 protected boolean checkReferencesExist(AssetTransferDocument assetTransferDocument) {
309 boolean valid = true;
310
311 assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.ASSET);
312 // If asset is loaned, ask a confirmation question
313 if (this.getAssetService().isAssetLoaned(assetTransferDocument.getAsset())) {
314 putError(CamsPropertyConstants.AssetTransferDocument.ASSET + "." + CamsPropertyConstants.AssetTransferDocument.CAPITAL_ASSET_NUMBER, CamsKeyConstants.Transfer.ERROR_TRFR_LOANED);
315 valid &= false;
316 }
317
318 if (StringUtils.isNotBlank(assetTransferDocument.getOrganizationOwnerChartOfAccountsCode())) {
319 assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_CHART_OF_ACCOUNTS);
320 if (ObjectUtils.isNull(assetTransferDocument.getOrganizationOwnerChartOfAccounts())) {
321 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_CHART_OF_ACCOUNTS_CODE, CamsKeyConstants.Transfer.ERROR_OWNER_CHART_CODE_INVALID, assetTransferDocument.getOrganizationOwnerChartOfAccountsCode());
322 valid &= false;
323 }
324 }
325
326 if (StringUtils.isNotBlank(assetTransferDocument.getOrganizationOwnerAccountNumber())) {
327 assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_ACCOUNT);
328 if (ObjectUtils.isNull(assetTransferDocument.getOrganizationOwnerAccount())) {
329 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.Transfer.ERROR_OWNER_ACCT_INVALID, assetTransferDocument.getOrganizationOwnerAccountNumber(), assetTransferDocument.getOrganizationOwnerChartOfAccountsCode());
330 valid &= false;
331 }
332 }
333 if (StringUtils.isNotBlank(assetTransferDocument.getTransferOfFundsFinancialDocumentNumber())) {
334 TransferOfFundsDocument transferOfFundsFinancialDocument = assetTransferDocument.getTransferOfFundsFinancialDocument();
335 if (ObjectUtils.isNull(transferOfFundsFinancialDocument) || !KFSConstants.DocumentStatusCodes.APPROVED.equals(transferOfFundsFinancialDocument.getDocumentHeader().getFinancialDocumentStatusCode())) {
336 putError(CamsPropertyConstants.AssetTransferDocument.TRANSFER_FUND_FINANCIAL_DOC_NUM, CamsKeyConstants.Transfer.ERROR_TRFR_FDOC_INVALID);
337 valid &= false;
338 }
339 }
340 if (StringUtils.isNotBlank(assetTransferDocument.getCampusCode())) {
341 // assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.CAMPUS);
342 if (ObjectUtils.isNull(assetTransferDocument.getCampus())) {
343 putError(CamsPropertyConstants.AssetTransferDocument.CAMPUS_CODE, CamsKeyConstants.AssetLocation.ERROR_INVALID_CAMPUS_CODE, assetTransferDocument.getCampusCode());
344 valid &= false;
345 }
346 }
347 if (StringUtils.isNotBlank(assetTransferDocument.getBuildingCode())) {
348 assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.BUILDING);
349 if (ObjectUtils.isNull(assetTransferDocument.getBuilding())) {
350 putError(CamsPropertyConstants.AssetTransferDocument.BUILDING_CODE, CamsKeyConstants.AssetLocation.ERROR_INVALID_BUILDING_CODE, assetTransferDocument.getBuildingCode(), assetTransferDocument.getCampusCode());
351 valid &= false;
352 }
353 }
354 if (StringUtils.isNotBlank(assetTransferDocument.getBuildingRoomNumber())) {
355 assetTransferDocument.refreshReferenceObject(CamsPropertyConstants.AssetTransferDocument.BUILDING_ROOM);
356 if (ObjectUtils.isNull(assetTransferDocument.getBuildingRoom())) {
357 putError(CamsPropertyConstants.AssetTransferDocument.BUILDING_ROOM_NUMBER, CamsKeyConstants.AssetLocation.ERROR_INVALID_ROOM_NUMBER, assetTransferDocument.getBuildingCode(), assetTransferDocument.getBuildingRoomNumber(), assetTransferDocument.getCampusCode());
358 valid &= false;
359 }
360 }
361 if (StringUtils.isNotBlank(assetTransferDocument.getAssetRepresentative().getPrincipalName())) {
362 PersonService personService = SpringContext.getBean(org.kuali.rice.kim.service.PersonService.class);
363 Person person = personService.getPersonByPrincipalName(assetTransferDocument.getAssetRepresentative().getPrincipalName());
364 if (person != null) {
365 assetTransferDocument.setAssetRepresentative(person);
366 assetTransferDocument.setRepresentativeUniversalIdentifier(person.getPrincipalId());
367 }
368 else {
369 putError(CamsPropertyConstants.AssetTransferDocument.REP_USER_AUTH_ID, CamsKeyConstants.Transfer.ERROR_INVALID_USER_AUTH_ID, assetTransferDocument.getAssetRepresentative().getPrincipalName());
370 valid &= false;
371 }
372 }
373 return valid;
374 }
375
376
377 /**
378 * This method validates the new owner organization and account provided
379 *
380 * @param assetTransferDocument
381 * @return
382 */
383 protected boolean validateOwnerAccount(AssetTransferDocument assetTransferDocument) {
384 boolean valid = true;
385
386 Asset asset = assetTransferDocument.getAsset();
387 String finObjectSubTypeCode = asset.getFinancialObjectSubTypeCode();
388 if (ObjectUtils.isNotNull(asset.getAssetPayments()) && !asset.getAssetPayments().isEmpty()) {
389 AssetPayment firstAssetPayment = asset.getAssetPayments().get(0);
390 firstAssetPayment.refreshReferenceObject(CamsPropertyConstants.AssetPayment.FINANCIAL_OBJECT);
391 ObjectCodeService objectCodeService = (ObjectCodeService) SpringContext.getBean(ObjectCodeService.class);
392
393 ObjectCode objectCode = objectCodeService.getByPrimaryIdForCurrentYear(firstAssetPayment.getChartOfAccountsCode(),firstAssetPayment.getFinancialObjectCode());
394 finObjectSubTypeCode = objectCode.getFinancialObjectSubTypeCode();
395 }
396 boolean assetMovable = getAssetService().isAssetMovableCheckByPayment(finObjectSubTypeCode);
397
398 FinancialSystemTransactionalDocumentAuthorizerBase documentAuthorizer = (FinancialSystemTransactionalDocumentAuthorizerBase) SpringContext.getBean(DocumentHelperService.class).getDocumentAuthorizer(assetTransferDocument);
399 boolean isAuthorizedTransferMovable = documentAuthorizer.isAuthorized(assetTransferDocument, CamsConstants.CAM_MODULE_CODE, CamsConstants.PermissionNames.TRANSFER_NON_MOVABLE_ASSETS, GlobalVariables.getUserSession().getPerson().getPrincipalId());
400
401 // KFSMI-6169 - Not check permission for Transfer Non-Movable Assets when user approve the doc.
402 if (!assetTransferDocument.getDocumentHeader().getWorkflowDocument().getRouteHeader().isApproveRequested()){
403 if (!assetMovable && !isAuthorizedTransferMovable) {
404 GlobalVariables.getMessageMap().putErrorForSectionId(CamsPropertyConstants.COMMON_ERROR_SECTION_ID, CamsKeyConstants.Transfer.ERROR_INVALID_USER_GROUP_FOR_TRANSFER_NONMOVABLE_ASSET, asset.getCapitalAssetNumber().toString());
405 valid &= false;
406 }
407 }
408
409 // check if account is valid
410 Account organizationOwnerAccount = assetTransferDocument.getOrganizationOwnerAccount();
411 if (ObjectUtils.isNotNull(organizationOwnerAccount) && (organizationOwnerAccount.isExpired())) {
412 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.Transfer.ERROR_OWNER_ACCT_INVALID, assetTransferDocument.getOrganizationOwnerChartOfAccountsCode(), assetTransferDocument.getOrganizationOwnerAccountNumber());
413 valid &= false;
414 }
415 else if (getAssetService().isCapitalAsset(asset) && !asset.getAssetPayments().isEmpty()) {
416 // for a capital asset, check if plant account is defined
417 Organization ownerOrg = organizationOwnerAccount.getOrganization();
418 Account campusPlantAccount = ownerOrg.getCampusPlantAccount();
419 Account organizationPlantAccount = ownerOrg.getOrganizationPlantAccount();
420
421 if (assetMovable && ObjectUtils.isNull(organizationPlantAccount)) {
422 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.Transfer.ERROR_ORG_PLANT_FUND_UNKNOWN);
423 valid &= false;
424 }
425 if (!assetMovable && ObjectUtils.isNull(campusPlantAccount)) {
426 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_ACCOUNT_NUMBER, CamsKeyConstants.Transfer.ERROR_CAMPUS_PLANT_FUND_UNKNOWN);
427 valid &= false;
428 }
429 }
430 return valid;
431 }
432
433 /**
434 * checks that all the asset payments to be transfer has a valid object code in the new Chart of account code and current fiscal
435 * year
436 *
437 * @param assetTransferDocument
438 * @return
439 */
440 protected boolean validatePaymentObjectCodes(AssetTransferDocument assetTransferDocument) {
441 boolean valid = true;
442 List<AssetPayment> assetPayments = assetTransferDocument.getAsset().getAssetPayments();
443
444 String chartOfAccountsCode = assetTransferDocument.getOrganizationOwnerChartOfAccountsCode();
445 Integer fiscalYear = getUniversityDateService().getCurrentUniversityDate().getUniversityFiscalYear();
446
447 for (AssetPayment assetPayment : assetPayments) {
448 if (!CamsConstants.AssetPayment.TRANSFER_PAYMENT_CODE_Y.equals(assetPayment.getTransferPaymentCode())) {
449 if (this.getObjectCodeService().getByPrimaryId(fiscalYear, chartOfAccountsCode, assetPayment.getFinancialObjectCode()) == null) {
450 putError(CamsPropertyConstants.AssetTransferDocument.ORGANIZATION_OWNER_CHART_OF_ACCOUNTS_CODE, CamsKeyConstants.Transfer.ERROR_PAYMENT_OBJECT_CODE_NOT_FOUND, new String[] { assetPayment.getFinancialObjectCode(), fiscalYear.toString() });
451 valid = false;
452 }
453 }
454 }
455 return valid;
456 }
457
458 /**
459 * Convenience method to append the path prefix
460 */
461 public TypedArrayList putError(String propertyName, String errorKey, String... errorParameters) {
462 return GlobalVariables.getMessageMap().putError(CamsConstants.DOCUMENT_PATH + "." + propertyName, errorKey, errorParameters);
463 }
464
465 private boolean isNonCapitalAsset(Asset asset) {
466 boolean isNonCapitalAsset = false;
467
468 List<String> capitalAssetAquisitionTypeCodes = new ArrayList<String>();
469
470 capitalAssetAquisitionTypeCodes.addAll(SpringContext.getBean(ParameterService.class).getParameterValues(AssetGlobal.class, CamsConstants.AssetGlobal.CAPITAL_OBJECT_ACQUISITION_CODE_PARAM));
471 capitalAssetAquisitionTypeCodes.addAll(SpringContext.getBean(ParameterService.class).getParameterValues(AssetGlobal.class, CamsConstants.AssetGlobal.NON_NEW_ACQUISITION_GROUP_PARAM));
472 capitalAssetAquisitionTypeCodes.addAll(SpringContext.getBean(ParameterService.class).getParameterValues(AssetGlobal.class, CamsConstants.AssetGlobal.NEW_ACQUISITION_CODE_PARAM));
473 capitalAssetAquisitionTypeCodes.addAll(SpringContext.getBean(ParameterService.class).getParameterValues(Asset.class, CamsConstants.AssetGlobal.FABRICATED_ACQUISITION_CODE));
474 capitalAssetAquisitionTypeCodes.addAll(SpringContext.getBean(ParameterService.class).getParameterValues(AssetGlobal.class, CamsConstants.AssetGlobal.PRE_TAGGING_ACQUISITION_CODE));
475
476 if( ObjectUtils.isNotNull(asset.getAcquisitionTypeCode()) &&
477 capitalAssetAquisitionTypeCodes.contains(asset.getAcquisitionTypeCode()) ) isNonCapitalAsset = false;
478 else isNonCapitalAsset = true;
479
480 return isNonCapitalAsset;
481 }
482
483 public UniversityDateService getUniversityDateService() {
484 if (this.universityDateService == null) {
485 this.universityDateService = SpringContext.getBean(UniversityDateService.class);
486 }
487 return universityDateService;
488 }
489
490 public void setUniversityDateService(UniversityDateService universityDateService) {
491 this.universityDateService = universityDateService;
492 }
493
494 public AssetPaymentService getAssetPaymentService() {
495 if (this.assetPaymentService == null) {
496 this.assetPaymentService = SpringContext.getBean(AssetPaymentService.class);
497
498 }
499 return assetPaymentService;
500 }
501
502 public void setAssetPaymentService(AssetPaymentService assetPaymentService) {
503 this.assetPaymentService = assetPaymentService;
504 }
505
506 public AssetService getAssetService() {
507 if (this.assetService == null) {
508 this.assetService = SpringContext.getBean(AssetService.class);
509 }
510 return assetService;
511 }
512
513 public AssetLockService getAssetLockService() {
514 if (this.assetLockService == null) {
515 this.assetLockService = SpringContext.getBean(AssetLockService.class);
516 }
517 return assetLockService;
518 }
519
520
521 public void setAssetService(AssetService assetService) {
522 this.assetService = assetService;
523 }
524
525 public ObjectCodeService getObjectCodeService() {
526 if (this.objectCodeService == null) {
527 this.objectCodeService = SpringContext.getBean(ObjectCodeService.class);
528 }
529 return objectCodeService;
530 }
531
532 public void setObjectCodeService(ObjectCodeService objectCodeService) {
533 this.objectCodeService = objectCodeService;
534 }
535 }