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.cab.document.service.impl; 017 018 import java.util.HashMap; 019 import java.util.List; 020 import java.util.Map; 021 022 import org.kuali.kfs.fp.businessobject.CapitalAssetInformation; 023 import org.kuali.kfs.fp.businessobject.CapitalAssetInformationDetail; 024 import org.kuali.kfs.module.cab.CabConstants; 025 import org.kuali.kfs.module.cab.CabPropertyConstants; 026 import org.kuali.kfs.module.cab.businessobject.GeneralLedgerEntry; 027 import org.kuali.kfs.module.cab.businessobject.GeneralLedgerEntryAsset; 028 import org.kuali.kfs.module.cab.document.service.GlLineService; 029 import org.kuali.kfs.module.cam.CamsConstants; 030 import org.kuali.kfs.module.cam.CamsPropertyConstants; 031 import org.kuali.kfs.module.cam.CamsConstants.DocumentTypeName; 032 import org.kuali.kfs.module.cam.businessobject.Asset; 033 import org.kuali.kfs.module.cam.businessobject.AssetGlobal; 034 import org.kuali.kfs.module.cam.businessobject.AssetGlobalDetail; 035 import org.kuali.kfs.module.cam.businessobject.AssetPaymentAssetDetail; 036 import org.kuali.kfs.module.cam.businessobject.AssetPaymentDetail; 037 import org.kuali.kfs.module.cam.businessobject.defaultvalue.NextAssetNumberFinder; 038 import org.kuali.kfs.module.cam.document.AssetPaymentDocument; 039 import org.kuali.kfs.module.cam.document.service.AssetGlobalService; 040 import org.kuali.kfs.module.cam.util.ObjectValueUtils; 041 import org.kuali.kfs.sys.KFSConstants; 042 import org.kuali.kfs.sys.context.SpringContext; 043 import org.kuali.rice.kew.exception.WorkflowException; 044 import org.kuali.rice.kns.bo.PersistableBusinessObject; 045 import org.kuali.rice.kns.document.Document; 046 import org.kuali.rice.kns.document.MaintenanceDocument; 047 import org.kuali.rice.kns.service.BusinessObjectService; 048 import org.kuali.rice.kns.service.DocumentService; 049 import org.kuali.rice.kns.util.KNSConstants; 050 import org.kuali.rice.kns.util.KualiDecimal; 051 import org.kuali.rice.kns.util.ObjectUtils; 052 053 public class GlLineServiceImpl implements GlLineService { 054 private static final String CAB_DESC_PREFIX = "CAB created for FP "; 055 protected BusinessObjectService businessObjectService; 056 protected AssetGlobalService assetGlobalService; 057 058 059 /** 060 * @see org.kuali.kfs.module.cab.document.service.GlLineService#createAssetGlobalDocument(java.util.List, 061 * org.kuali.kfs.module.cab.businessobject.GeneralLedgerEntry) 062 */ 063 public Document createAssetGlobalDocument(List<GeneralLedgerEntry> entries, GeneralLedgerEntry primary) throws WorkflowException { 064 // initiate a new document 065 DocumentService documentService = SpringContext.getBean(DocumentService.class); 066 MaintenanceDocument document = (MaintenanceDocument) documentService.getNewDocument(DocumentTypeName.ASSET_ADD_GLOBAL); 067 // create asset global 068 AssetGlobal assetGlobal = createAssetGlobal(primary, document); 069 assetGlobal.setCapitalAssetBuilderOriginIndicator(true); 070 assetGlobal.setAcquisitionTypeCode(getAssetGlobalService().getNewAcquisitionTypeCode()); 071 updatePreTagInformation(primary, document, assetGlobal); 072 int seq = 0; 073 for (GeneralLedgerEntry generalLedgerEntry : entries) { 074 assetGlobal.getAssetPaymentDetails().add(createAssetPaymentDetail(generalLedgerEntry, document, ++seq)); 075 } 076 // save the document 077 document.getNewMaintainableObject().setMaintenanceAction(KNSConstants.MAINTENANCE_NEW_ACTION); 078 document.getDocumentHeader().setDocumentDescription(CAB_DESC_PREFIX + primary.getDocumentNumber()); 079 document.getNewMaintainableObject().setBusinessObject(assetGlobal); 080 document.getNewMaintainableObject().setBoClass(assetGlobal.getClass()); 081 documentService.saveDocument(document); 082 deactivateGLEntries(entries, document); 083 return document; 084 } 085 086 /** 087 * De-activate the GL Entries 088 * 089 * @param entries GL Entries 090 * @param document Document 091 */ 092 protected void deactivateGLEntries(List<GeneralLedgerEntry> entries, Document document) { 093 for (GeneralLedgerEntry generalLedgerEntry : entries) { 094 generalLedgerEntry.setTransactionLedgerSubmitAmount(generalLedgerEntry.getTransactionLedgerEntryAmount()); 095 generalLedgerEntry.setActivityStatusCode(CabConstants.ActivityStatusCode.ENROUTE); 096 createGeneralLedgerEntryAsset(generalLedgerEntry, document); 097 getBusinessObjectService().save(generalLedgerEntry); 098 } 099 } 100 101 /** 102 * This method reads the pre-tag information and creates objects for asset global document 103 * 104 * @param entry GL Line 105 * @param document Asset Global Maintenance Document 106 * @param assetGlobal Asset Global Object 107 */ 108 protected void updatePreTagInformation(GeneralLedgerEntry entry, MaintenanceDocument document, AssetGlobal assetGlobal) { 109 CapitalAssetInformation assetInformation = findCapitalAssetInformation(entry); 110 if (ObjectUtils.isNotNull(assetInformation) && assetInformation.getCapitalAssetNumber() == null) { 111 List<CapitalAssetInformationDetail> capitalAssetInformationDetails = assetInformation.getCapitalAssetInformationDetails(); 112 for (CapitalAssetInformationDetail capitalAssetInformationDetail : capitalAssetInformationDetails) { 113 // This is not added to constructor in CAMS to provide module isolation from CAMS 114 AssetGlobalDetail assetGlobalDetail = new AssetGlobalDetail(); 115 assetGlobalDetail.setDocumentNumber(document.getDocumentNumber()); 116 assetGlobalDetail.setCampusCode(capitalAssetInformationDetail.getCampusCode()); 117 assetGlobalDetail.setBuildingCode(capitalAssetInformationDetail.getBuildingCode()); 118 assetGlobalDetail.setBuildingRoomNumber(capitalAssetInformationDetail.getBuildingRoomNumber()); 119 assetGlobalDetail.setBuildingSubRoomNumber(capitalAssetInformationDetail.getBuildingSubRoomNumber()); 120 assetGlobalDetail.setSerialNumber(capitalAssetInformationDetail.getCapitalAssetSerialNumber()); 121 assetGlobalDetail.setCapitalAssetNumber(NextAssetNumberFinder.getLongValue()); 122 assetGlobalDetail.setCampusTagNumber(capitalAssetInformationDetail.getCapitalAssetTagNumber()); 123 AssetGlobalDetail uniqueAsset = new AssetGlobalDetail(); 124 ObjectValueUtils.copySimpleProperties(assetGlobalDetail, uniqueAsset); 125 assetGlobalDetail.getAssetGlobalUniqueDetails().add(uniqueAsset); 126 assetGlobal.getAssetSharedDetails().add(assetGlobalDetail); 127 } 128 assetGlobal.setVendorName(assetInformation.getVendorName()); 129 assetGlobal.setInventoryStatusCode(CamsConstants.InventoryStatusCode.CAPITAL_ASSET_ACTIVE_IDENTIFIABLE); 130 assetGlobal.setCapitalAssetTypeCode(assetInformation.getCapitalAssetTypeCode()); 131 assetGlobal.setManufacturerName(assetInformation.getCapitalAssetManufacturerName()); 132 assetGlobal.setManufacturerModelNumber(assetInformation.getCapitalAssetManufacturerModelNumber()); 133 assetGlobal.setCapitalAssetDescription(assetInformation.getCapitalAssetDescription()); 134 } 135 } 136 137 /** 138 * @see org.kuali.kfs.module.cab.document.service.GlLineService#findCapitalAssetInformation(org.kuali.kfs.module.cab.businessobject.GeneralLedgerEntry) 139 */ 140 public CapitalAssetInformation findCapitalAssetInformation(GeneralLedgerEntry entry) { 141 Map<String, String> primaryKeys = new HashMap<String, String>(); 142 primaryKeys.put(CabPropertyConstants.CapitalAssetInformation.DOCUMENT_NUMBER, entry.getDocumentNumber()); 143 CapitalAssetInformation assetInformation = (CapitalAssetInformation) businessObjectService.findByPrimaryKey(CapitalAssetInformation.class, primaryKeys); 144 return assetInformation; 145 } 146 147 /** 148 * Creates general ledger entry asset 149 * 150 * @param entry GeneralLedgerEntry 151 * @param maintDoc Document 152 */ 153 protected void createGeneralLedgerEntryAsset(GeneralLedgerEntry entry, Document document) { 154 // store the document number 155 GeneralLedgerEntryAsset entryAsset = new GeneralLedgerEntryAsset(); 156 entryAsset.setGeneralLedgerAccountIdentifier(entry.getGeneralLedgerAccountIdentifier()); 157 entryAsset.setCapitalAssetBuilderLineNumber(1); 158 entryAsset.setCapitalAssetManagementDocumentNumber(document.getDocumentNumber()); 159 entry.getGeneralLedgerEntryAssets().add(entryAsset); 160 } 161 162 163 /** 164 * Creates asset global 165 * 166 * @param entry GeneralLedgerEntry 167 * @param maintDoc MaintenanceDocument 168 * @return AssetGlobal 169 */ 170 protected AssetGlobal createAssetGlobal(GeneralLedgerEntry entry, MaintenanceDocument maintDoc) { 171 AssetGlobal assetGlobal = new AssetGlobal(); 172 assetGlobal.setOrganizationOwnerChartOfAccountsCode(entry.getChartOfAccountsCode()); 173 assetGlobal.setOrganizationOwnerAccountNumber(entry.getAccountNumber()); 174 assetGlobal.setDocumentNumber(maintDoc.getDocumentNumber()); 175 assetGlobal.setConditionCode(CamsConstants.Asset.CONDITION_CODE_E); 176 return assetGlobal; 177 } 178 179 180 public Document createAssetPaymentDocument(List<GeneralLedgerEntry> entries, GeneralLedgerEntry primaryGlEntry) throws WorkflowException { 181 // Find out the GL Entry 182 // initiate a new document 183 DocumentService documentService = SpringContext.getBean(DocumentService.class); 184 AssetPaymentDocument document = (AssetPaymentDocument) documentService.getNewDocument(DocumentTypeName.ASSET_PAYMENT); 185 document.setCapitalAssetBuilderOriginIndicator(true); 186 document.getDocumentHeader().setDocumentDescription(CAB_DESC_PREFIX + primaryGlEntry.getDocumentNumber()); 187 updatePreTagInformation(primaryGlEntry, document); 188 // Asset Payment Detail 189 int seq = 0; 190 for (GeneralLedgerEntry generalLedgerEntry : entries) { 191 AssetPaymentDetail detail = createAssetPaymentDetail(generalLedgerEntry, document, ++seq); 192 document.getSourceAccountingLines().add(detail); 193 } 194 // Asset payment asset detail 195 // save the document 196 documentService.saveDocument(document); 197 deactivateGLEntries(entries, document); 198 return document; 199 } 200 201 /** 202 * Updates pre tag information received from FP document 203 * 204 * @param entry GeneralLedgerEntry 205 * @param document AssetPaymentDocument 206 */ 207 protected void updatePreTagInformation(GeneralLedgerEntry entry, AssetPaymentDocument document) { 208 CapitalAssetInformation assetInformation = findCapitalAssetInformation(entry); 209 if (ObjectUtils.isNotNull(assetInformation) && assetInformation.getCapitalAssetNumber() != null) { 210 AssetPaymentAssetDetail assetPaymentAssetDetail = new AssetPaymentAssetDetail(); 211 assetPaymentAssetDetail.setDocumentNumber(document.getDocumentNumber()); 212 assetPaymentAssetDetail.setCapitalAssetNumber(assetInformation.getCapitalAssetNumber()); 213 assetPaymentAssetDetail.refreshReferenceObject(CamsPropertyConstants.AssetPaymentAssetDetail.ASSET); 214 Asset asset = assetPaymentAssetDetail.getAsset(); 215 if (ObjectUtils.isNotNull(asset)) { 216 assetPaymentAssetDetail.setPreviousTotalCostAmount(asset.getTotalCostAmount() != null ? asset.getTotalCostAmount() : KualiDecimal.ZERO); 217 document.getAssetPaymentAssetDetail().add(assetPaymentAssetDetail); 218 } 219 } 220 } 221 222 /** 223 * Creates asset payment detail based on GL line. to CAB 224 * 225 * @param entry GeneralLedgerEntry 226 * @param document Document 227 * @return AssetPaymentDetail 228 */ 229 protected AssetPaymentDetail createAssetPaymentDetail(GeneralLedgerEntry entry, Document document, int seqNo) { 230 // This is not added to constructor in CAMS to provide module isolation from CAMS 231 AssetPaymentDetail detail = new AssetPaymentDetail(); 232 detail.setDocumentNumber(document.getDocumentNumber()); 233 detail.setSequenceNumber(seqNo); 234 detail.setPostingYear(entry.getUniversityFiscalYear()); 235 detail.setPostingPeriodCode(entry.getUniversityFiscalPeriodCode()); 236 detail.setChartOfAccountsCode(entry.getChartOfAccountsCode()); 237 detail.setAccountNumber(replaceFiller(entry.getAccountNumber())); 238 detail.setSubAccountNumber(replaceFiller(entry.getSubAccountNumber())); 239 detail.setFinancialObjectCode(replaceFiller(entry.getFinancialObjectCode())); 240 detail.setProjectCode(replaceFiller(entry.getProjectCode())); 241 detail.setOrganizationReferenceId(replaceFiller(entry.getOrganizationReferenceId())); 242 detail.setAmount(KFSConstants.GL_CREDIT_CODE.equals(entry.getTransactionDebitCreditCode()) ? entry.getTransactionLedgerEntryAmount().negated() : entry.getTransactionLedgerEntryAmount()); 243 detail.setExpenditureFinancialSystemOriginationCode(replaceFiller(entry.getFinancialSystemOriginationCode())); 244 detail.setExpenditureFinancialDocumentNumber(entry.getDocumentNumber()); 245 detail.setExpenditureFinancialDocumentTypeCode(replaceFiller(entry.getFinancialDocumentTypeCode())); 246 detail.setExpenditureFinancialDocumentPostedDate(entry.getTransactionDate()); 247 detail.setPurchaseOrderNumber(replaceFiller(entry.getReferenceFinancialDocumentNumber())); 248 detail.setTransferPaymentIndicator(false); 249 return detail; 250 } 251 252 /** 253 * If the value contains only the filler characters, then return blank 254 * 255 * @param val Value 256 * @return blank if value if a filler 257 */ 258 protected String replaceFiller(String val) { 259 if (val == null) { 260 return ""; 261 } 262 char[] charArray = val.trim().toCharArray(); 263 for (char c : charArray) { 264 if (c != '-') { 265 return val; 266 } 267 } 268 return ""; 269 } 270 271 /** 272 * Gets the businessObjectService attribute. 273 * 274 * @return Returns the businessObjectService. 275 */ 276 public BusinessObjectService getBusinessObjectService() { 277 return businessObjectService; 278 } 279 280 /** 281 * Sets the businessObjectService attribute value. 282 * 283 * @param businessObjectService The businessObjectService to set. 284 */ 285 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 286 this.businessObjectService = businessObjectService; 287 } 288 289 private AssetGlobalService getAssetGlobalService() { 290 return assetGlobalService; 291 } 292 293 public void setAssetGlobalService(AssetGlobalService assetGlobalService) { 294 this.assetGlobalService = assetGlobalService; 295 } 296 297 }