├── .gitignore ├── AUTHORS ├── LICENSE.md ├── MoquiConf.xml ├── README.md ├── build.gradle ├── component.xml ├── data ├── BasicData.xml ├── ComponentEmailData.xml ├── ComponentMessageDataEn.xml ├── ComponentSecurityData.xml ├── ComponentServiceJobData.xml ├── EntityData.xml ├── SecurityData.xml ├── WorkflowData.xml └── WorkflowDemoData.xml ├── entity ├── EntityEntities.xml ├── EntityViewEntities.xml ├── WorkflowEntities.xml └── WorkflowViewEntities.xml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── myaddons.xml ├── screen ├── Workflow.xml └── Workflow │ ├── WorkflowInstance.xml │ └── WorkflowInstance │ ├── EditWorkflowInstance.xml │ ├── FindWorkflowInstance.xml │ ├── FindWorkflowInstanceEvent.xml │ └── FindWorkflowInstanceVariable.xml ├── service ├── org │ └── moqui │ │ ├── basic │ │ └── BasicServices.xml │ │ ├── entity │ │ └── EntityFieldServices.xml │ │ ├── security │ │ └── SecurityServices.xml │ │ └── workflow │ │ └── WorkflowServices.xml ├── workflow.rest.xml └── workflow.secas.xml ├── settings.gradle └── src └── main └── java └── org └── moqui ├── basic ├── StatusFlowService.java └── StatusItemService.java ├── entity ├── EntityFieldService.java └── util │ ├── EntityConditionBuilder.java │ └── EntityFieldType.java ├── security ├── UserGroupService.java └── UserService.java ├── util ├── BooleanComparisonOperator.java ├── ContextUtil.java ├── DateComparisonOperator.java ├── EntityFieldType.java ├── JsonUtil.java ├── NumberComparisonOperator.java ├── ServerUtil.java ├── StringUtil.java ├── TextComparisonOperator.java ├── TimeFrequency.java └── TimestampUtil.java └── workflow ├── WorkflowService.java ├── WorkflowTypeService.java ├── activity ├── AbstractWorkflowActivity.java ├── WorkflowActivity.java ├── WorkflowAdjustmentActivity.java ├── WorkflowConditionActivity.java ├── WorkflowEnterActivity.java ├── WorkflowExitActivity.java ├── WorkflowNotificationActivity.java ├── WorkflowServiceActivity.java └── WorkflowUserActivity.java ├── condition ├── BooleanCondition.java ├── DateCondition.java ├── NumberCondition.java ├── ScriptCondition.java ├── TextCondition.java └── WorkflowCondition.java └── util ├── WorkflowActivityType.java ├── WorkflowAdjustmentType.java ├── WorkflowConditionType.java ├── WorkflowCrowdType.java ├── WorkflowEventType.java ├── WorkflowInstanceStatus.java ├── WorkflowLaunchType.java ├── WorkflowNotificationType.java ├── WorkflowPortType.java ├── WorkflowTaskStatus.java ├── WorkflowTaskType.java ├── WorkflowUtil.java └── WorkflowVariableType.java /.gitignore: -------------------------------------------------------------------------------- 1 | # gradle/build files 2 | build/ 3 | .gradle 4 | 5 | # runtime added files 6 | lib/ 7 | 8 | # IntelliJ IDEA files 9 | .idea/ 10 | out/ 11 | *.ipr 12 | *.iws 13 | *.iml 14 | 15 | # Eclipse files (and some general ones also used by Eclipse) 16 | .metadata 17 | .gradle 18 | bin/ 19 | tmp/ 20 | *.tmp 21 | *.bak 22 | *.swp 23 | *~.nib 24 | local.properties 25 | .settings/ 26 | .loadpath 27 | 28 | # NetBeans files 29 | nbproject/private/ 30 | nbbuild/ 31 | .nb-gradle/ 32 | # allow dist, some JS libs in webroot/assets use it: dist/ 33 | nbdist/ 34 | nbactions.xml 35 | nb-configuration.xml 36 | 37 | # OSX auto files 38 | .DS_Store 39 | .AppleDouble 40 | .LSOverride 41 | ._* 42 | 43 | # Windows auto files 44 | Thumbs.db 45 | ehthumbs.db 46 | Desktop.ini 47 | 48 | # Linux auto files 49 | *~ 50 | 51 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Moqui Workflow Engine (https://github.com/Netvariant/moqui-workflow) 2 | 3 | This software is in the public domain under CC0 1.0 Universal plus a 4 | Grant of Patent License. 5 | 6 | To the extent possible under law, the author(s) have dedicated all 7 | copyright and related and neighboring rights to this software to the 8 | public domain worldwide. This software is distributed without any 9 | warranty. 10 | 11 | You should have received a copy of the CC0 Public Domain Dedication 12 | along with this software (see the LICENSE.md file). If not, see 13 | . 14 | 15 | =========================================================================== 16 | 17 | Copyright Waiver 18 | 19 | I dedicate any and all copyright interest in this software to the 20 | public domain. I make this dedication for the benefit of the public at 21 | large and to the detriment of my heirs and successors. I intend this 22 | dedication to be an overt act of relinquishment in perpetuity of all 23 | present and future rights to this software under copyright law. 24 | 25 | To the best of my knowledge and belief, my contributions are either 26 | originally authored by me or are derived from prior works which I have 27 | verified are also in the public domain and are not subject to claims 28 | of copyright by other parties. 29 | 30 | To the best of my knowledge and belief, no individual, business, 31 | organization, government, or other entity has any copyright interest 32 | in my contributions, and I affirm that I will not make contributions 33 | that are otherwise encumbered. 34 | 35 | Signed by git commit adding my legal name and git username: 36 | 37 | Written in 2019 by Ayman Abi Abdallah - aabiabdallah 38 | 39 | =========================================================================== 40 | 41 | Grant of Patent License 42 | 43 | I hereby grant to recipients of software a perpetual, worldwide, 44 | non-exclusive, no-charge, royalty-free, irrevocable (except as stated in 45 | this section) patent license to make, have made, use, offer to sell, sell, 46 | import, and otherwise transfer the Work, where such license applies only to 47 | those patent claims licensable by me that are necessarily infringed by my 48 | Contribution(s) alone or by combination of my Contribution(s) with the 49 | Work to which such Contribution(s) was submitted. If any entity institutes 50 | patent litigation against me or any other entity (including a cross-claim 51 | or counterclaim in a lawsuit) alleging that my Contribution, or the Work to 52 | which I have contributed, constitutes direct or contributory patent 53 | infringement, then any patent licenses granted to that entity under this 54 | Agreement for that Contribution or Work shall terminate as of the date such 55 | litigation is filed. 56 | 57 | Signed by git commit adding my legal name and git username: 58 | 59 | Written in 2019 by Ayman Abi Abdallah - aabiabdallah 60 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Because of a lack of patent licensing in CC0 1.0 this software includes a 2 | separate Grant of Patent License adapted from Apache License 2.0. 3 | 4 | =========================================================================== 5 | 6 | Creative Commons Legal Code 7 | 8 | CC0 1.0 Universal 9 | 10 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 11 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 12 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 13 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 14 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 15 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 16 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 17 | HEREUNDER. 18 | 19 | Statement of Purpose 20 | 21 | The laws of most jurisdictions throughout the world automatically confer 22 | exclusive Copyright and Related Rights (defined below) upon the creator 23 | and subsequent owner(s) (each and all, an "owner") of an original work of 24 | authorship and/or a database (each, a "Work"). 25 | 26 | Certain owners wish to permanently relinquish those rights to a Work for 27 | the purpose of contributing to a commons of creative, cultural and 28 | scientific works ("Commons") that the public can reliably and without fear 29 | of later claims of infringement build upon, modify, incorporate in other 30 | works, reuse and redistribute as freely as possible in any form whatsoever 31 | and for any purposes, including without limitation commercial purposes. 32 | These owners may contribute to the Commons to promote the ideal of a free 33 | culture and the further production of creative, cultural and scientific 34 | works, or to gain reputation or greater distribution for their Work in 35 | part through the use and efforts of others. 36 | 37 | For these and/or other purposes and motivations, and without any 38 | expectation of additional consideration or compensation, the person 39 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 40 | is an owner of Copyright and Related Rights in the Work, voluntarily 41 | elects to apply CC0 to the Work and publicly distribute the Work under its 42 | terms, with knowledge of his or her Copyright and Related Rights in the 43 | Work and the meaning and intended legal effect of CC0 on those rights. 44 | 45 | 1. Copyright and Related Rights. A Work made available under CC0 may be 46 | protected by copyright and related or neighboring rights ("Copyright and 47 | Related Rights"). Copyright and Related Rights include, but are not 48 | limited to, the following: 49 | 50 | i. the right to reproduce, adapt, distribute, perform, display, 51 | communicate, and translate a Work; 52 | ii. moral rights retained by the original author(s) and/or performer(s); 53 | iii. publicity and privacy rights pertaining to a person's image or 54 | likeness depicted in a Work; 55 | iv. rights protecting against unfair competition in regards to a Work, 56 | subject to the limitations in paragraph 4(a), below; 57 | v. rights protecting the extraction, dissemination, use and reuse of data 58 | in a Work; 59 | vi. database rights (such as those arising under Directive 96/9/EC of the 60 | European Parliament and of the Council of 11 March 1996 on the legal 61 | protection of databases, and under any national implementation 62 | thereof, including any amended or successor version of such 63 | directive); and 64 | vii. other similar, equivalent or corresponding rights throughout the 65 | world based on applicable law or treaty, and any national 66 | implementations thereof. 67 | 68 | 2. Waiver. To the greatest extent permitted by, but not in contravention 69 | of, applicable law, Affirmer hereby overtly, fully, permanently, 70 | irrevocably and unconditionally waives, abandons, and surrenders all of 71 | Affirmer's Copyright and Related Rights and associated claims and causes 72 | of action, whether now known or unknown (including existing as well as 73 | future claims and causes of action), in the Work (i) in all territories 74 | worldwide, (ii) for the maximum duration provided by applicable law or 75 | treaty (including future time extensions), (iii) in any current or future 76 | medium and for any number of copies, and (iv) for any purpose whatsoever, 77 | including without limitation commercial, advertising or promotional 78 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 79 | member of the public at large and to the detriment of Affirmer's heirs and 80 | successors, fully intending that such Waiver shall not be subject to 81 | revocation, rescission, cancellation, termination, or any other legal or 82 | equitable action to disrupt the quiet enjoyment of the Work by the public 83 | as contemplated by Affirmer's express Statement of Purpose. 84 | 85 | 3. Public License Fallback. Should any part of the Waiver for any reason 86 | be judged legally invalid or ineffective under applicable law, then the 87 | Waiver shall be preserved to the maximum extent permitted taking into 88 | account Affirmer's express Statement of Purpose. In addition, to the 89 | extent the Waiver is so judged Affirmer hereby grants to each affected 90 | person a royalty-free, non transferable, non sublicensable, non exclusive, 91 | irrevocable and unconditional license to exercise Affirmer's Copyright and 92 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 93 | maximum duration provided by applicable law or treaty (including future 94 | time extensions), (iii) in any current or future medium and for any number 95 | of copies, and (iv) for any purpose whatsoever, including without 96 | limitation commercial, advertising or promotional purposes (the 97 | "License"). The License shall be deemed effective as of the date CC0 was 98 | applied by Affirmer to the Work. Should any part of the License for any 99 | reason be judged legally invalid or ineffective under applicable law, such 100 | partial invalidity or ineffectiveness shall not invalidate the remainder 101 | of the License, and in such case Affirmer hereby affirms that he or she 102 | will not (i) exercise any of his or her remaining Copyright and Related 103 | Rights in the Work or (ii) assert any associated claims and causes of 104 | action with respect to the Work, in either case contrary to Affirmer's 105 | express Statement of Purpose. 106 | 107 | 4. Limitations and Disclaimers. 108 | 109 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 110 | surrendered, licensed or otherwise affected by this document. 111 | b. Affirmer offers the Work as-is and makes no representations or 112 | warranties of any kind concerning the Work, express, implied, 113 | statutory or otherwise, including without limitation warranties of 114 | title, merchantability, fitness for a particular purpose, non 115 | infringement, or the absence of latent or other defects, accuracy, or 116 | the present or absence of errors, whether or not discoverable, all to 117 | the greatest extent permissible under applicable law. 118 | c. Affirmer disclaims responsibility for clearing rights of other persons 119 | that may apply to the Work or any use thereof, including without 120 | limitation any person's Copyright and Related Rights in the Work. 121 | Further, Affirmer disclaims responsibility for obtaining any necessary 122 | consents, permissions or other rights required for any use of the 123 | Work. 124 | d. Affirmer understands and acknowledges that Creative Commons is not a 125 | party to this document and has no duty or obligation with respect to 126 | this CC0 or use of the Work. 127 | 128 | 129 | =========================================================================== 130 | 131 | Grant of Patent License 132 | 133 | "License" shall mean the terms and conditions for use, reproduction, and 134 | distribution. 135 | 136 | "Licensor" shall mean the original copyright owner or entity authorized by 137 | the original copyright owner that is granting the License. 138 | 139 | "Legal Entity" shall mean the union of the acting entity and all other 140 | entities that control, are controlled by, or are under common control with 141 | that entity. For the purposes of this definition, "control" means (i) the 142 | power, direct or indirect, to cause the direction or management of such 143 | entity, whether by contract or otherwise, or (ii) ownership of fifty 144 | percent (50%) or more of the outstanding shares, or (iii) beneficial 145 | ownership of such entity. 146 | 147 | "You" (or "Your") shall mean an individual or Legal Entity exercising 148 | permissions granted by this License. 149 | 150 | "Source" form shall mean the preferred form for making modifications, 151 | including but not limited to software source code, documentation source, 152 | and configuration files. 153 | 154 | "Object" form shall mean any form resulting from mechanical transformation 155 | or translation of a Source form, including but not limited to compiled 156 | object code, generated documentation, and conversions to other media types. 157 | 158 | "Work" shall mean the work of authorship, whether in Source or Object form, 159 | made available under the License, as indicated by a copyright notice that 160 | is included in or attached to the work. 161 | 162 | "Derivative Works" shall mean any work, whether in Source or Object form, 163 | that is based on (or derived from) the Work and for which the editorial 164 | revisions, annotations, elaborations, or other modifications represent, as 165 | a whole, an original work of authorship. For the purposes of this License, 166 | Derivative Works shall not include works that remain separable from, or 167 | merely link (or bind by name) to the interfaces of, the Work and 168 | Derivative Works thereof. 169 | 170 | "Contribution" shall mean any work of authorship, including the original 171 | version of the Work and any modifications or additions to that Work or 172 | Derivative Works thereof, that is intentionally submitted to Licensor for 173 | inclusion in the Work by the copyright owner or by an individual or Legal 174 | Entity authorized to submit on behalf of the copyright owner. For the 175 | purposes of this definition, "submitted" means any form of electronic, 176 | verbal, or written communication sent to the Licensor or its 177 | representatives, including but not limited to communication on electronic 178 | mailing lists, source code control systems, and issue tracking systems that 179 | are managed by, or on behalf of, the Licensor for the purpose of discussing 180 | and improving the Work, but excluding communication that is conspicuously 181 | marked or otherwise designated in writing by the copyright owner as "Not a 182 | Contribution." 183 | 184 | "Contributor" shall mean Licensor and any individual or Legal Entity on 185 | behalf of whom a Contribution has been received by Licensor and 186 | subsequently incorporated within the Work. 187 | 188 | Each Contributor hereby grants to You a perpetual, worldwide, 189 | non-exclusive, no-charge, royalty-free, irrevocable (except as stated in 190 | this section) patent license to make, have made, use, offer to sell, sell, 191 | import, and otherwise transfer the Work, where such license applies only to 192 | those patent claims licensable by such Contributor that are necessarily 193 | infringed by their Contribution(s) alone or by combination of their 194 | Contribution(s) with the Work to which such Contribution(s) was submitted. 195 | If You institute patent litigation against any entity (including a 196 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 197 | Contribution incorporated within the Work constitutes direct or 198 | contributory patent infringement, then any patent licenses granted to You 199 | under this License for that Work shall terminate as of the date such 200 | litigation is filed. 201 | -------------------------------------------------------------------------------- /MoquiConf.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Moqui Workflow Component 2 | 3 | Extendable workflow engine for the [Moqui Framework](https://www.moqui.org). 4 | 5 | ## Table of Contents 6 | 7 | - [Concepts](#concepts) 8 | - [Installation](#installation) 9 | - [Configuration](#configuration) 10 | - [Artifact Groups](#artifact-groups) 11 | - [Authors](#authors) 12 | - [License](#license) 13 | 14 | ## Concepts 15 | 16 | A `Workflow` is a set of activities involved in moving from the beginning to the end of a work process. 17 | Each workflow is linked to a single entity by means of a `WorkflowType`. 18 | When the workflow engine is triggered for a specific entity value it creates a new `WorkflowInstance`. 19 | 20 | ## Installation 21 | 22 | You will be carrying out these steps to install the workflow engine. 23 | 24 | * Download the Moqui Framework (optional) 25 | * Download the [myaddons.xml](myaddons.xml) file 26 | * Download the workflow component 27 | 28 | ### Download the Moqui Framework 29 | 30 | In case you don't have the Moqui Framework yet then you can can download it using this command: 31 | 32 | ```shell 33 | $ git clone https://github.com/moqui/moqui-framework.git 34 | ``` 35 | 36 | ### Download the myaddons.xml file 37 | 38 | Using **wget**: 39 | 40 | ```shell 41 | $ cd moqui-framework 42 | $ wget https://raw.githubusercontent.com/netvariant/moqui-workflow/master/myaddons.xml 43 | ``` 44 | 45 | Using **curl**: 46 | 47 | ```shell 48 | $ cd moqui-framework 49 | $ curl -O https://raw.githubusercontent.com/netvariant/moqui-workflow/master/myaddons.xml 50 | ``` 51 | 52 | If neither command is available then download [myaddons.xml](myaddons.xml) file manually and copy it to the Moqui Framework root directory. 53 | 54 | ### Download the workflow component 55 | 56 | You're all set to download the workflow component, just run this command and you're done! 57 | 58 | ```shell 59 | $ ./gradlew getComponent -Pcomponent=moqui-workflow 60 | ``` 61 | 62 | ## Configuration 63 | 64 | Configuring the workflow engine involves these tasks. 65 | 66 | * Define workflow types 67 | * Expose entity fields 68 | * Design a workflow 69 | * Trigger workflow engine 70 | 71 | ### Define workflow types 72 | 73 | Workflow types are stores in the `moqui.workflow.WorkflowType` entity and must be defined before the workflow engine is used. 74 | You can define a new workflow type in your component seed data as follows: 75 | 76 | ```xml 77 | 78 | ``` 79 | 80 | A brief explanation of the workflow type fields can be found in the table below: 81 | 82 | | Field Name | Description | 83 | | :--- | :--- | 84 | | typeId | Type primary key | 85 | | typeName | User friendly type name | 86 | | statusTypeId | Allowed statuses for this type of workflow | 87 | | primaryEntityName | Entity used by the workflow engine for write operations | 88 | | primaryViewEntityName | View entity used by the workflow engine for read operations | 89 | | primaryKeyField | Entity primary key field name | 90 | 91 | ### Expose entity fields 92 | 93 | You may not wish to expose all entity fields in the workflow designer. You can control this using the `moqui.entity.EntityField` entity. 94 | You can define a new workflow type in your component seed data as follows: 95 | 96 | ```xml 97 | 98 | ``` 99 | 100 | ### Design a workflow 101 | 102 | You can design workflows using the standalone [Workflow Designer](https://github.com/Netvariant/workflow-designer). 103 | 104 | ### Trigger workflow engine 105 | 106 | You can start/stop workflow instances using Moqui services. The workflow engine comes with the following services: 107 | 108 | | Service Name | Description | 109 | | :--- | :--- | 110 | | moqui.workflow.WorkflowServices.create#WorkflowInstance | Creates a new workflow instance | 111 | | moqui.workflow.WorkflowServices.start#WorkflowInstance | Starts an existing workflow instance | 112 | | moqui.workflow.WorkflowServices.suspend#WorkflowInstance | Suspends an existing workflow instance | 113 | | moqui.workflow.WorkflowServices.resume#WorkflowInstance | Resumed a suspended workflow instance | 114 | | moqui.workflow.WorkflowServices.abort#WorkflowInstance | Aborts an active workflow instance | 115 | 116 | In a real life scenario you calling the above services using SECA/EECA rules. 117 | 118 | ## Artifact Groups 119 | 120 | Loading the `moqui-workflow` component seed data will automatically create two artifact groups. Add them to your user groups to grant members access. 121 | 122 | | Group Name | Description | 123 | | :--- | :--- | 124 | | Workflow App | Allows access to the workflow application within Moqui | 125 | | Moqui Workflow REST API | Allows access to the workflow REST APIs, this is required by the workflow designer | 126 | 127 | ## Authors 128 | 129 | This project was build with :heart: by the good fellas at [Netvariant](https://www.netvariant.com). 130 | 131 | ## License 132 | 133 | [![license](http://img.shields.io/badge/license-CC0%201.0%20Universal-blue.svg)](https://github.com/Netvariant/moqui-workflow/blob/master/LICENSE.md) 134 | 135 | This project is licensed under the CC0 License - see the [LICENSE.md](LICENSE.md) file for details. -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'groovy' 4 | } 5 | 6 | group 'org.moqui.workflow' 7 | version '1.0.0' 8 | description 'Moqui Workflow' 9 | 10 | sourceCompatibility = 1.8 11 | targetCompatibility = 1.8 12 | 13 | def jarBaseName = 'moqui-workflow' 14 | def moquiDir = projectDir.parentFile.parentFile.parentFile 15 | def frameworkDir = file(moquiDir.absolutePath + '/framework') 16 | def libDir = projectDir.absolutePath + '/lib' 17 | 18 | repositories { 19 | flatDir name: 'frameworkLib', dirs: frameworkDir.absolutePath + '/lib' 20 | flatDir name: 'projectLib', dirs: projectDir.absolutePath + '/lib' 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | compile( 26 | project(':framework'), 27 | project(':runtime:component:moqui-elasticsearch'), 28 | // Apache Commons 29 | 'org.apache.commons:commons-lang3:3.8', 30 | // JSON 31 | 'org.json:json:20180813' 32 | ) 33 | testCompile( 34 | project(':framework').configurations.testCompile.allDependencies 35 | ) 36 | } 37 | 38 | // Log4j has annotation processors, disable to avoid warning 39 | tasks.withType(JavaCompile) { options.compilerArgs << "-proc:none" } 40 | tasks.withType(GroovyCompile) { options.compilerArgs << "-proc:none" } 41 | 42 | // by default the Java plugin runs test on build, change to not do that (only run test if explicit task) 43 | check.dependsOn.clear() 44 | 45 | task cleanLib(type: Delete) { 46 | delete fileTree(dir: libDir, include: '*') 47 | } 48 | clean.dependsOn cleanLib 49 | 50 | task copyDependencies { 51 | doLast { 52 | copy { 53 | from (configurations.runtime 54 | - project(':framework').configurations.runtime 55 | - project(':runtime:component:moqui-elasticsearch').configurations.runtime 56 | - project(':runtime:component:moqui-workflow').jar.archivePath 57 | ) 58 | into file(libDir) 59 | } 60 | } 61 | } 62 | copyDependencies.dependsOn cleanLib 63 | 64 | test { 65 | dependsOn cleanTest 66 | include '**/MoquiWorkflowSuite.class' 67 | 68 | systemProperty 'moqui.runtime', moquiDir.absolutePath + '/runtime' 69 | systemProperty 'moqui.conf', 'conf/MoquiDevConf.xml' 70 | systemProperty 'moqui.init.static', 'true' 71 | 72 | // show standard out and standard error of the test JVM(s) on the console 73 | testLogging.showStandardStreams = true 74 | testLogging.showExceptions = true 75 | 76 | classpath += files(sourceSets.main.output.classesDirs) 77 | // filter out classpath entries that don't exist (gradle adds a bunch of these), or ElasticSearch JarHell will blow up 78 | classpath = classpath.filter { it.exists() } 79 | 80 | beforeTest { descriptor -> logger.lifecycle("Running test: ${descriptor}") } 81 | } 82 | 83 | jar { 84 | destinationDir = file(libDir) 85 | baseName = jarBaseName 86 | } 87 | jar.dependsOn copyDependencies -------------------------------------------------------------------------------- /component.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/BasicData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /data/ComponentEmailData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /data/ComponentMessageDataEn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /data/ComponentSecurityData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /data/ComponentServiceJobData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /data/EntityData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/SecurityData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /data/WorkflowDemoData.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /entity/EntityEntities.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | While we can use the EntityFacade to access ALL entity fields, this entity provides a convenient way to access entity fields we wish to expose to the application users. This is particularly useful in search and condition fields. 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /entity/EntityViewEntities.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netvariant/moqui-workflow/2ed01d6ded71d6bb25c49621cd973b7c447ef967/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-bin.zip 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /myaddons.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /screen/Workflow.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /screen/Workflow/WorkflowInstance.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /screen/Workflow/WorkflowInstance/EditWorkflowInstance.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 | 37 | 38 | 39 |
40 | 41 | 42 | 43 |
44 |
45 | 46 | 47 | 48 | 49 | 50 |
51 |
52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 |
129 |
130 | 131 | 132 | 134 | 135 |
136 |
137 |
-------------------------------------------------------------------------------- /screen/Workflow/WorkflowInstance/FindWorkflowInstance.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /screen/Workflow/WorkflowInstance/FindWorkflowInstanceEvent.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /screen/Workflow/WorkflowInstance/FindWorkflowInstanceVariable.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /service/org/moqui/basic/BasicServices.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /service/org/moqui/entity/EntityFieldServices.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /service/org/moqui/security/SecurityServices.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /service/org/moqui/workflow/WorkflowServices.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | -------------------------------------------------------------------------------- /service/workflow.rest.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /service/workflow.secas.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This settings file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * In a single project build this file can be empty or even removed. 6 | * 7 | * Detailed information about configuring a multi-project build in Gradle can be found 8 | * in the user guide at https://docs.gradle.org/4.3.1/userguide/multi_project_builds.html 9 | */ 10 | 11 | rootProject.name = 'moqui-workflow' 12 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/basic/StatusItemService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.basic; 15 | 16 | import org.apache.commons.lang3.time.StopWatch; 17 | import org.moqui.context.ExecutionContext; 18 | import org.moqui.context.MessageFacade; 19 | import org.moqui.context.UserFacade; 20 | import org.moqui.entity.*; 21 | import org.moqui.service.ServiceFacade; 22 | import org.moqui.util.ContextStack; 23 | import org.moqui.util.ContextUtil; 24 | import org.moqui.util.StringUtil; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | import java.util.*; 29 | 30 | /** 31 | * Service to retrieve status items. 32 | */ 33 | @SuppressWarnings("unused") 34 | public class StatusItemService { 35 | 36 | /** 37 | * Class logger. 38 | */ 39 | private final Logger logger = LoggerFactory.getLogger(getClass()); 40 | 41 | /** 42 | * Finds status items. 43 | * 44 | * @param ec Execution context 45 | * @return Output parameter map 46 | */ 47 | public Map findStatusItems(ExecutionContext ec) { 48 | 49 | // start the stop watch 50 | StopWatch stopWatch = new StopWatch(); 51 | stopWatch.start(); 52 | 53 | // shortcuts for convenience 54 | ContextStack cs = ec.getContext(); 55 | MessageFacade mf = ec.getMessage(); 56 | EntityFacade ef = ec.getEntity(); 57 | ServiceFacade sf = ec.getService(); 58 | UserFacade uf = ec.getUser(); 59 | 60 | // get the parameters 61 | int pageIndex = (Integer) cs.getOrDefault("pageIndex", 0); 62 | int pageSize = (Integer) cs.getOrDefault("pageSize", 10); 63 | String orderByField = (String) cs.getOrDefault("orderByField", "statusId"); 64 | String filter = (String) cs.getOrDefault("filter", null); 65 | 66 | // generate a new log ID 67 | String logId = ContextUtil.getLogId(ec); 68 | logger.debug(String.format("[%s] Finding status items ...", logId)); 69 | logger.debug(String.format("[%s] Param pageIndex=%s", logId, pageIndex)); 70 | logger.debug(String.format("[%s] Param pageSize=%s", logId, pageSize)); 71 | logger.debug(String.format("[%s] Param orderByField=%s", logId, orderByField)); 72 | logger.debug(String.format("[%s] Param filter=%s", logId, filter)); 73 | 74 | // prepare the conditions 75 | EntityConditionFactory ecf = ef.getConditionFactory(); 76 | EntityCondition findCondition = ecf.getTrueCondition(); 77 | 78 | // add the filter 79 | if(StringUtil.isValidElasticsearchQuery(filter)) { 80 | Map resp = sf.sync().name("org.moqui.search.SearchServices.search#DataDocuments") 81 | .parameter("indexName", "workflow") 82 | .parameter("documentType", "MoquiStatusItem") 83 | .parameter("queryString", filter) 84 | .call(); 85 | 86 | Set idSet = new HashSet<>(); 87 | if(resp!=null && resp.containsKey("documentList")) { 88 | List documentList = (List) resp.get("documentList"); 89 | for (Object documentObj : documentList) { 90 | if(documentObj instanceof Map) { 91 | idSet.add((String) ((Map) documentObj).get("statusId")); 92 | } 93 | } 94 | } 95 | 96 | findCondition = ecf.makeCondition( 97 | findCondition, 98 | EntityCondition.JoinOperator.AND, 99 | ecf.makeCondition("statusId", EntityCondition.ComparisonOperator.IN, idSet) 100 | ); 101 | } 102 | 103 | // find 104 | String userId = uf.getUserId(); 105 | ArrayList> statusItemList = new ArrayList<>(); 106 | EntityList statusItems = ef.find("moqui.basic.StatusItem") 107 | .condition(findCondition) 108 | .searchFormMap(cs, null, null, null, false) 109 | .offset(pageIndex, pageSize) 110 | .limit(pageSize) 111 | .orderBy(orderByField) 112 | .list(); 113 | for (EntityValue statusItem : statusItems) { 114 | statusItemList.add(statusItem.getMap()); 115 | } 116 | 117 | // count 118 | long totalRows = ef.find("moqui.basic.StatusItem") 119 | .condition(findCondition) 120 | .searchFormMap(cs, null, null, null, false) 121 | .count(); 122 | 123 | // log the processing time 124 | stopWatch.stop(); 125 | logger.debug(String.format("[%s] Found %d items in %d milliseconds", logId, statusItemList.size(), stopWatch.getTime())); 126 | 127 | // return the output parameters 128 | HashMap outParams = new HashMap<>(); 129 | outParams.put("totalRows", totalRows); 130 | outParams.put("statusItemList", statusItemList); 131 | return outParams; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/entity/EntityFieldService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.entity; 15 | 16 | import org.moqui.entity.util.EntityFieldType; 17 | import org.moqui.util.ContextUtil; 18 | import org.apache.commons.lang3.time.StopWatch; 19 | import org.moqui.context.ExecutionContext; 20 | import org.moqui.context.L10nFacade; 21 | import org.moqui.context.MessageFacade; 22 | import org.moqui.util.ContextStack; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | import java.util.ArrayList; 27 | import java.util.HashMap; 28 | import java.util.Map; 29 | 30 | /** 31 | * Service to retrieve field comparison operators. 32 | */ 33 | @SuppressWarnings("unused") 34 | public class EntityFieldService { 35 | 36 | /** 37 | * Class logger. 38 | */ 39 | private final Logger logger = LoggerFactory.getLogger(getClass()); 40 | 41 | /** 42 | * Finds field comparison operators. 43 | * 44 | * @param ec Execution context 45 | * @return Output parameter map 46 | */ 47 | public Map findFieldComparisonOperators(ExecutionContext ec) { 48 | 49 | // start the stop watch 50 | StopWatch stopWatch = new StopWatch(); 51 | stopWatch.start(); 52 | 53 | // shortcuts for convenience 54 | ContextStack cs = ec.getContext(); 55 | MessageFacade mf = ec.getMessage(); 56 | L10nFacade lf = ec.getL10n(); 57 | EntityFacade ef = ec.getEntity(); 58 | 59 | // get the parameters 60 | String fieldId = (String) cs.getOrDefault("fieldId", null); 61 | 62 | // generate a new log ID 63 | String logId = ContextUtil.getLogId(ec); 64 | logger.debug(String.format("[%s] Finding field comparison operators ...", logId)); 65 | logger.debug(String.format("[%s] Param fieldId=%s", logId, fieldId)); 66 | 67 | // validate the field 68 | EntityValue field = ef.find("moqui.entity.EntityField") 69 | .condition("fieldId", fieldId) 70 | .one(); 71 | if(field==null) { 72 | stopWatch.stop(); 73 | mf.addError(lf.localize("ENTITY_FIELD_NOT_FOUND")); 74 | logger.error(String.format("[%s] Field with ID %s was not found", logId, fieldId)); 75 | return new HashMap<>(); 76 | } 77 | 78 | // get field type 79 | EntityFieldType fieldType; 80 | try { 81 | fieldType = EntityFieldType.valueOf(field.getString("fieldTypeEnumId")); 82 | } catch (IllegalArgumentException e) { 83 | fieldType = EntityFieldType.ENTITY_FLD_TEXT; 84 | } 85 | 86 | // get enum type 87 | String enumTypeId; 88 | switch(fieldType) { 89 | case ENTITY_FLD_BOOLEAN: 90 | enumTypeId = "BooleanComparisonOperator"; 91 | break; 92 | case ENTITY_FLD_DATE: 93 | enumTypeId = "DateComparisonOperator"; 94 | break; 95 | case ENTITY_FLD_TEXT: 96 | enumTypeId = "TextComparisonOperator"; 97 | break; 98 | case ENTITY_FLD_NUMBER: 99 | enumTypeId = "NumberComparisonOperator"; 100 | break; 101 | default: 102 | enumTypeId = "_NA_"; 103 | } 104 | 105 | // find 106 | ArrayList> operatorList = new ArrayList<>(); 107 | EntityList operators = ef.find("moqui.basic.Enumeration") 108 | .condition("enumTypeId", enumTypeId) 109 | .list(); 110 | for (EntityValue operator : operators) { 111 | operatorList.add(operator.getMap()); 112 | } 113 | 114 | // log the processing time 115 | stopWatch.stop(); 116 | logger.debug(String.format("[%s] Found %d comparison operators in %d milliseconds", logId, operatorList.size(), stopWatch.getTime())); 117 | 118 | // return the output parameters 119 | HashMap outParams = new HashMap<>(); 120 | outParams.put("operatorList", operatorList); 121 | return outParams; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/entity/util/EntityFieldType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.entity.util; 15 | 16 | /** 17 | * Known entity field types. 18 | */ 19 | public enum EntityFieldType { 20 | ENTITY_FLD_TEXT, 21 | ENTITY_FLD_NUMBER, 22 | ENTITY_FLD_DATE, 23 | ENTITY_FLD_BOOLEAN 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/security/UserGroupService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.security; 15 | 16 | import org.apache.commons.lang3.time.StopWatch; 17 | import org.moqui.context.ExecutionContext; 18 | import org.moqui.entity.*; 19 | import org.moqui.service.ServiceFacade; 20 | import org.moqui.util.ContextStack; 21 | import org.moqui.util.ContextUtil; 22 | import org.moqui.util.StringUtil; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | import java.util.*; 27 | 28 | /** 29 | * Service to retrieve user groups. 30 | */ 31 | @SuppressWarnings("unused") 32 | public class UserGroupService { 33 | 34 | /** 35 | * Class logger. 36 | */ 37 | private final Logger logger = LoggerFactory.getLogger(getClass()); 38 | 39 | /** 40 | * Finds user groups. 41 | * 42 | * @param ec Execution context 43 | * @return Output parameter map 44 | */ 45 | public Map findUserGroups(ExecutionContext ec) { 46 | 47 | // start the stop watch 48 | StopWatch stopWatch = new StopWatch(); 49 | stopWatch.start(); 50 | 51 | // shortcuts for convenience 52 | ContextStack cs = ec.getContext(); 53 | EntityFacade ef = ec.getEntity(); 54 | ServiceFacade sf = ec.getService(); 55 | 56 | // get the parameters 57 | int pageIndex = (Integer) cs.getOrDefault("pageIndex", 0); 58 | int pageSize = (Integer) cs.getOrDefault("pageSize", 10); 59 | String orderByField = (String) cs.getOrDefault("orderByField", "userGroupId"); 60 | String filter = (String) cs.getOrDefault("filter", null); 61 | 62 | // generate a new log ID 63 | String logId = ContextUtil.getLogId(ec); 64 | logger.debug(String.format("[%s] Finding user groups ...", logId)); 65 | logger.debug(String.format("[%s] Param pageIndex=%s", logId, pageIndex)); 66 | logger.debug(String.format("[%s] Param pageSize=%s", logId, pageSize)); 67 | logger.debug(String.format("[%s] Param orderByField=%s", logId, orderByField)); 68 | logger.debug(String.format("[%s] Param filter=%s", logId, filter)); 69 | 70 | // prepare the conditions 71 | EntityConditionFactory ecf = ef.getConditionFactory(); 72 | EntityCondition findCondition = ecf.getTrueCondition(); 73 | 74 | // add the filter 75 | if (StringUtil.isValidElasticsearchQuery(filter)) { 76 | Map resp = sf.sync().name("org.moqui.search.SearchServices.search#DataDocuments") 77 | .parameter("indexName", "workflow") 78 | .parameter("documentType", "MoquiUserGroup") 79 | .parameter("queryString", filter) 80 | .call(); 81 | 82 | Set idSet = new HashSet<>(); 83 | if (resp != null && resp.containsKey("documentList")) { 84 | List documentList = (List) resp.get("documentList"); 85 | for (Object documentObj : documentList) { 86 | if (documentObj instanceof Map) { 87 | idSet.add((String) ((Map) documentObj).get("userGroupId")); 88 | } 89 | } 90 | } 91 | 92 | findCondition = ecf.makeCondition( 93 | findCondition, 94 | EntityCondition.JoinOperator.AND, 95 | ecf.makeCondition("userGroupId", EntityCondition.ComparisonOperator.IN, idSet) 96 | ); 97 | } 98 | 99 | // find user groups 100 | ArrayList> userGroupList = new ArrayList<>(); 101 | EntityList userGroups = ef.find("moqui.security.UserGroup") 102 | .condition(findCondition) 103 | .searchFormMap(cs, null, null, null, false) 104 | .offset(pageIndex, pageSize) 105 | .limit(pageSize) 106 | .orderBy(orderByField) 107 | .list(); 108 | for (EntityValue userGroup : userGroups) { 109 | userGroupList.add(userGroup.getMap()); 110 | } 111 | 112 | // count user groups 113 | long totalRows = ef.find("moqui.security.UserGroup") 114 | .condition(findCondition) 115 | .searchFormMap(cs, null, null, null, false) 116 | .count(); 117 | 118 | // log the processing time 119 | stopWatch.stop(); 120 | logger.debug(String.format("[%s] Found %d user groups in %d milliseconds", logId, userGroupList.size(), stopWatch.getTime())); 121 | 122 | // return the output parameters 123 | HashMap outParams = new HashMap<>(); 124 | outParams.put("totalRows", totalRows); 125 | outParams.put("userGroupList", userGroupList); 126 | return outParams; 127 | } 128 | } -------------------------------------------------------------------------------- /src/main/java/org/moqui/security/UserService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.security; 15 | 16 | import org.apache.commons.lang3.time.StopWatch; 17 | import org.moqui.context.*; 18 | import org.moqui.entity.*; 19 | import org.moqui.service.ServiceFacade; 20 | import org.moqui.util.ContextStack; 21 | import org.moqui.util.ContextUtil; 22 | import org.moqui.util.StringUtil; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | import java.util.*; 27 | 28 | /** 29 | * Service to login and retrieve users. 30 | */ 31 | @SuppressWarnings("unused") 32 | public class UserService { 33 | 34 | /** 35 | * Class logger. 36 | */ 37 | private final Logger logger = LoggerFactory.getLogger(getClass()); 38 | 39 | /** 40 | * Finds users. 41 | * 42 | * @param ec Execution context 43 | * @return Output parameter map 44 | */ 45 | public Map findUsers(ExecutionContext ec) { 46 | 47 | // start the stop watch 48 | StopWatch stopWatch = new StopWatch(); 49 | stopWatch.start(); 50 | 51 | // shortcuts for convenience 52 | ContextStack cs = ec.getContext(); 53 | EntityFacade ef = ec.getEntity(); 54 | ServiceFacade sf = ec.getService(); 55 | 56 | // get the parameters 57 | int pageIndex = (Integer) cs.getOrDefault("pageIndex", 0); 58 | int pageSize = (Integer) cs.getOrDefault("pageSize", 10); 59 | String orderByField = (String) cs.getOrDefault("orderByField", "userId"); 60 | String filter = (String) cs.getOrDefault("filter", null); 61 | 62 | // generate a new log ID 63 | String logId = ContextUtil.getLogId(ec); 64 | logger.debug(String.format("[%s] Finding users ...", logId)); 65 | logger.debug(String.format("[%s] Param pageIndex=%s", logId, pageIndex)); 66 | logger.debug(String.format("[%s] Param pageSize=%s", logId, pageSize)); 67 | logger.debug(String.format("[%s] Param orderByField=%s", logId, orderByField)); 68 | logger.debug(String.format("[%s] Param filter=%s", logId, filter)); 69 | 70 | // prepare the conditions 71 | EntityConditionFactory ecf = ef.getConditionFactory(); 72 | EntityCondition findCondition = ecf.makeCondition("disabled", EntityCondition.ComparisonOperator.EQUALS, "N"); 73 | 74 | // add the filter 75 | if (StringUtil.isValidElasticsearchQuery(filter)) { 76 | Map resp = sf.sync().name("org.moqui.search.SearchServices.search#DataDocuments") 77 | .parameter("indexName", "workflow") 78 | .parameter("documentType", "MoquiUser") 79 | .parameter("queryString", filter) 80 | .call(); 81 | 82 | Set idSet = new HashSet<>(); 83 | if (resp != null && resp.containsKey("documentList")) { 84 | List documentList = (List) resp.get("documentList"); 85 | for (Object documentObj : documentList) { 86 | if (documentObj instanceof Map) { 87 | idSet.add((String) ((Map) documentObj).get("userId")); 88 | } 89 | } 90 | } 91 | 92 | findCondition = ecf.makeCondition( 93 | findCondition, 94 | EntityCondition.JoinOperator.AND, 95 | ecf.makeCondition("userId", EntityCondition.ComparisonOperator.IN, idSet) 96 | ); 97 | } 98 | 99 | // find users 100 | ArrayList> userList = new ArrayList<>(); 101 | EntityList users = ef.find("moqui.security.UserAccount") 102 | .condition(findCondition) 103 | .searchFormMap(cs, null, null, null, false) 104 | .offset(pageIndex, pageSize) 105 | .limit(pageSize) 106 | .orderBy(orderByField) 107 | .selectFields(Arrays.asList("userId", "username", "userFullName", "emailAddress", "externalUserId", "creationDate")) 108 | .list(); 109 | for (EntityValue user : users) { 110 | userList.add(user.getMap()); 111 | } 112 | 113 | // count users 114 | long totalRows = ef.find("moqui.security.UserAccount") 115 | .condition(findCondition) 116 | .searchFormMap(cs, null, null, null, false) 117 | .count(); 118 | 119 | // log the processing time 120 | stopWatch.stop(); 121 | logger.debug(String.format("[%s] Found %d users in %d milliseconds", logId, userList.size(), stopWatch.getTime())); 122 | 123 | // return the output parameters 124 | HashMap outParams = new HashMap<>(); 125 | outParams.put("totalRows", totalRows); 126 | outParams.put("userList", userList); 127 | return outParams; 128 | } 129 | 130 | /** 131 | * Logs in a user. 132 | * 133 | * @param ec Execution context 134 | * @return Output parameter map 135 | */ 136 | public Map loginUser(ExecutionContext ec) { 137 | 138 | // start the stop watch 139 | StopWatch stopWatch = new StopWatch(); 140 | stopWatch.start(); 141 | 142 | // shortcuts for convenience 143 | ContextStack cs = ec.getContext(); 144 | L10nFacade lf = ec.getL10n(); 145 | MessageFacade mf = ec.getMessage(); 146 | EntityFacade ef = ec.getEntity(); 147 | UserFacade uf = ec.getUser(); 148 | WebFacade wf = ec.getWeb(); 149 | 150 | // generate a new log ID 151 | String logId = ContextUtil.getLogId(ec); 152 | logger.debug(String.format("[%s] Logging in user ...", logId)); 153 | 154 | // verify the user account 155 | String userId = uf.getUserId(); 156 | EntityValue userAccount = uf.getUserAccount(); 157 | if (userAccount == null) { 158 | mf.addError(lf.localize("USER_INVALID_CREDENTIALS")); 159 | logger.error(String.format("[%s] Invalid username or password", logId)); 160 | return new HashMap<>(); 161 | } 162 | 163 | // log the processing time 164 | stopWatch.stop(); 165 | logger.debug(String.format("[%s] User %s logged in in %d milliseconds", logId, userId, stopWatch.getTime())); 166 | 167 | // return the output parameters 168 | HashMap outParams = new HashMap<>(); 169 | outParams.put("apiKey", uf.getLoginKey()); 170 | outParams.put("sessionToken", wf == null ? null : wf.getSessionToken()); 171 | outParams.put("userId", uf.getUserId()); 172 | outParams.put("userFullName", userAccount.getString("userFullName")); 173 | return outParams; 174 | } 175 | 176 | /** 177 | * Logs out the session user. 178 | * 179 | * @param ec Execution context 180 | */ 181 | public Map logoutUser(ExecutionContext ec) { 182 | 183 | // start the stop watch 184 | StopWatch stopWatch = new StopWatch(); 185 | stopWatch.start(); 186 | 187 | // shortcuts for convenience 188 | ContextStack cs = ec.getContext(); 189 | MessageFacade mf = ec.getMessage(); 190 | EntityFacade ef = ec.getEntity(); 191 | UserFacade uf = ec.getUser(); 192 | WebFacade wf = ec.getWeb(); 193 | 194 | // generate a new log ID 195 | String logId = ContextUtil.getLogId(ec); 196 | logger.debug(String.format("[%s] Logging out user ...", logId)); 197 | 198 | // logout user 199 | String userId = uf.getUserId(); 200 | uf.logoutUser(); 201 | 202 | // log the processing time 203 | stopWatch.stop(); 204 | logger.debug(String.format("[%s] User %s logged out in %d milliseconds", logId, userId, stopWatch.getTime())); 205 | 206 | // return the output parameters 207 | HashMap outParams = new HashMap<>(); 208 | outParams.put("userId", userId); 209 | return outParams; 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/BooleanComparisonOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | /** 17 | * Known boolean comparison operators. 18 | */ 19 | public enum BooleanComparisonOperator { 20 | BOOL_TRUE, 21 | BOOL_FALSE 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/ContextUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | import org.apache.commons.lang3.RandomStringUtils; 17 | import org.moqui.context.ExecutionContext; 18 | import org.moqui.util.ContextStack; 19 | 20 | import java.util.Map; 21 | 22 | /** 23 | * Utility class that facilitates dealing with the Execution Context. 24 | */ 25 | public class ContextUtil { 26 | 27 | /** 28 | * Key used to store log ID in context. 29 | */ 30 | public static final String CONTEXT_LOG_ID = "LOG_ID"; 31 | 32 | /** 33 | * Gets the context log ID. If the context log ID is not defined 34 | * then a new value is generated and returned. 35 | * 36 | * @param ec Execution context 37 | * @return Context log ID 38 | */ 39 | public static String getLogId(ExecutionContext ec) { 40 | ContextStack cs = ec.getContext(); 41 | Map shared = cs.getSharedMap(); 42 | if(!shared.containsKey(CONTEXT_LOG_ID)) { 43 | String logId = RandomStringUtils.randomAlphanumeric(6); 44 | shared.put(CONTEXT_LOG_ID, logId); 45 | } 46 | return (String) shared.get(CONTEXT_LOG_ID); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/DateComparisonOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | /** 17 | * Known date comparison operators. 18 | */ 19 | public enum DateComparisonOperator { 20 | DATE_EQUALS, 21 | DATE_NOT_EQUALS, 22 | DATE_BEFORE, 23 | DATE_AFTER 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/EntityFieldType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | /** 17 | * Known entity field types. 18 | */ 19 | public enum EntityFieldType { 20 | ENTITY_FLD_TEXT, 21 | ENTITY_FLD_NUMBER, 22 | ENTITY_FLD_DATE, 23 | ENTITY_FLD_BOOLEAN 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/JsonUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | import org.json.JSONObject; 17 | 18 | /** 19 | * Utility class that facilities dealing with JSON objects. 20 | */ 21 | public class JsonUtil { 22 | 23 | /** 24 | * Gets the JSON value denoted by key. 25 | * 26 | * @param json JSON object 27 | * @param key Field key 28 | * @return Field value as {@code String} or {@code null} if the key doesn't exist 29 | */ 30 | public static String getStringValue(JSONObject json, String key) { 31 | return json.has(key) ? (json.get(key).equals(JSONObject.NULL) ? null : json.getString(key)) : null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/NumberComparisonOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | /** 17 | * Known number comparison operators. 18 | */ 19 | public enum NumberComparisonOperator { 20 | NUM_EQUALS, 21 | NUM_NOT_EQUALS, 22 | NUM_LESS_THAN, 23 | NUM_LESS_THAN_EQUALS, 24 | NUM_GREATER_THAN, 25 | NUM_GREATER_THAN_EQUALS, 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/ServerUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | import java.net.InetAddress; 17 | import java.net.UnknownHostException; 18 | 19 | /** 20 | * Utility class that facilities dealings with the host machine. 21 | */ 22 | public class ServerUtil { 23 | 24 | /** 25 | * Gets the local server name. 26 | * 27 | * @return Local server name 28 | */ 29 | public static String getServerName() { 30 | try { 31 | return InetAddress.getLocalHost().getHostName(); 32 | } catch (UnknownHostException e) { 33 | return InetAddress.getLoopbackAddress().getHostName(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | import org.apache.lucene.queryparser.flexible.standard.parser.StandardSyntaxParser; 17 | 18 | import java.util.ArrayList; 19 | import java.util.Collections; 20 | import java.util.List; 21 | 22 | /** 23 | * Utility class that offers some additional string operations. 24 | */ 25 | public class StringUtil { 26 | 27 | /** 28 | * Shuffles the characters of a given string. 29 | * 30 | * @param input Input string 31 | * @return Randomly shuffled string 32 | */ 33 | public static String shuffle(String input) { 34 | List chars = new ArrayList<>(); 35 | for(char c:input.toCharArray()){ 36 | chars.add(c); 37 | } 38 | Collections.shuffle(chars); 39 | StringBuilder sb = new StringBuilder(); 40 | for(Character ch: chars) { 41 | sb.append(ch); 42 | } 43 | return sb.toString(); 44 | } 45 | 46 | /** 47 | * Checks if the specified query is valid in Elasticsearch. 48 | * 49 | * @param query Query string 50 | * @return {@code true} if the query is properly formatted and {@code false} otherwise 51 | */ 52 | public static boolean isValidElasticsearchQuery(String query) { 53 | if(query==null) { 54 | return false; 55 | } 56 | try { 57 | new StandardSyntaxParser().parse(query, null); 58 | return true; 59 | } catch (Exception e) { 60 | return false; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/TextComparisonOperator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | /** 17 | * Known text comparison operators. 18 | */ 19 | public enum TextComparisonOperator { 20 | TXT_EQUALS, 21 | TXT_NOT_EQUALS, 22 | TXT_STARTS_WITH, 23 | TXT_ENDS_WITH, 24 | TXT_CONTAINS, 25 | TXT_NOT_CONTAINS, 26 | TXT_EMPTY, 27 | TXT_NOT_EMPTY 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/TimeFrequency.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | /** 17 | * Known time frequencies. 18 | */ 19 | public enum TimeFrequency { 20 | TF_century, 21 | TF_day, 22 | TF_decade, 23 | TF_hr, 24 | TF_millenium, 25 | TF_min, 26 | TF_mon, 27 | TF_ms, 28 | TF_s, 29 | TF_score, 30 | TF_wk, 31 | TF_yr 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/util/TimestampUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.util; 15 | 16 | import java.sql.Timestamp; 17 | 18 | /** 19 | * Utility class that offers a few additional Timestamps operations. 20 | */ 21 | @SuppressWarnings("unused") 22 | public class TimestampUtil { 23 | 24 | /** 25 | * Checks if today's date falls within the specified range. 26 | * 27 | * @param fromDate The range start 28 | * @param toDate The range end 29 | * @return {@code true} if today's date falls within the specified range 30 | */ 31 | public static boolean isWithinRange(Timestamp fromDate, Timestamp toDate) { 32 | long now = System.currentTimeMillis(); 33 | long from = fromDate==null ? now : fromDate.getTime(); 34 | long to = toDate==null ? now : toDate.getTime(); 35 | return now>=from && now<=to; 36 | } 37 | 38 | /** 39 | * Gets a new timestamp with the current date. 40 | * 41 | * @return Current date timestamp 42 | */ 43 | public static Timestamp now() { 44 | return new Timestamp(System.currentTimeMillis()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/WorkflowTypeService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow; 15 | 16 | import org.apache.commons.lang3.time.StopWatch; 17 | import org.moqui.context.ExecutionContext; 18 | import org.moqui.context.MessageFacade; 19 | import org.moqui.context.UserFacade; 20 | import org.moqui.entity.EntityFacade; 21 | import org.moqui.entity.EntityList; 22 | import org.moqui.entity.EntityValue; 23 | import org.moqui.service.ServiceFacade; 24 | import org.moqui.util.ContextStack; 25 | import org.moqui.util.ContextUtil; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.util.ArrayList; 30 | import java.util.HashMap; 31 | import java.util.Map; 32 | 33 | /** 34 | * Service to retrieve workflow types. 35 | */ 36 | @SuppressWarnings("unused") 37 | public class WorkflowTypeService { 38 | 39 | /** 40 | * Class logger. 41 | */ 42 | private final Logger logger = LoggerFactory.getLogger(getClass()); 43 | 44 | /** 45 | * Finds workflows. 46 | * 47 | * @param ec Execution context 48 | * @return Output parameter map 49 | */ 50 | public Map findWorkflowTypes(ExecutionContext ec) { 51 | 52 | // start the stop watch 53 | StopWatch stopWatch = new StopWatch(); 54 | stopWatch.start(); 55 | 56 | // shortcuts for convenience 57 | ContextStack cs = ec.getContext(); 58 | MessageFacade mf = ec.getMessage(); 59 | EntityFacade ef = ec.getEntity(); 60 | ServiceFacade sf = ec.getService(); 61 | UserFacade uf = ec.getUser(); 62 | 63 | // get the parameters 64 | int pageIndex = (Integer) cs.getOrDefault("pageIndex", 0); 65 | int pageSize = (Integer) cs.getOrDefault("pageSize", 10); 66 | String orderByField = (String) cs.getOrDefault("orderByField", "typeId"); 67 | String filter = (String) cs.getOrDefault("filter", null); 68 | 69 | // generate a new log ID 70 | String logId = ContextUtil.getLogId(ec); 71 | logger.debug(String.format("[%s] Finding workflow types ...", logId)); 72 | logger.debug(String.format("[%s] Param pageIndex=%s", logId, pageIndex)); 73 | logger.debug(String.format("[%s] Param pageSize=%s", logId, pageSize)); 74 | logger.debug(String.format("[%s] Param orderByField=%s", logId, orderByField)); 75 | 76 | // find 77 | ArrayList> workflowTypeList = new ArrayList<>(); 78 | EntityList workflowTypes = ef.find("moqui.workflow.WorkflowType") 79 | .offset(pageIndex, pageSize) 80 | .limit(pageSize) 81 | .orderBy(orderByField) 82 | .searchFormMap(cs, null, null, null, false) 83 | .list(); 84 | for (EntityValue workflowType : workflowTypes) { 85 | workflowTypeList.add(workflowType.getMap()); 86 | } 87 | 88 | // count 89 | long totalRows = ef.find("moqui.workflow.WorkflowType") 90 | .searchFormMap(cs, null, null, null, false) 91 | .count(); 92 | 93 | // log the processing time 94 | stopWatch.stop(); 95 | logger.debug(String.format("[%s] Found %d workflow types in %d milliseconds", logId, workflowTypeList.size(), stopWatch.getTime())); 96 | 97 | // return the output parameters 98 | HashMap outParams = new HashMap<>(); 99 | outParams.put("totalRows", totalRows); 100 | outParams.put("workflowTypeList", workflowTypeList); 101 | return outParams; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/activity/AbstractWorkflowActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.activity; 15 | 16 | import org.moqui.entity.EntityValue; 17 | import org.slf4j.Logger; 18 | import org.slf4j.LoggerFactory; 19 | 20 | /** 21 | * Abstract workflow activity class holding attributes common to most implementations. 22 | */ 23 | public abstract class AbstractWorkflowActivity implements WorkflowActivity { 24 | 25 | /** 26 | * Class logger. 27 | */ 28 | protected final Logger logger = LoggerFactory.getLogger(getClass()); 29 | /** 30 | * Activity entity. 31 | */ 32 | protected EntityValue activity; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/activity/WorkflowActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.activity; 15 | 16 | import org.moqui.context.ExecutionContext; 17 | import org.moqui.entity.EntityValue; 18 | 19 | /** 20 | * Interface that defined required workflow activity methods. 21 | */ 22 | public interface WorkflowActivity { 23 | 24 | /** 25 | * Executes the activity. 26 | * 27 | * @param ec Execution context 28 | * @param instance Workflow instance 29 | * @return {@code true} if the activity executed successfully and {@code false} otherwise 30 | */ 31 | boolean execute(ExecutionContext ec, EntityValue instance); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/activity/WorkflowAdjustmentActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.activity; 15 | 16 | import org.moqui.util.ContextUtil; 17 | import org.moqui.workflow.util.WorkflowAdjustmentType; 18 | import org.moqui.workflow.util.WorkflowEventType; 19 | import org.moqui.workflow.util.WorkflowUtil; 20 | import org.apache.commons.lang3.EnumUtils; 21 | import org.apache.commons.lang3.StringUtils; 22 | import org.apache.commons.lang3.time.StopWatch; 23 | import org.json.JSONObject; 24 | import org.moqui.context.ExecutionContext; 25 | import org.moqui.entity.EntityFacade; 26 | import org.moqui.entity.EntityValue; 27 | import org.moqui.service.ServiceFacade; 28 | 29 | /** 30 | * Workflow activity used to adjustment payload. 31 | */ 32 | public class WorkflowAdjustmentActivity extends AbstractWorkflowActivity { 33 | 34 | /** 35 | * Creates a new activity. 36 | * 37 | * @param activity Activity entity 38 | */ 39 | public WorkflowAdjustmentActivity(EntityValue activity) { 40 | this.activity = activity; 41 | } 42 | 43 | @Override 44 | public boolean execute(ExecutionContext ec, EntityValue instance) { 45 | 46 | // start the stop watch 47 | StopWatch stopWatch = new StopWatch(); 48 | stopWatch.start(); 49 | 50 | // shortcuts for convenience 51 | EntityFacade ef = ec.getEntity(); 52 | ServiceFacade sf = ec.getService(); 53 | 54 | // get attributes 55 | String activityId = activity.getString("activityId"); 56 | String activityTypeEnumId = activity.getString("activityTypeEnumId"); 57 | String activityTypeDescription = activity.getString("activityTypeDescription"); 58 | String instanceId = instance.getString("instanceId"); 59 | 60 | // generate a new log ID 61 | String logId = ContextUtil.getLogId(ec); 62 | logger.debug(String.format("[%s] Executing %s activity (%s) ...", logId, activityTypeEnumId, activityId)); 63 | 64 | // get attributes 65 | JSONObject nodeData = new JSONObject(activity.getString("nodeData")); 66 | WorkflowAdjustmentType adjustmentType = nodeData.has("adjustmentTypeEnumId") ? EnumUtils.getEnum(WorkflowAdjustmentType.class, nodeData.getString("adjustmentTypeEnumId")) : null; 67 | String statusId = nodeData.has("statusId") ? nodeData.getString("statusId") : null; 68 | String variableId = nodeData.has("variableId") ? nodeData.getString("variableId") : null; 69 | String definedValue = nodeData.has("definedValue") ? nodeData.getString("definedValue") : null; 70 | 71 | // perform adjustment 72 | if (adjustmentType == WorkflowAdjustmentType.WF_ADJUST_STATUS && StringUtils.isNotBlank(statusId)) { 73 | 74 | // get the workflow 75 | EntityValue workflow = ef.find("moqui.workflow.WorkflowDetail") 76 | .condition("workflowId", instance.getString("workflowId")) 77 | .one(); 78 | 79 | // get the entity 80 | String primaryEntityName = workflow.getString("primaryEntityName"); 81 | String primaryKeyField = workflow.getString("primaryKeyField"); 82 | String primaryKeyValue = instance.getString("primaryKeyValue"); 83 | 84 | // update the status 85 | try { 86 | logger.debug(String.format("[%s] Changing status to: %s", logId, statusId)); 87 | sf.sync().name(String.format("update#%s", primaryEntityName)) 88 | .parameter(primaryKeyField, primaryKeyValue) 89 | .parameter("statusId", statusId) 90 | .call(); 91 | } catch (Exception e) { 92 | stopWatch.stop(); 93 | logger.error(String.format("[%s] An error occurred while updating entity status: %s", logId, e.getMessage()), e); 94 | WorkflowUtil.createWorkflowEvent( 95 | ec, 96 | instanceId, 97 | WorkflowEventType.WF_EVENT_ACTIVITY, 98 | String.format("Failed to execute %s activity (%s) due to error: %s", activityTypeDescription, activityId, e.getMessage()), 99 | true 100 | ); 101 | return false; 102 | } 103 | } else if (adjustmentType == WorkflowAdjustmentType.WF_ADJUST_VARIABLE && StringUtils.isNotBlank(variableId)) { 104 | 105 | // update the variable 106 | try { 107 | logger.debug(String.format("[%s] Updating variable %s to: %s", logId, variableId, definedValue)); 108 | sf.sync().name("moqui.workflow.WorkflowServices.update#WorkflowInstanceVariable") 109 | .parameter("instanceId", instanceId) 110 | .parameter("variableId", variableId) 111 | .parameter("valueExpression", definedValue) 112 | .call(); 113 | } catch (Exception e) { 114 | stopWatch.stop(); 115 | logger.error(String.format("[%s] An error occurred while updating workflow instance variable: %s", logId, e.getMessage()), e); 116 | WorkflowUtil.createWorkflowEvent( 117 | ec, 118 | instanceId, 119 | WorkflowEventType.WF_EVENT_ACTIVITY, 120 | String.format("Failed to execute %s activity (%s) due to error: %s", activityTypeDescription, activityId, e.getMessage()), 121 | true 122 | ); 123 | return false; 124 | } 125 | } 126 | 127 | // create event 128 | WorkflowUtil.createWorkflowEvent( 129 | ec, 130 | instanceId, 131 | WorkflowEventType.WF_EVENT_ACTIVITY, 132 | String.format("Executed %s activity (%s)", activityTypeDescription, activityId), 133 | false 134 | ); 135 | 136 | // log the processing time 137 | stopWatch.stop(); 138 | logger.debug(String.format("[%s] %s activity (%s) executed in %d milliseconds", logId, activityTypeEnumId, activityId, stopWatch.getTime())); 139 | 140 | // activity executed successfully 141 | return true; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/activity/WorkflowEnterActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.activity; 15 | 16 | import org.moqui.util.ContextUtil; 17 | import org.moqui.workflow.util.WorkflowEventType; 18 | import org.moqui.workflow.util.WorkflowUtil; 19 | import org.apache.commons.lang3.time.StopWatch; 20 | import org.moqui.context.ExecutionContext; 21 | import org.moqui.entity.EntityValue; 22 | 23 | /** 24 | * Workflow activity used as an entry point for any workflow instance. 25 | */ 26 | public class WorkflowEnterActivity extends AbstractWorkflowActivity { 27 | 28 | /** 29 | * Creates a new activity. 30 | * 31 | * @param activity Activity entity 32 | */ 33 | public WorkflowEnterActivity(EntityValue activity) { 34 | this.activity = activity; 35 | } 36 | 37 | @Override 38 | public boolean execute(ExecutionContext ec, EntityValue instance) { 39 | 40 | // start the stop watch 41 | StopWatch stopWatch = new StopWatch(); 42 | stopWatch.start(); 43 | 44 | // get attributes 45 | String activityId = activity.getString("activityId"); 46 | String activityTypeEnumId = activity.getString("activityTypeEnumId"); 47 | String activityTypeDescription = activity.getString("activityTypeDescription"); 48 | String instanceId = instance.getString("instanceId"); 49 | 50 | // generate a new log ID 51 | String logId = ContextUtil.getLogId(ec); 52 | logger.debug(String.format("[%s] Executing %s activity (%s) ...", logId, activityTypeEnumId, activityId)); 53 | 54 | // create event 55 | WorkflowUtil.createWorkflowEvent( 56 | ec, 57 | instanceId, 58 | WorkflowEventType.WF_EVENT_START, 59 | "Workflow started", 60 | false 61 | ); 62 | 63 | // create event 64 | WorkflowUtil.createWorkflowEvent( 65 | ec, 66 | instanceId, 67 | WorkflowEventType.WF_EVENT_ACTIVITY, 68 | String.format("Executed %s activity (%s)", activityTypeDescription, activityId), 69 | false 70 | ); 71 | 72 | // log the processing time 73 | stopWatch.stop(); 74 | logger.debug(String.format("[%s] %s activity (%s) executed in %d milliseconds", logId, activityTypeEnumId, activityId, stopWatch.getTime())); 75 | 76 | // activity executed successfully 77 | return true; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/activity/WorkflowExitActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.activity; 15 | 16 | import org.moqui.util.ContextUtil; 17 | import org.moqui.util.TimestampUtil; 18 | import org.moqui.workflow.util.WorkflowEventType; 19 | import org.moqui.workflow.util.WorkflowInstanceStatus; 20 | import org.moqui.workflow.util.WorkflowUtil; 21 | import org.apache.commons.lang3.time.StopWatch; 22 | import org.json.JSONObject; 23 | import org.moqui.context.ExecutionContext; 24 | import org.moqui.entity.EntityValue; 25 | import org.moqui.service.ServiceFacade; 26 | 27 | /** 28 | * Workflow activity used as an exit point to stop a workflow instance. 29 | */ 30 | public class WorkflowExitActivity extends AbstractWorkflowActivity { 31 | 32 | /** 33 | * Creates a new activity. 34 | * 35 | * @param activity Activity entity 36 | */ 37 | public WorkflowExitActivity(EntityValue activity) { 38 | this.activity = activity; 39 | } 40 | 41 | @Override 42 | public boolean execute(ExecutionContext ec, EntityValue instance) { 43 | 44 | // start the stop watch 45 | StopWatch stopWatch = new StopWatch(); 46 | stopWatch.start(); 47 | 48 | // shortcuts for convenience 49 | ServiceFacade sf = ec.getService(); 50 | 51 | // get attributes 52 | String activityId = activity.getString("activityId"); 53 | String activityTypeEnumId = activity.getString("activityTypeEnumId"); 54 | String activityTypeDescription = activity.getString("activityTypeDescription"); 55 | String instanceId = instance.getString("instanceId"); 56 | 57 | // generate a new log ID 58 | String logId = ContextUtil.getLogId(ec); 59 | logger.debug(String.format("[%s] Executing %s activity (%s) ...", logId, activityTypeEnumId, activityId)); 60 | 61 | // get attributes 62 | JSONObject nodeData = new JSONObject(activity.getString("nodeData")); 63 | Integer resultCode = nodeData.has("resultCode") ? nodeData.getInt("resultCode") : null; 64 | 65 | // update workflow instance 66 | logger.debug(String.format("[%s] Exiting instance %s with result code %s", logId, instanceId, resultCode)); 67 | sf.sync().name("update#moqui.workflow.WorkflowInstance") 68 | .parameter("instanceId", instanceId) 69 | .parameter("statusId", WorkflowInstanceStatus.WF_INST_STAT_COMPLETE) 70 | .parameter("resultCode", resultCode) 71 | .parameter("lastUpdateDate", TimestampUtil.now()) 72 | .call(); 73 | 74 | // create event 75 | WorkflowUtil.createWorkflowEvent( 76 | ec, 77 | instanceId, 78 | WorkflowEventType.WF_EVENT_ACTIVITY, 79 | String.format("Executed %s activity (%s)", activityTypeDescription, activityId), 80 | false 81 | ); 82 | 83 | // create event 84 | WorkflowUtil.createWorkflowEvent( 85 | ec, 86 | instanceId, 87 | WorkflowEventType.WF_EVENT_FINISH, 88 | "Workflow finished", 89 | false 90 | ); 91 | 92 | // log the processing time 93 | stopWatch.stop(); 94 | logger.debug(String.format("[%s] %s activity (%s) executed in %d milliseconds", logId, activityTypeEnumId, activityId, stopWatch.getTime())); 95 | 96 | // activity executed successfully 97 | return true; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/activity/WorkflowNotificationActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.activity; 15 | 16 | import org.moqui.util.ContextUtil; 17 | import org.moqui.util.TimestampUtil; 18 | import org.moqui.workflow.util.WorkflowCrowdType; 19 | import org.moqui.workflow.util.WorkflowEventType; 20 | import org.moqui.workflow.util.WorkflowNotificationType; 21 | import org.moqui.workflow.util.WorkflowUtil; 22 | import org.apache.commons.lang3.EnumUtils; 23 | import org.apache.commons.lang3.StringUtils; 24 | import org.apache.commons.lang3.time.StopWatch; 25 | import org.json.JSONObject; 26 | import org.moqui.context.ExecutionContext; 27 | import org.moqui.entity.EntityFacade; 28 | import org.moqui.entity.EntityList; 29 | import org.moqui.entity.EntityValue; 30 | import org.moqui.service.ServiceFacade; 31 | 32 | import java.util.ArrayList; 33 | import java.util.HashMap; 34 | import java.util.Map; 35 | 36 | /** 37 | * Workflow activity used to send out different types of notifications. 38 | */ 39 | public class WorkflowNotificationActivity extends AbstractWorkflowActivity { 40 | 41 | /** 42 | * Creates a new activity. 43 | * 44 | * @param activity Activity entity 45 | */ 46 | public WorkflowNotificationActivity(EntityValue activity) { 47 | this.activity = activity; 48 | } 49 | 50 | @Override 51 | public boolean execute(ExecutionContext ec, EntityValue instance) { 52 | 53 | // start the stop watch 54 | StopWatch stopWatch = new StopWatch(); 55 | stopWatch.start(); 56 | 57 | // shortcuts for convenience 58 | EntityFacade ef = ec.getEntity(); 59 | ServiceFacade sf = ec.getService(); 60 | 61 | // get attributes 62 | String activityId = activity.getString("activityId"); 63 | String activityTypeEnumId = activity.getString("activityTypeEnumId"); 64 | String activityTypeDescription = activity.getString("activityTypeDescription"); 65 | String instanceId = instance.getString("instanceId"); 66 | String inputUserId = instance.getString("inputUserId"); 67 | 68 | // generate a new log ID 69 | String logId = ContextUtil.getLogId(ec); 70 | logger.debug(String.format("[%s] Executing %s activity (%s) ...", logId, activityTypeEnumId, activityId)); 71 | 72 | // get attributes 73 | JSONObject nodeData = new JSONObject(activity.getString("nodeData")); 74 | WorkflowNotificationType notificationType = nodeData.has("notificationTypeEnumId") ? EnumUtils.getEnum(WorkflowNotificationType.class, nodeData.getString("notificationTypeEnumId")) : null; 75 | WorkflowCrowdType crowdType = nodeData.has("crowdTypeEnumId") ? EnumUtils.getEnum(WorkflowCrowdType.class, nodeData.getString("crowdTypeEnumId")) : null; 76 | String userId = nodeData.has("userId") ? nodeData.getString("userId") : null; 77 | String userGroupId = nodeData.has("userGroupId") ? nodeData.getString("userGroupId") : null; 78 | String message = nodeData.has("message") ? nodeData.getString("message") : null; 79 | 80 | // init body parameters 81 | Map bodyParameters = new HashMap<>(); 82 | bodyParameters.put("message", message); 83 | 84 | // get the user accounts 85 | ArrayList userAccounts = new ArrayList<>(); 86 | if (crowdType == WorkflowCrowdType.WF_CROWD_USER && StringUtils.isNotBlank(userId)) { 87 | EntityValue userAccount = ef.find("moqui.security.UserAccount") 88 | .condition("userId", userId) 89 | .one(); 90 | if (userAccount!=null) { 91 | userAccounts.add(userAccount); 92 | } 93 | } else if (crowdType == WorkflowCrowdType.WF_CROWD_USER_GROUP && StringUtils.isNotBlank(userGroupId)) { 94 | EntityList groupMembers = ef.find("moqui.security.UserGroupMember") 95 | .condition("userGroupId", userGroupId) 96 | .conditionDate("fromDate", "thruDate", TimestampUtil.now()) 97 | .list(); 98 | for (EntityValue groupMember : groupMembers) { 99 | EntityValue userAccount = ef.find("moqui.security.UserAccount") 100 | .condition("userId", groupMember.getString("userId")) 101 | .one(); 102 | if (userAccount != null) { 103 | userAccounts.add(userAccount); 104 | } 105 | } 106 | } else if (crowdType == WorkflowCrowdType.WF_CROWD_INITIATOR) { 107 | EntityValue userAccount = ef.find("moqui.security.UserAccount") 108 | .condition("userId", inputUserId) 109 | .one(); 110 | if (userAccount != null) { 111 | userAccounts.add(userAccount); 112 | } 113 | } 114 | 115 | // send notification 116 | if (notificationType == WorkflowNotificationType.WF_NOTIFY_EMAIL) { 117 | for(EntityValue userAccount : userAccounts) { 118 | sf.async().name("org.moqui.impl.EmailServices.send#EmailTemplate") 119 | .parameter("emailTemplateId", "PF_WF_EMAIL") 120 | .parameter("toAddresses", userAccount.getString("emailAddress")) 121 | .parameter("bodyParameters", bodyParameters) 122 | .call(); 123 | } 124 | } else if (notificationType == WorkflowNotificationType.WF_NOTIFY_SMS) { 125 | // TODO: Implement SMS gateway connect 126 | } else if (notificationType == WorkflowNotificationType.WF_NOTIFY_PUSH) { 127 | // TODO: Implement Push notification provider 128 | } 129 | 130 | // create event 131 | WorkflowUtil.createWorkflowEvent( 132 | ec, 133 | instanceId, 134 | WorkflowEventType.WF_EVENT_ACTIVITY, 135 | String.format("Executed %s activity (%s)", activityTypeDescription, activityId), 136 | false 137 | ); 138 | 139 | // log the processing time 140 | stopWatch.stop(); 141 | logger.debug(String.format("[%s] %s activity (%s) executed in %d milliseconds", logId, activityTypeEnumId, activityId, stopWatch.getTime())); 142 | 143 | // activity executed successfully 144 | return true; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/activity/WorkflowServiceActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.activity; 15 | 16 | import org.moqui.util.ContextUtil; 17 | import org.moqui.workflow.util.WorkflowEventType; 18 | import org.moqui.workflow.util.WorkflowUtil; 19 | import org.apache.commons.lang3.StringUtils; 20 | import org.apache.commons.lang3.time.StopWatch; 21 | import org.json.JSONObject; 22 | import org.moqui.context.ExecutionContext; 23 | import org.moqui.entity.EntityValue; 24 | import org.moqui.service.ServiceException; 25 | import org.moqui.service.ServiceFacade; 26 | 27 | import java.util.Map; 28 | 29 | /** 30 | * Workflow activity used to execute a Moqui service. 31 | */ 32 | public class WorkflowServiceActivity extends AbstractWorkflowActivity { 33 | 34 | /** 35 | * Creates a new activity. 36 | * 37 | * @param activity Activity entity 38 | */ 39 | public WorkflowServiceActivity(EntityValue activity) { 40 | this.activity = activity; 41 | } 42 | 43 | @Override 44 | public boolean execute(ExecutionContext ec, EntityValue instance) { 45 | 46 | // start the stop watch 47 | StopWatch stopWatch = new StopWatch(); 48 | stopWatch.start(); 49 | 50 | // shortcuts for convenience 51 | ServiceFacade sf = ec.getService(); 52 | 53 | // get attributes 54 | String activityId = activity.getString("activityId"); 55 | String activityTypeEnumId = activity.getString("activityTypeEnumId"); 56 | String activityTypeDescription = activity.getString("activityTypeDescription"); 57 | String instanceId = instance.getString("instanceId"); 58 | 59 | // generate a new log ID 60 | String logId = ContextUtil.getLogId(ec); 61 | logger.debug(String.format("[%s] Executing %s activity (%s) ...", logId, activityTypeEnumId, activityId)); 62 | 63 | // get service name 64 | JSONObject nodeData = new JSONObject(activity.getString("nodeData")); 65 | String serviceName = nodeData.has("serviceName") ? nodeData.getString("serviceName").trim() : null; 66 | String parameters = nodeData.has("parameters") ? nodeData.getString("parameters") : null; 67 | 68 | // execute service 69 | if(StringUtils.isNotBlank(serviceName)) { 70 | logger.debug(String.format("[%s] Executing service: %s", logId, serviceName)); 71 | try { 72 | Map response = sf.sync() 73 | .name(serviceName) 74 | .parameter("instance", instance) 75 | .parameter("parameters", parameters) 76 | .call(); 77 | logger.debug(String.format("[%s] Service executed successfully", logId)); 78 | logger.debug(String.format("[%s] Got response: %s", logId, response.toString())); 79 | } catch (ServiceException e) { 80 | stopWatch.stop(); 81 | logger.error(String.format("[%s] An error occurred while running service: %s", logId, e.getMessage()), e); 82 | WorkflowUtil.createWorkflowEvent( 83 | ec, 84 | instanceId, 85 | WorkflowEventType.WF_EVENT_ACTIVITY, 86 | String.format("Failed to execute %s activity (%s) due to error: %s", activityTypeDescription, activityId, e.getMessage()), 87 | true 88 | ); 89 | return false; 90 | } 91 | } 92 | 93 | // create event 94 | WorkflowUtil.createWorkflowEvent( 95 | ec, 96 | instanceId, 97 | WorkflowEventType.WF_EVENT_ACTIVITY, 98 | String.format("Executed %s activity (%s)", activityTypeDescription, activityId), 99 | false 100 | ); 101 | 102 | // log the processing time 103 | stopWatch.stop(); 104 | logger.debug(String.format("[%s] %s activity (%s) executed in %d milliseconds", logId, activityTypeEnumId, activityId, stopWatch.getTime())); 105 | 106 | // activity executed successfully 107 | return true; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/activity/WorkflowUserActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.activity; 15 | 16 | import org.apache.commons.lang3.EnumUtils; 17 | import org.apache.commons.lang3.StringUtils; 18 | import org.apache.commons.lang3.time.DateUtils; 19 | import org.apache.commons.lang3.time.StopWatch; 20 | import org.json.JSONArray; 21 | import org.json.JSONObject; 22 | import org.moqui.context.ExecutionContext; 23 | import org.moqui.entity.EntityFacade; 24 | import org.moqui.entity.EntityList; 25 | import org.moqui.entity.EntityValue; 26 | import org.moqui.service.ServiceFacade; 27 | import org.moqui.util.ContextUtil; 28 | import org.moqui.util.TimeFrequency; 29 | import org.moqui.util.TimestampUtil; 30 | import org.moqui.workflow.util.*; 31 | 32 | import java.math.BigDecimal; 33 | import java.sql.Timestamp; 34 | import java.util.ArrayList; 35 | import java.util.Date; 36 | import java.util.Map; 37 | 38 | /** 39 | * Workflow activity used to create different types of user tasks. 40 | */ 41 | public class WorkflowUserActivity extends AbstractWorkflowActivity { 42 | 43 | /** 44 | * Creates a new activity. 45 | * 46 | * @param activity Activity entity 47 | */ 48 | public WorkflowUserActivity(EntityValue activity) { 49 | this. activity = activity; 50 | } 51 | 52 | @Override 53 | public boolean execute(ExecutionContext ec, EntityValue instance) { 54 | 55 | // start the stop watch 56 | StopWatch stopWatch = new StopWatch(); 57 | stopWatch.start(); 58 | 59 | // shortcuts for convenience 60 | EntityFacade ef = ec.getEntity(); 61 | ServiceFacade sf = ec.getService(); 62 | 63 | // get attributes 64 | String activityId = activity.getString("activityId"); 65 | String activityTypeEnumId = activity.getString("activityTypeEnumId"); 66 | String activityTypeDescription = activity.getString("activityTypeDescription"); 67 | String instanceId = instance.getString("instanceId"); 68 | String inputUserId = instance.getString("inputUserId"); 69 | 70 | // generate a new log ID 71 | String logId = ContextUtil.getLogId(ec); 72 | logger.debug(String.format("[%s] Executing %s activity (%s) ...", logId, activityTypeEnumId, activityId)); 73 | 74 | // get attributes 75 | JSONObject nodeData = new JSONObject(activity.getString("nodeData")); 76 | WorkflowTaskType taskType = nodeData.has("taskTypeEnumId") ? EnumUtils.getEnum(WorkflowTaskType.class, nodeData.getString("taskTypeEnumId")) : null; 77 | JSONArray crowds = nodeData.has("crowds") ? nodeData.getJSONArray("crowds") : new JSONArray(); 78 | String variableId = nodeData.has("variableId") ? nodeData.getString("variableId") : null; 79 | String summary = nodeData.has("summary") ? nodeData.getString("summary") : null; 80 | String description = nodeData.has("description") ? nodeData.getString("description") : null; 81 | int timeoutInterval = nodeData.has("timeoutInterval") ? nodeData.getInt("timeoutInterval") : 0; 82 | String timeoutUomId = nodeData.has("timeoutUomId") ? nodeData.getString("timeoutUomId") : null; 83 | 84 | // get the user accounts 85 | ArrayList userAccounts = new ArrayList<>(); 86 | for (int i=0; i resp = sf.sync().name("create#moqui.workflow.WorkflowInstanceTask") 126 | .parameter("instanceId", instanceId) 127 | .parameter("activityId", activityId) 128 | .parameter("assignedUserId", userId) 129 | .parameter("taskTypeEnumId", taskType) 130 | .parameter("variableId", variableId) 131 | .parameter("statusId", WorkflowTaskStatus.WF_TASK_STAT_PEND) 132 | .parameter("summary", summary) 133 | .parameter("description", description) 134 | .call(); 135 | String taskId = (String) resp.get("taskId"); 136 | logger.debug(String.format("[%s] Added task %s for user %s", logId, taskId, userId)); 137 | } 138 | 139 | // set the instance timeout 140 | if(timeoutInterval > 0 && StringUtils.isNotBlank(timeoutUomId)) { 141 | Map convertResp = sf.sync().name("org.moqui.impl.BasicServices.convert#Uom") 142 | .parameter("uomId", timeoutUomId) 143 | .parameter("toUomId", TimeFrequency.TF_min.name()) 144 | .parameter("amount", timeoutInterval) 145 | .call(); 146 | int timeoutIntervalMins = ((BigDecimal)convertResp.get("convertedAmount")).intValue(); 147 | 148 | Date timeoutDate = DateUtils.addMinutes(new Date(), timeoutIntervalMins); 149 | Timestamp timeoutDateTs = new Timestamp(timeoutDate.getTime()); 150 | sf.sync().name("update#moqui.workflow.WorkflowInstance") 151 | .parameter("instanceId", instanceId) 152 | .parameter("timeoutDate", timeoutDateTs) 153 | .parameter("lastUpdateDate", TimestampUtil.now()) 154 | .call(); 155 | } 156 | 157 | // create event 158 | WorkflowUtil.createWorkflowEvent( 159 | ec, 160 | instanceId, 161 | WorkflowEventType.WF_EVENT_ACTIVITY, 162 | String.format("Executed %s activity (%s)", activityTypeDescription, activityId), 163 | false 164 | ); 165 | 166 | // log the processing time 167 | stopWatch.stop(); 168 | logger.debug(String.format("[%s] %s activity (%s) executed in %d milliseconds", logId, activityTypeEnumId, activityId, stopWatch.getTime())); 169 | 170 | // activity executed successfully 171 | return true; 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/condition/BooleanCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.condition; 15 | 16 | import org.moqui.util.BooleanComparisonOperator; 17 | import org.moqui.context.ExecutionContext; 18 | import org.moqui.entity.EntityValue; 19 | 20 | /** 21 | * Boolean condition. 22 | */ 23 | public class BooleanCondition implements WorkflowCondition { 24 | 25 | /** 26 | * Check value. 27 | */ 28 | private boolean value; 29 | /** 30 | * Comparison operator. 31 | */ 32 | private BooleanComparisonOperator operator; 33 | 34 | /** 35 | * Creates a new condition. 36 | * 37 | * @param value Field value 38 | * @param operator Comparison operator 39 | */ 40 | public BooleanCondition(Boolean value, BooleanComparisonOperator operator) { 41 | this.value = value; 42 | this.operator = operator; 43 | } 44 | 45 | @Override 46 | public boolean evaluate(ExecutionContext ec, EntityValue instance) throws Exception { 47 | switch(operator) { 48 | case BOOL_TRUE: 49 | return value; 50 | case BOOL_FALSE: 51 | return !value; 52 | default: 53 | return false; 54 | } 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return String.format("%s %s", value, operator); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/condition/DateCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.condition; 15 | 16 | import org.moqui.util.DateComparisonOperator; 17 | import org.apache.commons.lang3.time.DateUtils; 18 | import org.moqui.context.ExecutionContext; 19 | import org.moqui.entity.EntityValue; 20 | 21 | import java.util.Date; 22 | 23 | /** 24 | * Date condition. 25 | */ 26 | public class DateCondition implements WorkflowCondition { 27 | 28 | /** 29 | * Left operand. 30 | */ 31 | private Date leftOperand; 32 | /** 33 | * Right operand. 34 | */ 35 | private Date rightOperand; 36 | /** 37 | * Comparison operator. 38 | */ 39 | private DateComparisonOperator operator; 40 | 41 | /** 42 | * Creates a new condition. 43 | * 44 | * @param leftOperand Left operand 45 | * @param operator Comparison operator 46 | * @param rightOperand Right operand 47 | */ 48 | public DateCondition(Date leftOperand, DateComparisonOperator operator, Date rightOperand) { 49 | this.leftOperand = leftOperand; 50 | this.operator = operator; 51 | this.rightOperand = rightOperand; 52 | } 53 | 54 | @Override 55 | public boolean evaluate(ExecutionContext ec, EntityValue instance) throws Exception { 56 | switch(operator) { 57 | case DATE_BEFORE: 58 | return leftOperand.before(rightOperand); 59 | case DATE_AFTER: 60 | return leftOperand.after(rightOperand); 61 | case DATE_EQUALS: 62 | return DateUtils.isSameDay(leftOperand, rightOperand); 63 | case DATE_NOT_EQUALS: 64 | return !DateUtils.isSameDay(leftOperand, rightOperand); 65 | default: 66 | return false; 67 | } 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return String.format("%s %s %s", leftOperand, operator, rightOperand); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/condition/NumberCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.condition; 15 | 16 | import org.moqui.util.NumberComparisonOperator; 17 | import org.moqui.context.ExecutionContext; 18 | import org.moqui.entity.EntityValue; 19 | 20 | /** 21 | * Number condition. 22 | */ 23 | public class NumberCondition implements WorkflowCondition { 24 | 25 | /** 26 | * Left operand. 27 | */ 28 | private long leftOperand; 29 | /** 30 | * Right operand. 31 | */ 32 | private long rightOperand; 33 | /** 34 | * Comparison operator. 35 | */ 36 | private NumberComparisonOperator operator; 37 | 38 | /** 39 | * Creates a new condition. 40 | * 41 | * @param leftOperand Left operand 42 | * @param operator Comparison operator 43 | * @param rightOperand Right operand 44 | */ 45 | public NumberCondition(long leftOperand, NumberComparisonOperator operator, long rightOperand) { 46 | this.leftOperand = leftOperand; 47 | this.operator = operator; 48 | this.rightOperand = rightOperand; 49 | } 50 | 51 | @Override 52 | public boolean evaluate(ExecutionContext ec, EntityValue instance) throws Exception { 53 | switch(operator) { 54 | case NUM_LESS_THAN: 55 | return leftOperand < rightOperand; 56 | case NUM_LESS_THAN_EQUALS: 57 | return leftOperand <= rightOperand; 58 | case NUM_GREATER_THAN: 59 | return leftOperand > rightOperand; 60 | case NUM_GREATER_THAN_EQUALS: 61 | return leftOperand >= rightOperand; 62 | case NUM_EQUALS: 63 | return leftOperand == rightOperand; 64 | case NUM_NOT_EQUALS: 65 | return leftOperand != rightOperand; 66 | default: 67 | return false; 68 | } 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | return String.format("%s %s %s", leftOperand, operator, rightOperand); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/condition/ScriptCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.condition; 15 | 16 | import org.apache.commons.lang3.RandomStringUtils; 17 | import org.apache.commons.lang3.StringUtils; 18 | import org.moqui.context.ExecutionContext; 19 | import org.moqui.entity.EntityFacade; 20 | import org.moqui.entity.EntityList; 21 | import org.moqui.entity.EntityValue; 22 | 23 | import javax.script.ScriptEngine; 24 | import javax.script.ScriptEngineManager; 25 | 26 | /** 27 | * Script condition. 28 | */ 29 | public class ScriptCondition implements WorkflowCondition { 30 | 31 | /** 32 | * Script code. 33 | */ 34 | private String script; 35 | 36 | /** 37 | * Creates a new condition. 38 | * 39 | * @param script Script code 40 | */ 41 | public ScriptCondition(String script) { 42 | this.script = script; 43 | } 44 | 45 | @Override 46 | public boolean evaluate(ExecutionContext ec, EntityValue instance) throws Exception { 47 | 48 | // shortcuts for convenience 49 | EntityFacade ef = ec.getEntity(); 50 | 51 | // init script engine 52 | ScriptEngineManager manager = new ScriptEngineManager(); 53 | ScriptEngine engine = manager.getEngineByName("JavaScript"); 54 | 55 | // replace properties 56 | script = script.replaceAll(" ", ""); 57 | EntityList variables = ef.find("moqui.workflow.WorkflowInstanceVariableDetail") 58 | .condition("instanceId", instance.get("instanceId")) 59 | .list(); 60 | for (EntityValue variable : variables) { 61 | String variableName = variable.getString("variableName"); 62 | Object definedValue = variable.get("definedValue"); 63 | String tempVariableName = RandomStringUtils.randomAlphabetic(4); 64 | script = StringUtils.replace(script, String.format("{{%s}}", variableName), tempVariableName); 65 | engine.put(tempVariableName, definedValue); 66 | } 67 | 68 | // evaluate script 69 | Object result = engine.eval(script); 70 | 71 | // process result 72 | if (result instanceof Boolean) { 73 | return ((Boolean) result); 74 | } else if (result instanceof Number) { 75 | return ((Number) result).longValue() > 0; 76 | } else { 77 | return false; 78 | } 79 | } 80 | 81 | @Override 82 | public String toString() { 83 | return script; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/condition/TextCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.condition; 15 | 16 | import org.moqui.util.TextComparisonOperator; 17 | import org.apache.commons.lang3.StringUtils; 18 | import org.moqui.context.ExecutionContext; 19 | import org.moqui.entity.EntityValue; 20 | 21 | /** 22 | * Text condition. 23 | */ 24 | public class TextCondition implements WorkflowCondition { 25 | 26 | /** 27 | * Left operand. 28 | */ 29 | private String leftOperand; 30 | /** 31 | * Right operand. 32 | */ 33 | private String rightOperand; 34 | /** 35 | * Comparison operator. 36 | */ 37 | private TextComparisonOperator operator; 38 | 39 | /** 40 | * Creates a new condition. 41 | * 42 | * @param leftOperand Left operand 43 | * @param operator Comparison operator 44 | * @param rightOperand Right operand 45 | */ 46 | public TextCondition(String leftOperand, TextComparisonOperator operator, String rightOperand) { 47 | this.leftOperand = leftOperand; 48 | this.operator = operator; 49 | this.rightOperand = rightOperand; 50 | } 51 | 52 | @Override 53 | public boolean evaluate(ExecutionContext ec, EntityValue instance) throws Exception { 54 | switch(operator) { 55 | case TXT_STARTS_WITH: 56 | return StringUtils.startsWith(leftOperand, rightOperand); 57 | case TXT_ENDS_WITH: 58 | return StringUtils.endsWith(leftOperand, rightOperand); 59 | case TXT_CONTAINS: 60 | return StringUtils.contains(leftOperand, rightOperand); 61 | case TXT_NOT_CONTAINS: 62 | return !StringUtils.contains(leftOperand, rightOperand); 63 | case TXT_EQUALS: 64 | return StringUtils.equals(leftOperand, rightOperand); 65 | case TXT_NOT_EQUALS: 66 | return !StringUtils.equals(leftOperand, rightOperand); 67 | case TXT_EMPTY: 68 | return StringUtils.isEmpty(leftOperand); 69 | case TXT_NOT_EMPTY: 70 | return StringUtils.isNotEmpty(leftOperand); 71 | default: 72 | return false; 73 | } 74 | } 75 | 76 | @Override 77 | public String toString() { 78 | return String.format("%s %s %s", leftOperand, operator, rightOperand); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/condition/WorkflowCondition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.condition; 15 | 16 | import org.moqui.context.ExecutionContext; 17 | import org.moqui.entity.EntityValue; 18 | 19 | /** 20 | * Interface that defined required workflow condition methods. 21 | */ 22 | public interface WorkflowCondition { 23 | 24 | /** 25 | * Evaluates the condition. 26 | * 27 | * @param ec Execution context 28 | * @param instance Workflow instance 29 | * @return Evaluation result 30 | * @throws Exception if an error occurs while evaluating condition 31 | */ 32 | boolean evaluate(ExecutionContext ec, EntityValue instance) throws Exception; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowActivityType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | import org.apache.commons.lang3.StringUtils; 17 | 18 | /** 19 | * Known workflow activity types. 20 | */ 21 | public enum WorkflowActivityType { 22 | WF_ACTIVITY_ENTER, 23 | WF_ACTIVITY_EXIT, 24 | WF_ACTIVITY_CONDITION, 25 | WF_ACTIVITY_USER, 26 | WF_ACTIVITY_ADJUST, 27 | WF_ACTIVITY_SERVICE, 28 | WF_ACTIVITY_NOTIFY; 29 | 30 | /** 31 | * Gets the activity type from the specified node type. 32 | * 33 | * @param nodeType Node type 34 | * @return Activity type 35 | */ 36 | public static WorkflowActivityType fromNodeType(String nodeType) { 37 | if(StringUtils.equals(nodeType, "EnterActivity")) { 38 | return WF_ACTIVITY_ENTER; 39 | } else if(StringUtils.equals(nodeType, "ExitActivity")) { 40 | return WF_ACTIVITY_EXIT; 41 | } else if(StringUtils.equals(nodeType, "ConditionActivity")) { 42 | return WF_ACTIVITY_CONDITION; 43 | } else if(StringUtils.equals(nodeType, "UserActivity")) { 44 | return WF_ACTIVITY_USER; 45 | } else if(StringUtils.equals(nodeType, "AdjustmentActivity")) { 46 | return WF_ACTIVITY_ADJUST; 47 | } else if(StringUtils.equals(nodeType, "ServiceActivity")) { 48 | return WF_ACTIVITY_SERVICE; 49 | } else if(StringUtils.equals(nodeType, "NotificationActivity")) { 50 | return WF_ACTIVITY_NOTIFY; 51 | } else { 52 | return null; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowAdjustmentType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow adjustment types. 18 | */ 19 | public enum WorkflowAdjustmentType { 20 | WF_ADJUST_STATUS, 21 | WF_ADJUST_VARIABLE, 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowConditionType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow condition types. 18 | */ 19 | public enum WorkflowConditionType { 20 | WF_CONDITION_FIELD, 21 | WF_CONDITION_VARIABLE, 22 | WF_CONDITION_SCRIPT 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowCrowdType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow crowd types. 18 | */ 19 | public enum WorkflowCrowdType { 20 | WF_CROWD_USER_GROUP, 21 | WF_CROWD_USER, 22 | WF_CROWD_INITIATOR 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowEventType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow event types. 18 | */ 19 | public enum WorkflowEventType { 20 | WF_EVENT_START, 21 | WF_EVENT_FINISH, 22 | WF_EVENT_SUSPEND, 23 | WF_EVENT_RESUME, 24 | WF_EVENT_ACTIVITY, 25 | WF_EVENT_TRANSITION, 26 | WF_EVENT_REMINDER 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowInstanceStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow instance statuses. 18 | */ 19 | public enum WorkflowInstanceStatus { 20 | WF_INST_STAT_PEND, 21 | WF_INST_STAT_ACTIVE, 22 | WF_INST_STAT_COMPLETE, 23 | WF_INST_STAT_ABORT, 24 | WF_INST_STAT_SUSPEND 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowLaunchType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow launch types. 18 | */ 19 | public enum WorkflowLaunchType { 20 | WF_LAUNCH_TRIGGER, 21 | WF_LAUNCH_PERIODIC, 22 | WF_LAUNCH_MANUAL 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowNotificationType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow notification types. 18 | */ 19 | public enum WorkflowNotificationType { 20 | WF_NOTIFY_EMAIL, 21 | WF_NOTIFY_SMS, 22 | WF_NOTIFY_PUSH 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowPortType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow port types. 18 | */ 19 | public enum WorkflowPortType { 20 | WF_PORT_INPUT, 21 | WF_PORT_SUCCESS, 22 | WF_PORT_FAILURE, 23 | WF_PORT_TIMEOUT; 24 | 25 | /** 26 | * Gets the description of the specified port type. 27 | * 28 | * @param portType Port type 29 | * @return Port description 30 | */ 31 | public static String portTypeDescription(WorkflowPortType portType) { 32 | switch (portType) { 33 | case WF_PORT_FAILURE: 34 | return "Failure"; 35 | case WF_PORT_INPUT: 36 | return "Input"; 37 | case WF_PORT_SUCCESS: 38 | return "Success"; 39 | case WF_PORT_TIMEOUT: 40 | return "Timeout"; 41 | default: 42 | return "Unknown"; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowTaskStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow task statuses. 18 | */ 19 | public enum WorkflowTaskStatus { 20 | WF_TASK_STAT_PEND, 21 | WF_TASK_STAT_PROGRESS, 22 | WF_TASK_STAT_DONE, 23 | WF_TASK_STAT_APPROVE, 24 | WF_TASK_STAT_REJECT, 25 | WF_TASK_STAT_OBSOLETE 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowTaskType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow task types. 18 | */ 19 | public enum WorkflowTaskType { 20 | WF_TASK_APPROVAL, 21 | WF_TASK_VARIABLE, 22 | WF_TASK_MANUAL 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | import org.moqui.context.ExecutionContext; 17 | import org.moqui.util.ServerUtil; 18 | 19 | /** 20 | * Utility class that offers common workflow functions. 21 | */ 22 | public class WorkflowUtil { 23 | 24 | /** 25 | * Creates a new workflow event. 26 | * 27 | * @param ec Execution context 28 | * @param instanceId Workflow instance ID 29 | * @param event Workflow event type 30 | * @param description Event description 31 | * @param wasError Error indicator 32 | */ 33 | public static void createWorkflowEvent(ExecutionContext ec, String instanceId, WorkflowEventType event, String description, boolean wasError) { 34 | ec.getService().sync().name("create#moqui.workflow.WorkflowInstanceEvent") 35 | .parameter("instanceId", instanceId) 36 | .parameter("eventTypeEnumId", event.name()) 37 | .parameter("sourceName", ServerUtil.getServerName()) 38 | .parameter("description", description) 39 | .parameter("wasError", wasError ? "Y" : "N") 40 | .call(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/org/moqui/workflow/util/WorkflowVariableType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This software is in the public domain under CC0 1.0 Universal plus a 3 | * Grant of Patent License. 4 | * 5 | * To the extent possible under law, the author(s) have dedicated all 6 | * copyright and related and neighboring rights to this software to the 7 | * public domain worldwide. This software is distributed without any 8 | * warranty. 9 | * 10 | * You should have received a copy of the CC0 Public Domain Dedication 11 | * along with this software (see the LICENSE.md file). If not, see 12 | * . 13 | */ 14 | package org.moqui.workflow.util; 15 | 16 | /** 17 | * Known workflow variable types. 18 | */ 19 | public enum WorkflowVariableType { 20 | WF_VAR_TEXT, 21 | WF_VAR_NUMBER 22 | } 23 | --------------------------------------------------------------------------------