diff --git a/src/main/java/de/metas/ui/web/process/ProcessInstance.java b/src/main/java/de/metas/ui/web/process/ProcessInstance.java index ed7bd1fbf..a59b4263e 100644 --- a/src/main/java/de/metas/ui/web/process/ProcessInstance.java +++ b/src/main/java/de/metas/ui/web/process/ProcessInstance.java @@ -37,6 +37,9 @@ import de.metas.process.ProcessExecutionResult.RecordsToOpen; import de.metas.process.ProcessExecutor; import de.metas.process.ProcessInfo; +import de.metas.ui.web.process.ProcessInstanceResult.OpenReportAction; +import de.metas.ui.web.process.ProcessInstanceResult.OpenSingleDocument; +import de.metas.ui.web.process.ProcessInstanceResult.OpenViewAction; import de.metas.ui.web.process.descriptor.ProcessDescriptor; import de.metas.ui.web.process.exceptions.ProcessExecutionException; import de.metas.ui.web.view.IDocumentViewSelection; @@ -286,17 +289,43 @@ public ProcessInstanceResult startProcess() .setAD_PInstance_ID(processExecutionResult.getAD_PInstance_ID()) .setSummary(summary) .setError(processExecutionResult.isError()); + // - // Result: report - final File reportTempFile = saveReportToDiskIfAny(processExecutionResult); - if (reportTempFile != null) + // Create result post process actions { - resultBuilder.setReportData(processExecutionResult.getReportFilename(), processExecutionResult.getReportContentType(), reportTempFile); - } + final File reportTempFile = saveReportToDiskIfAny(processExecutionResult); + final RecordsToOpen recordsToOpen = processExecutionResult.getRecordsToOpen(); - // - // Result: records to select - updateRecordsToOpen(resultBuilder, processExecutor.getProcessInfo(), processExecutionResult.getRecordsToOpen()); + // + // Result: report + if (reportTempFile != null) + { + resultBuilder.setAction(OpenReportAction.builder() + .filename(processExecutionResult.getReportFilename()) + .contentType(processExecutionResult.getReportContentType()) + .tempFile(reportTempFile) + .build()); + } + // + // View + else if (recordsToOpen != null && recordsToOpen.isGridView()) + { + final IDocumentViewSelection view = createView(processExecutor.getProcessInfo(), recordsToOpen); + resultBuilder.setAction(OpenViewAction.builder() + .windowId(view.getAD_Window_ID()) + .viewId(view.getViewId()) + .build()); + } + // + // Single document + else if (recordsToOpen != null && !recordsToOpen.isGridView()) + { + final DocumentPath documentPath = extractSingleDocumentPath(recordsToOpen); + resultBuilder.setAction(OpenSingleDocument.builder() + .documentPath(documentPath) + .build()); + } + } // final ProcessInstanceResult result = resultBuilder.build(); @@ -343,29 +372,6 @@ private static final File saveReportToDiskIfAny(final ProcessExecutionResult pro return reportFile; } - private void updateRecordsToOpen(final ProcessInstanceResult.Builder resultBuilder, final ProcessInfo processInfo, final RecordsToOpen recordsToOpen) - { - if (recordsToOpen == null) - { - return; - } - // - // View - else if (recordsToOpen.isGridView()) - { - final IDocumentViewSelection view = createView(processInfo, recordsToOpen); - resultBuilder.openView(view.getAD_Window_ID(), view.getViewId()); - } - // - // Single document - else - { - final DocumentPath documentPath = extractSingleDocumentPath(recordsToOpen); - resultBuilder.openSingleDocument(documentPath); - } - - } - private final IDocumentViewSelection createView(final ProcessInfo processInfo, final RecordsToOpen recordsToOpen) { final List recordRefs = recordsToOpen.getRecords(); diff --git a/src/main/java/de/metas/ui/web/process/ProcessInstanceResult.java b/src/main/java/de/metas/ui/web/process/ProcessInstanceResult.java index f4eab33e2..6746fbd65 100644 --- a/src/main/java/de/metas/ui/web/process/ProcessInstanceResult.java +++ b/src/main/java/de/metas/ui/web/process/ProcessInstanceResult.java @@ -9,8 +9,11 @@ import com.google.common.base.MoreObjects; -import de.metas.printing.esb.base.util.Check; import de.metas.ui.web.window.datatypes.DocumentPath; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NonNull; +import lombok.Setter; /* * #%L @@ -46,17 +49,7 @@ public static final Builder builder() private final int adPInstanceId; private final String summary; private final boolean error; - - // Report to open (optional) - private final String reportFilename; - private final String reportContentType; - private final File reportTempFile; - - // View or single document to open (optional) - private final int openViewWindowId; - private final String openViewId; - // - private final DocumentPath openSingleDocumentPath; + private final ResultAction action; private ProcessInstanceResult(final Builder builder) { @@ -65,13 +58,7 @@ private ProcessInstanceResult(final Builder builder) summary = builder.summary; error = builder.error; - reportFilename = builder.reportFilename; - reportContentType = builder.reportContentType; - reportTempFile = builder.reportTempFile; - - openViewWindowId = builder.openViewWindowId; - openViewId = builder.openViewId; - openSingleDocumentPath = builder.openSingleDocumentPath; + action = builder.action; } @Override @@ -82,15 +69,7 @@ public String toString() .add("adPInstanceId", adPInstanceId) .add("summary", summary) .add("error", error) - // - .add("reportFilename", reportFilename) - .add("reportContentType", reportContentType) - .add("reportTempFile", reportTempFile) - // - .add("openViewWindowId", openViewWindowId > 0 ? openViewWindowId : null) - .add("openViewId", openViewId) - .add("openSingleDocumentPath", openSingleDocumentPath) - // + .add("action", action) .toString(); } @@ -114,34 +93,75 @@ public boolean isError() return error; } - public String getReportFilename() + /** @return action or null */ + public ResultAction getAction() { - return reportFilename; + return action; } - public String getReportContentType() + /** @return action of given type; never returns null */ + public T getAction(final Class actionType) { - return reportContentType; + final ResultAction action = getAction(); + if (action == null) + { + throw new IllegalStateException("No action defined"); + } + if (!actionType.isAssignableFrom(action.getClass())) + { + throw new IllegalStateException("Action is not of type " + actionType + " but " + action.getClass()); + } + @SuppressWarnings("unchecked") + final T actionCasted = (T)action; + return actionCasted; } - public byte[] getReportData() + // + // + // + // + // + + /** Base interface for all post-process actions */ + public static interface ResultAction { - return Util.readBytes(reportTempFile); } - public int getOpenViewWindowId() + @lombok.Value + @lombok.Builder + public static final class OpenReportAction implements ResultAction { - return openViewWindowId; + @NonNull + private final String filename; + @NonNull + private final String contentType; + @NonNull + @Setter(AccessLevel.NONE) + @Getter(AccessLevel.NONE) + private final File tempFile; + + public byte[] getReportData() + { + return Util.readBytes(tempFile); + } + } - public String getOpenViewId() + @lombok.Value + @lombok.Builder + public static final class OpenViewAction implements ResultAction { - return openViewId; + private final int windowId; + @NonNull + private final String viewId; } - public DocumentPath getOpenSingleDocumentPath() + @lombok.Value + @lombok.Builder + public static final class OpenSingleDocument implements ResultAction { - return openSingleDocumentPath; + @NonNull + private final DocumentPath documentPath; } public static final class Builder @@ -150,16 +170,7 @@ public static final class Builder private String summary; private boolean error; - // Report to open (optional) - private String reportFilename; - private String reportContentType; - private File reportTempFile; - - // View or single document to open (optional) - private int openViewWindowId; - private String openViewId; - // - private DocumentPath openSingleDocumentPath; + private ResultAction action; private Builder() { @@ -189,43 +200,9 @@ public Builder setError(final boolean error) return this; } - public Builder setReportData(final String reportFileName, final String reportContentType, final File reportTempFile) - { - reportFilename = reportFileName; - this.reportContentType = reportContentType; - this.reportTempFile = reportTempFile; - return this; - } - - public Builder openView(final int viewWindowId, final String viewId) + public Builder setAction(final ResultAction action) { - if (viewWindowId > 0) - { - openViewWindowId = viewWindowId; - - Check.assumeNotEmpty(viewId, "viewId is not empty"); - openViewId = viewId; - } - else - { - openViewWindowId = -1; - openViewId = null; - } - - // reset the single document to open - openSingleDocumentPath = null; - - return this; - } - - public Builder openSingleDocument(final DocumentPath documentPath) - { - openSingleDocumentPath = documentPath; - - // reset the view to open - openViewWindowId = -1; - openViewId = null; - + this.action = action; return this; } } diff --git a/src/main/java/de/metas/ui/web/process/ProcessRestController.java b/src/main/java/de/metas/ui/web/process/ProcessRestController.java index a1abaa22f..a3c4c4886 100644 --- a/src/main/java/de/metas/ui/web/process/ProcessRestController.java +++ b/src/main/java/de/metas/ui/web/process/ProcessRestController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.RestController; import de.metas.ui.web.config.WebConfig; +import de.metas.ui.web.process.ProcessInstanceResult.OpenReportAction; import de.metas.ui.web.process.descriptor.ProcessLayout; import de.metas.ui.web.process.json.JSONCreateProcessInstanceRequest; import de.metas.ui.web.process.json.JSONProcessInstance; @@ -159,9 +160,10 @@ public ResponseEntity getReport( { final ProcessInstanceResult executionResult = instancesRepository.forProcessInstanceReadonly(pinstanceId, processInstance -> processInstance.getExecutionResult()); - final String reportFilename = executionResult.getReportFilename(); - final String reportContentType = executionResult.getReportContentType(); - final byte[] reportData = executionResult.getReportData(); + final OpenReportAction action = executionResult.getAction(OpenReportAction.class); + final String reportFilename = action.getFilename(); + final String reportContentType = action.getContentType(); + final byte[] reportData = action.getReportData(); final String reportFilenameEffective = Util.coalesce(filename, reportFilename, ""); diff --git a/src/main/java/de/metas/ui/web/process/json/JSONProcessInstanceResult.java b/src/main/java/de/metas/ui/web/process/json/JSONProcessInstanceResult.java index 78b71b540..83b0cd407 100644 --- a/src/main/java/de/metas/ui/web/process/json/JSONProcessInstanceResult.java +++ b/src/main/java/de/metas/ui/web/process/json/JSONProcessInstanceResult.java @@ -2,13 +2,22 @@ import java.io.Serializable; +import org.adempiere.util.Check; +import org.slf4j.Logger; + import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import de.metas.logging.LogManager; import de.metas.ui.web.process.ProcessInstanceResult; +import de.metas.ui.web.process.ProcessInstanceResult.OpenReportAction; +import de.metas.ui.web.process.ProcessInstanceResult.OpenSingleDocument; +import de.metas.ui.web.process.ProcessInstanceResult.OpenViewAction; +import de.metas.ui.web.process.ProcessInstanceResult.ResultAction; import de.metas.ui.web.window.datatypes.DocumentPath; +import lombok.Getter; /* * #%L @@ -33,13 +42,15 @@ */ @SuppressWarnings("serial") -@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE) +@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE) public final class JSONProcessInstanceResult implements Serializable { public static final JSONProcessInstanceResult of(final ProcessInstanceResult result) { return new JSONProcessInstanceResult(result); } + + private static final Logger logger = LogManager.getLogger(JSONProcessInstanceResult.class); @JsonProperty("pinstanceId") private final int pinstanceId; @@ -49,35 +60,45 @@ public static final JSONProcessInstanceResult of(final ProcessInstanceResult res private final String summary; @JsonProperty("error") private final boolean error; + + @JsonProperty("action") + @JsonInclude(JsonInclude.Include.NON_NULL) + private final JSONResultAction action; // // Report @JsonProperty("reportFilename") @JsonInclude(JsonInclude.Include.NON_EMPTY) - private final String reportFilename; + @Deprecated + private String reportFilename; @JsonProperty("reportContentType") @JsonInclude(JsonInclude.Include.NON_EMPTY) - private final String reportContentType; + @Deprecated + private String reportContentType; // // Open view @JsonProperty("openViewWindowId") @JsonInclude(JsonInclude.Include.NON_EMPTY) - private final Integer openViewWindowId; + @Deprecated + private Integer openViewWindowId; // @JsonProperty("openViewId") @JsonInclude(JsonInclude.Include.NON_EMPTY) - private final String openViewId; + @Deprecated + private String openViewId; // // Open single document @JsonProperty("openDocumentWindowId") @JsonInclude(JsonInclude.Include.NON_EMPTY) - private final Integer openDocumentWindowId; + @Deprecated + private Integer openDocumentWindowId; // @JsonProperty("openDocumentId") @JsonInclude(JsonInclude.Include.NON_EMPTY) - private final String openDocumentId; + @Deprecated + private String openDocumentId; private JSONProcessInstanceResult(final ProcessInstanceResult result) { @@ -85,31 +106,32 @@ private JSONProcessInstanceResult(final ProcessInstanceResult result) summary = result.getSummary(); error = result.isError(); - - // - // Report - reportFilename = result.getReportFilename(); - reportContentType = result.getReportContentType(); - + + action = toJSONResultAction(result.getAction()); + // - // View - openViewWindowId = result.getOpenViewWindowId() > 0 ? result.getOpenViewWindowId() : null; - openViewId = result.getOpenViewId(); - - // - // Single document + // Update action related deprecated fields: + if(action == null) + { + // nothing + } + else if (action instanceof JSONOpenReportAction) + { + JSONOpenReportAction openReportAction = (JSONOpenReportAction)action; + this.reportFilename = openReportAction.getFilename(); + this.reportContentType = openReportAction.getContentType(); + } + else if(action instanceof JSONOpenViewAction) { - final DocumentPath singleDocumentPath = result.getOpenSingleDocumentPath(); - if (singleDocumentPath == null) - { - openDocumentWindowId = null; - openDocumentId = null; - } - else - { - openDocumentWindowId = singleDocumentPath.getAD_Window_ID(); - openDocumentId = singleDocumentPath.getDocumentId().toJson(); - } + JSONOpenViewAction openViewAction = (JSONOpenViewAction)action; + openViewWindowId = openViewAction.getWindowId() > 0 ? openViewAction.getWindowId() : 0; + openViewId = openViewAction.getViewId(); + } + else if(action instanceof JSONOpenSingleDocumentAction) + { + final JSONOpenSingleDocumentAction openSingleDocumentAction = (JSONOpenSingleDocumentAction)action; + openDocumentWindowId = openSingleDocumentAction.getWindowId(); + openDocumentId = openSingleDocumentAction.getDocumentId(); } } @@ -137,4 +159,98 @@ public String getReportContentType() { return reportContentType; } + + /** Converts {@link ResultAction} to JSON */ + private static final JSONResultAction toJSONResultAction(final ResultAction resultAction) + { + if(resultAction == null) + { + return null; + } + else if (resultAction instanceof OpenReportAction) + { + final OpenReportAction openReportAction = (OpenReportAction)resultAction; + return new JSONOpenReportAction(openReportAction.getFilename(), openReportAction.getContentType()); + } + else if(resultAction instanceof OpenViewAction) + { + OpenViewAction openViewAction = (OpenViewAction)resultAction; + return new JSONOpenViewAction(openViewAction.getWindowId(), openViewAction.getViewId()); + } + else if(resultAction instanceof OpenSingleDocument) + { + final OpenSingleDocument openDocumentAction = (OpenSingleDocument)resultAction; + final DocumentPath documentPath = openDocumentAction.getDocumentPath(); + return new JSONOpenSingleDocumentAction(documentPath.getAD_Window_ID(), documentPath.getDocumentId().toJson()); + } + else + { + logger.warn("Unknown result action: {}. Ignoring it.", resultAction); + return null; + } + } + + // + // + // + // + // + + @Getter + public static abstract class JSONResultAction + { + @JsonProperty("type") + private final String type; + + protected JSONResultAction(final String type) + { + Check.assumeNotEmpty(type, "type is not empty"); + this.type = type; + } + } + + @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE) + @lombok.Getter + public static class JSONOpenReportAction extends JSONResultAction + { + private final String filename; + private final String contentType; + + public JSONOpenReportAction(String filename, String contentType) + { + super("openReport"); + this.filename = filename; + this.contentType = contentType; + } + } + + @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE) + @lombok.Getter + public static class JSONOpenViewAction extends JSONResultAction + { + private final int windowId; + private final String viewId; + + public JSONOpenViewAction(int windowId, String viewId) + { + super("openView"); + this.windowId = windowId; + this.viewId = viewId; + } + } + + @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE) + @lombok.Getter + public static class JSONOpenSingleDocumentAction extends JSONResultAction + { + private final int windowId; + private final String documentId; + + public JSONOpenSingleDocumentAction(int windowId, String documentId) + { + super("openDocument"); + this.windowId = windowId; + this.documentId = documentId; + } + } }