protected void cancelOnlineReviewDocument( ProtocolOnlineReviewDocumentBase protocolOnlineReviewDocument, ProtocolSubmissionBase submission, String annotation) { try { final String principalId = identityManagementService .getPrincipalByPrincipalName(KRADConstants.SYSTEM_USER) .getPrincipalId(); WorkflowDocument workflowDocument = WorkflowDocumentFactory.loadDocument( principalId, protocolOnlineReviewDocument.getDocumentNumber()); if (workflowDocument.isEnroute() || workflowDocument.isInitiated() || workflowDocument.isSaved()) { workflowDocument.superUserCancel( String.format( "Review Cancelled from assign reviewers action by %s", GlobalVariables.getUserSession().getPrincipalId())); } } catch (Exception e) { String errorMessage = String.format( "Exception generated while executing superUserCancel on document %s in removeOnlineReviewDocument. Message: %s", protocolOnlineReviewDocument.getDocumentNumber(), e.getMessage()); LOG.error(errorMessage); throw new RuntimeException(errorMessage, e); } }
/** * Adding the role qualifications for the processing chart and organization * * @see * org.kuali.rice.kns.document.authorization.DocumentAuthorizerBase#addRoleQualification(org.kuali.rice.kns.bo.BusinessObject, * java.util.Map) */ @Override protected void addRoleQualification(Object businessObject, Map<String, String> attributes) { super.addRoleQualification(businessObject, attributes); if (businessObject != null && businessObject instanceof PaymentApplicationDocument) { final PaymentApplicationDocument document = (PaymentApplicationDocument) businessObject; final WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); if (workflowDocument.isInitiated() || workflowDocument.isSaved() || workflowDocument .isCompletionRequested()) { // only add processing chart and org if we're PreRoute final AccountsReceivableDocumentHeader arDocumentHeader = document.getAccountsReceivableDocumentHeader(); if (!ObjectUtils.isNull(arDocumentHeader)) { if (!StringUtils.isBlank(arDocumentHeader.getProcessingChartOfAccCodeAndOrgCode())) { attributes.put( KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, arDocumentHeader.getProcessingChartOfAccountCode()); } if (!StringUtils.isBlank(arDocumentHeader.getProcessingOrganizationCode())) { attributes.put( KfsKimAttributes.ORGANIZATION_CODE, arDocumentHeader.getProcessingOrganizationCode()); } } } } }
/** * Test the approval of a protocol. The protocol status and its corresponding action should be set * to approved. */ @Test public void runApprovedTest() throws Exception { ProtocolDocument protocolDocument = ProtocolFactory.createProtocolDocument(); protocolSubmitActionService.submitToIrbForReview( protocolDocument.getProtocol(), getMockSubmitAction()); documentService.routeDocument(protocolDocument, null, null); documentService.blanketApproveDocument(protocolDocument, null, null); WorkflowDocument workflowDoc = getWorkflowDocument(protocolDocument); WorkflowDocumentActionsService info = GlobalResourceLoader.getService("rice.kew.workflowDocumentActionsService"); RoutingReportCriteria.Builder reportCriteriaBuilder = RoutingReportCriteria.Builder.createByDocumentId(workflowDoc.getDocumentId()); DocumentDetail results1 = info.executeSimulation(reportCriteriaBuilder.build()); assertTrue(workflowDoc.isFinal()); // the status update is not happening within doRouteStatusChange anymore // assertEquals(protocolDocument.getProtocol().getProtocolStatusCode(), // ProtocolStatus.ACTIVE_OPEN_TO_ENROLLMENT); assertTrue(protocolDocument.getProtocol().isActive()); // verifyProtocolAction(protocolDocument.getProtocol().getProtocolId(), // ProtocolActionType.APPROVED); }
/** * @see * org.kuali.kfs.module.ar.document.service.InvoiceRecurrenceService#isInvoiceApproved(String) */ @Override public boolean isInvoiceApproved(String invoiceNumber) { boolean success = true; if (ObjectUtils.isNull(invoiceNumber)) { return success; } CustomerInvoiceDocument customerInvoiceDocument = null; try { customerInvoiceDocument = (CustomerInvoiceDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(invoiceNumber); } catch (WorkflowException e) { } if (ObjectUtils.isNotNull(customerInvoiceDocument)) { WorkflowDocument workflowDocument = customerInvoiceDocument.getDocumentHeader().getWorkflowDocument(); if (!(workflowDocument.isApproved())) { success = false; } } else { success = false; } return success; }
@Override public List<String> buildListForFYI(AwardDocument awardDocument) throws WorkflowException { WorkflowDocument document = awardDocument.getDocumentHeader().getWorkflowDocument(); RoutingReportCriteria reportCriteria = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId()).build(); // gather the IDs for action requests that predate the simulation DocumentRouteHeaderValue routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId()); Set<String> preexistingActionRequestIds = getActionRequestIds(routeHeader); // run the simulation via WorkflowUtility DocumentDetail documentDetail = workflowUtility.executeSimulation(reportCriteria); // fabricate our ActionRequestValueS from the results List<ActionRequestValue> actionRequests = reconstituteActionRequestValues(documentDetail, preexistingActionRequestIds); List<String> actionIds = new ArrayList<String>(); for (ActionRequestValue request : actionRequests) { if (request.isGroupRequest()) { actionIds.addAll( KimApiServiceLocator.getGroupService().getMemberPrincipalIds(request.getGroupId())); } if (request.isUserRequest()) { actionIds.add(request.getPrincipalId()); } } return actionIds; }
/** * @see * org.kuali.rice.krad.service.DocumentService#getByDocumentHeaderIdSessionless(java.lang.String) */ @Override public Document getByDocumentHeaderIdSessionless(String documentHeaderId) throws WorkflowException { if (documentHeaderId == null) { throw new IllegalArgumentException("invalid (null) documentHeaderId"); } WorkflowDocument workflowDocument = null; if (LOG.isDebugEnabled()) { LOG.debug("Retrieving doc id: " + documentHeaderId + " from workflow service."); } Person person = getPersonService().getPersonByPrincipalName(KRADConstants.SYSTEM_USER); workflowDocument = workflowDocumentService.loadWorkflowDocument(documentHeaderId, person); Class<? extends Document> documentClass = getDocumentClassByTypeName(workflowDocument.getDocumentTypeName()); // retrieve the Document Document document = getLegacyDataAdapter().findByDocumentHeaderId(documentClass, documentHeaderId); return postProcessDocument(documentHeaderId, workflowDocument, document); }
/** * Overridden to guarantee that form of copied document is set to whatever the entry mode of the * document is * * @see org.kuali.rice.kns.web.struts.action.KualiTransactionalDocumentActionBase#copy * (org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, * javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public ActionForward copy( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { ActionForward forward = null; String docID = "docId"; if (request.getParameter(docID) == null) { forward = super.copy(mapping, form, request, response); } else { // this is copy document from Procurement Gateway: // use this url to call: // http://localhost:8080/kfs-dev/purapRequisition.do?methodToCall=copy&docId=xxxx String docId = request.getParameter(docID); KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form; CuRequisitionDocument document = null; document = (CuRequisitionDocument) getDocumentService().getByDocumentHeaderId(docId); document.toCopyFromGateway(); kualiDocumentFormBase.setDocument(document); WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); kualiDocumentFormBase.setDocTypeName(workflowDocument.getDocumentTypeName()); SpringContext.getBean(SessionDocumentService.class) .addDocumentToUserSession(GlobalVariables.getUserSession(), workflowDocument); forward = mapping.findForward(RiceConstants.MAPPING_BASIC); } return forward; }
/** * @see * org.kuali.rice.ken.service.NotificationWorkflowDocumentService#terminateWorkflowDocument(org.kuali.rice.kew.api.WorkflowDocument) */ public void terminateWorkflowDocument(WorkflowDocument document) { document.superUserCancel( "terminating document: documentId=" + document.getDocumentId() + ", appDocId=" + document.getApplicationDocumentId()); }
public ProtocolOnlineReviewDocumentBase createProtocolOnlineReviewDocument( ProtocolSubmissionBase protocolSubmission, ProtocolReviewer protocolReviewer, String documentDescription, String documentExplanation, String documentOrganizationDocumentNumber, Date dateRequested, Date dateDue, String principalId) throws WorkflowException { IacucProtocolOnlineReviewDocument protocolReviewDocument; Person person = personService.getPerson(principalId); WorkflowDocument workflowDocument = workflowDocumentService.createWorkflowDocument( IACUC_PROTOCOL_ONLINE_REVIEW_DOCUMENT_TYPE, person); DocumentHeader docHeader = new DocumentHeader(); docHeader.setWorkflowDocument(workflowDocument); docHeader.setDocumentNumber(workflowDocument.getDocumentId().toString()); protocolReviewDocument = new IacucProtocolOnlineReviewDocument(); protocolReviewDocument.setDocumentNumber(docHeader.getDocumentNumber()); protocolReviewDocument.setDocumentHeader(docHeader); protocolReviewDocument.getProtocolOnlineReview().setProtocol(protocolSubmission.getProtocol()); protocolReviewDocument .getProtocolOnlineReview() .setProtocolId(protocolSubmission.getProtocolId()); protocolReviewDocument.getProtocolOnlineReview().setProtocolSubmission(protocolSubmission); protocolReviewDocument .getProtocolOnlineReview() .setSubmissionIdFk(protocolSubmission.getSubmissionId()); protocolReviewDocument .getProtocolOnlineReview() .setProtocolOnlineReviewStatusCode(IacucProtocolOnlineReviewStatus.SAVED_STATUS_CD); protocolReviewDocument .getProtocolOnlineReview() .setDateRequested( dateRequested == null ? new Date((new java.util.Date()).getTime()) : dateRequested); protocolReviewDocument.getProtocolOnlineReview().setDateDue(dateDue); protocolReviewDocument .getProtocolOnlineReview() .setProtocolReviewerId(protocolReviewer.getProtocolReviewerId()); protocolReviewDocument.getProtocolOnlineReview().setProtocolReviewer(protocolReviewer); docHeader.setDocumentDescription(documentDescription); docHeader.setOrganizationDocumentNumber(documentOrganizationDocumentNumber); docHeader.setExplanation(documentExplanation); documentService.saveDocument(protocolReviewDocument); return protocolReviewDocument; }
/** * Creates a new ProtocolReviewDocument. * * <p>Handles creating the workflow document, and the underlying ProtocolReview BO linking the * protocol, submission, and reviewer. * * @param protocolSubmission The protocol submission * @param protocolReviewerBean The bean that holds * @param documentDescription the description for the created document * @param documentExplanation the explanation for the created document * @param documentOrganizationNumber the organizationNumber for the created document * @param principalId The principalId to use when creating the workflow document. Usually this * should be the principal of the user creating the review. * @return * @throws WorkflowException */ protected ProtocolOnlineReviewDocumentBase createProtocolOnlineReviewDocument( ProtocolSubmissionBase protocolSubmission, ProtocolReviewer protocolReviewer, String documentDescription, String documentExplanation, String documentOrganizationDocumentNumber, Date dateRequested, Date dateDue, String principalId) throws WorkflowException { ProtocolOnlineReviewDocumentBase protocolReviewDocument; Person person = personService.getPerson(principalId); WorkflowDocument workflowDocument = workflowDocumentService.createWorkflowDocument(getProtocolOLRDocumentTypeHook(), person); DocumentHeader docHeader = new DocumentHeader(); docHeader.setWorkflowDocument(workflowDocument); docHeader.setDocumentNumber(workflowDocument.getDocumentId().toString()); protocolReviewDocument = getNewProtocolOnlineReviewDocumentInstanceHook(); protocolReviewDocument.setDocumentNumber(docHeader.getDocumentNumber()); protocolReviewDocument.setDocumentHeader(docHeader); protocolReviewDocument.getProtocolOnlineReview().setProtocol(protocolSubmission.getProtocol()); protocolReviewDocument .getProtocolOnlineReview() .setProtocolId(protocolSubmission.getProtocolId()); protocolReviewDocument.getProtocolOnlineReview().setProtocolSubmission(protocolSubmission); protocolReviewDocument .getProtocolOnlineReview() .setSubmissionIdFk(protocolSubmission.getSubmissionId()); protocolReviewDocument .getProtocolOnlineReview() .setProtocolOnlineReviewStatusCode(getProtocolOLRSavedStatusCodeHook()); protocolReviewDocument .getProtocolOnlineReview() .setDateRequested( dateRequested == null ? new Date((new java.util.Date()).getTime()) : dateRequested); protocolReviewDocument.getProtocolOnlineReview().setDateDue(dateDue); protocolReviewDocument .getProtocolOnlineReview() .setProtocolReviewerId(protocolReviewer.getProtocolReviewerId()); protocolReviewDocument.getProtocolOnlineReview().setProtocolReviewer(protocolReviewer); docHeader.setDocumentDescription(documentDescription); docHeader.setOrganizationDocumentNumber(documentOrganizationDocumentNumber); docHeader.setExplanation(documentExplanation); documentService.saveDocument(protocolReviewDocument); return protocolReviewDocument; }
@Override public boolean canEditDocumentOverview(Document document) { WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); Set<String> nodeNames = workflowDocument.getCurrentNodeNames(); return workflowDocument.isEnroute() && CollectionUtils.isNotEmpty(nodeNames) && nodeNames.contains(KFSConstants.RouteLevelNames.ACCOUNT_REVIEW_FULL_EDIT) && workflowDocument.isApprovalRequested() && !workflowDocument.isAcknowledgeRequested(); }
protected void performDisapprove(ProtocolBase protocol) throws Exception { if (protocol.getProtocolDocument() != null) { WorkflowDocument currentWorkflowDocument = protocol.getProtocolDocument().getDocumentHeader().getWorkflowDocument(); if (currentWorkflowDocument != null) { currentWorkflowDocument.disapprove( "Protocol document disapproved after committee decision"); } } getProtocolOnlineReviewService() .cancelOnlineReviews( protocol.getProtocolSubmission(), "Protocol Review cancelled - protocol has been disapproved."); }
/** * Tests that an exception is not thrown if you try to execute a "route" command on a document you * did not initiate. */ @Test public void testRouteDocumentAsNonInitiatorUser() throws Exception { WorkflowDocument firstDocument = WorkflowDocumentFactory.createDocument( getPrincipalIdForName("user1"), DOCUMENT_TYPE_POLICY_TEST_NAME); WorkflowDocument document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("user2"), firstDocument.getDocumentId()); try { document.route(""); } catch (Exception e) { e.printStackTrace(); fail( "Exception thrown but should not have have been... Exception was of type " + e.getClass().getName() + " and message was " + e.getMessage()); } document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("user1"), firstDocument.getDocumentId()); assertEquals( "Document should be in Enroute status.", DocumentStatus.ENROUTE, document.getStatus()); // verify that there is 1 action taken Collection<ActionTakenValue> actionTakens = KEWServiceLocator.getActionTakenService().findByDocumentId(document.getDocumentId()); assertEquals("There should be 1 action taken.", 1, actionTakens.size()); }
/** * Tests that an exception is thrown if you try to execute a "route" command on an already routed * document. */ @Test public void testRouteAlreadyRoutedDocument() throws Exception { WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), DOCUMENT_TYPE_NAME); document.route(""); assertTrue("Document should be ENROUTE.", document.isEnroute()); assertFalse("There should not be a request to ewestfal.", document.isApprovalRequested()); // verify that only 1 action taken has been performed Collection<ActionTakenValue> actionTakens = KEWServiceLocator.getActionTakenService().findByDocumentId(document.getDocumentId()); assertEquals("There should be only 1 action taken.", 1, actionTakens.size()); // now try and route the document again, an exception should be thrown try { document.route(""); fail("A WorkflowException should have been thrown."); } catch (InvalidActionTakenException e) { e.printStackTrace(); } // verify that there is still only 1 action taken (the transaction above should have rolled // back) actionTakens = KEWServiceLocator.getActionTakenService().findByDocumentId(document.getDocumentId()); assertEquals("There should still be only 1 action taken.", 1, actionTakens.size()); }
private WorkflowAttributeDefinition.Builder getWorkflowAttributeDefinitionVO( String attributeName, WorkflowDocument document) { for (WorkflowAttributeDefinition attributeDefinition : document.getAttributeDefinitions()) { if (attributeDefinition.getAttributeName().equals(attributeName)) { return WorkflowAttributeDefinition.Builder.create(attributeDefinition); } } return WorkflowAttributeDefinition.Builder.create(attributeName); }
/** * Check if workflow is at the specific node * * @param workflowDocument * @param nodeName * @return */ protected boolean isAtTravelNode(WorkflowDocument workflowDocument) { Set<String> nodeNames = workflowDocument.getNodeNames(); for (String nodeNamesNode : nodeNames) { if (TemWorkflowConstants.RouteNodeNames.AP_TRAVEL.equals(nodeNamesNode)) { return true; } } return false; }
/** * @see * org.kuali.rice.ken.service.NotificationWorkflowDocumentService#clearAllFyisAndAcknowledgeNotificationWorkflowDocument(java.lang.String, * org.kuali.rice.ken.document.kew.NotificationWorkflowDocument, java.lang.String) */ public void clearAllFyisAndAcknowledgeNotificationWorkflowDocument( String initiatorUserId, WorkflowDocument workflowDocument, String annotation) { List<ActionRequest> reqs = workflowDocument.getRootActionRequests(); for (int i = 0; i < reqs.size(); i++) { LOG.info("Action Request[" + i + "] = " + reqs.get(i).getActionRequested()); if (reqs.get(i).getActionRequested().equals(ActionRequestType.ACKNOWLEDGE)) { workflowDocument.acknowledge(annotation); } else if (reqs.get(i).getActionRequested().equals(ActionRequestType.FYI)) { workflowDocument.logAnnotation(annotation); workflowDocument.fyi(); } else { throw new WorkflowRuntimeException( "Invalid notification action request in workflow document (" + workflowDocument.getDocumentId() + ") was encountered. Should be either an acknowledge or fyi and was not."); } } }
/** * Cancel that calls superUserCancel if the document is in route and the current user is the * routed by user of the document. * * @see * org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#cancel(org.apache.struts.action.ActionMapping, * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ @Override public ActionForward cancel( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { AwardBudgetDocument awardBudgetDocument = ((AwardBudgetForm) form).getAwardBudgetDocument(); WorkflowDocument workflowDoc = awardBudgetDocument.getDocumentHeader().getWorkflowDocument(); if (workflowDoc.isEnroute() && StringUtils.equals( GlobalVariables.getUserSession().getPrincipalId(), workflowDoc.getRoutedByPrincipalId())) { workflowDoc.superUserCancel("Cancelled by Routed By User"); return mapping.findForward(Constants.MAPPING_BASIC); } else { return super.cancel(mapping, form, request, response); } }
public boolean isValidRemovalRequest( ProtocolOnlineReviewDocument document, ProtocolReviewerBean reviewer, int reviewerIndex) { boolean isValid = true; WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); String propertyName = Constants.PROTOCOL_ASSIGN_REVIEWERS_PROPERTY_KEY + ".reviewer[" + reviewerIndex + "].reviewerTypeCode"; String documentRouteStatus = workflowDocument.getStatus().getCode(); // 1. check to see the workflow status if (StringUtils.equals(KewApiConstants.ROUTE_HEADER_FINAL_CD, documentRouteStatus)) { // we just report the warning, the request is still valid - the action should prompt for // confirmation. reportWarning( propertyName, KeyConstants.ERROR_PROTOCOL_REVIEWER_CANNOT_REMOVE_REVIEW_FINAL, reviewer.getFullName()); } if (document.getProtocolOnlineReview().getCommitteeScheduleMinutes().size() > 0) { // there are review comments that will be deleted by this operation // just report the warning. reportWarning( propertyName, KeyConstants.ERROR_PROTOCOL_REVIEWER_CANNOT_REMOVE_REVIEW_EXISTING_COMMENTS, reviewer.getFullName(), "" + document.getProtocolOnlineReview().getCommitteeScheduleMinutes().size()); } if (StringUtils.equals( document.getProtocolOnlineReview().getProtocolOnlineReviewStatusCode(), ProtocolOnlineReviewStatus.FINAL_STATUS_CD)) { reportWarning( propertyName, KeyConstants.ERROR_PROTOCOL_REVIEWER_CANNOT_REMOVE_FINAL_REVIEW, reviewer.getFullName()); } return isValid; }
protected void finalizeOnlineReviewDocument( ProtocolOnlineReviewDocumentBase protocolOnlineReviewDocument, ProtocolSubmissionBase submission, String annotation) { try { final String principalId = identityManagementService .getPrincipalByPrincipalName(KRADConstants.SYSTEM_USER) .getPrincipalId(); WorkflowDocument workflowDocument = WorkflowDocumentFactory.loadDocument( principalId, protocolOnlineReviewDocument.getDocumentNumber()); ProtocolOnlineReviewBase review = protocolOnlineReviewDocument.getProtocolOnlineReview(); review.addActionPerformed( "Finalize:" + workflowDocument.getStatus().getCode() + ":" + review.getProtocolOnlineReviewStatusCode()); if (workflowDocument.isEnroute() || workflowDocument.isInitiated() || workflowDocument.isSaved()) { workflowDocument.superUserBlanketApprove(annotation); } } catch (Exception e) { String errorMessage = String.format( "Workflow exception generated while executing superUserApprove on document %s in finalizeOnlineReviewDocument. Message:%s", protocolOnlineReviewDocument.getDocumentNumber(), e.getMessage()); LOG.error(errorMessage); throw new RuntimeException(errorMessage, e); } }
/** * This is temporary until workflow 2.0 and reads from a table to get documents whose status has * changed to A (approved - no outstanding approval actions requested) * * @param documentHeaderId * @return Document * @throws WorkflowException */ @Override public Document getByDocumentHeaderId(String documentHeaderId) throws WorkflowException { if (documentHeaderId == null) { throw new IllegalArgumentException("invalid (null) documentHeaderId"); } boolean internalUserSession = false; try { // KFSMI-2543 - allowed method to run without a user session so it can be used // by workflow processes if (GlobalVariables.getUserSession() == null) { internalUserSession = true; GlobalVariables.setUserSession(new UserSession(KRADConstants.SYSTEM_USER)); GlobalVariables.clear(); } WorkflowDocument workflowDocument = null; if (LOG.isDebugEnabled()) { LOG.debug("Retrieving doc id: " + documentHeaderId + " from workflow service."); } workflowDocument = getWorkflowDocumentService() .loadWorkflowDocument(documentHeaderId, GlobalVariables.getUserSession().getPerson()); UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), workflowDocument); Class<? extends Document> documentClass = getDocumentClassByTypeName(workflowDocument.getDocumentTypeName()); // retrieve the Document Document document = getLegacyDataAdapter().findByDocumentHeaderId(documentClass, documentHeaderId); return postProcessDocument(documentHeaderId, workflowDocument, document); } finally { // if a user session was established for this call, clear it out if (internalUserSession) { GlobalVariables.clear(); GlobalVariables.setUserSession(null); } } }
/** * Tests that an exception is not thrown if you try to execute a "route" command on a document you * did not initiate. */ @Test public void testRouteDefaultDocumentAsNonInitiatorUser() throws Exception { WorkflowDocument firstDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), DOCUMENT_TYPE_NAME); WorkflowDocument document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("user2"), firstDocument.getDocumentId()); try { document.route(""); fail("Exception should have been thrown."); } catch (Exception e) { e.printStackTrace(); } assertFalse("Document should not be ENROUTE.", document.isEnroute()); // assertFalse("There should not be a request to user2.", // document.isApprovalRequested()); // // // verify that there are no actions taken // Collection actionTakens = // KEWServiceLocator.getActionTakenService().findByDocumentId(document.getDocumentId()); // assertEquals("There should be 0 actions taken.", 0, actionTakens.size()); }
protected boolean isAuthorizedToHierarchyChildAckWorkflowAction(Document document, Person user) { boolean authorized = true; final ProposalDevelopmentDocument pdDocument = ((ProposalDevelopmentDocument) document); if (pdDocument.getDevelopmentProposal().isChild()) { try { WorkflowDocument parentWDoc = getProposalHierarchyService().getParentWorkflowDocument(pdDocument); if ((!parentWDoc.isAcknowledgeRequested()) || parentWDoc.isInitiated()) { authorized = false; } } catch (ProposalHierarchyException e) { LOG.error( String.format( "Could not find parent workflow document for proposal document number:%s, which claims to be a child. Returning false.", pdDocument.getDocumentHeader().getDocumentNumber()), e); authorized = false; } } return authorized; }
@Override public Document recallDocument(Document document, String annotation, boolean cancel) throws WorkflowException { checkForNulls(document); WorkflowDocument workflowDocument = KRADServiceLocatorWeb.getDocumentService() .getByDocumentHeaderId(document.getDocumentNumber()) .getDocumentHeader() .getWorkflowDocument(); if (!workflowDocument.isFinal() && !workflowDocument.isProcessed()) { Note note = createNoteFromDocument(document, annotation); document.addNote(note); getNoteService().save(note); } prepareWorkflowDocument(document); getWorkflowDocumentService() .recall(document.getDocumentHeader().getWorkflowDocument(), annotation, cancel); UserSessionUtils.addWorkflowDocument( GlobalVariables.getUserSession(), document.getDocumentHeader().getWorkflowDocument()); removeAdHocPersonsAndWorkgroups(document); return document; }
protected boolean hasBeenRoutedOrCanceled(ProposalDevelopmentDocument document) { WorkflowDocument workflowDoc = document.getDocumentHeader().getWorkflowDocument(); return !workflowDoc.isInitiated() && !workflowDoc.isSaved(); }
/** * This method specifies if this document may be edited; i.e. it's only initiated or saved * * @return boolean */ public boolean isEditable() { WorkflowDocument workflowDoc = getDocumentHeader().getWorkflowDocument(); return workflowDoc.isInitiated() || workflowDoc.isSaved(); }
public void updateDOM(Document dom, Element configElement, EDLContext edlContext) { // String action = // edlContext.getRequestParser().getPropertyValueAsString(WorkflowDocumentActions.USER_ACTION_REQUEST_KEY); // we don't want to clear the attribute content if they are just opening up the document to view // it! if (!edlContext.getUserAction().isLoadAction()) { RequestParser requestParser = edlContext.getRequestParser(); try { WorkflowDocument document = (WorkflowDocument) requestParser.getAttribute(RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY); // clear attribute content so that duplicate attribute values are not added during // submission of a new EDL form values version document.clearAttributeContent(); Document edlDef = EdlServiceLocator.getEDocLiteService() .getDefinitionXml(edlContext.getEdocLiteAssociation()); XPath xpath = XPathHelper.newXPath(edlDef); NodeList attributeNodes = (NodeList) xpath.evaluate("/edl/attributes/attribute", edlDef, XPathConstants.NODESET); for (int index = 0; index < attributeNodes.getLength(); index++) { Element attributeElem = (Element) attributeNodes.item(index); String attributeName = attributeElem.getAttribute("name"); WorkflowAttributeDefinition.Builder attributeDefBuilder = getWorkflowAttributeDefinitionVO(attributeName, document); NodeList fieldNodes = (NodeList) xpath.evaluate("./field", attributeElem, XPathConstants.NODESET); for (int fIndex = 0; fIndex < fieldNodes.getLength(); fIndex++) { Element fieldElem = (Element) fieldNodes.item(fIndex); String edlField = fieldElem.getAttribute("edlField"); String attributeField = fieldElem.getAttribute("attributeField"); PropertyDefinition property = attributeDefBuilder.getPropertyDefinition(attributeField); String value = requestParser.getParameterValue(edlField); if (property == null) { property = PropertyDefinition.create(attributeField, value); } else { // modify the current property attributeDefBuilder.getPropertyDefinitions().remove(property); property = PropertyDefinition.create(property.getName(), value); } attributeDefBuilder.addPropertyDefinition(property); } // validate if they are taking an action on the document (i.e. it's annotatable) boolean curAttrValid = true; if (edlContext.getUserAction().isValidatableAction()) { List<? extends RemotableAttributeErrorContract> errors = document.validateAttributeDefinition(attributeDefBuilder.build()); if (!errors.isEmpty()) { edlContext.setInError(true); curAttrValid = false; } Map<String, String> fieldErrors = (Map<String, String>) edlContext .getRequestParser() .getAttribute(RequestParser.GLOBAL_FIELD_ERRORS_KEY); for (RemotableAttributeErrorContract error : errors) { fieldErrors.put(error.getAttributeName(), error.getMessage()); } } if (curAttrValid) { if (edlContext.getUserAction().isValidatableAction()) { for (int fIndex = 0; fIndex < fieldNodes.getLength(); fIndex++) { Element fieldElem = (Element) fieldNodes.item(fIndex); String edlField = fieldElem.getAttribute("edlField"); String attributeField = fieldElem.getAttribute("attributeField"); PropertyDefinition property = attributeDefBuilder.getPropertyDefinition(attributeField); String value = requestParser.getParameterValue(edlField); if (property == null) { property = PropertyDefinition.create(attributeField, value); } else { // modify the current property attributeDefBuilder.getPropertyDefinitions().remove(property); property = PropertyDefinition.create(property.getName(), value); } attributeDefBuilder.addPropertyDefinition(property); } WorkflowAttributeDefinition attributeDef = attributeDefBuilder.build(); document.addAttributeDefinition(attributeDef); } } } } catch (Exception e) { if (e instanceof RuntimeException) { throw (RuntimeException) e; } throw new WorkflowRuntimeException("Failed to process attribute.", e); } } }
/** * Creates a new document by document type name. The principal name passed in will be used as the * document initiator. If the initiatorPrincipalNm is null or blank, the current user will be * used. * * @see org.kuali.rice.krad.service.DocumentService#getNewDocument(String, String) */ @Override public Document getNewDocument(String documentTypeName, String initiatorPrincipalNm) throws WorkflowException { // argument validation String watchName = "DocumentServiceImpl.getNewDocument"; StopWatch watch = new StopWatch(); watch.start(); if (LOG.isDebugEnabled()) { LOG.debug(watchName + ": started"); } if (StringUtils.isBlank(documentTypeName)) { throw new IllegalArgumentException("invalid (blank) documentTypeName"); } if (GlobalVariables.getUserSession() == null) { throw new IllegalStateException( "GlobalVariables must be populated with a valid UserSession before a new document can be created"); } // get the class for this docTypeName Class<? extends Document> documentClass = getDocumentClassByTypeName(documentTypeName); // get the initiator Person initiator = null; if (StringUtils.isBlank(initiatorPrincipalNm)) { initiator = GlobalVariables.getUserSession().getPerson(); } else { initiator = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(initiatorPrincipalNm); if (initiator == null) { initiator = GlobalVariables.getUserSession().getPerson(); } } // get the authorization DocumentAuthorizer documentAuthorizer = getDocumentDictionaryService().getDocumentAuthorizer(documentTypeName); DocumentPresentationController documentPresentationController = getDocumentDictionaryService().getDocumentPresentationController(documentTypeName); // make sure this person is authorized to initiate if (LOG.isDebugEnabled()) { LOG.debug( "calling canInitiate from getNewDocument(" + documentTypeName + "," + initiatorPrincipalNm + ")"); } if (!documentPresentationController.canInitiate(documentTypeName) || !documentAuthorizer.canInitiate(documentTypeName, initiator)) { throw new DocumentAuthorizationException( initiator.getPrincipalName(), "initiate", documentTypeName); } // initiate new workflow entry, get the workflow doc WorkflowDocument workflowDocument = getWorkflowDocumentService().createWorkflowDocument(documentTypeName, initiator); UserSessionUtils.addWorkflowDocument(GlobalVariables.getUserSession(), workflowDocument); // create a new document header object DocumentHeader documentHeader = new DocumentHeader(); documentHeader.setWorkflowDocument(workflowDocument); documentHeader.setDocumentNumber(workflowDocument.getDocumentId()); // build Document of specified type Document document = null; try { // all maintenance documents have same class if (MaintenanceDocumentBase.class.isAssignableFrom(documentClass)) { Class<?>[] defaultConstructor = new Class[] {String.class}; Constructor<? extends Document> cons = documentClass.getConstructor(defaultConstructor); if (cons == null) { throw new ConfigurationException( "Could not find constructor with document type name parameter needed for Maintenance Document Base class"); } document = cons.newInstance(documentTypeName); } else { // non-maintenance document document = documentClass.newInstance(); } } catch (IllegalAccessException e) { throw new RuntimeException("Error instantiating Document", e); } catch (InstantiationException e) { throw new RuntimeException("Error instantiating Document", e); } catch (SecurityException e) { throw new RuntimeException("Error instantiating Maintenance Document", e); } catch (NoSuchMethodException e) { throw new RuntimeException( "Error instantiating Maintenance Document: No constructor with String parameter found", e); } catch (IllegalArgumentException e) { throw new RuntimeException("Error instantiating Maintenance Document", e); } catch (InvocationTargetException e) { throw new RuntimeException("Error instantiating Maintenance Document", e); } document.setDocumentHeader(documentHeader); document.setDocumentNumber(documentHeader.getDocumentNumber()); watch.stop(); if (LOG.isDebugEnabled()) { LOG.debug(watchName + ": " + watch.toString()); } return document; }
@Test public void testParallelRoute() throws Exception { WorkflowDocument document = WorkflowDocumentFactory.createDocument( getPrincipalIdForName("ewestfal"), DOCUMENT_TYPE_NAME); document.saveDocumentData(); assertTrue("Document should be initiated", document.isInitiated()); assertEquals("Should be no action requests.", 0, document.getRootActionRequests().size()); Collection<RouteNodeInstance> nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals("Wrong number of active nodes.", 1, nodeInstances.size()); document.route("Routing for parallel"); // should have generated a request to "bmcgough" document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("bmcgough"), document.getDocumentId()); assertTrue("Document should be enroute", document.isEnroute()); List<ActionRequestValue> actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId()); assertEquals("Incorrect pending action requests.", 1, actionRequests.size()); ActionRequestValue bRequest = actionRequests.get(0); assertNotNull("Should have been routed through node instance.", bRequest.getNodeInstance()); assertTrue(document.isApprovalRequested()); document.approve("Approving test"); // document should split at this point and generate an ack to temay and approves to rkirkend and // pmckown document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("rkirkend"), document.getDocumentId()); assertTrue("Document should be enroute", document.isEnroute()); actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId()); assertEquals("Incorrect pending action requests.", 3, actionRequests.size()); boolean isToTemay = false; boolean isToPmckown = false; boolean isToRkirkend = false; for (Iterator iterator = actionRequests.iterator(); iterator.hasNext(); ) { ActionRequestValue actionRequest = (ActionRequestValue) iterator.next(); if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("temay"))) { isToTemay = true; assertEquals( "Request should be activated.", ActionRequestStatus.ACTIVATED.getCode(), actionRequest.getStatus()); assertEquals( "Wrong action requested.", KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, actionRequest.getActionRequested()); assertNotNull( "Should have been routed through node instance.", actionRequest.getNodeInstance()); assertEquals( "Invalid node.", ACKNOWLEDGE_1_NODE, actionRequest.getNodeInstance().getRouteNode().getRouteNodeName()); } if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("rkirkend"))) { isToRkirkend = true; assertEquals( "Request should be activated.", ActionRequestStatus.ACTIVATED.getCode(), actionRequest.getStatus()); assertEquals( "Wrong action requested.", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, actionRequest.getActionRequested()); assertNotNull( "Should have been routed through node instance.", actionRequest.getNodeInstance()); assertEquals( "Invalid node.", WORKFLOW_DOCUMENT_2_NODE, actionRequest.getNodeInstance().getRouteNode().getRouteNodeName()); } if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("pmckown"))) { isToPmckown = true; assertEquals( "Request should be activated.", ActionRequestStatus.ACTIVATED.getCode(), actionRequest.getStatus()); assertEquals( "Wrong action requested.", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, actionRequest.getActionRequested()); assertNotNull( "Should have been routed through node instance.", actionRequest.getNodeInstance()); assertEquals( "Invalid node.", WORKFLOW_DOCUMENT_3_NODE, actionRequest.getNodeInstance().getRouteNode().getRouteNodeName()); } } assertTrue("No request to temay.", isToTemay); assertTrue("No request to pmckown.", isToPmckown); assertTrue("No request to rkirkend.", isToRkirkend); // check that we are at both nodes, one in each branch Set<String> nodeNames = document.getNodeNames(); assertEquals("Wrong number of node names.", 2, nodeNames.size()); boolean isNode2 = false; boolean isNode3 = false; for (String name : nodeNames) { if (name.equals(WORKFLOW_DOCUMENT_2_NODE)) { isNode2 = true; } if (name.equals(WORKFLOW_DOCUMENT_3_NODE)) { isNode3 = true; } } assertTrue("Not at node2.", isNode2); assertTrue("Not at node3.", isNode3); nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals("Wrong number of active nodes.", 2, nodeInstances.size()); Iterator<RouteNodeInstance> iterator = nodeInstances.iterator(); RouteNodeInstance instance1 = (RouteNodeInstance) iterator.next(); RouteNodeInstance instance2 = (RouteNodeInstance) iterator.next(); assertNotNull("Node should be in branch.", instance1.getBranch()); assertNotNull("Node should be in branch.", instance2.getBranch()); assertTrue( "Branches should be different.", !instance1.getBranch().getBranchId().equals(instance2.getBranch().getBranchId())); document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("rkirkend"), document.getDocumentId()); assertTrue("Should have request.", document.isApprovalRequested()); document.approve("Git-r-dun"); nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals("Wrong number of active nodes.", 2, nodeInstances.size()); boolean isAtJoin = false; boolean isAtWD3 = false; for (RouteNodeInstance nodeInstance : nodeInstances) { if (nodeInstance.getRouteNode().getRouteNodeName().equals(JOIN_NODE)) { assertEquals( "Join branch should be split branch.", instance1.getBranch().getParentBranch().getBranchId(), nodeInstance.getBranch().getBranchId()); isAtJoin = true; } if (nodeInstance.getRouteNode().getRouteNodeName().equals(WORKFLOW_DOCUMENT_3_NODE)) { isAtWD3 = true; } } assertTrue("Not at join", isAtJoin); assertTrue("Not at WD3", isAtWD3); document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("pmckown"), document.getDocumentId()); assertTrue("Should have request.", document.isApprovalRequested()); document.approve("Do it."); nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals("Wrong number of active nodes.", 1, nodeInstances.size()); boolean isAtWDF = false; for (RouteNodeInstance nodeInstance : nodeInstances) { if (nodeInstance.getRouteNode().getRouteNodeName().equals(WORKFLOW_DOCUMENT_FINAL_NODE)) { isAtWDF = true; } } assertTrue("Not at WDF", isAtWDF); document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("xqi"), document.getDocumentId()); assertTrue("Should still be enroute.", document.isEnroute()); assertTrue("Should have request.", document.isApprovalRequested()); document.approve("I'm the last approver"); assertTrue("Document should be processed.", document.isProcessed()); nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals( "The doc is processed so no node instances should be active", 0, nodeInstances.size()); document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("temay"), document.getDocumentId()); assertTrue("Should have request.", document.isAcknowledgeRequested()); document.acknowledge(""); assertTrue(document.isFinal()); }
@Test public void testAdhocApproversJoinScenario() throws Exception { WorkflowDocument document = WorkflowDocumentFactory.createDocument( getPrincipalIdForName("ewestfal"), "AdHocApproversDocType"); document.route(""); // should send an approve to bmcgough document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("bmcgough"), document.getDocumentId()); assertTrue("Bmcgough should have approve request.", document.isApprovalRequested()); document.approve(""); // at this point the document should pass the split, and end up at the WorkflowDocument2 node // and the AdHocApproversJoin node // after bypassing the AdHocJoinPoint Set<String> nodeNames = document.getNodeNames(); assertEquals("There should be two node names.", 2, nodeNames.size()); assertTrue("Should be at WorkflowDocument2 node.", nodeNames.contains("WorkflowDocument2")); assertTrue("Should be at WorkflowDocument2 node.", nodeNames.contains("AdHocApproversJoin")); // pmckown has the request at the adhoc approvers node, if we approve as him then the document // should _not_ transition out // of it's current nodes document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("pmckown"), document.getDocumentId()); assertTrue("Pmckown should have approve request.", document.isApprovalRequested()); document.approve(""); // the document should still be at the same nodes nodeNames = document.getNodeNames(); assertEquals("There should be two node names.", 2, nodeNames.size()); assertTrue("Should be at WorkflowDocument2 node.", nodeNames.contains("WorkflowDocument2")); assertTrue("Should be at WorkflowDocument2 node.", nodeNames.contains("AdHocApproversJoin")); // at WorkflowDocument2, rkirkend is the approver, if we approve as him we should end up at the // WorkflowDocumentFinal node document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("rkirkend"), document.getDocumentId()); assertTrue("Rkirkend should have approve request.", document.isApprovalRequested()); document.approve(""); // the document should now be at WorkflowDocumentFinal with a request to xqi nodeNames = document.getNodeNames(); assertEquals("There should be one node name.", 1, nodeNames.size()); assertTrue( "Should be at WorkflowDocumentFinal node.", nodeNames.contains("WorkflowDocumentFinal")); document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("xqi"), document.getDocumentId()); assertTrue("Document should still be enroute.", document.isEnroute()); document.approve(""); assertTrue("Document should now be final.", document.isFinal()); }