diff --git a/workflow/workflow-demos-test/src_test/test/bpm/TestOrder.java b/workflow/workflow-demos-test/src_test/test/bpm/TestOrder.java
new file mode 100644
index 000000000..b60947d4e
--- /dev/null
+++ b/workflow/workflow-demos-test/src_test/test/bpm/TestOrder.java
@@ -0,0 +1,77 @@
+package test.bpm;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+import ch.ivyteam.ivy.bpm.engine.client.BpmClient;
+import ch.ivyteam.ivy.bpm.engine.client.element.BpmElement;
+import ch.ivyteam.ivy.bpm.engine.client.element.BpmProcess;
+import ch.ivyteam.ivy.bpm.exec.client.IvyProcessTest;
+import ch.ivyteam.ivy.environment.Ivy;
+import ch.ivyteam.ivy.notification.impl.NotificationRepository;
+import ch.ivyteam.ivy.notification.query.NotificationQuery;
+import ch.ivyteam.ivy.scripting.objects.Tuple;
+import ch.ivyteam.ivy.workflow.CaseState;
+import workflow.order.Order;
+import workflow.order.Person;
+
+@IvyProcessTest
+public class TestOrder
+{
+ private static final BpmProcess ORDER_PROCESS = BpmProcess.name("OrderProcess");
+
+ private static final BpmElement START_ORDER = ORDER_PROCESS.elementName("startOrder");
+ private static final BpmElement INPUT_ORDER = ORDER_PROCESS.elementName("Input Order");
+ private static final BpmElement PROCESS_ORDER = ORDER_PROCESS.elementName("Process Order");
+ private static final BpmElement DELIVER_ORDER = ORDER_PROCESS.elementName("Deliver Order");
+ private static final BpmElement SEND_INVOICE = ORDER_PROCESS.elementName("Send Invoice");
+ private static final BpmElement BOOK_PAYMENT = ORDER_PROCESS.elementName("Book Payment");
+
+ private static final Person CUSTOMER = new Person();
+ private static final Order ORDER = new Order();
+
+ static
+ {
+ CUSTOMER.setName("Doe");
+ CUSTOMER.setSurname("John");
+ ORDER.setProduct("Ferrari Testarossa");
+ }
+
+ @Test
+ void runProcess(BpmClient bpmClient)
+ {
+ bpmClient.mock().uiOf(INPUT_ORDER).with(this::inputOrder);
+ bpmClient.mock().uiOf(PROCESS_ORDER).withNoAction();
+ bpmClient.mock().uiOf(DELIVER_ORDER).withNoAction();
+ bpmClient.mock().uiOf(DELIVER_ORDER).withNoAction();
+ bpmClient.mock().uiOf(SEND_INVOICE).withNoAction();
+ bpmClient.mock().uiOf(BOOK_PAYMENT).withNoAction();
+
+ NotificationQuery nofiticationQuery = NotificationRepository.of(Ivy.wf().getSecurityContext()).query();
+ var notifications = nofiticationQuery.executor().count();
+
+ var result = bpmClient.start().process(START_ORDER)
+ .as().everybody().execute();
+ bpmClient.start().anyActiveTask(result).as().role("Processor").execute();
+ bpmClient.start().anyActiveTask(result).as().role("Deliverer").execute();
+ bpmClient.start().anyActiveTask(result).as().role("Finance").execute();
+ bpmClient.start().anyActiveTask(result).as().role("Finance").execute();
+
+ assertThat(result.workflow().activeCase().getState()).isEqualTo(CaseState.DONE);
+ assertThat(nofiticationQuery.executor().count()).isEqualTo(notifications + 9);
+ }
+
+ private void inputOrder(Tuple parameters, Tuple results)
+ {
+ try
+ {
+ results.set("customer", CUSTOMER);
+ results.set("order", ORDER);
+ }
+ catch (NoSuchFieldException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+ }
+}
diff --git a/workflow/workflow-demos/cms/Notification/business/Templates/Order/mail/Content.html b/workflow/workflow-demos/cms/Notification/business/Templates/Order/mail/Content.html
new file mode 100644
index 000000000..efb3cff09
--- /dev/null
+++ b/workflow/workflow-demos/cms/Notification/business/Templates/Order/mail/Content.html
@@ -0,0 +1,17 @@
+
+
+ "/>
+ <%= ivy.cm.co("/Notification/business/Templates/Order/Labels/Title") %>
+ <%= ivy.cm.co("/Notification/business/Templates/Order/Labels/Greeting") %> <%= ivy.session.getSessionUser().getFullName() %>
+
+
+ <%= ivy.cm.co("/Notification/business/Templates/Order/Labels/Message") %> |
+ | <%= ivy.html.escape(message) %> |
+
+
+ <%= ivy.cm.co("/Notification/business/Templates/Order/Labels/Customer") %> |
+ <%= ivy.html.escape(payload.get("surname")) %> <%= ivy.html.escape(payload.get("name")) %> |
+
+
+
+
diff --git a/workflow/workflow-demos/cms/cms_de.yaml b/workflow/workflow-demos/cms/cms_de.yaml
index d1f46cffc..b3b32f63c 100644
--- a/workflow/workflow-demos/cms/cms_de.yaml
+++ b/workflow/workflow-demos/cms/cms_de.yaml
@@ -1,3 +1,7 @@
+Categories:
+ notification:
+ cssIcon: si si-messages-bubble
+ name: 8. Notification
Dialogs:
agileBPM:
define_WF:
@@ -107,15 +111,14 @@ Dialogs:
selectParkingLot: Parkplatz auswählen
Emails:
accepted: akzeptiert
- confirmParkingLot: "\r\nHallo <%=in.name%>\r\n
\r\n\r\nDer Parkplatz Nr. <%=in.selectedParkingLotNr%> wurde für Sie reserviert. \r\n
\r\n\r\nWir wünschen Ihnen einen schönen Tag.\r\n
\r\n"
+ confirmParkingLot: "\nHallo <%=in.name%>\n
\n\nDer Parkplatz Nr. <%=in.selectedParkingLotNr%> wurde für Sie reserviert. \n
\n\nWir wünschen Ihnen einen schönen Tag.\n
\n"
declined: abgelehnt
parkingLotReservationHeader: Ihr Parkplatz wurde reserviert
- procurementRequestNotification: "\r\nHallo <%=in.requester.fullName%> \r\n
\r\n\r\nIhr Antrag wurde <%=(in.accepted ? \"angenommen\" : \"abgelehnt\")%>: \r\n
\r\n\r\n<%=in.amount%> Stück '<%=in.description%>' zum Gesamtpreis von <%=in.totalPrice%> <%=ivy.cms.co(\"/Dialogs/procurementRequest/currencySymbol\"\
- )%> \r\n
\r\n\r\nFreundliche Grüsse \r\n
\r\n"
+ procurementRequestNotification: "\nHallo <%=in.requester.fullName%> \n
\n\nIhr Antrag wurde <%=(in.accepted ? \"angenommen\" : \"abgelehnt\")%>: \n
\n\n<%=in.amount%> Stück '<%=in.description%>' zum Gesamtpreis von <%=in.totalPrice%> <%=ivy.cms.co(\"/Dialogs/procurementRequest/currencySymbol\"\
+ )%> \n
\n\nFreundliche Grüsse \n
\n"
senderMail: noreply@axonivy.com
welcomeHeader: Willkommen
- welcomeMail: "\r\nHallo <%=in.name%> \r\n
\r\n\r\nWillkommen in unserem Unternehmen. Wir freuen uns, Sie bei uns begrüssen zu dürfen! \r\n
\r\n\r\nWenn Sie Fragen haben, wenden Sie sich bitte an Ihren Teamleiter oder an Ihren HR Manager. \r\n
\r\n\r\nWir wünschen Ihnen einen schö\
- nen Tag! \r\n
\r\n"
+ welcomeMail: "\nHallo <%=in.name%> \n
\n\nWillkommen in unserem Unternehmen. Wir freuen uns, Sie bei uns begrüssen zu dürfen! \n
\n\nWenn Sie Fragen haben, wenden Sie sich bitte an Ihren Teamleiter oder an Ihren HR Manager. \n
\n\nWir wünschen Ihnen einen schönen Tag! \n
\n"
yourRequestHasBeen: 'Ihre Anfrage wurde '
Labels:
AdhocWorkflow: Beschreiben Sie Ihren Workflow
@@ -125,6 +128,19 @@ Labels:
InsertTheTask: Aufgabe einfügen
TaskUser-Explain: Komma getrennte Liste von Benutzern
title: Self Service Ad-Hoc Workflow
+Notification:
+ Messages:
+ InvoiceSent: Die Rechnung für die Bestellung {0} wurde versendet
+ OrderDelivered: Bestellung {0} wurde an Kunde {1} {2} ausgeliefert
+ OrderFinished: Die Bestellung {0} wurde erfolgreich abgeschlossen
+ business:
+ Templates:
+ Order:
+ Labels:
+ Customer: Kunde
+ Greeting: 'Hallo '
+ Message: Meldung
+ Title: Bestellungsinformation
TaskDescriptions:
DeliverKeyCardDesc: Bitte liefern Sie die Schlüsselkarte aus für
acceptRequest: Antrag annehmen
@@ -138,8 +154,11 @@ TaskDescriptions:
verifyRequest: Prüfe Antrag
Texts:
Adhoc-Explain: ' Geben Sie Ihren Kommentar ein und drücken Sie Senden um weiterzufahren.
'
- AdhocWF-Explain: "\r\nDefinieren und starten Sie einen Workflow auf Knopfdruck. \r\n
\r\n"
- Approval-Explain: "\r\nTreffen Sie Ihre Entscheidung und klicken Sie auf Senden um weiterzufahren. \r\n
\r\n"
- QA-Explain: "\r\nBeantworten Sie die Frage und Senden Sie Ihre Antwort an den Fragesteller zurück.\r\n
\r\n"
+ AdhocWF-Explain: "\nDefinieren und starten Sie einen Workflow auf Knopfdruck. \n
\n"
+ Approval-Explain: "\nTreffen Sie Ihre Entscheidung und klicken Sie auf Senden um weiterzufahren. \n
\n"
+ QA-Explain: |
+
+ Beantworten Sie die Frage und Senden Sie Ihre Antwort an den Fragesteller zurück.
+
QAresponse-Explain: ' Sie können eine Anschlussfrage Zurücksenden oder den Workflow Beenden.
'
ToDo-Explain: ' Bestätigen Sie, dass das TODO Erledigt wurde oder lehnen Sie es ab.
'
diff --git a/workflow/workflow-demos/cms/cms_en.yaml b/workflow/workflow-demos/cms/cms_en.yaml
index 2be6174a2..a3f483bc3 100644
--- a/workflow/workflow-demos/cms/cms_en.yaml
+++ b/workflow/workflow-demos/cms/cms_en.yaml
@@ -20,6 +20,9 @@ Categories:
cssIcon: si si-multiple-neutral-1
name: 2. Human Tasks
tooltip: How to integrate humans into workflows
+ notification:
+ cssIcon: si si-messages-bubble
+ name: 8. Notification
signal:
cssIcon: si si-network-signal
name: 3. Signals
@@ -138,14 +141,46 @@ Dialogs:
selectParkingLot: Select parking lot
Emails:
accepted: accepted
- confirmParkingLot: "\r\nHello <%=in.name%>\r\n
\r\n\r\nWe reserved the parking lot nr. <%=in.selectedParkingLotNr%> for you.\r\n
\r\n\r\nHave a nice day.\r\n
\r\n"
+ confirmParkingLot: |
+
+ Hello <%=in.name%>
+
+
+ We reserved the parking lot nr. <%=in.selectedParkingLotNr%> for you.
+
+
+ Have a nice day.
+
declined: declined
parkingLotReservationHeader: Your parking lot has been reserved
- procurementRequestNotification: "\r\nHello <%=in.requester.fullName%>\r\n
\r\n\r\nYour request has been <%=(in.accepted ? \"accepted\" : \"declined\")%>:\r\n
\r\n\r\n<%=in.amount%> pieces of '<%=in.description%>' for a total of <%=in.totalPrice%> <%=ivy.cms.co(\"/Dialogs/procurementRequest/currencySymbol\"\
- )%>\r\n
\r\n\r\nKind regards\r\n
\r\n"
+ procurementRequestNotification: |
+
+ Hello <%=in.requester.fullName%>
+
+
+ Your request has been <%=(in.accepted ? "accepted" : "declined")%>:
+
+
+ <%=in.amount%> pieces of '<%=in.description%>' for a total of <%=in.totalPrice%> <%=ivy.cms.co("/Dialogs/procurementRequest/currencySymbol")%>
+
+
+ Kind regards
+
senderMail: noreply@axonivy.com
welcomeHeader: Welcome
- welcomeMail: "\r\nHello <%=in.name%>\r\n
\r\n\r\nWelcome at our company. It is a great pleasure to have you here!\r\n
\r\n\r\nIf you have any question, please don't hesitate to contact your teamleader or your HR Manager.\r\n
\r\n\r\nHave a nice day!\r\n
\r\n"
+ welcomeMail: |
+
+ Hello <%=in.name%>
+
+
+ Welcome at our company. It is a great pleasure to have you here!
+
+
+ If you have any question, please don't hesitate to contact your teamleader or your HR Manager.
+
+
+ Have a nice day!
+
yourRequestHasBeen: Your request has been
Labels:
AdhocWorkflow: Describe your Workflow
@@ -155,6 +190,23 @@ Labels:
InsertTheTask: Insert the task
TaskUser-Explain: Comma separated list of users
title: Self Service Ad-hoc Workflow
+Notification:
+ Messages:
+ InvoiceSent: The invoice for order {0} was sent
+ OrderDelivered: Order {0} delivered to customer {1} {2}
+ OrderFinished: The order {0} successfully finished
+ business:
+ Templates:
+ Order:
+ Labels:
+ Customer: Customer
+ Greeting: Hello
+ Message: Message
+ Title: Order Information
+ web:
+ Subject: |-
+ <%= ivy.html.escape(message) %>
+ <%= ivy.cm.co("/Notification/business/Templates/Order/Labels/Customer") %> <%= ivy.html.escape(payload.get("surname")) %> <%= ivy.html.escape(payload.get("name")) %>
ProcessDescriptions:
AdHocDescription: 'Self Service Process: Launch an ad-hoc Workflow based on a predefined flow pattern.'
AdHocName: Ad-hoc Process
@@ -194,9 +246,21 @@ TaskDescriptions:
setupWorkstationDesc: 'Please set up the workstation for '
verifyRequest: Verify Request
Texts:
- Adhoc-Explain: "\r\nEnter your comment and press Send to proceed the workflow.\r\n
\r\n"
- AdhocWF-Explain: "\r\nDefine and launch a Workflow at your fingertip: Select a flow pattern, add some tasks and start the Workflow. \r\n
\r\n\r\n\r\n
\r\n"
- Approval-Explain: "\r\nEnter your decision and press Send to proceed the workflow.\r\n
\r\n"
- QA-Explain: "\r\nAnswer the question and Send your answer back to the caller. \r\n
\r\n"
- QAresponse-Explain: "\r\nYou can Send back a follow-up question or Finish the Workflow.\r\n
\r\n"
- ToDo-Explain: "\r\nConfirm that the TODO is Done or decline it.\r\n
\r\n"
+ Adhoc-Explain: |
+
+ Enter your comment and press Send to proceed the workflow.
+
+ AdhocWF-Explain: "\nDefine and launch a Workflow at your fingertip: Select a flow pattern, add some tasks and start the Workflow. \n
\n\n\n
\n"
+ Approval-Explain: |
+
+ Enter your decision and press Send to proceed the workflow.
+
+ QA-Explain: "\nAnswer the question and Send your answer back to the caller. \n
\n"
+ QAresponse-Explain: |
+
+ You can Send back a follow-up question or Finish the Workflow.
+
+ ToDo-Explain: |
+
+ Confirm that the TODO is Done or decline it.
+
diff --git a/workflow/workflow-demos/config/roles.xml b/workflow/workflow-demos/config/roles.xml
index 348c3943a..d10d8e204 100644
--- a/workflow/workflow-demos/config/roles.xml
+++ b/workflow/workflow-demos/config/roles.xml
@@ -29,4 +29,16 @@
Executive Manager
+
+ Order
+
+ Deliverer
+
+
+ Processor
+
+
+ Finance
+
+
diff --git a/workflow/workflow-demos/config/users.xml b/workflow/workflow-demos/config/users.xml
index 142003b30..c8dd322bb 100644
--- a/workflow/workflow-demos/config/users.xml
+++ b/workflow/workflow-demos/config/users.xml
@@ -17,6 +17,7 @@
IT Manager
Office Manager
Executive Manager
+ Processor
wt
@@ -41,6 +42,7 @@
James Bond
james.bond@axonivy.com
Office Manager
+ Deliverer
hf
@@ -53,5 +55,6 @@
Benjamin Franklin
benjamin.franklin@axonivy.com
Executive Manager
+ Finance
diff --git a/workflow/workflow-demos/dataclasses/workflow/order/Order.ivyClass b/workflow/workflow-demos/dataclasses/workflow/order/Order.ivyClass
new file mode 100644
index 000000000..44df56cce
--- /dev/null
+++ b/workflow/workflow-demos/dataclasses/workflow/order/Order.ivyClass
@@ -0,0 +1,4 @@
+Order #class
+workflow.order #namespace
+product String #field
+product PERSISTENT #fieldModifier
diff --git a/workflow/workflow-demos/dataclasses/workflow/order/OrderData.ivyClass b/workflow/workflow-demos/dataclasses/workflow/order/OrderData.ivyClass
new file mode 100644
index 000000000..f6af4cf6c
--- /dev/null
+++ b/workflow/workflow-demos/dataclasses/workflow/order/OrderData.ivyClass
@@ -0,0 +1,6 @@
+OrderData #class
+workflow.order #namespace
+customer workflow.order.Person #field
+customer PERSISTENT #fieldModifier
+order workflow.order.Order #field
+order PERSISTENT #fieldModifier
diff --git a/workflow/workflow-demos/dataclasses/workflow/order/Person.ivyClass b/workflow/workflow-demos/dataclasses/workflow/order/Person.ivyClass
new file mode 100644
index 000000000..23b1648e4
--- /dev/null
+++ b/workflow/workflow-demos/dataclasses/workflow/order/Person.ivyClass
@@ -0,0 +1,6 @@
+Person #class
+workflow.order #namespace
+name String #field
+name PERSISTENT #fieldModifier
+surname String #field
+surname PERSISTENT #fieldModifier
diff --git a/workflow/workflow-demos/processes/BusinessNotification/OrderProcess.p.json b/workflow/workflow-demos/processes/BusinessNotification/OrderProcess.p.json
new file mode 100644
index 000000000..24d29ec84
--- /dev/null
+++ b/workflow/workflow-demos/processes/BusinessNotification/OrderProcess.p.json
@@ -0,0 +1,398 @@
+{
+ "$schema" : "https://json-schema.axonivy.com/process/11.2.2/process.json",
+ "id" : "18DD058BCE48D418",
+ "config" : {
+ "data" : "workflow.order.OrderData"
+ },
+ "elements" : [ {
+ "id" : "f0",
+ "type" : "RequestStart",
+ "name" : "startOrder",
+ "config" : {
+ "signature" : "startOrder",
+ "request" : {
+ "name" : "8.1 Business Notification",
+ "category" : "notification",
+ "customFields" : [
+ { "name" : "cssIcon", "value" : "si si-messages-bubble" }
+ ]
+ },
+ "permission" : {
+ "anonymous" : false
+ },
+ "persistOnStart" : true,
+ "task" : {
+ "name" : "New Order"
+ },
+ "case" : {
+ "name" : "New Order"
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 88, "y" : 96 }
+ },
+ "connect" : [
+ { "id" : "f2", "to" : "f3" }
+ ]
+ }, {
+ "id" : "f1",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 1408, "y" : 600 }
+ }
+ }, {
+ "id" : "f3",
+ "type" : "DialogCall",
+ "name" : "Input Order",
+ "config" : {
+ "dialog" : "workflow.order.InputOrder:start()",
+ "output" : {
+ "map" : {
+ "out" : "in",
+ "out.customer" : "result.customer",
+ "out.order" : "result.order"
+ }
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 216, "y" : 96 }
+ },
+ "connect" : [
+ { "id" : "f4", "to" : "f5" }
+ ]
+ }, {
+ "id" : "f5",
+ "type" : "Script",
+ "name" : "Send New Order",
+ "config" : {
+ "output" : {
+ "code" : [
+ "import ch.ivyteam.ivy.notification.business.BusinessNotification;",
+ "import ch.ivyteam.ivy.security.IRole;",
+ "",
+ "/*",
+ " Sends a new business notification",
+ " with the message \"New Order received\"",
+ " to all users that owns the role \"Processor\"",
+ "*/",
+ "IRole processor = ivy.security.roles().find(\"Processor\");",
+ "BusinessNotification",
+ " .create()",
+ " .message().text(\"New order received\")",
+ " .receivers().add(processor)",
+ " .send();"
+ ]
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 376, "y" : 96 }
+ },
+ "connect" : [
+ { "id" : "f6", "to" : "f7" }
+ ]
+ }, {
+ "id" : "f7",
+ "type" : "TaskSwitchEvent",
+ "config" : {
+ "task" : {
+ "name" : "Process order <%= in1.order.product %> for customer <%= in1.customer.surname %> <%= in1.customer.name %>",
+ "description" : "Please process the order of a <%= in1.order.product %> for the customer <%= in1.customer.surname %> <%= in1.customer.name %>",
+ "responsible" : {
+ "activator" : "Processor"
+ }
+ },
+ "case" : {
+ "name" : "Order <%=in1.order.product%> for customer <%= in1.customer.surname %> <%= in1.customer.name%>"
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 376, "y" : 192 }
+ },
+ "connect" : [
+ { "id" : "f8", "to" : "f9" }
+ ]
+ }, {
+ "id" : "f9",
+ "type" : "DialogCall",
+ "name" : "Process Order",
+ "config" : {
+ "dialog" : "workflow.order.ProcessOrder:start(workflow.order.Person,workflow.order.Order)",
+ "call" : {
+ "map" : {
+ "param.customer" : "in.customer",
+ "param.order" : "in.order"
+ }
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 376, "y" : 264 }
+ },
+ "connect" : [
+ { "id" : "f10", "to" : "f11" }
+ ]
+ }, {
+ "id" : "f11",
+ "type" : "Script",
+ "name" : "Send Order Processed",
+ "config" : {
+ "output" : {
+ "code" : [
+ "import ch.ivyteam.ivy.notification.business.BusinessNotification;",
+ "import ch.ivyteam.ivy.security.IRole;",
+ "",
+ "/*",
+ " Sends a new business notification",
+ " with the message \"Order {0} processed for customer {1} {2}\" ",
+ " using placeholders in the message that are replaced by the given additional arguments",
+ " to all users that owns the role \"Processor\"",
+ "*/",
+ "IRole processor = ivy.security.roles().find(\"Processor\");",
+ "BusinessNotification",
+ " .create()",
+ " .message().text(\"Order {0} processed for customer {1} {2}\", in.order.product, in.customer.surname, in.customer.name)",
+ " .receivers().add(processor)",
+ " .send();"
+ ]
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 544, "y" : 264 }
+ },
+ "connect" : [
+ { "id" : "f12", "to" : "f13" }
+ ]
+ }, {
+ "id" : "f13",
+ "type" : "TaskSwitchEvent",
+ "config" : {
+ "task" : {
+ "name" : "Deliver order <%= in1.order.product %> to customer <%= in1.customer.surname %> <%= in1.customer.name %>",
+ "description" : "Please deliver the order <%= in1.order.product %> to customer <%= in1.customer.surname %> <%=in1.customer.name %>",
+ "responsible" : {
+ "activator" : "Deliverer"
+ }
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 544, "y" : 336 }
+ },
+ "connect" : [
+ { "id" : "f14", "to" : "f15" }
+ ]
+ }, {
+ "id" : "f15",
+ "type" : "DialogCall",
+ "name" : "Deliver Order",
+ "config" : {
+ "dialog" : "workflow.order.DeliverOrder:start(workflow.order.Person,workflow.order.Order)",
+ "call" : {
+ "map" : {
+ "param.customer" : "in.customer",
+ "param.order" : "in.order"
+ }
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 544, "y" : 416 }
+ },
+ "connect" : [
+ { "id" : "f16", "to" : "f17" }
+ ]
+ }, {
+ "id" : "f17",
+ "type" : "Script",
+ "name" : "Send Order Delivered",
+ "config" : {
+ "output" : {
+ "code" : [
+ "import ch.ivyteam.ivy.notification.business.BusinessNotification;",
+ "/*",
+ " Sends a new business notification",
+ " with the mutli-lingual message stored in CMS under path \"/Notification/Messages/OrderDelivered\" ",
+ " using placeholders in the message that are replaced by the given additional arguments",
+ " to all users that were involved in the current case. ",
+ " Involved in a case means the user has worked on or has a role that was involved in the case.",
+ "*/",
+ "BusinessNotification",
+ " .create()",
+ " .message().fromCms(\"/Notification/Messages/OrderDelivered\", in.order.product, in.customer.surname, in.customer.name)",
+ " .receivers().addCase().allInvolved()",
+ " .send();"
+ ]
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 712, "y" : 416 }
+ },
+ "connect" : [
+ { "id" : "f18", "to" : "f19" }
+ ]
+ }, {
+ "id" : "f19",
+ "type" : "TaskSwitchEvent",
+ "config" : {
+ "task" : {
+ "name" : "Send invoice for order <%= in1.order.product %> to customer <%= in1.customer.surname %> <%= in1.customer.name %>",
+ "description" : "Please send invoice for the order <%= in1.order.product %> to the customer <%= in1.customer.surname %> <%=in1.customer.name %>"
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 712, "y" : 496 }
+ },
+ "connect" : [
+ { "id" : "f20", "to" : "f21" }
+ ]
+ }, {
+ "id" : "f21",
+ "type" : "DialogCall",
+ "name" : "Send Invoice",
+ "config" : {
+ "dialog" : "workflow.order.SendInvoice:start(workflow.order.Person,workflow.order.Order)",
+ "call" : {
+ "map" : {
+ "param.customer" : "in.customer",
+ "param.order" : "in.order"
+ }
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 712, "y" : 600 }
+ },
+ "connect" : [
+ { "id" : "f22", "to" : "f23" }
+ ]
+ }, {
+ "id" : "f23",
+ "type" : "Script",
+ "name" : "Send Invoice Sent",
+ "config" : {
+ "output" : {
+ "code" : [
+ "import ch.ivyteam.ivy.notification.business.BusinessNotification;",
+ "/*",
+ " Sends a new business notification",
+ " with the mutli-lingual message stored in CMS under path \"/Notification/Messages/InvoiceSent\"",
+ " using placeholders in the message that are replaced by the given additional arguments",
+ " to all users that could have worked on the current task.",
+ " The format of the message is defined by the given template (see CMS \"/Notification/business/Templates/Order/web/Subject\") ",
+ " and payload object.",
+ "*/",
+ "BusinessNotification",
+ " .create()",
+ " .template(\"Order\")",
+ " .payload(in.customer)",
+ " .message().fromCms(\"/Notification/Messages/InvoiceSent\", in.order.product)",
+ " .receivers().addTask().activator()",
+ " .send();"
+ ]
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 872, "y" : 600 }
+ },
+ "connect" : [
+ { "id" : "f24", "to" : "f25" }
+ ]
+ }, {
+ "id" : "f25",
+ "type" : "TaskSwitchEvent",
+ "config" : {
+ "task" : {
+ "name" : "Book payment for order <%= in1.order.product %> by customer <%= in1.customer.surname %> <%= in1.customer.name %>",
+ "description" : "Please book payment for the order <%= in1.order.product %> by the customer <%= in1.customer.surname %> <%=in1.customer.name %>",
+ "responsible" : {
+ "activator" : "Finance"
+ }
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 992, "y" : 600 }
+ },
+ "connect" : [
+ { "id" : "f26", "to" : "f27" }
+ ]
+ }, {
+ "id" : "f27",
+ "type" : "DialogCall",
+ "name" : "Book Payment",
+ "config" : {
+ "dialog" : "workflow.order.BookPayment:start(workflow.order.Person,workflow.order.Order)",
+ "call" : {
+ "map" : {
+ "param.customer" : "in.customer",
+ "param.order" : "in.order"
+ }
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 1120, "y" : 600 }
+ },
+ "connect" : [
+ { "id" : "f28", "to" : "f29" }
+ ]
+ }, {
+ "id" : "f29",
+ "type" : "Script",
+ "name" : "Send Order Finished",
+ "config" : {
+ "output" : {
+ "code" : [
+ "import ch.ivyteam.ivy.notification.business.BusinessNotification;",
+ "/*",
+ " Sends a new business notification",
+ " with the mutli-lingual message stored in CMS under path \"/Notification/Messages/OrderFinished\"",
+ " using placeholders in the message that are replaced by the given additional argument",
+ " to all users that were involved in the current case.",
+ " The format of the message is defined by the given template (see CMS \"/Notification/business/Templates/Order/web/Subject\") ",
+ " and payload object.",
+ "*/",
+ "BusinessNotification",
+ " .create()",
+ " .template(\"Order\")",
+ " .payload(in.customer)",
+ " .message().fromCms(\"/Notification/Messages/OrderFinished\", in.order.product)",
+ " .receivers().addCase().allInvolved()",
+ " .send();"
+ ]
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 1280, "y" : 600 }
+ },
+ "connect" : [
+ { "id" : "f30", "to" : "f1" }
+ ]
+ }, {
+ "id" : "f40",
+ "type" : "ProcessAnnotation",
+ "name" : [
+ "**Business Notification Demo**",
+ "",
+ "This demo shows you how you can send business notifications in your process.",
+ "Starts with the simplest way first, then shows how you can use process data in your messages, use multi-lingual messages, and finally how to use templates."
+ ],
+ "visual" : {
+ "at" : { "x" : 696, "y" : 92 },
+ "size" : { "width" : 416, "height" : 132 }
+ }
+ } ],
+ "layout" : {
+ "lanes" : [ {
+ "name" : "OrderProcess",
+ "size" : 688,
+ "lanes" : [ {
+ "name" : "Customer",
+ "size" : 192
+ }, {
+ "name" : "Processor",
+ "size" : 144
+ }, {
+ "name" : "Deliverer",
+ "size" : 160
+ }, {
+ "name" : "Finance",
+ "size" : 192
+ } ]
+ } ]
+ }
+}
\ No newline at end of file
diff --git a/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPayment.rddescriptor b/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPayment.rddescriptor
new file mode 100644
index 000000000..ae605f0d9
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPayment.rddescriptor
@@ -0,0 +1,7 @@
+
+
+
+ viewTechnology
+ JSF
+
+
diff --git a/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPayment.xhtml b/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPayment.xhtml
new file mode 100644
index 000000000..f841107b7
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPayment.xhtml
@@ -0,0 +1,30 @@
+
+
+
+ Book Payment
+
+
+ Please book the payment for the order #{data.order.product} of the following customer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPaymentData.ivyClass b/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPaymentData.ivyClass
new file mode 100644
index 000000000..c2f041dbc
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPaymentData.ivyClass
@@ -0,0 +1,6 @@
+BookPaymentData #class
+workflow.order.BookPayment #namespace
+customer workflow.order.Person #field
+customer PERSISTENT #fieldModifier
+order workflow.order.Order #field
+order PERSISTENT #fieldModifier
diff --git a/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPaymentProcess.p.json b/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPaymentProcess.p.json
new file mode 100644
index 000000000..c9e606aef
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/BookPayment/BookPaymentProcess.p.json
@@ -0,0 +1,58 @@
+{
+ "$schema" : "https://json-schema.axonivy.com/process/11.2.2/process.json",
+ "id" : "18DD091E562C6448",
+ "kind" : "HTML_DIALOG",
+ "config" : {
+ "data" : "workflow.order.BookPayment.BookPaymentData"
+ },
+ "elements" : [ {
+ "id" : "f0",
+ "type" : "HtmlDialogStart",
+ "name" : "start(Person,Order)",
+ "config" : {
+ "signature" : "start",
+ "input" : {
+ "params" : [
+ { "name" : "customer", "type" : "workflow.order.Person", "desc" : "" },
+ { "name" : "order", "type" : "workflow.order.Order", "desc" : "" }
+ ],
+ "map" : {
+ "out.customer" : "param.customer",
+ "out.order" : "param.order"
+ }
+ },
+ "guid" : "18DD091E56275DFB"
+ },
+ "visual" : {
+ "at" : { "x" : 96, "y" : 64 }
+ },
+ "connect" : [
+ { "id" : "f2", "to" : "f1" }
+ ]
+ }, {
+ "id" : "f1",
+ "type" : "HtmlDialogEnd",
+ "visual" : {
+ "at" : { "x" : 224, "y" : 64 }
+ }
+ }, {
+ "id" : "f3",
+ "type" : "HtmlDialogEventStart",
+ "name" : "close",
+ "config" : {
+ "guid" : "18DD091E563A2C01"
+ },
+ "visual" : {
+ "at" : { "x" : 96, "y" : 160 }
+ },
+ "connect" : [
+ { "id" : "f5", "to" : "f4" }
+ ]
+ }, {
+ "id" : "f4",
+ "type" : "HtmlDialogExit",
+ "visual" : {
+ "at" : { "x" : 224, "y" : 160 }
+ }
+ } ]
+}
\ No newline at end of file
diff --git a/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrder.rddescriptor b/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrder.rddescriptor
new file mode 100644
index 000000000..ae605f0d9
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrder.rddescriptor
@@ -0,0 +1,7 @@
+
+
+
+ viewTechnology
+ JSF
+
+
diff --git a/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrder.xhtml b/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrder.xhtml
new file mode 100644
index 000000000..37e9998e1
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrder.xhtml
@@ -0,0 +1,32 @@
+
+
+
+ Deliver Order
+
+
+ Please deliver the order #{data.order.product} to the following customer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrderData.ivyClass b/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrderData.ivyClass
new file mode 100644
index 000000000..2c6a8b73d
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrderData.ivyClass
@@ -0,0 +1,6 @@
+DeliverOrderData #class
+workflow.order.DeliverOrder #namespace
+customer workflow.order.Person #field
+customer PERSISTENT #fieldModifier
+order workflow.order.Order #field
+order PERSISTENT #fieldModifier
diff --git a/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrderProcess.p.json b/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrderProcess.p.json
new file mode 100644
index 000000000..940aaed42
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/DeliverOrder/DeliverOrderProcess.p.json
@@ -0,0 +1,58 @@
+{
+ "$schema" : "https://json-schema.axonivy.com/process/11.2.2/process.json",
+ "id" : "18DD09146F26D0B7",
+ "kind" : "HTML_DIALOG",
+ "config" : {
+ "data" : "workflow.order.DeliverOrder.DeliverOrderData"
+ },
+ "elements" : [ {
+ "id" : "f0",
+ "type" : "HtmlDialogStart",
+ "name" : "start(Person,Order)",
+ "config" : {
+ "signature" : "start",
+ "input" : {
+ "params" : [
+ { "name" : "customer", "type" : "workflow.order.Person", "desc" : "" },
+ { "name" : "order", "type" : "workflow.order.Order", "desc" : "" }
+ ],
+ "map" : {
+ "out.customer" : "param.customer",
+ "out.order" : "param.order"
+ }
+ },
+ "guid" : "18DD09146F290CF2"
+ },
+ "visual" : {
+ "at" : { "x" : 96, "y" : 64 }
+ },
+ "connect" : [
+ { "id" : "f2", "to" : "f1" }
+ ]
+ }, {
+ "id" : "f1",
+ "type" : "HtmlDialogEnd",
+ "visual" : {
+ "at" : { "x" : 224, "y" : 64 }
+ }
+ }, {
+ "id" : "f3",
+ "type" : "HtmlDialogEventStart",
+ "name" : "close",
+ "config" : {
+ "guid" : "18DD09146F392ECC"
+ },
+ "visual" : {
+ "at" : { "x" : 96, "y" : 160 }
+ },
+ "connect" : [
+ { "id" : "f5", "to" : "f4" }
+ ]
+ }, {
+ "id" : "f4",
+ "type" : "HtmlDialogExit",
+ "visual" : {
+ "at" : { "x" : 224, "y" : 160 }
+ }
+ } ]
+}
\ No newline at end of file
diff --git a/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrder.rddescriptor b/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrder.rddescriptor
new file mode 100644
index 000000000..ae605f0d9
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrder.rddescriptor
@@ -0,0 +1,7 @@
+
+
+
+ viewTechnology
+ JSF
+
+
diff --git a/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrder.xhtml b/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrder.xhtml
new file mode 100644
index 000000000..b479fead2
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrder.xhtml
@@ -0,0 +1,38 @@
+
+
+
+ Input Order
+
+
+ Please input your name, surname and the product you want to order
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrderData.ivyClass b/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrderData.ivyClass
new file mode 100644
index 000000000..375ebafd3
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrderData.ivyClass
@@ -0,0 +1,6 @@
+InputOrderData #class
+workflow.order.InputOrder #namespace
+customer workflow.order.Person #field
+customer PERSISTENT #fieldModifier
+order workflow.order.Order #field
+order PERSISTENT #fieldModifier
diff --git a/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrderProcess.p.json b/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrderProcess.p.json
new file mode 100644
index 000000000..8dbd4775f
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/InputOrder/InputOrderProcess.p.json
@@ -0,0 +1,58 @@
+{
+ "$schema" : "https://json-schema.axonivy.com/process/11.2.2/process.json",
+ "id" : "18DD08E2F9139D91",
+ "kind" : "HTML_DIALOG",
+ "config" : {
+ "data" : "workflow.order.InputOrder.InputOrderData"
+ },
+ "elements" : [ {
+ "id" : "f0",
+ "type" : "HtmlDialogStart",
+ "name" : "start()",
+ "config" : {
+ "signature" : "start",
+ "result" : {
+ "params" : [
+ { "name" : "customer", "type" : "workflow.order.Person", "desc" : "" },
+ { "name" : "order", "type" : "workflow.order.Order", "desc" : "" }
+ ],
+ "map" : {
+ "result.customer" : "in.customer",
+ "result.order" : "in.order"
+ }
+ },
+ "guid" : "18DD08E2F9365903"
+ },
+ "visual" : {
+ "at" : { "x" : 96, "y" : 64 }
+ },
+ "connect" : [
+ { "id" : "f2", "to" : "f1" }
+ ]
+ }, {
+ "id" : "f1",
+ "type" : "HtmlDialogEnd",
+ "visual" : {
+ "at" : { "x" : 224, "y" : 64 }
+ }
+ }, {
+ "id" : "f3",
+ "type" : "HtmlDialogEventStart",
+ "name" : "close",
+ "config" : {
+ "guid" : "18DD08E2F9812505"
+ },
+ "visual" : {
+ "at" : { "x" : 96, "y" : 160 }
+ },
+ "connect" : [
+ { "id" : "f5", "to" : "f4" }
+ ]
+ }, {
+ "id" : "f4",
+ "type" : "HtmlDialogExit",
+ "visual" : {
+ "at" : { "x" : 224, "y" : 160 }
+ }
+ } ]
+}
\ No newline at end of file
diff --git a/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrder.rddescriptor b/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrder.rddescriptor
new file mode 100644
index 000000000..ae605f0d9
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrder.rddescriptor
@@ -0,0 +1,7 @@
+
+
+
+ viewTechnology
+ JSF
+
+
diff --git a/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrder.xhtml b/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrder.xhtml
new file mode 100644
index 000000000..44ea43811
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrder.xhtml
@@ -0,0 +1,31 @@
+
+
+
+ Process Order
+
+
+ Please process the following order for the customer #{data.customer.surname} #{data.customer.name}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrderData.ivyClass b/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrderData.ivyClass
new file mode 100644
index 000000000..ae16c971d
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrderData.ivyClass
@@ -0,0 +1,6 @@
+ProcessOrderData #class
+workflow.order.ProcessOrder #namespace
+customer workflow.order.Person #field
+customer PERSISTENT #fieldModifier
+order workflow.order.Order #field
+order PERSISTENT #fieldModifier
diff --git a/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrderProcess.p.json b/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrderProcess.p.json
new file mode 100644
index 000000000..a75cfdad4
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/ProcessOrder/ProcessOrderProcess.p.json
@@ -0,0 +1,58 @@
+{
+ "$schema" : "https://json-schema.axonivy.com/process/11.2.2/process.json",
+ "id" : "18DD090F513A0977",
+ "kind" : "HTML_DIALOG",
+ "config" : {
+ "data" : "workflow.order.ProcessOrder.ProcessOrderData"
+ },
+ "elements" : [ {
+ "id" : "f0",
+ "type" : "HtmlDialogStart",
+ "name" : "start(Person,Order)",
+ "config" : {
+ "signature" : "start",
+ "input" : {
+ "params" : [
+ { "name" : "customer", "type" : "workflow.order.Person", "desc" : "" },
+ { "name" : "order", "type" : "workflow.order.Order", "desc" : "" }
+ ],
+ "map" : {
+ "out.customer" : "param.customer",
+ "out.order" : "param.order"
+ }
+ },
+ "guid" : "18DD090F514F2CE6"
+ },
+ "visual" : {
+ "at" : { "x" : 96, "y" : 64 }
+ },
+ "connect" : [
+ { "id" : "f2", "to" : "f1" }
+ ]
+ }, {
+ "id" : "f1",
+ "type" : "HtmlDialogEnd",
+ "visual" : {
+ "at" : { "x" : 224, "y" : 64 }
+ }
+ }, {
+ "id" : "f3",
+ "type" : "HtmlDialogEventStart",
+ "name" : "close",
+ "config" : {
+ "guid" : "18DD090F5154A11F"
+ },
+ "visual" : {
+ "at" : { "x" : 96, "y" : 160 }
+ },
+ "connect" : [
+ { "id" : "f5", "to" : "f4" }
+ ]
+ }, {
+ "id" : "f4",
+ "type" : "HtmlDialogExit",
+ "visual" : {
+ "at" : { "x" : 224, "y" : 160 }
+ }
+ } ]
+}
\ No newline at end of file
diff --git a/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoice.rddescriptor b/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoice.rddescriptor
new file mode 100644
index 000000000..ae605f0d9
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoice.rddescriptor
@@ -0,0 +1,7 @@
+
+
+
+ viewTechnology
+ JSF
+
+
diff --git a/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoice.xhtml b/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoice.xhtml
new file mode 100644
index 000000000..a647fe6c3
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoice.xhtml
@@ -0,0 +1,30 @@
+
+
+
+ Send Invoice
+
+
+ Please send an invoice for the order #{data.order.product} to the following customer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoiceData.ivyClass b/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoiceData.ivyClass
new file mode 100644
index 000000000..6f98516ae
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoiceData.ivyClass
@@ -0,0 +1,6 @@
+SendInvoiceData #class
+workflow.order.SendInvoice #namespace
+customer workflow.order.Person #field
+customer PERSISTENT #fieldModifier
+order workflow.order.Order #field
+order PERSISTENT #fieldModifier
diff --git a/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoiceProcess.p.json b/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoiceProcess.p.json
new file mode 100644
index 000000000..94730e124
--- /dev/null
+++ b/workflow/workflow-demos/src_hd/workflow/order/SendInvoice/SendInvoiceProcess.p.json
@@ -0,0 +1,58 @@
+{
+ "$schema" : "https://json-schema.axonivy.com/process/11.2.2/process.json",
+ "id" : "18DD091A87AABF1F",
+ "kind" : "HTML_DIALOG",
+ "config" : {
+ "data" : "workflow.order.SendInvoice.SendInvoiceData"
+ },
+ "elements" : [ {
+ "id" : "f0",
+ "type" : "HtmlDialogStart",
+ "name" : "start(Person,Order)",
+ "config" : {
+ "signature" : "start",
+ "input" : {
+ "params" : [
+ { "name" : "customer", "type" : "workflow.order.Person", "desc" : "" },
+ { "name" : "order", "type" : "workflow.order.Order", "desc" : "" }
+ ],
+ "map" : {
+ "out.customer" : "param.customer",
+ "out.order" : "param.order"
+ }
+ },
+ "guid" : "18DD091A87B2BC8D"
+ },
+ "visual" : {
+ "at" : { "x" : 96, "y" : 64 }
+ },
+ "connect" : [
+ { "id" : "f2", "to" : "f1" }
+ ]
+ }, {
+ "id" : "f1",
+ "type" : "HtmlDialogEnd",
+ "visual" : {
+ "at" : { "x" : 224, "y" : 64 }
+ }
+ }, {
+ "id" : "f3",
+ "type" : "HtmlDialogEventStart",
+ "name" : "close",
+ "config" : {
+ "guid" : "18DD091A87BD09E3"
+ },
+ "visual" : {
+ "at" : { "x" : 96, "y" : 160 }
+ },
+ "connect" : [
+ { "id" : "f5", "to" : "f4" }
+ ]
+ }, {
+ "id" : "f4",
+ "type" : "HtmlDialogExit",
+ "visual" : {
+ "at" : { "x" : 224, "y" : 160 }
+ }
+ } ]
+}
\ No newline at end of file