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 }