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.batch.service.impl; 017 018 import java.io.BufferedReader; 019 import java.io.File; 020 import java.io.FileNotFoundException; 021 import java.io.FileReader; 022 import java.io.IOException; 023 import java.sql.Timestamp; 024 import java.text.SimpleDateFormat; 025 import java.util.ArrayList; 026 import java.util.HashMap; 027 import java.util.List; 028 import java.util.Locale; 029 import java.util.Map; 030 031 import org.apache.commons.lang.StringUtils; 032 import org.kuali.kfs.module.cam.CamsConstants; 033 import org.kuali.kfs.module.cam.CamsPropertyConstants; 034 import org.kuali.kfs.module.cam.batch.service.AssetBarcodeInventoryLoadService; 035 import org.kuali.kfs.module.cam.businessobject.Asset; 036 import org.kuali.kfs.module.cam.businessobject.BarcodeInventoryErrorDetail; 037 import org.kuali.kfs.module.cam.document.BarcodeInventoryErrorDocument; 038 import org.kuali.kfs.module.cam.document.validation.event.ValidateBarcodeInventoryEvent; 039 import org.kuali.kfs.module.cam.document.web.struts.AssetBarCodeInventoryInputFileForm; 040 import org.kuali.kfs.sys.KFSConstants; 041 import org.kuali.kfs.sys.KFSKeyConstants; 042 import org.kuali.rice.kew.exception.WorkflowException; 043 import org.kuali.rice.kew.util.KEWConstants; 044 import org.kuali.rice.kns.bo.AdHocRoutePerson; 045 import org.kuali.rice.kns.bo.AdHocRouteRecipient; 046 import org.kuali.rice.kns.document.Document; 047 import org.kuali.rice.kns.service.BusinessObjectService; 048 import org.kuali.rice.kns.service.DataDictionaryService; 049 import org.kuali.rice.kns.service.DateTimeService; 050 import org.kuali.rice.kns.service.DocumentService; 051 import org.kuali.rice.kns.service.KualiRuleService; 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.workflow.service.WorkflowDocumentService; 056 057 /** 058 * Implementation of the AssetBarcodeInventoryLoadService interface. Handles loading, parsing, and storing of incoming barcode 059 * inventory files. 060 */ 061 public class AssetBarcodeInventoryLoadServiceImpl implements AssetBarcodeInventoryLoadService { 062 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AssetBarcodeInventoryLoadServiceImpl.class); 063 064 public static final String MESSAGE_NO_DOCUMENT_CREATED = "NO barcode inventory error document was created."; 065 public static final String DOCUMENTS_MSG = "The following barcode inventory error document were created"; 066 public static final String TOTAL_RECORDS_UPLOADED_MSG = "Total records uploaded"; 067 public static final String TOTAL_RECORDS_IN_ERROR_MSG = "Total records in error"; 068 069 protected static final int MAX_NUMBER_OF_COLUMNS = 8; 070 protected static final String DOCUMENT_EXPLANATION = "BARCODE ERROR INVENTORY"; 071 072 private BusinessObjectService businessObjectService; 073 private WorkflowDocumentService workflowDocumentService; 074 private DataDictionaryService dataDictionaryService; 075 private KualiRuleService kualiRuleService; 076 private DocumentService documentService; 077 private ParameterService parameterService; 078 private DateTimeService dateTimeService; 079 080 /** 081 * Determines whether or not the BCIE document has all its records corrected or deleted 082 * 083 * @param document 084 * @return boolean 085 */ 086 public boolean isFullyProcessed(Document document) { 087 BarcodeInventoryErrorDocument barcodeInventoryErrorDocument = (BarcodeInventoryErrorDocument)document; 088 boolean result = true; 089 List<BarcodeInventoryErrorDetail> barcodeInventoryErrorDetails = barcodeInventoryErrorDocument.getBarcodeInventoryErrorDetail(); 090 BarcodeInventoryErrorDetail barcodeInventoryErrorDetail; 091 092 for (BarcodeInventoryErrorDetail detail : barcodeInventoryErrorDetails) { 093 if (detail.getErrorCorrectionStatusCode().equals(CamsConstants.BarCodeInventoryError.STATUS_CODE_ERROR)) { 094 result = false; 095 break; 096 } 097 } 098 return result; 099 } 100 101 /** 102 * @see org.kuali.kfs.module.cam.batch.service.AssetBarcodeInventoryLoadService#isCurrentUserInitiator(org.kuali.rice.kns.document.Document) 103 */ 104 public boolean isCurrentUserInitiator(Document document) { 105 if (document != null) { 106 return GlobalVariables.getUserSession().getPerson().getPrincipalId().equalsIgnoreCase(document.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId()); 107 } 108 return false; 109 } 110 111 /** 112 * @see org.kuali.module.cams.service.AssetBarcodeInventoryLoadService#isFileFormatValid(java.io.File) 113 */ 114 public boolean isFileFormatValid(File file) { 115 LOG.debug("isFileFormatValid(File file) - start"); 116 String fileName = file.getName(); 117 118 BufferedReader input = null; 119 120 // Getting the length of each field that needs to be validated 121 Integer campusTagNumberMaxLength = dataDictionaryService.getAttributeMaxLength(Asset.class, CamsPropertyConstants.Asset.CAMPUS_TAG_NUMBER); 122 Integer inventoryScannedCodeMaxLength = new Integer(1); 123 Integer InventoryDateMaxLength = dataDictionaryService.getAttributeMaxLength(BarcodeInventoryErrorDetail.class, CamsPropertyConstants.BarcodeInventory.INVENTORY_DATE); 124 Integer campusCodeMaxLength = dataDictionaryService.getAttributeMaxLength(Asset.class, CamsPropertyConstants.Asset.CAMPUS_CODE); 125 Integer buildingCodeMaxLength = dataDictionaryService.getAttributeMaxLength(Asset.class, CamsPropertyConstants.Asset.BUILDING_CODE); 126 Integer buildingRoomNumberMaxLength = dataDictionaryService.getAttributeMaxLength(Asset.class, CamsPropertyConstants.Asset.BUILDING_ROOM_NUMBER); 127 Integer buildingSubRoomNumberMaxLength = dataDictionaryService.getAttributeMaxLength(Asset.class, CamsPropertyConstants.Asset.BUILDING_SUB_ROOM_NUMBER); 128 Integer conditionCodeMaxLength = dataDictionaryService.getAttributeMaxLength(Asset.class, CamsPropertyConstants.Asset.CONDITION_CODE); 129 130 // Getting the label of each field from data dictionary. 131 String campusTagNumberLabel = dataDictionaryService.getAttributeLabel(Asset.class, CamsPropertyConstants.Asset.CAMPUS_TAG_NUMBER); 132 String inventoryScannedCodeLabel = dataDictionaryService.getAttributeLabel(Asset.class, CamsPropertyConstants.BarcodeInventory.UPLOAD_SCAN_INDICATOR); 133 String InventoryDateLabel = dataDictionaryService.getAttributeLabel(BarcodeInventoryErrorDetail.class, CamsPropertyConstants.BarcodeInventory.INVENTORY_DATE); 134 String campusCodeLabel = dataDictionaryService.getAttributeLabel(Asset.class, CamsPropertyConstants.Asset.CAMPUS_CODE); 135 String buildingCodeLabel = dataDictionaryService.getAttributeLabel(Asset.class, CamsPropertyConstants.Asset.BUILDING_CODE); 136 String buildingRoomNumberLabel = dataDictionaryService.getAttributeLabel(Asset.class, CamsPropertyConstants.Asset.BUILDING_ROOM_NUMBER); 137 String buildingSubRoomNumberLabel = dataDictionaryService.getAttributeLabel(Asset.class, CamsPropertyConstants.Asset.BUILDING_SUB_ROOM_NUMBER); 138 String conditionCodeLabel = dataDictionaryService.getAttributeLabel(Asset.class, CamsPropertyConstants.Asset.CONDITION_CODE); 139 140 try { 141 int recordCount = 0; 142 String errorMsg = ""; 143 String errorMessage = ""; 144 boolean proceed = true; 145 String lengthError = "exceeds maximum length"; 146 147 input = new BufferedReader(new FileReader(file)); 148 String line = null; 149 150 151 while ((line = input.readLine()) != null) { 152 recordCount++; 153 errorMsg = ""; 154 line = StringUtils.remove(line, "\""); 155 156 String[] column = org.springframework.util.StringUtils.delimitedListToStringArray(line, ","); 157 158 if (MAX_NUMBER_OF_COLUMNS < column.length) { 159 // Error more columns that allowed. put it in the constants class. 160 errorMsg += " Barcode inventory file has record(s) with more than " + MAX_NUMBER_OF_COLUMNS + " columns\n"; 161 proceed = false; 162 } 163 else if (MAX_NUMBER_OF_COLUMNS > column.length) { 164 errorMsg += " Barcode inventory file has record(s) with less than " + MAX_NUMBER_OF_COLUMNS + " columns\n"; 165 proceed = false; 166 } 167 else { 168 169 // Validating length of each field 170 if (column[0].length() > campusTagNumberMaxLength.intValue()) { 171 errorMsg += ", " + campusTagNumberLabel; 172 } 173 174 if (column[1].length() > inventoryScannedCodeMaxLength.intValue()) { 175 errorMsg += ", " + inventoryScannedCodeLabel; 176 } 177 178 if (column[2].length() > InventoryDateMaxLength.intValue()) { 179 errorMsg += ", " + InventoryDateLabel; 180 } 181 182 if (column[3].length() > campusCodeMaxLength.intValue()) { 183 errorMsg += ", " + campusCodeLabel; 184 } 185 if (column[4].length() > buildingCodeMaxLength.intValue()) { 186 errorMsg += ", " + buildingCodeLabel; 187 } 188 if (column[5].length() > buildingRoomNumberMaxLength.intValue()) { 189 errorMsg += ", " + buildingRoomNumberLabel; 190 } 191 if (column[6].length() > buildingSubRoomNumberMaxLength.intValue()) { 192 errorMsg += ", " + buildingSubRoomNumberLabel; 193 } 194 if (column[7].length() > conditionCodeMaxLength.intValue()) { 195 errorMsg += ", " + conditionCodeLabel; 196 } 197 198 if (!StringUtils.isBlank(errorMsg)) { 199 errorMsg += " " + lengthError; 200 } 201 202 // Validating other than the length of the fields 203 if (!column[1].equals(CamsConstants.BarCodeInventory.BCI_SCANED_INTO_DEVICE) && !column[1].equals(CamsConstants.BarCodeInventory.BCI_MANUALLY_KEYED_CODE)) { 204 errorMsg += ", " + inventoryScannedCodeLabel + " is invalid"; 205 } 206 } 207 if (!StringUtils.isBlank(errorMsg)) { 208 errorMsg = "Error on record number " + recordCount + ": " + errorMsg.substring(2) + "\n"; 209 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_CUSTOM, errorMsg); 210 errorMessage += errorMsg; 211 LOG.error(errorMsg); 212 } 213 if (!proceed) 214 break; 215 } 216 if (!StringUtils.isBlank(errorMessage)) { 217 return false; 218 } 219 220 return true; 221 } 222 catch (FileNotFoundException e1) { 223 LOG.error("file to parse not found " + fileName, e1); 224 throw new RuntimeException("Cannot find the file requested to be parsed " + fileName + " " + e1.getMessage(), e1); 225 } 226 catch (Exception e) { 227 LOG.error("Error running file validation - File: " + fileName, e); 228 throw new IllegalArgumentException("Error running file validation - File: " + fileName); 229 } 230 finally { 231 LOG.debug("isFileFormatValid(File file) - end"); 232 try { 233 if (input != null) { 234 input.close(); 235 } 236 } 237 catch (IOException ex) { 238 LOG.error("isFileFormatValid() error closing file.", ex); 239 } 240 } 241 242 } 243 244 /** 245 * @see org.kuali.module.cams.service.AssetBarCodeInventoryLoadService#processFile(java.io.File) 246 */ 247 public boolean processFile(File file, AssetBarCodeInventoryInputFileForm form) { 248 LOG.debug("processFile(File file) - start"); 249 250 BufferedReader input = null; 251 String fileName = file.getName(); 252 253 String day; 254 String month; 255 String year; 256 String hours; 257 String minutes; 258 String seconds; 259 boolean isValid = true; 260 261 SimpleDateFormat formatter = new SimpleDateFormat(CamsConstants.DateFormats.MONTH_DAY_YEAR + " " + CamsConstants.DateFormats.STANDARD_TIME, Locale.US); 262 formatter.setLenient(false); 263 264 BarcodeInventoryErrorDetail barcodeInventoryErrorDetail; 265 List<BarcodeInventoryErrorDetail> barcodeInventoryErrorDetails = new ArrayList<BarcodeInventoryErrorDetail>(); 266 267 List<BarcodeInventoryErrorDocument> barcodeInventoryErrorDocuments = new ArrayList<BarcodeInventoryErrorDocument>(); 268 try { 269 Long ln = new Long(1); 270 input = new BufferedReader(new FileReader(file)); 271 String line = null; 272 273 while ((line = input.readLine()) != null) { 274 line = StringUtils.remove(line, "\""); 275 String[] lineStrings = org.springframework.util.StringUtils.delimitedListToStringArray(line, ","); 276 277 // Parsing date so it can be validated. 278 lineStrings[2] = StringUtils.rightPad(lineStrings[2].trim(), 14, "0"); 279 280 day = lineStrings[2].substring(0, 2); 281 month = lineStrings[2].substring(2, 4); 282 year = lineStrings[2].substring(4, 8); 283 hours = lineStrings[2].substring(8, 10); 284 minutes = lineStrings[2].substring(10, 12); 285 seconds = lineStrings[2].substring(12); 286 287 String stringDate = month + "/" + day + "/" + year + " " + hours + ":" + minutes + ":" + seconds; 288 Timestamp timestamp = null; 289 290 // If date has invalid format set its value to null 291 try { 292 timestamp = new Timestamp(formatter.parse(stringDate).getTime()); 293 } 294 catch (Exception e) { 295 } 296 297 // Its set to null because for some reason java parses "00000000000000" as 0002-11-30 298 if (lineStrings[2].equals(StringUtils.repeat("0", 14))) { 299 timestamp = null; 300 } 301 302 barcodeInventoryErrorDetail = new BarcodeInventoryErrorDetail(); 303 barcodeInventoryErrorDetail.setUploadRowNumber(ln); 304 barcodeInventoryErrorDetail.setAssetTagNumber(lineStrings[0].trim()); 305 barcodeInventoryErrorDetail.setUploadScanIndicator(lineStrings[1].equals(CamsConstants.BarCodeInventory.BCI_SCANED_INTO_DEVICE)); 306 barcodeInventoryErrorDetail.setUploadScanTimestamp(timestamp); 307 barcodeInventoryErrorDetail.setCampusCode(lineStrings[3].trim().toUpperCase()); 308 barcodeInventoryErrorDetail.setBuildingCode(lineStrings[4].trim().toUpperCase()); 309 barcodeInventoryErrorDetail.setBuildingRoomNumber(lineStrings[5].trim().toUpperCase()); 310 barcodeInventoryErrorDetail.setBuildingSubRoomNumber(lineStrings[6].trim().toUpperCase()); 311 barcodeInventoryErrorDetail.setAssetConditionCode(lineStrings[7].trim().toUpperCase()); 312 barcodeInventoryErrorDetail.setErrorCorrectionStatusCode(CamsConstants.BarCodeInventoryError.STATUS_CODE_ERROR); 313 barcodeInventoryErrorDetail.setCorrectorUniversalIdentifier(GlobalVariables.getUserSession().getPerson().getPrincipalId()); 314 315 barcodeInventoryErrorDetails.add(barcodeInventoryErrorDetail); 316 ln++; 317 } 318 processBarcodeInventory(barcodeInventoryErrorDetails, form); 319 320 // Removing *.done files that are created automatically by the framework. 321 this.removeDoneFile(file); 322 323 return true; 324 } 325 catch (FileNotFoundException e1) { 326 LOG.error("file to parse not found " + fileName, e1); 327 throw new RuntimeException("Cannot find the file requested to be parsed " + fileName + " " + e1.getMessage(), e1); 328 } 329 catch (Exception ex) { 330 LOG.error("Error reading file", ex); 331 throw new IllegalArgumentException("Error reading file: " + ex.getMessage(), ex); 332 } 333 finally { 334 LOG.debug("processFile(File file) - End"); 335 336 try { 337 if (input != null) { 338 input.close(); 339 } 340 } 341 catch (IOException ex) { 342 LOG.error("loadFlatFile() error closing file.", ex); 343 } 344 } 345 } 346 347 /** 348 * This method removes the *.done files. If not deleted, then the program will display the name of the file in a puldown menu 349 * with a label of ready for process. 350 * 351 * @param file 352 */ 353 protected void removeDoneFile(File file) { 354 String filePath = file.getAbsolutePath(); 355 File doneFile = new File(StringUtils.substringBeforeLast(filePath, ".") + ".done"); 356 357 if (doneFile.exists()) { 358 doneFile.delete(); 359 } 360 } 361 362 /** 363 * This method invokes the rules in order to validate each records of the barcode file and invokes the method that updates the 364 * asset table with the records that passes the rules validation 365 * 366 * @param barcodeInventoryErrorDetails 367 */ 368 protected void processBarcodeInventory(List<BarcodeInventoryErrorDetail> barcodeInventoryErrorDetails, AssetBarCodeInventoryInputFileForm form) throws Exception { 369 Long lineNumber = new Long(0); 370 boolean docCreated = false; 371 int errorRecCount = 0; 372 int totalRecCount = 0; 373 374 BarcodeInventoryErrorDocument barcodeInventoryErrorDocument = createInvalidBarcodeInventoryDocument(barcodeInventoryErrorDetails, form.getUploadDescription()); 375 // apply rules for the new cash control detail 376 kualiRuleService.applyRules(new ValidateBarcodeInventoryEvent("", barcodeInventoryErrorDocument, true)); 377 378 List<BarcodeInventoryErrorDetail> tmpBarcodeInventoryErrorDetails = new ArrayList<BarcodeInventoryErrorDetail>(); 379 380 for (BarcodeInventoryErrorDetail barcodeInventoryErrorDetail : barcodeInventoryErrorDetails) { 381 totalRecCount++; 382 // if no error found, then update asset table. 383 if (!barcodeInventoryErrorDetail.getErrorCorrectionStatusCode().equals(CamsConstants.BarCodeInventoryError.STATUS_CODE_ERROR)) { 384 this.updateAssetInformation(barcodeInventoryErrorDetail,true); 385 } 386 else { 387 errorRecCount++; 388 lineNumber++; 389 // Assigning the row number to each invalid BCIE record 390 barcodeInventoryErrorDetail.setUploadRowNumber(lineNumber); 391 392 // Storing in temp collection the invalid BCIE records. 393 tmpBarcodeInventoryErrorDetails.add(barcodeInventoryErrorDetail); 394 } 395 } 396 // ********************************************************************* 397 // Storing the invalid barcode inventory records. 398 // ********************************************************************* 399 String documentsCreated = ""; 400 if (!tmpBarcodeInventoryErrorDetails.isEmpty()) { 401 documentsCreated = this.createBarcodeInventoryErrorDocuments(tmpBarcodeInventoryErrorDetails, barcodeInventoryErrorDocument, form); 402 docCreated = true; 403 } 404 405 if (!docCreated) { 406 form.getMessages().add(MESSAGE_NO_DOCUMENT_CREATED); 407 } 408 else { 409 // Adding the list of documents that were created in the message list 410 form.getMessages().add(DOCUMENTS_MSG + ": " + documentsCreated.substring(2)); 411 } 412 form.getMessages().add(TOTAL_RECORDS_UPLOADED_MSG + ": " + StringUtils.rightPad(Integer.toString(totalRecCount), 5, " ")); 413 form.getMessages().add(TOTAL_RECORDS_IN_ERROR_MSG + ": " + StringUtils.rightPad(Integer.toString(errorRecCount), 5, " ")); 414 } 415 416 417 /** 418 * This method... 419 * 420 * @param bcies 421 * @param barcodeInventoryErrorDocument 422 */ 423 protected String createBarcodeInventoryErrorDocuments(List<BarcodeInventoryErrorDetail> bcies, BarcodeInventoryErrorDocument barcodeInventoryErrorDocument, AssetBarCodeInventoryInputFileForm form) { 424 List<BarcodeInventoryErrorDetail> barcodeInventoryErrorDetails = new ArrayList<BarcodeInventoryErrorDetail>(); 425 boolean isFirstDocument = true; 426 int ln = 0; 427 int bcieCount = 0; 428 String documentsCreated = ""; 429 int maxNumberRecordsPerDocument = 300; 430 431 try { 432 if (parameterService.parameterExists(BarcodeInventoryErrorDocument.class, CamsConstants.Parameters.MAX_NUMBER_OF_RECORDS_PER_DOCUMENT)) { 433 maxNumberRecordsPerDocument = new Integer(parameterService.getParameterValue(BarcodeInventoryErrorDocument.class, CamsConstants.Parameters.MAX_NUMBER_OF_RECORDS_PER_DOCUMENT)).intValue(); 434 } 435 436 while (true) { 437 if ((ln > maxNumberRecordsPerDocument) || (bcieCount >= bcies.size())) { 438 // This if was added in order to not waste the document already created and not create a new one. 439 if (!isFirstDocument) { 440 barcodeInventoryErrorDocument = createInvalidBarcodeInventoryDocument(barcodeInventoryErrorDetails, form.getUploadDescription()); 441 } 442 documentsCreated += ", " + barcodeInventoryErrorDocument.getDocumentNumber(); 443 444 barcodeInventoryErrorDocument.setBarcodeInventoryErrorDetail(barcodeInventoryErrorDetails); 445 saveInvalidBarcodeInventoryDocument(barcodeInventoryErrorDocument); 446 447 barcodeInventoryErrorDetails = new ArrayList<BarcodeInventoryErrorDetail>(); 448 449 if (bcieCount >= bcies.size()) 450 break; 451 452 ln = 0; 453 isFirstDocument = false; 454 } 455 456 BarcodeInventoryErrorDetail barcodeInventoryErrorDetail =bcies.get(bcieCount); 457 barcodeInventoryErrorDetail.setUploadRowNumber(Long.valueOf(ln+1)); 458 barcodeInventoryErrorDetails.add(barcodeInventoryErrorDetail); 459 460 ln++; 461 bcieCount++; 462 } 463 } 464 catch (Exception e) { 465 LOG.error("Error creating BCIE documents", e); 466 throw new IllegalArgumentException("Error creating BCIE documents: " + e.getMessage(), e); 467 } 468 return documentsCreated; 469 } 470 471 472 /** 473 * This method updates the asset information particularly the building code, bulding room, building subrool, campus code, and 474 * condition code 475 * 476 * @param barcodeInventoryErrorDetail 477 */ 478 public void updateAssetInformation(BarcodeInventoryErrorDetail barcodeInventoryErrorDetail, boolean updateWithDateAssetWasScanned) { 479 Map<String, String> fieldValues = new HashMap<String, String>(); 480 fieldValues.put(CamsPropertyConstants.Asset.CAMPUS_TAG_NUMBER, barcodeInventoryErrorDetail.getAssetTagNumber()); 481 Asset asset = ((List<Asset>) businessObjectService.findMatching(Asset.class, fieldValues)).get(0); 482 483 asset.setInventoryScannedCode((barcodeInventoryErrorDetail.isUploadScanIndicator() ? CamsConstants.BarCodeInventory.BCI_SCANED_INTO_DEVICE : CamsConstants.BarCodeInventory.BCI_MANUALLY_KEYED_CODE)); 484 asset.setBuildingCode(barcodeInventoryErrorDetail.getBuildingCode()); 485 asset.setBuildingRoomNumber(barcodeInventoryErrorDetail.getBuildingRoomNumber()); 486 asset.setBuildingSubRoomNumber(barcodeInventoryErrorDetail.getBuildingSubRoomNumber()); 487 asset.setCampusCode(barcodeInventoryErrorDetail.getCampusCode()); 488 asset.setConditionCode(barcodeInventoryErrorDetail.getAssetConditionCode()); 489 490 if (updateWithDateAssetWasScanned) { 491 asset.setLastInventoryDate(barcodeInventoryErrorDetail.getUploadScanTimestamp()); 492 } else { 493 asset.setLastInventoryDate(new Timestamp(this.dateTimeService.getCurrentSqlDate().getTime())); 494 } 495 496 // Updating asset information 497 businessObjectService.save(asset); 498 } 499 500 /** 501 * This method creates a transaction document with the invalid barcode inventory records 502 * 503 * @param barcodeInventoryErrorDetails 504 * @return BarcodeInventoryErrorDocument 505 */ 506 protected BarcodeInventoryErrorDocument createInvalidBarcodeInventoryDocument(List<BarcodeInventoryErrorDetail> barcodeInventoryErrorDetails, String uploadDescription) throws WorkflowException { 507 BarcodeInventoryErrorDocument document = (BarcodeInventoryErrorDocument) documentService.getNewDocument(BarcodeInventoryErrorDocument.class); 508 509 document.getDocumentHeader().setExplanation(DOCUMENT_EXPLANATION); 510 document.getDocumentHeader().setFinancialDocumentTotalAmount(new KualiDecimal(0)); 511 document.getDocumentHeader().setDocumentDescription(uploadDescription); 512 document.setUploaderUniversalIdentifier(GlobalVariables.getUserSession().getPerson().getPrincipalId()); 513 document.setBarcodeInventoryErrorDetail(barcodeInventoryErrorDetails); 514 515 return document; 516 } 517 518 519 /** 520 * saves the barcode inventory document 521 * 522 * @param document 523 */ 524 protected void saveInvalidBarcodeInventoryDocument(BarcodeInventoryErrorDocument document) { 525 try { 526 // The errors are being deleted because, when the document services finds any error then, changes are not saved. 527 GlobalVariables.clear(); 528 529 // no adhoc recipient need to add when submit doc. doc will route to the doc uploader, i.e. initiator automtically. 530 List<AdHocRouteRecipient> adHocRouteRecipients = new ArrayList<AdHocRouteRecipient>(); 531 documentService.routeDocument(document, "Routed Update Barcode Inventory Document", adHocRouteRecipients); 532 } 533 catch (Exception e) { 534 LOG.error("Error persisting document # " + document.getDocumentHeader().getDocumentNumber() + " " + e.getMessage(), e); 535 throw new RuntimeException("Error persisting document # " + document.getDocumentHeader().getDocumentNumber() + " " + e.getMessage(), e); 536 } 537 } 538 539 /** 540 * This method builds a recipient for Approval. 541 * 542 * @param userId 543 * @return 544 */ 545 protected AdHocRouteRecipient buildApprovePersonRecipient(String userId) { 546 AdHocRouteRecipient adHocRouteRecipient = new AdHocRoutePerson(); 547 adHocRouteRecipient.setActionRequested(KEWConstants.ACTION_REQUEST_APPROVE_REQ); 548 adHocRouteRecipient.setId(userId); 549 return adHocRouteRecipient; 550 } 551 552 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 553 this.businessObjectService = businessObjectService; 554 } 555 556 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) { 557 this.dataDictionaryService = dataDictionaryService; 558 } 559 560 public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) { 561 this.workflowDocumentService = workflowDocumentService; 562 } 563 564 public void setKualiRuleService(KualiRuleService ruleService) { 565 this.kualiRuleService = ruleService; 566 } 567 568 public void setDocumentService(DocumentService documentService) { 569 this.documentService = documentService; 570 } 571 572 public ParameterService getParameterService() { 573 return parameterService; 574 } 575 576 public void setParameterService(ParameterService parameterService) { 577 this.parameterService = parameterService; 578 } 579 580 public void setDateTimeService(DateTimeService dateTimeService) { 581 this.dateTimeService = dateTimeService; 582 } 583 }