From 7240ed88e068eee01c1318c71558b7c38995ca7d Mon Sep 17 00:00:00 2001 From: stefan Date: Mon, 5 Aug 2024 09:33:20 +0200 Subject: [PATCH 1/3] SLIMSSVC-15672-adapt-structure-for-code-snippets: modify main readme to include code-snippets new folder --- cookbook/readme.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cookbook/readme.md b/cookbook/readme.md index f13a1a7..b27f26f 100644 --- a/cookbook/readme.md +++ b/cookbook/readme.md @@ -49,8 +49,10 @@ external library: `slimsservice-api-6.9.1.jar`. ## What's inside? -Under the [cookbook/plugins](plugins) folder you will find several sub-folders, broken into categories: +Under the [cookbook](cookbook) folder you will find two main sub-folders that will contain entire plugins ([cookbook/plugins](plugins)) or simple code snippets ([cookbook/code-snippets](code-snippets)). +### Plugins +You will find several sub-folders with entire plugins, broken into categories:
@@ -152,4 +154,14 @@ Under the [cookbook/plugins](plugins) folder you will find several sub-folders, * Generating Excels, XML, TXT, and CSV files from Grid templates and thymeleaf * Importing a SLIMS-formatted excel import file via a plugin +
+ +### Code snippets + +
+ + +#### [UserService snippets](code-snippets/userService.md) + +
\ No newline at end of file From e16d7c321ff4ee691f18e06efdcbe4714775900c Mon Sep 17 00:00:00 2001 From: bralower Date: Wed, 12 Feb 2025 13:41:50 -0800 Subject: [PATCH 2/3] Add an example for creating an order, linking content, creating requests, and scheduling the order --- .../create-order-and-schedule/LICENSE.txt | 27 ++++ .../create-order-and-schedule/build.gradle | 4 + .../create-order-and-schedule/readme.md | 38 +++++ .../CreateOrderCustomConfiguration.java | 33 ++++ .../com/genohm/slims/custom/SpringConfig.java | 19 +++ .../custom/beans/CreateOrderAndSchedule.java | 145 ++++++++++++++++++ .../beans/CreateOrderAndScheduleBuilder.java | 23 +++ .../src/main/resources/plugin.properties | 14 ++ .../src/main/resources/slimsgate.xml | 47 ++++++ .../main/resources/spring/camel-context.xml | 23 +++ settings.gradle | 1 + 11 files changed, 374 insertions(+) create mode 100644 cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/LICENSE.txt create mode 100644 cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/build.gradle create mode 100644 cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/readme.md create mode 100644 cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/CreateOrderCustomConfiguration.java create mode 100644 cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/SpringConfig.java create mode 100644 cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java create mode 100644 cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndScheduleBuilder.java create mode 100644 cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/plugin.properties create mode 100644 cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/slimsgate.xml create mode 100644 cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/spring/camel-context.xml diff --git a/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/LICENSE.txt b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/LICENSE.txt new file mode 100644 index 0000000..b3631ec --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/LICENSE.txt @@ -0,0 +1,27 @@ +Sample Plugin License + +Copyright 2021 Agilent Technologies Inc. + +Redistribution and use of Sample Plugins in source, executable and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + + 1. Redistribution of Sample Plugins in source code, executable or binary form + must retain the above copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other materials provided with + the distribution. + + 2. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products associated with Sample Plugins + without specific prior written permission from Agilent Technologies Inc. + +SAMPLE-PLUGINS ARE PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/build.gradle b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/build.gradle new file mode 100644 index 0000000..2337eb9 --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/build.gradle @@ -0,0 +1,4 @@ +/* + * Copyright 2021 Agilent Technologies Inc. + */ + diff --git a/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/readme.md b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/readme.md new file mode 100644 index 0000000..f085d51 --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/readme.md @@ -0,0 +1,38 @@ +--- +plugin-name: "create-order-and-schedule" +--- + +# General Introduction +This plugin creates a new order (using the order type from the plugin configuration), links the selected content to the +order, applies a request to each of the selected content (using the requestable type in the plugin configuration), then +schedules the new order. + +## Usage: _Content Management_ +## Type: *slimsgate* + +# Step 1: +## User inputs: +none +## Process +An order is created, the content is linked to the order (by creating OrderContent), requestables are added to each +content record, and then order is scheduled. A feedback map outlining the content and the order is output to the next +step. + + +# Step 2: +## User inputs: +none +## Process +This step is just for displaying the feedback map. + +# Required Configuration +- A valid requestable +- A valid order type + +# Parameters description +* (String) **requestableUid**: The UID for the requestable that will be used to create requests for the selected content. +* (String) **orderTypeUid**: The UID for the desired order type for the new order. + +# Troubleshooting +The only expected errors include being unable to find the requestable or order type. + diff --git a/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/CreateOrderCustomConfiguration.java b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/CreateOrderCustomConfiguration.java new file mode 100644 index 0000000..36ed989 --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/CreateOrderCustomConfiguration.java @@ -0,0 +1,33 @@ +/* + * Copyright 2021 Agilent Technologies Inc. + */ + +package com.genohm.slims.custom; + +public class CreateOrderCustomConfiguration { + + private String requestableUid; + private String orderTypeUid; + + public CreateOrderCustomConfiguration() { + + } + + public String getRequestableUid() { + return requestableUid; + } + public String getOrderTypeUid() { + return orderTypeUid; + } + + public static CreateOrderCustomConfiguration getDefault() { + CreateOrderCustomConfiguration createOrderCustomConfiguration = new CreateOrderCustomConfiguration(); + + // used to query for the desired requestable to add to content in the new order + createOrderCustomConfiguration.requestableUid = "rqbl_wf_simplified_workflow_simplified_1"; + + // used to look up the desired order type for the new order + createOrderCustomConfiguration.orderTypeUid = "rdtp_default_workflow_order"; + return createOrderCustomConfiguration; + } +} diff --git a/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/SpringConfig.java b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/SpringConfig.java new file mode 100644 index 0000000..24cd940 --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/SpringConfig.java @@ -0,0 +1,19 @@ +/* + * Copyright 2021 Agilent Technologies Inc. + */ + +package com.genohm.slims.custom; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; + +/** + * There are cases where you might need to modify this file, but 99% of the time you can just copy it as-is + */ +@Configuration +@ComponentScan("com.genohm.slims.custom") +@ImportResource("classpath:spring/camel-context.xml") +public class SpringConfig { + +} diff --git a/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java new file mode 100644 index 0000000..fec919e --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java @@ -0,0 +1,145 @@ +/* + * Copyright 2021 Agilent Technologies Inc. + */ + +package com.genohm.slims.custom.beans; + +import com.genohm.slims.api.AddRequestService; +import com.genohm.slims.common.model.Content; +import com.genohm.slims.common.model.Order; +import com.genohm.slims.common.model.OrderContent; +import com.genohm.slims.common.model.OrderContentMeta; +import com.genohm.slims.common.model.OrderMeta; +import com.genohm.slims.common.model.OrderType; +import com.genohm.slims.common.model.Requestable; +import com.genohm.slims.common.model.User; +import com.genohm.slims.common.slimsgate.SlimsgateParameter; +import com.genohm.slims.common.util.StringUtil; +import com.genohm.slims.custom.CreateOrderCustomConfiguration; +import com.genohm.slims.server.dao.common.ActiveUser; +import com.genohm.slims.server.dao.common.Dao; +import com.genohm.slims.server.repository.queriers.ContentQueries; +import com.genohm.slims.server.repository.queriers.OrderTypeQueries; +import com.genohm.slims.server.repository.queriers.RequestableQueries; +import com.genohm.slims.server.service.order.ScheduleOrderService; +import com.genohm.slims.server.util.EntityFactoryUtil; +import com.genohm.slimsgate.camel.gatekeeper.SlimsGateErrorException; +import com.genohm.slimsgate.camel.gatekeeper.SlimsGateKeeperConstants; +import com.genohm.slimsgate.camel.gatekeeper.SlimsProxy; +import com.genohm.slimsgateclient.workflow.SlimsFlowInitParam; +import org.apache.camel.Handler; +import org.apache.camel.Header; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class CreateOrderAndSchedule { + + @Autowired private CreateOrderCustomConfiguration createOrderCustomConfiguration; + + @Autowired private OrderTypeQueries orderTypeQueries; + @Autowired private ContentQueries contentQueries; + @Autowired private RequestableQueries requestableQueries; + + @Autowired private Dao orderDao; + @Autowired private Dao orderContentDao; + @Autowired private ScheduleOrderService scheduleOrderService; + @Autowired private AddRequestService addRequestService; + + @Transactional + @Handler + public Map execute( + @Header(SlimsGateKeeperConstants.SLIMS_PROXY) SlimsProxy slimsProxy, + @Header(SlimsGateKeeperConstants.SLIMS_WORKFLOW_INIT_PARAMETER) + SlimsFlowInitParam initParam) { + // get logger from slimsProxy to allow logging to the UI (vs just to the server log file) + Logger logger = slimsProxy.getLogger(getClass()); + + // get the user running the plugin so the audit trail shows their user instead of the "Slimsgate" user + User user = ActiveUser.get(); + + // get content primary keys from the input parameters + Map initParamValues = initParam.getInputParameterValues(); + List samplePks = + Arrays.asList( + StringUtil.getAsLongArray( + initParamValues.get(SlimsgateParameter.SLIMS_SELECT_SAMPLES))); + + // query for Content records using the PKs of the selected content + List sampleContentList = contentQueries.findByPks(samplePks); + + // get order type record using the unique identifier in the plugin configuration + OrderType workflowOrderType = + orderTypeQueries + .findByUniqueIdentifier(createOrderCustomConfiguration.getOrderTypeUid()) + .toJavaUtil() + .orElseThrow( + () -> + new SlimsGateErrorException( + String.format( + "Could not find the order type with UID %s.", + createOrderCustomConfiguration.getOrderTypeUid()))); + + // create an order by first making a map and then adding it to the database + Map order = new HashMap<>(); + order.put(OrderMeta.FK_ORDER_TYPE, workflowOrderType.getRdtp_pk()); // add the order type PK to the map + Map newOrderMap = orderDao.add(order, user); // commit the order to the database + + // convert the order to a SLIMS entity in preparation for adding requests and scheduling + Order newOrder = EntityFactoryUtil.createInstance(Order.class, newOrderMap); + + for (Content content : sampleContentList) { + // create a new order content record and add it to the database. This is how the content is linked to the order + Map newOrderContent = new HashMap<>(); + newOrderContent.put(OrderContentMeta.FK_CONTENT, content.getCntn_pk()); + newOrderContent.put(OrderContentMeta.FK_ORDER, newOrderMap.get(OrderMeta.PK)); + orderContentDao.add(newOrderContent, user); + + // query for the requestable defined in the configuration + Requestable requestable = + requestableQueries + .findByUniqueIdentifier(createOrderCustomConfiguration.getRequestableUid()) + .toJavaUtil() + .orElseThrow( + () -> + new SlimsGateErrorException( + String.format( + "Could not find requestable with UID %s.", + createOrderCustomConfiguration.getRequestableUid()))); + + // add the request to the content/order + addRequestService.createWorkflowRequest(content, requestable, newOrder, new HashMap<>()); + } + + // schedule the order + scheduleOrderService.scheduleWorkflowOrder(newOrder, user); + + // return the feedback map for display in the last step of the plugin + return createFeedback(newOrder, sampleContentList); + } + + private Map createFeedback(Order order, List samples) { + Map feedback = new HashMap<>(); + StringBuilder feedbackSb = new StringBuilder(); + + feedbackSb.append("

Created content barcodes

"); + feedbackSb.append("
    "); + samples.forEach(sample -> feedbackSb.append(String.format("
  • %s
  • ", sample.getCntn_barCode()))); + feedbackSb.append("
"); + + feedbackSb.append("
"); + + feedbackSb.append("

Order barcode

"); + feedbackSb.append(order.getOrdr_barCode()); + + feedback.put("results", feedbackSb.toString()); + return feedback; + } +} diff --git a/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndScheduleBuilder.java b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndScheduleBuilder.java new file mode 100644 index 0000000..ad5b19e --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndScheduleBuilder.java @@ -0,0 +1,23 @@ +/* + * Copyright 2021 Agilent Technologies Inc. + */ + +package com.genohm.slims.custom.beans; + +import org.apache.camel.builder.RouteBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class CreateOrderAndScheduleBuilder extends RouteBuilder { + + @Autowired CreateOrderAndSchedule createOrderAndSchedule; + + @Override + public void configure() throws Exception { + from("direct:create-order-and-schedule") + .bean(createOrderAndSchedule) + .routeId("create-order-and-schedule"); + } + +} \ No newline at end of file diff --git a/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/plugin.properties b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/plugin.properties new file mode 100644 index 0000000..5cf0177 --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/plugin.properties @@ -0,0 +1,14 @@ +# +# Copyright 2021 Agilent Technologies Inc. +# + +# This is the classpath of the Configuration class of your plugin, starting from this plugin's src/main/java/ path +config-class=com.genohm.slims.custom.CreateOrderCustomConfiguration +# This is the "type" of plugin it is. Use SLIMSGATE unless you are just creating a library to use as a dependency for other plugins (see library-template) +type=SLIMSGATE +# This is the minimum "minor" version of your SLIMS "major" version that your plugin will run on +# The first two numbers have to match the version of SLIMS where you plan to install the plugin + # If you have 6.8.16, this needs to be 6.8.X, and X must be <= 16 to run on your instance +# The third number should be 0 unless there is a specific minor version where a service that you need to use was added + # 6.9.0 means it will run on any 6.9 minor version +apiVersion=6.9.0 \ No newline at end of file diff --git a/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/slimsgate.xml b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/slimsgate.xml new file mode 100644 index 0000000..03ea51e --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/slimsgate.xml @@ -0,0 +1,47 @@ + + + + + create-order-and-schedule + Create order and schedule to workflow + contentmanagement + + Create order + true + + + + SLIMS_SELECT_SAMPLES + StringArray + true + + + + create-order-and-schedule + + + + executionFeedback + ValueMap + + + + + Feedback + + + + results + Feedback + 500 + executionFeedback + + + + slimsgate-dummy-route + + + + \ No newline at end of file diff --git a/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/spring/camel-context.xml b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/spring/camel-context.xml new file mode 100644 index 0000000..05d6731 --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/create-order-and-schedule/src/main/resources/spring/camel-context.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/settings.gradle b/settings.gradle index 4b079a2..67c3700 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,3 +7,4 @@ include 'templates:slims-vaadin-template' include 'templates:library-template' include 'templates:dto-template' include 'cookbook:plugins:direct-database-actions:basic-crud-actions' +include 'cookbook:plugins:ui-only-actions-as-code:create-order-and-schedule' \ No newline at end of file From 7d68ac464b993882a88893ce759809517b9fea39 Mon Sep 17 00:00:00 2001 From: bralower Date: Wed, 12 Feb 2025 13:53:44 -0800 Subject: [PATCH 3/3] Add UI actions readme --- .../plugins/ui-only-actions-as-code/readme.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 cookbook/plugins/ui-only-actions-as-code/readme.md diff --git a/cookbook/plugins/ui-only-actions-as-code/readme.md b/cookbook/plugins/ui-only-actions-as-code/readme.md new file mode 100644 index 0000000..0247395 --- /dev/null +++ b/cookbook/plugins/ui-only-actions-as-code/readme.md @@ -0,0 +1,53 @@ +# Plugins in this section + +
+ + + +## [ui-only-actions-as-code](ui-only-actions-as-code) + + + +
+ + + +#### Flows + + + +* [Create and schedule an order](create-order-and-schedule/src/main/resources/slimsgate.xml#L6) + +
+ +
+ + + +#### Slimsgate API Services demonstrated + + + +* Using PublicApi service classes + * [ScheduleOrderService](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L120) + * [AddRequestService](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L116) +* Using Dao<> classes to add records + * [Dao\](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L91) + * [Dao\](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L101) +* Fetching custom Class objects without custom fields + * [ContentQueries](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L74) + * [OrderTypeQueries](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L77) + * [RequestableQueries](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L104) +* Using Meta classes for default field names + * [OrderMeta](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L90) + * [OrderContentMeta](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L99) +* Throwing errors for users with [SlimsGateErrorException](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L85) +* Accessing inputs on step forms with [SlimsFlowInitParam](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L69) +* Using *StringUtil* to assist with casting Objects + * [Casting to Long[]](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L72) +* Accessing checked-off records with *SLIMS_SELECT_SAMPLES* + * [Slimsgate.xml configuration to require items be checked off](create-order-and-schedule/src/main/resources/slimsgate.xml#L13) + * [Accessing the pk's of checked-off items in your code](create-order-and-schedule/src/main/java/com/genohm/slims/custom/beans/CreateOrderAndSchedule.java#L70) + +
+