Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: openmrs/openmrs-core
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 9a52788bfd42
Choose a base ref
...
head repository: openmrs/openmrs-core
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 794f2ca9d284
Choose a head ref
  • 2 commits
  • 3 files changed
  • 2 contributors

Commits on Nov 12, 2013

  1. Copy the full SHA
    eb93031 View commit details

Commits on Nov 18, 2013

  1. Merge pull request #449 from dadepo/TRUNK-3094

    TRUNK-3094 Add delete/purge for pregram states in the workflow
    dkayiwa committed Nov 18, 2013
    Copy the full SHA
    794f2ca View commit details
Original file line number Diff line number Diff line change
@@ -16,6 +16,8 @@
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Map;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -24,116 +26,169 @@

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.PatientState;
import org.openmrs.ProgramWorkflow;
import org.openmrs.ProgramWorkflowState;
import org.openmrs.api.APIException;
import org.openmrs.api.ProgramWorkflowService;
import org.openmrs.api.context.Context;
import org.openmrs.api.impl.ProgramWorkflowServiceImpl;
import org.openmrs.web.WebConstants;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;

public class WorkflowFormController extends SimpleFormController {

protected final Log log = LogFactory.getLog(getClass());

protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
super.initBinder(request, binder);
binder.registerCustomEditor(java.lang.Integer.class, new CustomNumberEditor(java.lang.Integer.class, true));
}

/**
* This is called prior to displaying a form for the first time. It tells Spring the
* form/command object to load into the request
*
* @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
*/
protected Object formBackingObject(HttpServletRequest request) throws ServletException {
log.debug("called formBackingObject");

ProgramWorkflow wf = null;

if (Context.isAuthenticated()) {
ProgramWorkflowService ps = Context.getProgramWorkflowService();
String programWorkflowId = request.getParameter("programWorkflowId");
if (programWorkflowId != null)
wf = ps.getWorkflow(Integer.valueOf(programWorkflowId));

if (wf == null)
throw new IllegalArgumentException("Can't find workflow");
}

if (wf == null)
wf = new ProgramWorkflow();

return wf;
}

/**
* The onSubmit function receives the form/command object that was modified by the input form
* and saves it to the db
*
* @see org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse, java.lang.Object,
* org.springframework.validation.BindException)
*/
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object obj,
BindException errors) throws Exception {
log.debug("about to save " + obj);

HttpSession httpSession = request.getSession();

String view = getFormView();

if (Context.isAuthenticated()) {
ProgramWorkflow wf = (ProgramWorkflow) obj;

// get list of states, and update the command object
String statesStr = request.getParameter("newStates");
// This is a brute-force algorithm, but n will be small.
Set<Integer> doneSoFar = new HashSet<Integer>(); // concept ids done so far
for (StringTokenizer st = new StringTokenizer(statesStr, "|"); st.hasMoreTokens();) {
String str = st.nextToken();
String[] tmp = str.split(",");
Integer conceptId = Integer.valueOf(tmp[0]);
doneSoFar.add(conceptId);
ProgramWorkflowState pws = null;
for (ProgramWorkflowState s : wf.getStates()) {
if (s.getConcept().getConceptId().equals(conceptId)) {
pws = s;
break;
}
}
if (pws == null) {
pws = new ProgramWorkflowState();
pws.setConcept(Context.getConceptService().getConcept(conceptId));
wf.addState(pws);
} else {
// un-retire if necessary
if (pws.isRetired()) {
pws.setRetired(false);
}
}
pws.setInitial(Boolean.valueOf(tmp[1]));
pws.setTerminal(Boolean.valueOf(tmp[2]));
log.debug("pws: " + pws);
}
// retire states if we didn't see their concept during the loop above
for (ProgramWorkflowState s : wf.getStates()) {
if (!doneSoFar.contains(s.getConcept().getConceptId())) {
s.setRetired(true);
}
}

Context.getProgramWorkflowService().updateWorkflow(wf);
view = getSuccessView();
httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Workflow.saved");
}

return new ModelAndView(new RedirectView(view));
}


protected final Log log = LogFactory.getLog(getClass());

protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
super.initBinder(request, binder);
binder.registerCustomEditor(java.lang.Integer.class, new CustomNumberEditor(java.lang.Integer.class, true));
}

/**
* This is called prior to displaying a form for the first time. It tells Spring the
* form/command object to load into the request
*
* @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
*/
protected Object formBackingObject(HttpServletRequest request) throws ServletException {
log.debug("called formBackingObject");

ProgramWorkflow wf = null;

if (Context.isAuthenticated()) {
ProgramWorkflowService ps = Context.getProgramWorkflowService();
String programWorkflowId = request.getParameter("programWorkflowId");
if (programWorkflowId != null)
wf = ps.getWorkflow(Integer.valueOf(programWorkflowId));

if (wf == null)
throw new IllegalArgumentException("Can't find workflow");
}

if (wf == null)
wf = new ProgramWorkflow();

return wf;
}

/**
* The onSubmit function receives the form/command object that was modified by the input form
* and saves it to the db
*
* @see org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse, java.lang.Object,
* org.springframework.validation.BindException)
*/
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object obj,
BindException errors) throws Exception {
log.debug("about to save " + obj);
HttpSession httpSession = request.getSession();
String view = getFormView();
if (Context.isAuthenticated()) {
ProgramWorkflow wf = (ProgramWorkflow) obj;
// get list of states to be deleted
String statesToDelete = request.getParameter("deleteStates");
Set<Integer> cantBeDeleted = new HashSet<Integer>(); // holds concept ids that cant be deleted
if (!statesToDelete.equals("")) {
// then delete listed states first
Map<Integer,ProgramWorkflowState> toRemove = new HashMap<Integer,ProgramWorkflowState>();
for (StringTokenizer std = new StringTokenizer(statesToDelete, "|"); std.hasMoreTokens(); ) {
String str = std.nextToken();
String[] state = str.split(",");
Integer conceptIdDelete = Integer.valueOf(state[0]);
ProgramWorkflowState pws = null;


for (ProgramWorkflowState s : wf.getStates()) {
if (s.getConcept().getConceptId().equals(conceptIdDelete)) {
toRemove.put(conceptIdDelete, s);
break;
}
}

}


for (Map.Entry<Integer, ProgramWorkflowState> remove: toRemove.entrySet()) {
try {
wf.removeState(remove.getValue());
Context.getProgramWorkflowService().updateWorkflow(wf);
httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Workflow.saved");
log.debug("removed " + remove);
} catch (DataIntegrityViolationException e) {
httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, "error.object.state.inuse.cannot.delete");
wf.addState(remove.getValue());
// add to cant be deleted so it would be skipped from getting retired
cantBeDeleted.add(remove.getKey());
} catch (APIException e) {
httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, "error.general");
wf.addState(remove.getValue());
// add to cant be deleted so it would be skipped from getting retired
cantBeDeleted.add(remove.getKey());
}
}

}
// get list of states, and update the command object
String statesStr = request.getParameter("newStates");
if (!statesStr.equals("")) {
// This is a brute-force algorithm, but n will be small.
Set<Integer> doneSoFar = new HashSet<Integer>(); // concept ids done so far
for (StringTokenizer st = new StringTokenizer(statesStr, "|"); st.hasMoreTokens(); ) {
String str = st.nextToken();
String[] tmp = str.split(",");
Integer conceptId = Integer.valueOf(tmp[0]);
doneSoFar.add(conceptId);
ProgramWorkflowState pws = null;
for (ProgramWorkflowState s : wf.getStates()) {
if (s.getConcept().getConceptId().equals(conceptId)) {
pws = s;
break;
}
}
if (pws == null) {
pws = new ProgramWorkflowState();
pws.setConcept(Context.getConceptService().getConcept(conceptId));
wf.addState(pws);
} else {
// un-retire if necessary
if (pws.isRetired()) {
pws.setRetired(false);
}
}
pws.setInitial(Boolean.valueOf(tmp[1]));
pws.setTerminal(Boolean.valueOf(tmp[2]));
}
// retire states if we didn't see their concept during the loop above
for (ProgramWorkflowState s : wf.getStates()) {
if (!doneSoFar.contains(s.getConcept().getConceptId())) {
s.setRetired(true);
}
}
try {
Context.getProgramWorkflowService().updateWorkflow(wf);
httpSession.setAttribute(WebConstants.OPENMRS_MSG_ATTR, "Workflow.saved");
} catch (APIException e) {
httpSession.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, "error.general");
}
} else {
// no new state sent therefore retire all excluding deleted
for (ProgramWorkflowState s : wf.getStates()) {
if(!cantBeDeleted.contains(s.getConcept().getConceptId())){
s.setRetired(true);
}
}
Context.getProgramWorkflowService().updateWorkflow(wf);
}
}
view = getSuccessView();
return new ModelAndView(new RedirectView(view));
}
}
8 changes: 5 additions & 3 deletions webapp/src/main/webapp/WEB-INF/messages.properties
Original file line number Diff line number Diff line change
@@ -24,7 +24,8 @@ fix.error.plain=Please fix all errors and try again.
error.general=Error while submitting form
error.null=Cannot be empty or null
error.inuse=Value in use by another object
error.object.inuse.cannot.purge=This object is being referenced and cannot be deleted forever.
error.object.inuse.cannot.purge = This object is being referenced and cannot be deleted forever.
error.object.state.inuse.cannot.delete = The state cannot be deleted. It is already assigned to a patient.
error.name=Invalid name
error.description=Invalid description
error.checkdigit=Invalid checkdigit for
@@ -975,7 +976,7 @@ EncounterRole.delete=Delete Encounter Role
EncounterRole.retireEncounterRole=Retire Encounter Role
EncounterRole.retiredSuccessfully=Encounter Role retired successfully
EncounterRole.unretire=Unretire Encounter Role
EncounterRole.unretired=Encounter Role unretired successfully
EncounterRole.unretired=Encounter Role unretired successfully
EncounterRole.purgedSuccessfully=Encounter Role deleted forever successfully
EncounterRole.purgeEncounterRole=Delete Encounter Role Forever
EncounterRole.error.duplicateEncounterRoleNameSpecified=Encounter Role name already exists, please specify another
@@ -1002,7 +1003,7 @@ EncounterType.viewPrivilege=View Privilege
EncounterType.viewPrivilege.help=The privilege needed by a user to view encounters of this type
EncounterType.editPrivilege=Edit privilege
EncounterType.editPrivilege.help=The privilege needed by a user to edit encounters of this type
EncounterType.privilege.disclaimer=You do not have permission to view all encounters data, so some information may not be displayed.
EncounterType.privilege.disclaimer=You do not have permission to view all encounters data, so some information may not be displayed.
EncounterType.encounterTypes.locked=Encounter Types editing is not allowed, encounter types are locked
EncounterType.error.duplicateEncounterTypeNameSpecified=Encounter Type name already exists, please specify another

@@ -2186,6 +2187,7 @@ State.select=Select a state
State.list.title=Current State(s)
State.error.name.duplicate=State already exists
State.retire.confirmation=Are you sure you want to retire this state?
State.delete.confirmation=Are you sure you want to delete this state?
State.unretire.confirmation=Are you sure you want to unretire this state?
State.error.noDate=You cannot change from a non-null state without giving a change date
State.error.noState=You must choose a state
Loading