diff --git a/database/factories/SubProcessFactory.php b/database/factories/SubProcessFactory.php new file mode 100644 index 000000000..b98d4ee9b --- /dev/null +++ b/database/factories/SubProcessFactory.php @@ -0,0 +1,18 @@ +define(\ProcessMaker\Model\SubProcess::class, function () { + return [ + 'SP_UID' => G::generateUniqueID(), + 'PRO_UID' => G::generateUniqueID(), + 'TAS_UID' => G::generateUniqueID(), + 'PRO_PARENT' => G::generateUniqueID(), + 'TAS_PARENT' => G::generateUniqueID(), + 'SP_TYPE' => '', + 'SP_SYNCHRONOUS' => 0, + 'SP_SYNCHRONOUS_TYPE' => '', + 'SP_SYNCHRONOUS_WAIT' => 0, + 'SP_VARIABLES_OUT' => '', + 'SP_VARIABLES_IN' => '', + 'SP_GRID_IN' => '' + ]; +}); diff --git a/database/factories/TaskUserFactory.php b/database/factories/TaskUserFactory.php index a4c0a5e7d..2b7c65049 100644 --- a/database/factories/TaskUserFactory.php +++ b/database/factories/TaskUserFactory.php @@ -1,7 +1,5 @@ define(\ProcessMaker\Model\TaskUser::class, function(Faker $faker) { @@ -13,4 +11,60 @@ $factory->define(\ProcessMaker\Model\TaskUser::class, function(Faker $faker) { 'TU_TYPE' => 1, 'TU_RELATION' => 1 ]; +}); + +// Create a delegation with the foreign keys +$factory->state(\ProcessMaker\Model\TaskUser::class, 'foreign_keys', function (Faker $faker) { + $user = factory(\ProcessMaker\Model\User::class)->create(); + $task = factory(\ProcessMaker\Model\Task::class)->create(); + return [ + 'TAS_UID' => $task->TAS_UID, + 'USR_UID' => $user->USR_UID, + 'TU_TYPE' => 1, + 'TU_RELATION' => 1 + ]; +}); + +$factory->state(\ProcessMaker\Model\TaskUser::class, 'normal_assigment_user', function (Faker $faker) { + $user = factory(\ProcessMaker\Model\User::class)->create(); + $task = factory(\ProcessMaker\Model\Task::class)->create(); + return [ + 'TAS_UID' => $task->TAS_UID, + 'USR_UID' => $user->USR_UID, + 'TU_RELATION' => 1, + 'TU_TYPE' => 1, + ]; +}); + +$factory->state(\ProcessMaker\Model\TaskUser::class, 'normal_assigment_group', function (Faker $faker) { + $group = factory(\ProcessMaker\Model\Groupwf::class)->create(); + $task = factory(\ProcessMaker\Model\Task::class)->create(); + return [ + 'TAS_UID' => $task->TAS_UID, + 'USR_UID' => $group->GRP_UID, + 'TU_RELATION' => 2, + 'TU_TYPE' => 1, + ]; +}); + +$factory->state(\ProcessMaker\Model\TaskUser::class, 'adhoc_assigment_user', function (Faker $faker) { + $user = factory(\ProcessMaker\Model\User::class)->create(); + $task = factory(\ProcessMaker\Model\Task::class)->create(); + return [ + 'TAS_UID' => $task->TAS_UID, + 'USR_UID' => $user->USR_UID, + 'TU_RELATION' => 1, + 'TU_TYPE' => 2, + ]; +}); + +$factory->state(\ProcessMaker\Model\TaskUser::class, 'adhoc_assigment_group', function (Faker $faker) { + $group = factory(\ProcessMaker\Model\Groupwf::class)->create(); + $task = factory(\ProcessMaker\Model\Task::class)->create(); + return [ + 'TAS_UID' => $task->TAS_UID, + 'USR_UID' => $group->GRP_UID, + 'TU_RELATION' => 2, + 'TU_TYPE' => 2, + ]; }); \ No newline at end of file diff --git a/resources/assets/js/api/Api.js b/resources/assets/js/api/Api.js index 1d3430769..e9fc8d637 100644 --- a/resources/assets/js/api/Api.js +++ b/resources/assets/js/api/Api.js @@ -108,7 +108,7 @@ export default { url, credentials = window.config.SYS_CREDENTIALS, workspace = window.config.SYS_WORKSPACE, - server = window.config.SYS_SERVER, + server = window.config.SYS_SERVER_API, method = options.method || "get"; url = this.getUrl(_.extend(keys, credentials, { server }, { workspace }), service); @@ -130,7 +130,7 @@ export default { url, credentials = window.config.SYS_CREDENTIALS, workspace = window.config.SYS_WORKSPACE, - server = window.config.SYS_SERVER; + server = window.config.SYS_SERVER_API; url = this.getUrl(_.extend(keys, credentials, { server }, { workspace }), service); return axios({ @@ -152,7 +152,7 @@ export default { url, credentials = window.config.SYS_CREDENTIALS, workspace = window.config.SYS_WORKSPACE, - server = window.config.SYS_SERVER; + server = window.config.SYS_SERVER_API; url = this.getUrl(_.extend(keys, credentials, { server }, { workspace }), service); return axios({ @@ -175,7 +175,7 @@ export default { url, credentials = window.config.SYS_CREDENTIALS, workspace = window.config.SYS_WORKSPACE, - server = window.config.SYS_SERVER; + server = window.config.SYS_SERVER_API; url = this.getUrl(_.extend(keys, credentials, { server }, { workspace }), service); return axios({ @@ -197,7 +197,7 @@ export default { url, credentials = window.config.SYS_CREDENTIALS, workspace = window.config.SYS_WORKSPACE, - server = window.config.SYS_SERVER; + server = window.config.SYS_SERVER_API; url = this.getUrl(_.extend(keys, credentials, { server }, { workspace }), service); return axios({ diff --git a/resources/assets/js/api/CaseNotes.js b/resources/assets/js/api/CaseNotes.js index 4f463212b..b99dbff1b 100644 --- a/resources/assets/js/api/CaseNotes.js +++ b/resources/assets/js/api/CaseNotes.js @@ -10,7 +10,7 @@ export let caseNotes = { _.each(data.FILES, (f) => { params.append("filesToUpload[]", f); }) - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `appProxy/postNote`, params, { headers: { diff --git a/resources/assets/js/api/Cases.js b/resources/assets/js/api/Cases.js index 54b789ebd..df0c3bf77 100644 --- a/resources/assets/js/api/Cases.js +++ b/resources/assets/js/api/Cases.js @@ -51,7 +51,7 @@ export let cases = { params.append('delIndex', data.DEL_INDEX); params.append('action', 'todo'); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `appProxy/requestOpenSummary`, params); }, @@ -61,7 +61,7 @@ export let cases = { params.append('delIndex', data.DEL_INDEX); params.append('action', "getCasesInputDocuments"); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/cases_Ajax.php?action=getCasesInputDocuments`, params); }, @@ -71,7 +71,7 @@ export let cases = { params.append('delIndex', data.DEL_INDEX); params.append('action', "getCasesOutputDocuments"); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/cases_Ajax.php?action=getCasesOutputDocuments`, params); }, @@ -81,7 +81,7 @@ export let cases = { params.append('delIndex', data.DEL_INDEX); params.append('action', "todo"); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `appProxy/getSummary`, params, { headers: { @@ -97,12 +97,12 @@ export let cases = { params.append('tas', data.TAS_UID); params.append('start', "0"); params.append('limit', "30"); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `appProxy/getNotesList`, params); }, pendingtask(data) { - return axios.get(window.config.SYS_SERVER + + return axios.get(window.config.SYS_SERVER_API + '/api/1.0/' + window.config.SYS_WORKSPACE + '/home/' + data.APP_NUMBER + '/pending-tasks', { @@ -116,17 +116,17 @@ export let cases = { params.append('action', 'startCase'); params.append('processId', dt.pro_uid); params.append('taskId', dt.task_uid); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/casesStartPage_Ajax.php`, params); }, open(data) { - return axios.get(window.config.SYS_SERVER + + return axios.get(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/open?APP_UID=${data.APP_UID}&DEL_INDEX=${data.DEL_INDEX}&action=${data.ACTION}`); }, cases_open(data) { - return axios.get(window.config.SYS_SERVER + + return axios.get(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/cases_Open?APP_UID=${data.APP_UID}&DEL_INDEX=${data.DEL_INDEX}&action=${data.ACTION}`); }, @@ -135,7 +135,7 @@ export let cases = { params.append('action', 'cancelCase'); params.append('NOTE_REASON', data.COMMENT); params.append('NOTIFY_CANCEL', data.SEND); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/ajaxListener`, params); }, @@ -143,7 +143,7 @@ export let cases = { var params = new URLSearchParams(); params.append('action', 'getCaseMenu'); params.append('app_status', 'TO_DO'); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/ajaxListener`, params); }, @@ -152,13 +152,13 @@ export let cases = { params.append('action', 'unpauseCase'); params.append('sApplicationUID', data.APP_UID); params.append('iIndex', data.DEL_INDEX); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/cases_Ajax`, params); }, claim(data) { var params = new URLSearchParams(); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/cases_CatchExecute`, params); }, @@ -171,7 +171,7 @@ export let cases = { params.append('action', 'previusJump'); params.append('appNumber', dt.APP_NUMBER); params.append('actionFromList', dt.ACTION_FROM_LIST); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/cases_Ajax.php`, params); }, @@ -207,13 +207,13 @@ export let cases = { debugVars(data) { var params; if (data.filter === "all") { - return axios.get(window.config.SYS_SERVER + + return axios.get(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/debug_vars`); } else { params = new URLSearchParams(); params.append('filter', data.filter); - return axios.post(window.config.SYS_SERVER + + return axios.post(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/debug_vars`, params); } @@ -225,7 +225,7 @@ export let cases = { debugVarsTriggers(data) { let dc = _.random(0, 10000000000), r = _.random(1.0, 100.0); - return axios.get(window.config.SYS_SERVER + + return axios.get(window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/debug_triggers?r=${r}&_dc=${dc}`); }, @@ -233,7 +233,7 @@ export let cases = { export let casesHeader = { get() { - return axios.get(window.config.SYS_SERVER + + return axios.get(window.config.SYS_SERVER_API + '/api/1.0/' + window.config.SYS_WORKSPACE + '/home/counters', { diff --git a/resources/assets/js/api/Filters.js b/resources/assets/js/api/Filters.js index d7527475f..a82c6cc8b 100644 --- a/resources/assets/js/api/Filters.js +++ b/resources/assets/js/api/Filters.js @@ -39,7 +39,7 @@ export let filters = { var params = new URLSearchParams(); params.append("action", "startCase"); return axios.post( - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/casesStartPage_Ajax.php`, params @@ -87,7 +87,7 @@ export let filters = { */ userValues(query) { return axios.post( - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/casesList_Ajax?actionAjax=userValues&action=search`, { diff --git a/resources/assets/js/api/Menu.js b/resources/assets/js/api/Menu.js index c6ada4b82..f8dc27c88 100644 --- a/resources/assets/js/api/Menu.js +++ b/resources/assets/js/api/Menu.js @@ -3,7 +3,7 @@ import axios from 'axios'; export let menu = { get() { return axios.get( - window.config.SYS_SERVER + + window.config.SYS_SERVER_API + '/api/1.0/' + window.config.SYS_WORKSPACE + '/home/menu', { @@ -15,7 +15,7 @@ export let menu = { }, getCounters() { return axios.get( - window.config.SYS_SERVER + + window.config.SYS_SERVER_API + '/api/1.0/' + window.config.SYS_WORKSPACE + '/home/tasks/counter', { diff --git a/resources/assets/js/components/home/caseDetail/AttachedDocuments.vue b/resources/assets/js/components/home/caseDetail/AttachedDocuments.vue index 24d07a698..dd7e667c9 100644 --- a/resources/assets/js/components/home/caseDetail/AttachedDocuments.vue +++ b/resources/assets/js/components/home/caseDetail/AttachedDocuments.vue @@ -55,7 +55,7 @@ export default { }, href(item) { return ( - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/casesShowCaseNotes?a=${item.data.APP_DOC_UID}&v=${item.data.DOC_VERSION}` ); diff --git a/resources/assets/js/components/home/caseDetail/CaseComment.vue b/resources/assets/js/components/home/caseDetail/CaseComment.vue index 31fe9446a..831b93b3c 100644 --- a/resources/assets/js/components/home/caseDetail/CaseComment.vue +++ b/resources/assets/js/components/home/caseDetail/CaseComment.vue @@ -40,7 +40,7 @@ export default { path() { if (this.data) { return ( - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `users/users_ViewPhotoGrid?pUID=${this.data.data.USR_UID}` ); diff --git a/resources/assets/js/components/home/caseDetail/CaseComments.vue b/resources/assets/js/components/home/caseDetail/CaseComments.vue index 25f71bce7..d934c4e82 100644 --- a/resources/assets/js/components/home/caseDetail/CaseComments.vue +++ b/resources/assets/js/components/home/caseDetail/CaseComments.vue @@ -90,7 +90,7 @@ export default { computed: { pathImgOwner() { return ( - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `users/users_ViewPhotoGrid?pUID=${window.config.USR_UID}` ); diff --git a/resources/assets/js/components/home/caseDetail/CaseHistory.vue b/resources/assets/js/components/home/caseDetail/CaseHistory.vue index 22884178d..5ed45a4a8 100644 --- a/resources/assets/js/components/home/caseDetail/CaseHistory.vue +++ b/resources/assets/js/components/home/caseDetail/CaseHistory.vue @@ -27,7 +27,7 @@ export default { computed: { path() { let url = - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/ajaxListener?action=caseHistory`; return url; diff --git a/resources/assets/js/components/home/caseDetail/ChangeLog.vue b/resources/assets/js/components/home/caseDetail/ChangeLog.vue index 7587f1104..bf0fbc0e5 100644 --- a/resources/assets/js/components/home/caseDetail/ChangeLog.vue +++ b/resources/assets/js/components/home/caseDetail/ChangeLog.vue @@ -27,7 +27,7 @@ export default { computed: { path() { let url = - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/ajaxListener?action=changeLogHistory`; return url; diff --git a/resources/assets/js/components/home/caseDetail/IoDocuments.vue b/resources/assets/js/components/home/caseDetail/IoDocuments.vue index 7f6480ede..3cfe762fb 100644 --- a/resources/assets/js/components/home/caseDetail/IoDocuments.vue +++ b/resources/assets/js/components/home/caseDetail/IoDocuments.vue @@ -81,13 +81,13 @@ export default { href(item) { if (item.data.DOWNLOAD_LINK) { return ( - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/${item.data.DOWNLOAD_LINK}` ); } return ( - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/cases_ShowDocument?a=${item.data.APP_DOC_UID}&v=${item.data.DOC_VERSION}` ); @@ -96,7 +96,7 @@ export default { let random = _.random(0, 10000000), cacheTime = Date.now(); return ( - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/cases_ShowOutputDocument?a=${item.data.APP_DOC_UID}&v=${item.data.DOC_VERSION}&ext=doc&random=${random}&nocachetime=${cacheTime}` ); diff --git a/resources/assets/js/components/home/caseDetail/MoreInformation.vue b/resources/assets/js/components/home/caseDetail/MoreInformation.vue index 7fcd239ed..8321bb7fc 100644 --- a/resources/assets/js/components/home/caseDetail/MoreInformation.vue +++ b/resources/assets/js/components/home/caseDetail/MoreInformation.vue @@ -30,7 +30,7 @@ export default { let url = ""; if (this.data && this.data.DYN_UID) { url = - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + '/cases/summary?APP_UID='+this.data.APP_UID + '&DEL_INDEX=' + this.data.DEL_INDEX + diff --git a/resources/assets/js/components/home/caseDetail/ProcessMap.vue b/resources/assets/js/components/home/caseDetail/ProcessMap.vue index 165e82dca..6bf5ddf7c 100644 --- a/resources/assets/js/components/home/caseDetail/ProcessMap.vue +++ b/resources/assets/js/components/home/caseDetail/ProcessMap.vue @@ -29,7 +29,7 @@ export default { let url = ""; if (this.data && this.data.PRO_UID) { url = - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `designer?prj_uid=${this.data.PRO_UID}&prj_readonly=true&app_uid=${this.data.APP_UID}`; return url; diff --git a/resources/assets/js/home/AdvancedSearch.vue b/resources/assets/js/home/AdvancedSearch.vue index f72b21ee9..362496936 100644 --- a/resources/assets/js/home/AdvancedSearch.vue +++ b/resources/assets/js/home/AdvancedSearch.vue @@ -283,7 +283,7 @@ export default { USERNAME_DISPLAY_FORMAT: userDataFormat !== "" ? userDataFormat : this.$i18n.t("ID_UNASSIGNED"), EMAIL: data[i].user_tooltip.usr_email, POSITION: data[i].user_tooltip.usr_position, - AVATAR: userDataFormat !== "" ? window.config.SYS_SERVER + + AVATAR: userDataFormat !== "" ? window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `users/users_ViewPhotoGrid?pUID=${data[i].user_id}` : "", UNASSIGNED: userDataFormat !== "" ? true : false diff --git a/resources/assets/js/home/BatchRouting.vue b/resources/assets/js/home/BatchRouting.vue index 019b6b22c..faeacb8a1 100644 --- a/resources/assets/js/home/BatchRouting.vue +++ b/resources/assets/js/home/BatchRouting.vue @@ -27,7 +27,7 @@ export default { width: "100%", diffHeight: 10, path: - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + "cases/casesConsolidatedListExtJs?action=consolidated", }; diff --git a/resources/assets/js/home/MyCases.vue b/resources/assets/js/home/MyCases.vue index c06cff5de..baf3fdea3 100644 --- a/resources/assets/js/home/MyCases.vue +++ b/resources/assets/js/home/MyCases.vue @@ -354,7 +354,7 @@ export default { STATUS: data[i].tas_color, DELAYED_TITLE: this.delayedTitle(data[i], status), DELAYED_MSG: data[i].tas_status === "OVERDUE" && status !== "COMPLETED" ? data[i].delay : "", - AVATAR: userDataFormat !== "" ? window.config.SYS_SERVER + + AVATAR: userDataFormat !== "" ? window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `users/users_ViewPhotoGrid?pUID=${data[i].user_id}` : "", USERNAME: userDataFormat !== "" ? userDataFormat : this.$i18n.t("ID_UNASSIGNED"), diff --git a/resources/assets/js/home/MyDocuments.vue b/resources/assets/js/home/MyDocuments.vue index 3dc3f457a..b58436a7f 100644 --- a/resources/assets/js/home/MyDocuments.vue +++ b/resources/assets/js/home/MyDocuments.vue @@ -27,7 +27,7 @@ export default { width: "100%", diffHeight: 10, path: - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + "cases/casesStartPage?action=documents", }; diff --git a/resources/assets/js/home/TaskReassignments.vue b/resources/assets/js/home/TaskReassignments.vue index e07083ec4..4f4e35572 100644 --- a/resources/assets/js/home/TaskReassignments.vue +++ b/resources/assets/js/home/TaskReassignments.vue @@ -27,7 +27,7 @@ export default { width: "100%", diffHeight: 10, path: - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + "cases/casesListExtJs?action=to_reassign", }; diff --git a/resources/assets/js/home/XCase.vue b/resources/assets/js/home/XCase.vue index 3120db17e..7e3a55360 100644 --- a/resources/assets/js/home/XCase.vue +++ b/resources/assets/js/home/XCase.vue @@ -30,12 +30,12 @@ export default { this.dataCase = this.$parent.dataCase; if (this.dataCase.ACTION === "jump") { this.path = - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/open?APP_NUMBER=${this.dataCase.APP_NUMBER}&action=${this.dataCase.ACTION}&actionFromList=${this.dataCase.ACTION_FROM_LIST}`; } else { this.path = - window.config.SYS_SERVER + + window.config.SYS_SERVER_AJAX + window.config.SYS_URI + `cases/open?APP_UID=${this.dataCase.APP_UID}&DEL_INDEX=${this.dataCase.DEL_INDEX}&TAS_UID=${this.dataCase.TAS_UID}&action=${this.dataCase.ACTION}`; } diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Model/DelegationTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Model/DelegationTest.php index d7dc062ed..f26de1584 100644 --- a/tests/unit/workflow/engine/src/ProcessMaker/Model/DelegationTest.php +++ b/tests/unit/workflow/engine/src/ProcessMaker/Model/DelegationTest.php @@ -13,6 +13,7 @@ use ProcessMaker\Model\GroupUser; use ProcessMaker\Model\Groupwf; use ProcessMaker\Model\Process; use ProcessMaker\Model\ProcessCategory; +use ProcessMaker\Model\SubProcess; use ProcessMaker\Model\Task; use ProcessMaker\Model\TaskUser; use ProcessMaker\Model\User; @@ -2538,4 +2539,41 @@ class DelegationTest extends TestCase $this->assertNotEmpty($result); $this->assertEquals($result, $delegation->DEL_TITLE); } + + /** + * It should test the hasActiveParentsCases() method + * + * @covers \ProcessMaker\Model\Delegation::hasActiveParentsCases() + * @test + */ + public function it_should_test_the_has_active_parents_cases_method() + { + $process = factory(Process::class)->create(); + $processParent = factory(Process::class, 3)->create(); + factory(SubProcess::class)->create([ + 'PRO_UID' => $process['PRO_UID'], + 'PRO_PARENT' => $processParent[0]['PRO_UID'] + ]); + factory(SubProcess::class)->create([ + 'PRO_UID' => $process['PRO_UID'], + 'PRO_PARENT' => $processParent[1]['PRO_UID'] + ]); + factory(SubProcess::class)->create([ + 'PRO_UID' => $process['PRO_UID'], + 'PRO_PARENT' => $processParent[2]['PRO_UID'] + ]); + + $parents = SubProcess::getProParents($process['PRO_UID']); + + factory(Delegation::class)->create([ + 'PRO_UID' => $parents[0]['PRO_PARENT'], + 'TAS_UID' => $parents[0]['TAS_PARENT'], + 'DEL_THREAD_STATUS' => 'OPEN' + ]); + + $res = Delegation::hasActiveParentsCases($parents); + + // Assert the result is true + $this->assertTrue($res); + } } \ No newline at end of file diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Model/SubProcessTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Model/SubProcessTest.php new file mode 100644 index 000000000..61edcbb5f --- /dev/null +++ b/tests/unit/workflow/engine/src/ProcessMaker/Model/SubProcessTest.php @@ -0,0 +1,64 @@ +create(); + $processParent = factory(Process::class, 3)->create(); + factory(SubProcess::class)->create([ + 'PRO_UID' => $process['PRO_UID'], + 'PRO_PARENT' => $processParent[0]['PRO_UID'] + ]); + factory(SubProcess::class)->create([ + 'PRO_UID' => $process['PRO_UID'], + 'PRO_PARENT' => $processParent[1]['PRO_UID'] + ]); + factory(SubProcess::class)->create([ + 'PRO_UID' => $process['PRO_UID'], + 'PRO_PARENT' => $processParent[2]['PRO_UID'] + ]); + + $res = SubProcess::getProParents($process['PRO_UID']); + + $res = array_map(function ($x) { + return $x['PRO_PARENT']; + }, $res); + + // Assert the subprocess has three parents + $this->assertCount(3, $res); + + // Assert that the parents are the processes created + $this->assertContains($processParent[0]['PRO_UID'], $res); + $this->assertContains($processParent[1]['PRO_UID'], $res); + $this->assertContains($processParent[2]['PRO_UID'], $res); + } +} diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Model/TaskUserTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Model/TaskUserTest.php new file mode 100644 index 000000000..add792ba9 --- /dev/null +++ b/tests/unit/workflow/engine/src/ProcessMaker/Model/TaskUserTest.php @@ -0,0 +1,100 @@ +states('normal_assigment_user')->create(); + } else { + $assigment = factory(TaskUser::class)->states('normal_assigment_group')->create(); + } + } else { + if ($relation === 'USER'){ + $assigment = factory(TaskUser::class)->states('adhoc_assigment_user')->create(); + } else { + $assigment = factory(TaskUser::class)->states('adhoc_assigment_group')->create(); + } + } + + return $assigment; + } + /** + * Test belongs to TAS_UID + * + * @covers \ProcessMaker\Model\TaskUser::task() + * @test + */ + public function it_has_a_task() + { + $assigment = factory(TaskUser::class)->create([ + 'TAS_UID' => function () { + return factory(Task::class)->create()->TAS_UID; + } + ]); + $this->assertInstanceOf(Task::class, $assigment->task); + } + + /** + * Test belongs to USR_UID + * + * @covers \ProcessMaker\Model\TaskUser::user() + * @test + */ + public function it_has_a_user() + { + $assigment = factory(TaskUser::class)->create([ + 'USR_UID' => function () { + return factory(User::class)->create()->USR_UID; + } + ]); + $this->assertInstanceOf(User::class, $assigment->user); + } + + /** + * Test the assigment in the task + * + * @covers \ProcessMaker\Model\TaskUser::scopeAssigment() + * @covers \ProcessMaker\Model\TaskUser::getAssigment() + * @test + */ + public function it_has_an_assigment() + { + // Create factory + $assigment = $this->createAssigment(); + // Create the TaskUser object + $taskUser = new TaskUser(); + $response = $taskUser->getAssigment($assigment->TAS_UID, $assigment->USR_UID); + $this->assertNotEmpty($response); + // Create factory + $assigment = $this->createAssigment('NORMAL', 'GROUP'); + // Create the TaskUser object + $taskUser = new TaskUser(); + $response = $taskUser->getAssigment($assigment->TAS_UID, $assigment->USR_UID); + $this->assertNotEmpty($response); + } +} \ No newline at end of file diff --git a/workflow/engine/classes/Cases.php b/workflow/engine/classes/Cases.php index e476d0b64..4bef606e8 100644 --- a/workflow/engine/classes/Cases.php +++ b/workflow/engine/classes/Cases.php @@ -5876,11 +5876,11 @@ class Cases $opObjUid = $row['OP_OBJ_UID']; $obCaseStatus = $row['OP_CASE_STATUS']; - //The values of obCaseStatus is [ALL, COMPLETED, DRAFT, TO_DO, PAUSED] - //If the case is todo and we need the participate - //but we did not participated did not validate nothing and return array empty + // The values of obCaseStatus is [ALL, COMPLETED, DRAFT, TO_DO, PAUSED] + // If the case is todo and we need the participate + // but we did not participated did not validate nothing and return array empty $swParticipate = false; // must be false for default - if ($obCaseStatus != 'COMPLETED' && $opParticipated == 1) { + if ($opParticipated === 1) { $criteria = new Criteria('workflow'); $criteria->add(AppDelegationPeer::USR_UID, $usrUid); $criteria->add(AppDelegationPeer::APP_UID, $appUid); diff --git a/workflow/engine/classes/Derivation.php b/workflow/engine/classes/Derivation.php index 8a223fa03..8d507b519 100644 --- a/workflow/engine/classes/Derivation.php +++ b/workflow/engine/classes/Derivation.php @@ -801,9 +801,11 @@ class Derivation * @param bool $removeList * * @return void + * @deprecated function deprecated in Release 3.6.x */ private function updateList(array $arrayCurrentDelegationData, array $arrayNextDelegationData, $taskNextDelegation, array $arrayApplicationData, $delIndexNew, $aSp, $removeList) { + return; /*----------------------------------********---------------------------------*/ try { if ($arrayNextDelegationData["TAS_UID"] != "-1") { diff --git a/workflow/engine/content/translations/english/processmaker.en.po b/workflow/engine/content/translations/english/processmaker.en.po index 23221227e..5ffcd9d01 100755 --- a/workflow/engine/content/translations/english/processmaker.en.po +++ b/workflow/engine/content/translations/english/processmaker.en.po @@ -3383,6 +3383,12 @@ msgstr "You can not delete the template {0} because it has a relationship with E msgid "It is not possible to delete the department because it has subdepartments." msgstr "It is not possible to delete the department because it has subdepartments." +# TRANSLATION +# LABEL/ID_CANT_DELETE_SUB_PROCESS_PARENT_HAS_ACTIVE_CASES +#: LABEL/ID_CANT_DELETE_SUB_PROCESS_PARENT_HAS_ACTIVE_CASES +msgid "Is not possible to delete sub-process cases, while the master process has active cases." +msgstr "Is not possible to delete sub-process cases, while the master process has active cases." + # TRANSLATION # LABEL/ID_CANT_DELETE_DEPARTMENT_HAS_USERS #: LABEL/ID_CANT_DELETE_DEPARTMENT_HAS_USERS diff --git a/workflow/engine/data/mysql/insert.sql b/workflow/engine/data/mysql/insert.sql index 9f3b08360..6ef6d89ce 100755 --- a/workflow/engine/data/mysql/insert.sql +++ b/workflow/engine/data/mysql/insert.sql @@ -57371,6 +57371,7 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE ( 'LABEL','ID_CANNOT_IMPORT','en','CANNOT IMPORT','2017-10-03') , ( 'LABEL','ID_CANNOT_REMOVE_TEMPLATE_EMAIL_EVENT','en','You can not delete the template {0} because it has a relationship with Email Event','2016-07-05') , ( 'LABEL','ID_CANT_DELETE_DEPARTMENT_HAS_CHILDREN','en','It is not possible to delete the department because it has subdepartments.','2014-10-21') , +( 'LABEL','ID_CANT_DELETE_SUB_PROCESS_PARENT_HAS_ACTIVE_CASES','en','Is not possible to delete sub-process cases, while the master process has active cases.','2021-03-23') , ( 'LABEL','ID_CANT_DELETE_DEPARTMENT_HAS_USERS','en','Department cannot be deleted while it has assigned users.','2015-03-23') , ( 'LABEL','ID_CANT_RESOLVE_APPLICATION','en','Can''t resolve the Aplication ID for this request.','2014-01-15') , ( 'LABEL','ID_CANT_SAVE_TRIGGER','en','A trigger with the same name already exists in this process.','2014-05-29') , diff --git a/workflow/engine/methods/cases/ajaxListener.php b/workflow/engine/methods/cases/ajaxListener.php index 691e1eeeb..0b037d2c4 100644 --- a/workflow/engine/methods/cases/ajaxListener.php +++ b/workflow/engine/methods/cases/ajaxListener.php @@ -246,7 +246,17 @@ class Ajax || in_array($appUid, $userAuthorization['objectPermissions']['REASSIGN_MY_CASES']) ) { if (!AppDelay::isPaused($appUid, $index)) { - $options[] = ['text' => G::LoadTranslation('ID_REASSIGN'), 'fn' => 'getUsersToReassign']; + $subprocess = SubProcess::getSubProcessConfiguration( + $proUid, + $_SESSION['CURRENT_TASK'] + ); + if (empty($subprocess)) { + $options[] = ['text' => G::LoadTranslation('ID_REASSIGN'), 'fn' => 'getUsersToReassign']; + } else { + if ($subprocess['SP_SYNCHRONOUS'] == 0) { + $options[] = ['text' => G::LoadTranslation('ID_REASSIGN'), 'fn' => 'getUsersToReassign']; + } + } } } break; diff --git a/workflow/engine/methods/cases/casesHistoryDynaformPage_Ajax.php b/workflow/engine/methods/cases/casesHistoryDynaformPage_Ajax.php index 431102ce9..0fa2876fd 100644 --- a/workflow/engine/methods/cases/casesHistoryDynaformPage_Ajax.php +++ b/workflow/engine/methods/cases/casesHistoryDynaformPage_Ajax.php @@ -48,7 +48,7 @@ if ($actionAjax == 'historyDynaformGrid_Ajax') { $c = $oCase->getallDynaformsCriteria( $_SESSION['PROCESS'], $_SESSION['APPLICATION'], - $_SESSION['CURRENT_TASK'], + $_SESSION['TASK'], $_SESSION['USER_LOGGED'], $_SESSION['INDEX'] ); diff --git a/workflow/engine/methods/cases/cases_Step.php b/workflow/engine/methods/cases/cases_Step.php index 29ca5f703..7584b1c62 100644 --- a/workflow/engine/methods/cases/cases_Step.php +++ b/workflow/engine/methods/cases/cases_Step.php @@ -1053,7 +1053,7 @@ try { // Swap temporary APP_NUMBER $newAppNumber = $bmWebEntry->swapTemporaryAppNumber($caseId); $Fields['APP_NUMBER'] = $Fields['APP_DATA']['APP_NUMBER'] = $newAppNumber; - $derivationResponse = PMFDerivateCase($caseId, $delIndex, true); + $derivationResponse = PMFDerivateCase($caseId, $delIndex, false); if ($derivationResponse) { $webEntryUrl = $bmWebEntry->getCallbackUrlByTask($currentTask['TAS_UID']); $delegationData = $Fields['APP_DATA']; diff --git a/workflow/engine/methods/cases/viena_init.php b/workflow/engine/methods/cases/viena_init.php index 607ec9a8b..229ae00b0 100644 --- a/workflow/engine/methods/cases/viena_init.php +++ b/workflow/engine/methods/cases/viena_init.php @@ -136,7 +136,8 @@ $pmDynaform = new PmDynaform(); ScriptVariables::add('defaultOption', $defaultOption); ScriptVariables::add('_nodeId', isset($confDefaultOption) ? $confDefaultOption : "PM_USERS"); ScriptVariables::add('SYS_CREDENTIALS', $pmDynaform->getCredentials()); -ScriptVariables::add('SYS_SERVER', System::getHttpServerHostnameRequestsFrontEnd()); +ScriptVariables::add('SYS_SERVER_API', System::getHttpServerHostnameRequestsFrontEnd()); +ScriptVariables::add('SYS_SERVER_AJAX', System::getServerProtocolHost()); ScriptVariables::add('SYS_WORKSPACE', config("system.workspace")); ScriptVariables::add('SYS_URI', SYS_URI); ScriptVariables::add('SYS_LANG', SYS_LANG); diff --git a/workflow/engine/methods/processes/processes_DeleteCases.php b/workflow/engine/methods/processes/processes_DeleteCases.php index 7fdaee1bb..f2f156133 100644 --- a/workflow/engine/methods/processes/processes_DeleteCases.php +++ b/workflow/engine/methods/processes/processes_DeleteCases.php @@ -1,4 +1,8 @@ status = false; + $resp->msg = G::LoadTranslation('ID_CANT_DELETE_SUB_PROCESS_PARENT_HAS_ACTIVE_CASES'); + echo G::json_encode($resp); + die(); + } + } $process->deleteProcessCases($uid); } @@ -21,11 +34,9 @@ try { $resp->msg = G::LoadTranslation('ID_ALL_RECORDS_DELETED_SUCESSFULLY'); echo G::json_encode($resp); - } catch (Exception $e) { $resp->status = false; $resp->msg = $e->getMessage(); $resp->trace = $e->getTraceAsString(); echo G::json_encode($resp); } - diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php b/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php index d01e9de2e..7390dab78 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Cases.php @@ -4275,7 +4275,7 @@ class Cases $query->where('APPLICATION.APP_UID', '=', $appUid); // Filter by source task - if ($caseStatus != 'COMPLETED' && $sourceTask != '' && (int)$sourceTask != 0) { + if (!empty($sourceTask) && (int)$sourceTask != 0) { $query->where('STEP.TAS_UID', '=', $sourceTask); } diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Task.php b/workflow/engine/src/ProcessMaker/BusinessModel/Task.php index f9dbd8328..612ced2b1 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/Task.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Task.php @@ -1,10 +1,14 @@ validateActUid($sTaskUID); - $iType = 1; - $iRelation = ''; - $oCriteria = new \Criteria('workflow'); - $oCriteria->addSelectColumn( \TaskUserPeer::TU_RELATION ); - $oCriteria->add(\TaskUserPeer::USR_UID, $sAssigneeUID ); - $oCriteria->add(\TaskUserPeer::TAS_UID, $sTaskUID ); - $oCriteria->add(\TaskUserPeer::TU_TYPE, $iType ); - $oTaskUser = \TaskUserPeer::doSelectRS( $oCriteria ); - $oTaskUser->setFetchmode(\ResultSet::FETCHMODE_ASSOC); - while ($oTaskUser->next()) { - $aRow = $oTaskUser->getRow(); - $iRelation = $aRow['TU_RELATION']; - } - $oTaskUser = \TaskUserPeer::retrieveByPK( $sTaskUID, $sAssigneeUID, $iType, $iRelation ); - if (! is_null( $oTaskUser )) { - throw new \Exception(\G::LoadTranslation("ID_ALREADY_ASSIGNED", array($sAssigneeUID, $sTaskUID))); + Validator::proUid($proUid, '$prj_uid'); + $this->validateActUid($tasUid); + $taskUser = new TaskUser(); + $response = $taskUser->getAssigment($tasUid, $uid); + if (!empty($response)) { + throw new Exception(G::LoadTranslation("ID_ALREADY_ASSIGNED", [$uid, $tasUid])); } else { - $oTypeAssigneeG = \GroupwfPeer::retrieveByPK( $sAssigneeUID ); - $oTypeAssigneeU = \UsersPeer::retrieveByPK( $sAssigneeUID ); - if (is_null( $oTypeAssigneeG ) && is_null( $oTypeAssigneeU ) ) { - throw new \Exception(\G::LoadTranslation("ID_DOES_NOT_CORRESPOND", array($sAssigneeUID, $assType))); + $groupUid = Groupwf::query()->select()->group($uid)->get()->toArray(); + $userUid = User::query()->select()->user($uid)->get()->toArray(); + if (empty($groupUid) && empty($userUid)) { + throw new Exception(G::LoadTranslation("ID_DOES_NOT_CORRESPOND", [$uid, $type])); } - if (is_null( $oTypeAssigneeG ) && ! is_null( $oTypeAssigneeU) ) { - $type = "user"; - if ( $type != $assType ) { - throw new \Exception(\G::LoadTranslation("ID_DOES_NOT_CORRESPOND", array($sAssigneeUID, $assType))); - } + if (empty($groupUid) && !empty($userUid) && $type !== "user") { + throw new Exception(G::LoadTranslation("ID_DOES_NOT_CORRESPOND", [$uid, $type])); } - if (! is_null( $oTypeAssigneeG ) && is_null( $oTypeAssigneeU ) ) { - $type = "group"; - if ( $type != $assType ) { - throw new \Exception(\G::LoadTranslation("ID_DOES_NOT_CORRESPOND", array($sAssigneeUID, $assType))); - } - } - $oTaskUser = new \TaskUser(); - if ( $assType == "user" ) { - $oTaskUser->create(array('TAS_UID' => $sTaskUID, - 'USR_UID' => $sAssigneeUID, - 'TU_TYPE' => $iType, - 'TU_RELATION' => 1)); - } else { - $oTaskUser->create(array('TAS_UID' => $sTaskUID, - 'USR_UID' => $sAssigneeUID, - 'TU_TYPE' => $iType, - 'TU_RELATION' => 2)); + if (!empty($groupUid) && empty($userUid) && $type !== "group") { + throw new Exception(G::LoadTranslation("ID_DOES_NOT_CORRESPOND", [$uid, $type])); } + // Register the assigment + $attributes = [ + 'TAS_UID' => $tasUid, + 'USR_UID' => $uid, + 'TU_TYPE' => 1, + 'TU_RELATION' => ($type === "user") ? 1 : 2 + ]; + $assigment = TaskUser::create($attributes); + // Register the action in audit log + $assignTask = ($type === "user") ? 'AssignUserTask' : 'AssignGroupTask'; + G::auditlog($assignTask, 'Assign ' . $type . ' to Task -> ' . $tasUid . ',' . $type . ' Uid -> ' . $uid); } - } catch ( \Exception $e ) { + } catch (Exception $e) { throw $e; } } diff --git a/workflow/engine/src/ProcessMaker/Log/AuditLog.php b/workflow/engine/src/ProcessMaker/Log/AuditLog.php index f8e6960a8..05de22370 100644 --- a/workflow/engine/src/ProcessMaker/Log/AuditLog.php +++ b/workflow/engine/src/ProcessMaker/Log/AuditLog.php @@ -29,16 +29,21 @@ class AuditLog $this->columns = ['date', 'workspace', 'ip', 'id', 'user', 'action', 'description']; $this->actions = [ + // User "CreateUser" => G::LoadTranslation("ID_CREATE_USER"), "UpdateUser" => G::LoadTranslation("ID_UPDATE_USER"), "DeleteUser" => G::LoadTranslation("ID_DELETE_USER"), "EnableUser" => G::LoadTranslation("ID_ENABLE_USER"), "DisableUser" => G::LoadTranslation("ID_DISABLE_USER"), - "AssignAuthenticationSource" => G::LoadTranslation("ID_ASSIGN_AUTHENTICATION_SOURCE"), "AssignUserToGroup" => G::LoadTranslation("ID_ASSIGN_USER_TO_GROUP"), + "RemoveUser" => G::LoadTranslation("ID_REMOVE_USER"), + // Authentication + "AssignAuthenticationSource" => G::LoadTranslation("ID_ASSIGN_AUTHENTICATION_SOURCE"), "CreateAuthSource" => G::LoadTranslation("ID_CREATE_AUTH_SOURCE"), "UpdateAuthSource" => G::LoadTranslation("ID_UPDATE_AUTH_SOURCE"), "DeleteAuthSource" => G::LoadTranslation("ID_DELETE_AUTH_SOURCE"), + // Role + "AssignRole" => G::LoadTranslation("ID_ASSIGN_ROLE"), "CreateRole" => G::LoadTranslation("ID_CREATE_ROLE"), "UpdateRole" => G::LoadTranslation("ID_UPDATE_ROLE"), "DeleteRole" => G::LoadTranslation("ID_DELETE_ROLE"), @@ -46,70 +51,83 @@ class AuditLog "DeleteUserToRole" => G::LoadTranslation("ID_DELETE_USER_TO_ROLE"), "AddPermissionToRole" => G::LoadTranslation("ID_ADD_PERMISSION_TO_ROLE"), "DeletePermissionToRole" => G::LoadTranslation("ID_DELETE_PERMISSION_TO_ROLE"), + // Skin "CreateSkin" => G::LoadTranslation("ID_CREATE_SKIN"), "ImportSkin" => G::LoadTranslation("ID_IMPORT_SKIN"), "ExportSkin" => G::LoadTranslation("ID_EXPORT_SKIN"), "DeleteSkin" => G::LoadTranslation("ID_DELETE_SKIN"), + // Group "CreateGroup" => G::LoadTranslation("ID_CREATE_GROUP"), "UpdateGroup" => G::LoadTranslation("ID_UPDATE_GROUP"), "DeleteGroup" => G::LoadTranslation("ID_DELETE_GROUP"), + // Category "CreateCategory" => G::LoadTranslation("ID_CREATE_CATEGORY"), "UpdateCategory" => G::LoadTranslation("ID_UPDATE_CATEGORY"), "DeleteCategory" => G::LoadTranslation("ID_DELETE_CATEGORY"), + // Cache "BuildCache" => G::LoadTranslation("ID_BUILD_CACHE"), "ClearCache" => G::LoadTranslation("ID_CLEAR_CACHE"), + // Cron "ClearCron" => G::LoadTranslation("ID_CLEAR_CRON"), "UpdateEnvironmentSettings" => G::LoadTranslation("ID_UPDATE_ENVIRONMENT_SETTINGS"), "UpdateLoginSettings" => G::LoadTranslation("ID_UPDATE_LOGIN_SETTINGS"), "EnableHeartBeat" => G::LoadTranslation("ID_ENABLE_HEART_BEAT"), "DisableHeartBeat" => G::LoadTranslation("ID_DISABLE_HEART_BEAT"), + // PmTables "CreatePmtable" => G::LoadTranslation("ID_CREATE_PMTABLE"), "UpdatePmtable" => G::LoadTranslation("ID_UPDATE_PMTABLE"), "DeletePmtable" => G::LoadTranslation("ID_DELETE_PMTABLE"), "AddDataPmtable" => G::LoadTranslation("ID_ADD_DATA_PMTABLE"), "UpdateDataPmtable" => G::LoadTranslation("ID_UPDATE_DATA_PMTABLE"), "DeleteDataPmtable" => G::LoadTranslation("ID_DELETE_DATA_PMTABLE"), - "ImportTable" => G::LoadTranslation("ID_IMPORT_TABLE"), - "ExportTable" => G::LoadTranslation("ID_EXPORT_TABLE"), + "ImportPmTable" => G::LoadTranslation("ID_IMPORT_TABLE"), + "ExportPmTable" => G::LoadTranslation("ID_EXPORT_TABLE"), + // Calendar "CreateCalendar" => G::LoadTranslation("ID_CREATE_CALENDAR"), "UpdateCalendar" => G::LoadTranslation("ID_UPDATE_CALENDAR"), "DeleteCalendar" => G::LoadTranslation("ID_DELETE_CALENDAR"), + // Dashlet "CreateDashletInstance" => G::LoadTranslation("ID_CREATE_DASHLET_INSTANCE"), "UpdateDashletInstance" => G::LoadTranslation("ID_UPDATE_DASHLET_INSTANCE"), "DeleteDashletInstance" => G::LoadTranslation("ID_DELETE_DASHLET_INSTANCE"), - "CreateDepartament" => G::LoadTranslation("ID_CREATE_DEPARTAMENT"), - "CreateSubDepartament" => G::LoadTranslation("ID_CREATE_SUB_DEPARTAMENT"), - "UpdateDepartament" => G::LoadTranslation("ID_UPDATE_DEPARTAMENT"), - "UpdateSubDepartament" => G::LoadTranslation("ID_UPDATE_SUB_DEPARTAMENT"), - "DeleteDepartament" => G::LoadTranslation("ID_DELETE_DEPARTAMENT"), - "AssignManagerToDepartament" => G::LoadTranslation("ID_ASSIGN_MANAGER_TO_DEPARTAMENT"), - "AssignUserToDepartament" => G::LoadTranslation("ID_ASSIGN_USER_TO_DEPARTAMENT"), - "RemoveUsersFromDepartament" => G::LoadTranslation("ID_REMOVE_USERS_FROM_DEPARTAMENT"), - "AssignUserToGroup" => G::LoadTranslation("ID_ASSIGN_USER_TO_GROUP"), + // Department + "CreateDepartment" => G::LoadTranslation("ID_CREATE_DEPARTAMENT"), + "CreateSubDepartment" => G::LoadTranslation("ID_CREATE_SUB_DEPARTAMENT"), + "UpdateDepartment" => G::LoadTranslation("ID_UPDATE_DEPARTAMENT"), + "UpdateSubDepartment" => G::LoadTranslation("ID_UPDATE_SUB_DEPARTAMENT"), + "DeleteDepartment" => G::LoadTranslation("ID_DELETE_DEPARTAMENT"), + "AssignManagerToDepartment" => G::LoadTranslation("ID_ASSIGN_MANAGER_TO_DEPARTAMENT"), + "AssignUserToDepartment" => G::LoadTranslation("ID_ASSIGN_USER_TO_DEPARTAMENT"), + "RemoveUsersFromDepartment" => G::LoadTranslation("ID_REMOVE_USERS_FROM_DEPARTAMENT"), + // Language "UploadLanguage" => G::LoadTranslation("ID_UPLOAD_LANGUAGE"), "ExportLanguage" => G::LoadTranslation("ID_EXPORT_LANGUAGE"), "DeleteLanguage" => G::LoadTranslation("ID_DELETE_LAGUAGE"), + // Settings "UploadSystemSettings" => G::LoadTranslation("ID_UPLOAD_SYSTEM_SETTINGS"), "UpdateEmailSettings" => G::LoadTranslation("ID_UPDATE_EMAIL_SETTINGS"), "CreateEmailSettings" => G::LoadTranslation("ID_CREATE_EMAIL_SETTINGS"), + // Logo "UploadLogo" => G::LoadTranslation("ID_UPLOAD_LOGO"), "DeleteLogo" => G::LoadTranslation("ID_DELETE_LOGO"), "RestoreLogo" => G::LoadTranslation("ID_RESTORE_LOGO"), "ReplaceLogo" => G::LoadTranslation("ID_REPLACE_LOGO"), + // Plugin "InstallPlugin" => G::LoadTranslation("ID_INSTALL_PLUGIN"), "EnablePlugin" => G::LoadTranslation("ID_ENABLE_PLUGIN"), "DisablePlugin" => G::LoadTranslation("ID_DISABLE_PLUGIN"), "RemovePlugin" => G::LoadTranslation("ID_REMOVE_PLUGIN"), - "SetColumns" => G::LoadTranslation("ID_SET_COLUMNS"), + // AuditLog "EnableAuditLog" => G::LoadTranslation("ID_ENABLE_AUDIT_LOG"), "DisableAuditLog" => G::LoadTranslation("ID_DISABLE_AUDIT_LOG"), + // Process "EditProcess" => G::LoadTranslation("ID_EDIT_PROCESS"), "ExportProcess" => G::LoadTranslation("ID_EXPORT_PROCESS"), + "ImportProcess" => G::LoadTranslation("ID_IMPORT_PROCESS"), + "DeleteProcess" => G::LoadTranslation("ID_DELETE_PROCESS"), + // Web entry "WebEntry" => G::LoadTranslation("ID_WEB_ENTRY"), - "AssignRole" => G::LoadTranslation("ID_ASSIGN_ROLE"), - "RemoveUser" => G::LoadTranslation("ID_REMOVE_USER"), - "AddTask" => G::LoadTranslation("ID_ADD_TASK"), - "AddSubProcess" => G::LoadTranslation("ID_ADD_SUB_PROCESS"), + // Diagram "SaveTaskPosition" => G::LoadTranslation("ID_SAVE_TASK_POSITION"), "AddHorizontalLine" => G::LoadTranslation("ID_ADD_HORIZONTAL_LINE"), "AddVerticalLine" => G::LoadTranslation("ID_ADD_VERTICAL_LINE"), @@ -120,60 +138,75 @@ class AuditLog "UpdateText" => G::LoadTranslation("ID_UPDATE_TEXT"), "SaveTextPosition" => G::LoadTranslation("ID_SAVE_TEXT_POSITION"), "DeleteText" => G::LoadTranslation("ID_DELETE_TEXT"), + "EditEvent" => G::LoadTranslation("ID_EDIT_EVENT"), + "DeleteEvent" => G::LoadTranslation("ID_EVENT_DELETED"), + // File Manager "ProcessFileManager" => G::LoadTranslation("ID_PROCESS_FILE_MANAGER"), + // Process Permission "ProcessPermissions" => G::LoadTranslation("ID_PROCESS_PERMISSIONS"), "DeletePermissions" => G::LoadTranslation("ID_DELETE_PERMISSIONS"), + // Supervising "AssignSupervisorDynaform" => G::LoadTranslation("ID_ASSIGN_SUPERVISOR_DYNAFORM"), "RemoveSupervisorDynaform" => G::LoadTranslation("ID_REMOVE_SUPERVISOR_DYNAFORM"), "AssignSupervisorInput" => G::LoadTranslation("ID_ASSIGN_SUPERVISOR_INPUT"), "RemoveSupervisorInput" => G::LoadTranslation("ID_REMOVE_SUPERVISOR_INPUT"), + // Case Tracker "CaseTrackers" => G::LoadTranslation("ID_CASE_TRACKERS"), - "EditEvent" => G::LoadTranslation("ID_EDIT_EVENT"), - "DeleteEvent" => G::LoadTranslation("ID_EVENT_DELETED"), + // Dynaform "CreateDynaform" => G::LoadTranslation("ID_CREATE_DYNAFORM"), "UpdateDynaform" => G::LoadTranslation("ID_UPDATE_DYNAFORM"), "DeleteDynaform" => G::LoadTranslation("ID_DELETE_DYNAFORM"), "ConditionsEditorDynaform" => G::LoadTranslation("ID_CONDITIONS_EDITOR_DYNAFORM"), + "SetColumns" => G::LoadTranslation("ID_SET_COLUMNS"), + // Case Scheduler "CreateCaseScheduler" => G::LoadTranslation("ID_CREATE_CASE_SCHEDULER"), "UpdateCaseScheduler" => G::LoadTranslation("ID_UPDATE_CASE_SCHEDULER"), "DeleteCaseScheduler" => G::LoadTranslation("ID_DELETE_CASE_SCHEDULER"), + // Database Connection "CreateDatabaseConnection" => G::LoadTranslation("ID_CREATE_DATABASE_CONNECTION"), "UpdateDatabaseConnection" => G::LoadTranslation("ID_UPDATE_DATABASE_CONNECTION"), "DeleteDatabaseConnection" => G::LoadTranslation("ID_DELETE_DATABASE_CONNECTION"), + // Input Document "CreateInputDocument" => G::LoadTranslation("ID_CREATE_INPUT_DOCUMENT"), "UpdateInputDocument" => G::LoadTranslation("ID_UPDATE_INPUT_DOCUMENT"), "DeleteInputDocument" => G::LoadTranslation("ID_DELETE_INPUT_DOCUMENT"), + // Output Document "CreateOutputDocument" => G::LoadTranslation("ID_CREATE_OUTPUT_DOCUMENT"), "UpdateOutputDocument" => G::LoadTranslation("ID_UPDATE_OUTPUT_DOCUMENT"), "DeleteOutputDocument" => G::LoadTranslation("ID_DELETE_OUTPUT_DOCUMENT"), + // Trigger "CreateTrigger" => G::LoadTranslation("ID_CREATE_TRIGGER"), "UpdateTrigger" => G::LoadTranslation("ID_UPDATE_TRIGGER"), "DeleteTrigger" => G::LoadTranslation("ID_DELETE_TRIGGER"), - "DerivationRule" => G::LoadTranslation("ID_DERIVATION_RULE"), - "DeleteTask" => G::LoadTranslation("ID_DELETE_TASK"), - "DeleteSubProcess" => G::LoadTranslation("ID_DELETE_SUB_PROCESS"), - "OptionsMenuTask" => G::LoadTranslation("ID_OPTIONS_MENU_TASK"), - "SaveTaskProperties" => G::LoadTranslation("ID_SAVE_TASK_PROPERTIES"), - "DeleteRoutes" => G::LoadTranslation("ID_DELETE_ROUTES"), - "NewConditionFromStep" => G::LoadTranslation("ID_NEW_CONDITION_FROM_STEP"), "AssignTrigger" => G::LoadTranslation("ID_ASSIGN_TRIGGER"), "UpTrigger" => G::LoadTranslation("ID_UP_TRIGGER"), "DownTrigger" => G::LoadTranslation("ID_DOWN_TRIGGER"), + "DerivationRule" => G::LoadTranslation("ID_DERIVATION_RULE"), + "OptionsMenuTask" => G::LoadTranslation("ID_OPTIONS_MENU_TASK"), + "DeleteRoutes" => G::LoadTranslation("ID_DELETE_ROUTES"), + // Steps + "NewConditionFromStep" => G::LoadTranslation("ID_NEW_CONDITION_FROM_STEP"), "StepDelete" => G::LoadTranslation("ID_STEP_DELETE"), "StepUp" => G::LoadTranslation("ID_STEP_UP"), "StepDown" => G::LoadTranslation("ID_STEP_DOWN"), "SaveNewStep" => G::LoadTranslation("ID_SAVE_NEW_STEP"), + // Task + "AddTask" => G::LoadTranslation("ID_ADD_TASK"), + "AddSubProcess" => G::LoadTranslation("ID_ADD_SUB_PROCESS"), "AssignUserTask" => G::LoadTranslation("ID_ASSIGN_USER_TASK"), "AssignGroupTask" => G::LoadTranslation("ID_ASSIGN_GROUP_TASK"), "DeleteUserTask" => G::LoadTranslation("ID_DELETE_USER_TASK"), "DeleteGroupTask" => G::LoadTranslation("ID_DELETE_GROUP_TASK"), - "ImportProcess" => G::LoadTranslation("ID_IMPORT_PROCESS"), - "DeleteProcess" => G::LoadTranslation("ID_DELETE_PROCESS"), + "DeleteTask" => G::LoadTranslation("ID_DELETE_TASK"), + "DeleteSubProcess" => G::LoadTranslation("ID_DELETE_SUB_PROCESS"), + "SaveTaskProperties" => G::LoadTranslation("ID_SAVE_TASK_PROPERTIES"), + // GSuite "GSuiteConfigurationSaved" => G::LoadTranslation("ID_G_SUITE_CONFIGURATION_SAVED"), "GSuiteConnect" => G::LoadTranslation("ID_G_SUITE_CONNECT"), "GSuiteDisconnect" => G::LoadTranslation("ID_G_SUITE_DISCONNECT"), "GSuiteLoadGroups" => G::LoadTranslation("ID_G_SUITE_LOAD_GROUPS"), "GSuiteSyncUsers" => G::LoadTranslation("ID_G_SUITE_SYNC_USERS"), + // Saml "SamlEnable" => G::LoadTranslation("ID_SAML_ENABLE"), "SamlProvider" => G::LoadTranslation("ID_SAML_PROVIDER") ]; diff --git a/workflow/engine/src/ProcessMaker/Model/Delegation.php b/workflow/engine/src/ProcessMaker/Model/Delegation.php index 241ca7e93..2d889e07a 100644 --- a/workflow/engine/src/ProcessMaker/Model/Delegation.php +++ b/workflow/engine/src/ProcessMaker/Model/Delegation.php @@ -834,9 +834,9 @@ class Delegation extends Model */ public function scopeJoinPreviousIndex($query) { - $query->leftJoin('APP_DELEGATION AS AD', function( $leftJoin) { + $query->leftJoin('APP_DELEGATION AS AD', function ($leftJoin) { $leftJoin->on('APP_DELEGATION.APP_NUMBER', '=', 'AD.APP_NUMBER') - ->on('APP_DELEGATION.DEL_PREVIOUS', '=', 'AD.DEL_INDEX'); + ->on('APP_DELEGATION.DEL_PREVIOUS', '=', 'AD.DEL_INDEX'); }); return $query; @@ -1863,7 +1863,7 @@ class Delegation extends Model $cases = new Cases; if (!is_array($caseData)) { $r = $cases->unserializeData($caseData); - if($r !== false) { + if ($r !== false) { $caseData = $r; } } @@ -1877,13 +1877,13 @@ class Delegation extends Model // If is empty get the previous title if ($delIndexPrevious > 0) { $thread = self::getThreadInfo($appNumber, $delIndexPrevious); - if(empty($thread['DEL_TITLE'])) { - $threadTitle = '# '. $appNumber; + if (empty($thread['DEL_TITLE'])) { + $threadTitle = '# ' . $appNumber; } else { $threadTitle = $thread['DEL_TITLE']; } } else { - $threadTitle = '# '. $appNumber; + $threadTitle = '# ' . $appNumber; } } @@ -1949,4 +1949,24 @@ class Delegation extends Model return $results; } + + /** + * Check if a subprocess has active parent cases + * + * @param array $parents + * @return bool + */ + public static function hasActiveParentsCases($parents) + { + foreach ($parents as $parent) { + $query = Delegation::select()->where('PRO_UID', $parent['PRO_PARENT']) + ->where('TAS_UID', $parent['TAS_PARENT'])->where('DEL_THREAD_STATUS', 'OPEN') + ->limit(1); + $res = $query->get()->values()->toArray(); + if (!empty($res)) { + return true; + } + } + return false; + } } diff --git a/workflow/engine/src/ProcessMaker/Model/Groupwf.php b/workflow/engine/src/ProcessMaker/Model/Groupwf.php index 5a383010b..52b47bd04 100644 --- a/workflow/engine/src/ProcessMaker/Model/Groupwf.php +++ b/workflow/engine/src/ProcessMaker/Model/Groupwf.php @@ -29,5 +29,18 @@ class Groupwf extends Model { return $this->belongsTo(GroupUser::class, 'GRP_ID', 'GRP_ID'); } + + /** + * Scope for query to get the group uid + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param string $uid + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeGroup($query, $uid) + { + return $query->where('GRP_UID', $uid); + } } diff --git a/workflow/engine/src/ProcessMaker/Model/SubProcess.php b/workflow/engine/src/ProcessMaker/Model/SubProcess.php new file mode 100644 index 000000000..e7ec2421e --- /dev/null +++ b/workflow/engine/src/ProcessMaker/Model/SubProcess.php @@ -0,0 +1,26 @@ +where('PRO_UID', $proUid); + return $query->get()->values()->toArray(); + } +} diff --git a/workflow/engine/src/ProcessMaker/Model/TaskUser.php b/workflow/engine/src/ProcessMaker/Model/TaskUser.php index 841b55a2f..27815533f 100644 --- a/workflow/engine/src/ProcessMaker/Model/TaskUser.php +++ b/workflow/engine/src/ProcessMaker/Model/TaskUser.php @@ -10,6 +10,20 @@ class TaskUser extends Model public $timestamps = false; + /** + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = [ + 'TAS_UID', + 'TAS_ID', + 'USR_UID', + 'TU_TYPE', + 'TU_RELATION', + 'ASSIGNED_ID', + ]; + /** * Return the task this belongs to */ @@ -26,6 +40,21 @@ class TaskUser extends Model return $this->belongsTo(User::class, 'USR_UID', 'USR_UID'); } + /** + * Scope for query to get the assigment + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param string $tasUid + * @param string $usrUid + * @param integer $type + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeAssigment($query, $tasUid, $usrUid, $type = 1) + { + return $query->where('TAS_UID', $tasUid)->where('USR_UID', $usrUid)->where('TU_TYPE', $type); + } + /** * Get the task self services related to the user * @@ -69,4 +98,22 @@ class TaskUser extends Model return $tasks; } + + /** + * Get the specific assigment related to the task, by default the normal assigment + * + * @param string $tasUid + * @param string $uid + * @param integer $type, can be 1 = Normal or 2 = Ad-hoc + * + * @return array + */ + public static function getAssigment($tasUid, $uid, $type = 1) + { + $query = TaskUser::query()->select() + ->assigment($tasUid, $uid, $type); + $result = $query->get()->toArray(); + + return head($result); + } } \ No newline at end of file diff --git a/workflow/engine/src/ProcessMaker/Model/User.php b/workflow/engine/src/ProcessMaker/Model/User.php index cd6a9502f..807201242 100644 --- a/workflow/engine/src/ProcessMaker/Model/User.php +++ b/workflow/engine/src/ProcessMaker/Model/User.php @@ -41,8 +41,7 @@ class User extends Model */ public function scopeUser($query, string $usrUid) { - $result = $query->where('USR_UID', '=', $usrUid); - return $result; + return $query->where('USR_UID', '=', $usrUid); } /**