Questions and discussion about developing processes and programming in PHP, JavaScript, web services & REST API.
Forum rules: Please search to see if a question has already asked before creating a new topic. Please don't post the same question in multiple forums.
#812798
Hello,
I have a Grid where a user needs to set the operations for several products. To make things easier, I guess, I'm thinking to put one operation by row, like this:
Product | Operation
A | X
A | Y
B | Z
As this matrix has a variable number of rows, how can I solve this on the design? I want one case per row for the next task.
I can generate the cases programatically with PMFNewCase() but I don't know how to reflect that on the design!
Then, I want the final task to proceed when all these cases are finished only.

Thank you.
#812802
You can create a variable number of asynchronous subprocesses with a loop like this:
VariableNumberOfSubprocesses.png
VariableNumberOfSubprocesses.png (20.03 KiB) Viewed 6032 times
A counter variable can be set which keeps track of how many times the process has passed through the loop which is checked by the conditions in the exclusive gateways. (Note that two gateways must be used if there is the possibility that zero subprocesses will be created.)

The conditions in the first gateway would be something like:
empty(@%loopCounter) or @%loopCounter < @%totalLoops [go to subprocess]
@%loopCounter >= @%totalLoops [go to task 2]

and in the second gateway:
empty(@%loopCounter) or @%loopCounter <= @%totalLoops [go to first gateway]
@%loopCounter > @%totalLoops [go to task 2]

Task 1 has a trigger something like this:
Code: Select all
@%loopCounter = 0;
@%totalLoops = 0;
If (isset(@=operationsGrid) and is_array(@=operationsGrid)) {
   @%totalLoops = count(@=operationsGrid);
} 
The "Increment Counter" task has a trigger like this:
Code: Select all
@%loopCounter++; 
However, there is no easy way to create a variable number of synchronous subprocesses. (Synchronous means that the master process waits until the subprocess case finishes.) The best solution is to create a trigger that will create a variable number of new cases with PMFNewCase() in a separate process and then pause the master case. Then, add a trigger to fire at the end of the separate process that checks whether all the new cases have been completed and then will unpause the master case and pass the data from the cases to master case. Tell me if you need this and I can create a sample process for you.

Another option is to not use two processes, but have a variable number of parallel tasks.
#812812
Hello,
Thank you very much Amos.

One doubt: All the Cases, for the Sub-process, must be launched simultaneously (asynchronously). On the design, we need to wait for the Sub-process task to finish before launching the next Case!

Regarding the "Repeated Task Sample", I took a look at it before and it seemed to me that the values of the form (on the repeated task) will change for each loop. I need to keep different values for each loop.

Cheers.
#812822
zeiscas wrote:One doubt: All the Cases, for the Sub-process, must be launched simultaneously (asynchronously). On the design, we need to wait for the Sub-process task to finish before launching the next Case!
Exactly. The example process map I gave you in the previous post can be used if you want to start a bunch of asynchronous subprocess cases at the same time.

If you want to start a bunch of synchronous subprocess cases at the same time, there is no way to do it in ProcessMaker. The only solution is to use PMFNewCase() to create normal cases (not subprocess cases) and then use PMFPauseCase() to pause the master case in a trigger.
zeiscas wrote:Regarding the "Repeated Task Sample", I took a look at it before and it seemed to me that the values of the form (on the repeated task) will change for each loop. I need to keep different values for each loop.
Here is an example of how to store the values entered in a parallel task in a grid. Each time the parallel task is executed by a different user, another row is added to the grid and then the whole grid can be viewed in a later task. See:
viewtopic.php?f=41&t=710262&p=789936#p789936
#812979
Hi Amos,

I'm still struggling with this process. Basically, we receive a batch of several instruments. Each of them can be processed in different Departments and in parallel. Then, a certificate is issued for each. At the end, all must be delivered together (in some scenarios they can be delivered individually). I can just figure out this by using several processes asynchronously! But they are dependent. I don't want the "Process instrument" to be allowed to start interactively (this is the one I need to launch automatically; one case for each instrument x department).

Processes foreseen:
1. Receive instruments
2. Process instruments (n occurrences)
3. Issue certificate (only after the instrument have been processed in all departments)
4. Deliver Instruments

Which is the best solution for this?

Gracias.
#812991
I generally think that it is simpler to use a single process and use a task with a parallel marker for your "Process instruments". See the link to the example in the previous post.

If that won't be possible because "Process instruments" is complicated and requires multiple tasks, then you should create separate cases with PMFNewCase() and pause the master case until all the "Process instruments" cases have terminated.

The basic idea is to create a grid @=processInstrumentsList with a row for each "Process instruments" case. Then each "Process instruments" case will update the @=processInstrumentsList grid when it terminates. When the last "Process instruments" case terminates, it will unpause the master case, so it can continue to "Issue Certificate".
#812998
Thanks a lot Amos. I understood that from your previous post.
That can work, but I was wondering about a way of having some flexibility at the end; either delivering all the Instruments at once or one by one as soon as they are available (certificate issued) - An Instrument is processed in several departments, then a certificate is issued and is delivered to the customer!
The Next Department to be assigned for each Instrument can be selected by the Manager of the previous department (this is one of the possible solutions)...

Saludos.
#813005
It sounds like you want your "Process instruments" subcases to have a trigger with the option to start a "Issue certificate" subcase in a trigger or unpause the "Receive instruments" master case and let it start the "Issue certificate" subcase. You could have the manager who handles the "Process Instrument" case decide which to do by selecting an option in a dynaform and then the trigger code either calls PMFNewCase() or PMFUnpauseCase().
#813056
As this is complex I don't want to continue without be sure about its executability. So, I'm planning 1 Master process: Service request - where it will be registered all the Instruments and the first Division/Department to operate. Here I will trigger one case for each Instrument using PMFNewCase() for the "Service Execution" Process. Inside this process, I will have the "Service at Division" sub-process, which can be executed several times but with different parameters: Division and User at Division (for starting the task). This is where I'm having some issues. I want the Manager on the previous Division to only select the next Division and the system automatically selects one user for the next Division task (which belongs to that Division). I created each Division as a Department but I don't know how to select the Department users!?

Other option, is to have an exclusive gateway as a start element on the "Service at Division" sub-process. How to overcome the required "dummy" task here?

Should I use option 1 or 2?

Thanks a lot.
Attachments
ServiceAtDivisionOption2.JPG
Option 2 - Sub-process called by "Service Execution" where I need to know the Division and the User for the first task with Value Based Assignment.
ServiceAtDivisionOption2.JPG (23.26 KiB) Viewed 5953 times
ServiceatDivision.JPG
Option 1 - Sub-process called by "Service Execution" where i just need to know the next Division.
ServiceatDivision.JPG (70.54 KiB) Viewed 5953 times
ServiceByMI.JPG
Executed for each Instrument.
ServiceByMI.JPG (26.71 KiB) Viewed 5953 times
ServiceRequest.JPG
Master Process.
ServiceRequest.JPG (36.58 KiB) Viewed 5953 times
#813066
You can get members of a department with this code:
Code: Select all
$deptId = PMFGetUidFromText('Accounting', 'DEPO_TITLE')[0];
require_once 'classes/model/Department.php';
$d = new Department();
$aDeptInfo = $d->Load($deptId);
$managerId = $aDeptInfo["DEP_MANAGER"];
$aMembers = getUsersFromDepartment ($sDepUid, $managerId); 
#813087
I played with this a little more. The code I previously gave you won't work to get the list of members of a department. This code works:
Code: Select all
$deptId = PMFGetUidFromText('Sales', 'DEPO_TITLE')[0];
require_once 'classes/model/Department.php';
$d = new Department();
$aDeptInfo = $d->Load($deptId);
$managerId = $aDeptInfo["DEP_MANAGER"];

$oDpt = new \ProcessMaker\BusinessModel\Department();
$aDept = $oDpt->getUsers($deptId, 'ASSIGNED'); 
$aMembers = $aDept['data'];

//select a member randomly and assign him/her to the next task:
$index = array_rand($aMembers);
@@nextAssignedUser = $aMembers[$index]['USR_UID'];

//get a list of members to select one in a dropdown box:
@=membersList = array();
foreach ($aMembers as $aMember) {
   if ($aMember['STATUS'] == 'ACTIVE') {
      @=membersList[] = array($aMember['USR_UID'], $aMember['USR_FIRSTNAME'] .' '. $aMember['USR_LASTNAME']);
   }
} 
Here is the output of \ProcessMaker\BusinessModel\Department::getUsers():
Code: Select all
array(
    'total' => 2,
    'start' => 0,
    'limit' => 0,
    'filter' => null,
    'data' => array(
        array(
           'USR_UID' => '10654575559caec5e953104064429578',
           'USR_USERNAME' => 'amos',
           'USR_FIRSTNAME' => 'Amos',
           'USR_LASTNAME' => 'Batto',
           'USR_STATUS' => 'ACTIVE',
           'UPPER(USERS.USR_LASTNAME)' => 'BATTO',
           'USR_SUPERVISOR' => true
        ),
        array(
           'USR_UID' => '94707434959e564e8dffcb9050867868',
           'USR_USERNAME' => 'daniela',
           'USR_FIRSTNAME' => 'Daniela',
           'USR_LASTNAME' => 'Callisaya',
           'USR_STATUS' => 'ACTIVE',
           'UPPER(USERS.USR_LASTNAME)' => 'CALLISAYA',
           'USR_SUPERVISOR' => false
       )
   )
) 
Want to create your own meme coin?

In the world of cryptocurrencies, a unique and exc[…]

The market for cryptocurrencies is demonstrating a[…]

What's SAP FICO?

Embarking on a dissertation can be one of the most[…]

Hello. For rental housing, there are software solu[…]