@Override public boolean validate(AttributedDocumentEvent event) { boolean valid = true; GlobalVariables.getMessageMap().clearErrorPath(); TravelEntertainmentDocument document = (TravelEntertainmentDocument) event.getDocument(); boolean entertainmentHostAttached = false; List<Note> notes = document.getNotes(); for (Note note : notes) { if (ObjectUtils.isNotNull(note.getAttachment()) && TemConstants.AttachmentTypeCodes.ATTACHMENT_TYPE_ENT_HOST_CERT.equals( note.getAttachment().getAttachmentTypeCode())) { entertainmentHostAttached = true; break; } } // if host is not as payee than entertainment host certification is required ; otherwise not if (!document.getHostAsPayee() && !entertainmentHostAttached) { valid = addError(); } return valid; }
protected void addNotes( String documentNumber, List<SubObjectCode> listOfSubObjects, String messageKey, PersistableBusinessObject noteParent, Note noteTemplate) { for (int i = 0; i < listOfSubObjects.size(); i += getNumSubObjectsPerNote()) { try { String subAccountString = createSubObjectChunk(listOfSubObjects, i, i + getNumSubObjectsPerNote()); if (StringUtils.isNotBlank(subAccountString)) { String noteTextTemplate = kualiConfigurationService.getPropertyValueAsString(messageKey); String noteText = MessageFormat.format(noteTextTemplate, subAccountString); Note note = noteService.createNote( noteTemplate, noteParent, GlobalVariables.getUserSession().getPrincipalId()); note.setNoteText(noteText); note.setNotePostedTimestampToCurrent(); noteService.save(note); } } catch (Exception e) { LOG.error("Unable to create/save notes for document " + documentNumber, e); throw new RuntimeException("Unable to create/save notes for document " + documentNumber, e); } } }
/** * @see * org.kuali.rice.krad.service.DocumentService#disapproveDocument(org.kuali.rice.krad.document.Document, * java.lang.String) */ @Override public Document disapproveDocument(Document document, String annotation) throws Exception { checkForNulls(document); Note note = createNoteFromDocument(document, annotation); // if note type is BO, override and link disapprove notes to Doc Header if (document.getNoteType().equals(NoteType.BUSINESS_OBJECT)) { note.setNoteTypeCode(NoteType.DOCUMENT_HEADER.getCode()); note.setRemoteObjectIdentifier(document.getDocumentHeader().getObjectId()); } document.addNote(note); // SAVE THE NOTE // Note: This save logic is replicated here and in KualiDocumentAction, when to save (based on // doc state) should be moved // into a doc service method getNoteService().save(note); prepareWorkflowDocument(document); getWorkflowDocumentService() .disapprove(document.getDocumentHeader().getWorkflowDocument(), annotation); UserSessionUtils.addWorkflowDocument( GlobalVariables.getUserSession(), document.getDocumentHeader().getWorkflowDocument()); removeAdHocPersonsAndWorkgroups(document); return document; }
/** @see org.kuali.rice.krad.service.DocumentService */ @Override public void sendNoteRouteNotification(Document document, Note note, Person sender) throws WorkflowException { AdHocRouteRecipient routeRecipient = note.getAdHocRouteRecipient(); // build notification request Person requestedUser = this.getPersonService().getPersonByPrincipalName(routeRecipient.getId()); String senderName = sender.getFirstName() + " " + sender.getLastName(); String requestedName = requestedUser.getFirstName() + " " + requestedUser.getLastName(); String notificationText = kualiConfigurationService.getPropertyValueAsString( RiceKeyConstants.MESSAGE_NOTE_NOTIFICATION_ANNOTATION); if (StringUtils.isBlank(notificationText)) { throw new RuntimeException( "No annotation message found for note notification. Message needs added to application resources with key:" + RiceKeyConstants.MESSAGE_NOTE_NOTIFICATION_ANNOTATION); } notificationText = MessageFormat.format( notificationText, new Object[] {senderName, requestedName, note.getNoteText()}); List<AdHocRouteRecipient> routeRecipients = new ArrayList<AdHocRouteRecipient>(); routeRecipients.add(routeRecipient); workflowDocumentService.sendWorkflowNotification( document.getDocumentHeader().getWorkflowDocument(), notificationText, routeRecipients, KRADConstants.NOTE_WORKFLOW_NOTIFICATION_REQUEST_LABEL); // clear recipient allowing an notification to be sent to another person note.setAdHocRouteRecipient(new AdHocRoutePerson()); }
/** * @see * org.kuali.rice.krad.service.DocumentService#createNoteFromDocument(org.kuali.rice.krad.document.Document, * java.lang.String) */ @Override public Note createNoteFromDocument(Document document, String text) { Note note = new Note(); note.setNotePostedTimestamp(getDateTimeService().getCurrentTimestamp()); note.setNoteText(text); note.setNoteTypeCode(document.getNoteType().getCode()); PersistableBusinessObject bo = document.getNoteTarget(); // TODO gah! this is awful Person kualiUser = GlobalVariables.getUserSession().getPerson(); if (kualiUser == null) { throw new IllegalStateException("Current UserSession has a null Person."); } return bo == null ? null : getNoteService().createNote(note, bo, kualiUser.getPrincipalId()); }
private void linkNoteRemoteObjectId(Note note, PersistableBusinessObject noteTarget) { String objectId = noteTarget.getObjectId(); if (StringUtils.isBlank(objectId)) { throw new IllegalStateException( "Attempted to link a Note with a PersistableBusinessObject with no object id"); } note.setRemoteObjectIdentifier(noteTarget.getObjectId()); }
@Override public ActionForward insertBONote( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form; Note newNote = kualiDocumentFormBase.getNewNote(); NoteExtendedAttribute extendedAttribute = (NoteExtendedAttribute) newNote.getExtension(); ActionForward forward = super.insertBONote(mapping, form, request, response); if (newNote != kualiDocumentFormBase.getNewNote()) { Note addedNote = kualiDocumentFormBase .getDocument() .getNotes() .get(kualiDocumentFormBase.getDocument().getNotes().size() - 1); extendedAttribute.setNoteIdentifier(addedNote.getNoteIdentifier()); addedNote.setExtension(extendedAttribute); SpringContext.getBean(BusinessObjectService.class).save(extendedAttribute); addedNote.refreshReferenceObject("extension"); } return forward; }
protected void addMaintenanceLockedNotes( String documentNumber, Map<SubObjectCode, String> lockedSubObjects, String messageKey, PersistableBusinessObject noteParent, Note noteTemplate) { for (Map.Entry<SubObjectCode, String> entry : lockedSubObjects.entrySet()) { try { SubObjectCode subObjCd = entry.getKey(); String subObjectString = subObjCd.getUniversityFiscalYear() + " - " + subObjCd.getChartOfAccountsCode() + " - " + subObjCd.getAccountNumber() + " - " + subObjCd.getFinancialObjectCode() + " - " + subObjCd.getFinancialSubObjectCode(); if (StringUtils.isNotBlank(subObjectString)) { String noteTextTemplate = kualiConfigurationService.getPropertyValueAsString(messageKey); String noteText = MessageFormat.format(noteTextTemplate, subObjectString, entry.getValue()); Note note = noteService.createNote( noteTemplate, noteParent, GlobalVariables.getUserSession().getPrincipalId()); note.setNoteText(noteText); note.setNotePostedTimestampToCurrent(); noteService.save(note); } } catch (Exception e) { LOG.error("Unable to create/save notes for document " + documentNumber, e); throw new RuntimeException("Unable to create/save notes for document " + documentNumber, e); } } }
protected void addNoteAfterProcessingAgencyStagingExpense( MaintenanceDocument document, List<ErrorMessage> errors) { Principal kfsSystemUser = getIdentityService().getPrincipalByPrincipalName(KFSConstants.SYSTEM_USER); String errorText = getMessageAsString(errors); if (!StringUtils.isEmpty(errorText)) { // check maxLength on a Note and truncate if necessary Integer maxLength = getDataDictionaryService() .getAttributeMaxLength(Note.class, KRADConstants.NOTE_TEXT_PROPERTY_NAME); if (errorText.length() > maxLength) { LOG.warn("Adding a truncated error text to Note due to space limitations. Original text:"); LOG.warn(errorText); errorText = errorText.substring(0, maxLength); } final Note newNote = getDocumentService().createNoteFromDocument(document, errorText); newNote.setAuthorUniversalIdentifier(kfsSystemUser.getPrincipalId()); document.addNote(newNote); getNoteService().save(newNote); } }
// mjmc // ************************************************************************************************* private PurchaseOrderDocument copyNotesAndAttachmentsToPO( RequisitionDocument reqDoc, PurchaseOrderDocument poDoc) { purapService.saveDocumentNoValidation(poDoc); List<Note> notes = (List<Note>) reqDoc.getNotes(); int noteLength = notes.size(); if (noteLength > 0) { for (Note note : notes) { try { Note copyingNote = SpringContext.getBean(DocumentService.class) .createNoteFromDocument(poDoc, note.getNoteText()); purapService.saveDocumentNoValidation(poDoc); copyingNote.setNotePostedTimestamp(note.getNotePostedTimestamp()); copyingNote.setAuthorUniversalIdentifier(note.getAuthorUniversalIdentifier()); copyingNote.setNoteTopicText(note.getNoteTopicText()); Attachment originalAttachment = SpringContext.getBean(AttachmentService.class) .getAttachmentByNoteId(note.getNoteIdentifier()); NoteExtendedAttribute noteExtendedAttribute = (NoteExtendedAttribute) note.getExtension(); if (originalAttachment != null || (ObjectUtils.isNotNull(noteExtendedAttribute) && noteExtendedAttribute.isCopyNoteIndicator())) { if (originalAttachment != null) { Attachment newAttachment = SpringContext.getBean(AttachmentService.class) .createAttachment( (PersistableBusinessObject) copyingNote, originalAttachment.getAttachmentFileName(), originalAttachment.getAttachmentMimeTypeCode(), originalAttachment.getAttachmentFileSize().intValue(), originalAttachment.getAttachmentContents(), originalAttachment.getAttachmentTypeCode()); // new Attachment(); if (ObjectUtils.isNotNull(originalAttachment) && ObjectUtils.isNotNull(newAttachment)) { copyingNote.addAttachment(newAttachment); } } poDoc.addNote(copyingNote); } } catch (Exception e) { throw new RuntimeException(e); } } } purapService.saveDocumentNoValidation(poDoc); return poDoc; } // mjmc end
private Note truncateNoteTextTo800(Note note) { if (note.getNoteText().length() > 800) { note.setNoteText(note.getNoteText().substring(0, 799)); } return note; }
/** * This method is used to send emails to the agency * * @param invoices */ @Override public void sendInvoicesViaEmail(List<ContractsGrantsInvoiceDocument> invoices) throws AddressException, MessagingException { LOG.debug("sendInvoicesViaEmail() starting."); Properties props = getConfigProperties(); // Get session Session session = Session.getInstance(props, null); for (ContractsGrantsInvoiceDocument invoice : invoices) { List<InvoiceAddressDetail> invoiceAddressDetails = invoice.getInvoiceAddressDetails(); for (InvoiceAddressDetail invoiceAddressDetail : invoiceAddressDetails) { if (ArConstants.InvoiceTransmissionMethod.EMAIL.equals( invoiceAddressDetail.getInvoiceTransmissionMethodCode())) { // KFSTI-48 Refactor to retrieve the note through noteService Note note = noteService.getNoteByNoteId(invoiceAddressDetail.getNoteId()); if (ObjectUtils.isNotNull(note)) { MimeMessage message = new MimeMessage(session); // From Address String sender = parameterService.getParameterValueAsString( ContractsGrantsInvoiceEmailReportsBatchStep.class, ArConstants.CG_INVOICE_FROM_EMAIL_ADDRESS); message.setFrom(new InternetAddress(sender)); // To Address CustomerAddress customerAddress = invoiceAddressDetail.getCustomerAddress(); String recipients = customerAddress.getCustomerEmailAddress(); if (StringUtils.isNotEmpty(recipients)) { InternetAddress[] recipientAddress = {new InternetAddress(recipients)}; message.addRecipients(Message.RecipientType.TO, recipientAddress); } else { LOG.warn("No recipients indicated."); } // The Subject String subject = parameterService.getParameterValueAsString( ContractsGrantsInvoiceEmailReportsBatchStep.class, ArConstants.CG_INVOICE_EMAIL_SUBJECT); String bodyText = parameterService.getParameterValueAsString( ContractsGrantsInvoiceEmailReportsBatchStep.class, ArConstants.CG_INVOICE_EMAIL_BODY); Map<String, String> map = new HashMap<String, String>(); getEmailParameterList(map, invoice, customerAddress); subject = replaceValuesInString(subject, map); bodyText = replaceValuesInString(bodyText, map); message.setSubject(subject); if (StringUtils.isEmpty(subject)) { LOG.warn("Empty subject being sent."); } // Now the message body. // create and fill the first message part MimeBodyPart body = new MimeBodyPart(); body.setText(bodyText); // create and fill the second message part MimeBodyPart attachment = new MimeBodyPart(); // Use setText(text, charset), to show it off ! // create the Multipart and its parts to it Multipart multipart = new MimeMultipart(); multipart.addBodyPart(body); try { ByteArrayDataSource ds = new ByteArrayDataSource( note.getAttachment().getAttachmentContents(), "application/pdf"); attachment.setDataHandler(new DataHandler(ds)); attachment.setFileName(note.getAttachment().getAttachmentFileName()); multipart.addBodyPart(attachment); } catch (IOException ex) { LOG.error("problem during AREmailServiceImpl.sendInvoicesViaEmail()", ex); } // add the Multipart to the message message.setContent(multipart); // Finally, send the message! Transport.send(message); } } } invoice.setMarkedForProcessing(ArConstants.INV_RPT_PRCS_SENT); documentService.updateDocument(invoice); } }
/** * @see * org.kuali.kfs.sys.document.validation.Validation#validate(org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent) */ @SuppressWarnings("rawtypes") @Override public boolean validate(AttributedDocumentEvent event) { final Person currentUser = GlobalVariables.getUserSession().getPerson(); TemSourceAccountingLine line = null; if (event instanceof UpdateAccountingLineEvent) { line = (TemSourceAccountingLine) ((UpdateAccountingLineEvent) event).getUpdatedAccountingLine(); } else { line = (TemSourceAccountingLine) ((AccountingLineEvent) event).getAccountingLine(); } List<String> holdErrors = new ArrayList<String>(); holdErrors.addAll(GlobalVariables.getMessageMap().getErrorPath()); GlobalVariables.getMessageMap().clearErrorPath(); TravelDocument travelDocument = (TravelDocument) event.getDocument(); final boolean canUpdate = isAtTravelNode(event.getDocument().getDocumentHeader().getWorkflowDocument()) || isAdvancePaymentMethodException( event.getDocument(), line); // Are we at the travel node? If so, there's a chance that accounting lines // changed; if they did, that // was a permission granted to the travel manager so we should allow it. Also, if we're at // PaymentMethod and the line is an advance accounting line, that's allowed to boolean valid = true; String errorPath = TemPropertyConstants.NEW_SOURCE_ACCTG_LINE; for (TemSourceAccountingLine sourceLine : (List<TemSourceAccountingLine>) travelDocument.getSourceAccountingLines()) { if (line.equals(sourceLine)) { errorPath = "document." + TemPropertyConstants.SOURCE_ACCOUNTING_LINE + "[" + travelDocument.getSourceAccountingLines().indexOf(line) + "]"; break; } } // Test added accounting lines for null values and if there is an access change. valid = getTravelDocumentService().validateSourceAccountingLines(travelDocument, false); if ((!travelDocument .getAppDocStatus() .equalsIgnoreCase(TemConstants.TRAVEL_DOC_APP_DOC_STATUS_INIT)) && (!travelDocument .getAppDocStatus() .equalsIgnoreCase(TemConstants.TravelAuthorizationStatusCodeKeys.IN_PROCESS)) && (!travelDocument .getAppDocStatus() .equalsIgnoreCase(TemConstants.TravelAuthorizationStatusCodeKeys.CHANGE_IN_PROCESS))) { if (!line.getAccount() .getAccountFiscalOfficerUser() .getPrincipalId() .equals(currentUser.getPrincipalId()) && !canUpdate) { GlobalVariables.getMessageMap() .putError( KFSPropertyConstants.ACCOUNT_NUMBER, TemKeyConstants.ERROR_TA_FISCAL_OFFICER_ACCOUNT, line.getAccountNumber()); return false; } } GlobalVariables.getMessageMap().addToErrorPath(errorPath); // skip accounting line validation for TA if (!(event.getDocument() instanceof TravelAuthorizationDocument)) { if (ObjectUtils.isNotNull(line.getObjectTypeCode())) { // check to make sure they're the same List<AccountingDistribution> list = getAccountingDistributionService().buildDistributionFrom(travelDocument); List<AccountingLineDistributionKey> distributionList = new ArrayList<AccountingLineDistributionKey>(); List<String> expectedObjectCodes = new ArrayList<String>(); for (AccountingDistribution dist : list) { distributionList.add( new AccountingLineDistributionKey(dist.getObjectCode(), dist.getCardType())); expectedObjectCodes.add(dist.getObjectCode()); } final String expectedObjectCodesString = StringUtils.join(expectedObjectCodes, ", "); if (!distributionList.contains( new AccountingLineDistributionKey(line.getFinancialObjectCode(), line.getCardType()))) { GlobalVariables.getMessageMap() .putError( TravelAuthorizationFields.FIN_OBJ_CD, TemKeyConstants.ERROR_TEM_ACCOUNTING_LINES_OBJECT_CODE_CARD_TYPE, line.getFinancialObjectCode(), line.getCardType(), expectedObjectCodesString); valid &= false; } } } if (line.getAmount().isLessEqual(KualiDecimal.ZERO) && !travelDocument.getBlanketTravel()) { GlobalVariables.getMessageMap() .putError( KFSPropertyConstants.AMOUNT, KFSKeyConstants.ERROR_CUSTOM, "Amount must be greater than zero."); valid &= false; } if (valid) { // Fly America validation TravelDocument document = (TravelDocument) event.getDocument(); List<TemExpense> allExpenses = new ArrayList<TemExpense>(); allExpenses.addAll(document.getImportedExpenses()); allExpenses.addAll(document.getActualExpenses()); if (allExpenses.size() > 0) { boolean hasAttachment = false; boolean showFlyAmerica = false; for (Note note : document.getNotes()) { if (note.getAttachment() != null) { hasAttachment = true; break; } } boolean isCGEnabled = getParameterService() .getParameterValueAsBoolean( KFSConstants.CoreModuleNamespaces.CHART, KFSConstants.RouteLevelNames.ACCOUNT, KFSConstants.ChartApcParms.ACCOUNT_FUND_GROUP_DENOTES_CG); if (isCGEnabled) { for (TemExpense expense : allExpenses) { if (expense.getExpenseTypeCode().equals(TemConstants.ExpenseTypes.AIRFARE)) { Map<String, Object> fieldValues = new HashMap<String, Object>(); fieldValues.put(KRADPropertyConstants.CODE, TemConstants.ExpenseTypes.AIRFARE); fieldValues.put(KRADPropertyConstants.NAME, expense.getTravelCompanyCodeName()); TravelCompanyCode travelCompany = getBusinessObjectService().findByPrimaryKey(TravelCompanyCode.class, fieldValues); if (travelCompany != null && travelCompany.isForeignCompany()) { String financialObjectCode = expense.getExpenseTypeObjectCode() != null ? expense.getExpenseTypeObjectCode().getFinancialObjectCode() : null; if (travelDocument instanceof TravelAuthorizationDocument && expense instanceof ActualExpense) { if (document.getTripType() != null) { financialObjectCode = document.getTripType().getEncumbranceObjCode(); } } if (financialObjectCode != null && financialObjectCode.equals(line.getFinancialObjectCode())) { String cg = getParameterService() .getParameterValueAsString( KFSConstants.CoreModuleNamespaces.CHART, KFSConstants.RouteLevelNames.ACCOUNT, KFSConstants.ChartApcParms.ACCOUNT_CG_DENOTING_VALUE); if (line.getAccount() == null) { line.refreshReferenceObject(KFSPropertyConstants.ACCOUNT); } if (line.getAccount().getSubFundGroup() == null) { line.refreshReferenceObject(KFSPropertyConstants.SUB_FUND_GROUP); } if (line.getAccount().getSubFundGroup().getFundGroupCode().equals(cg)) { showFlyAmerica = true; } } } } } } // Fly America error has been triggered, determine what accounting line to show it on. if (showFlyAmerica && !hasAttachment) { boolean newLine = true; for (TemSourceAccountingLine sourceLine : (List<TemSourceAccountingLine>) travelDocument.getSourceAccountingLines()) { if (line.equals(sourceLine)) { newLine = false; } } // if line is a new accounting line or a current one being saved/submitted in the // document. // figure out where the new accounting line will be added and set the error to that line # if (newLine) { GlobalVariables.getMessageMap().clearErrorPath(); int newIndex = document .getSourceAccountingLine(document.getSourceAccountingLines().size() - 1) .getSequenceNumber() + 1; errorPath = "document." + TemPropertyConstants.SOURCE_ACCOUNTING_LINE + "[" + newIndex + "]"; GlobalVariables.getMessageMap().addToErrorPath(errorPath); } GlobalVariables.getMessageMap() .putError( KFSPropertyConstants.ACCOUNT_NUMBER, TemKeyConstants.ERROR_ACCOUNTING_LINE_CG); } } } GlobalVariables.getMessageMap().clearErrorPath(); GlobalVariables.getMessageMap().getErrorPath().addAll(holdErrors); return valid; }