Dynamic calculation of the number of groups members - alfresco

For example, there are one exclusivegateway and two sequenceFlow.
<sequenceFlow id="flow1" sourceRef="exclusivegateway" targetRef="usertask1">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${approveCount == N}]]>
</conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow2" sourceRef="exclusivegateway" targetRef="usertask2">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${approveCount < N}]]>
</conditionExpression>
</sequenceFlow>
Depending on conditions, executed one or the other task.
In business process I want to dynamically calculate the number N. This number is equal to the sum of all participants of the business process.
(for example, I have two groups and the first group included 10 participants, the second group included 5. Then N must be equal to 15).
Is it possible in Activiti by using JavaScript to calculate the number of participants in these groups?

You could definitely use either JavaScript or Java API for getting the the number of users in a couple of groups. Check this page for JS people API for example: http://docs.alfresco.com/5.1/references/API-JS-getMembers.html
So I imagine a Script task/execution listener before your exclusive gateway, implementing that logic should be the easiest way to do this, as it won't even require restarting the server:
var membersG1 = people.getMembers("GROUP_MY_GROUP1_NAME");
var membersG2 = people.getMembers("GROUP_MY_GROUP2_NAME");
execution.setVariable("N", membersG1.length + membersG2.length);
Note that this is one of many many possible ways for implementing what you specified.

Related

MS Project: How to set daily actual work for a task using a JavaScript Add-In?

I want to synchronize data for actual work from a web-based application of my company with MS Project. I am currently developing an Add-In with JavaScript in order to achieve this:
The red circle in my screenshot shows the data that I want to set programmatically. However, I have no idea how to achieve this.
I understand that I can get Task GUIDs and then set task fields using the task GUID and the field ID. This way I can save the cumulative actual work, but not per day like in my screenshot.
The API Docs on the MS Office Website are rather hard to read and navigate. Any help would be apprechiated!
Let's first separate the language from the operation.
Operationally, based on your circle, you want to set work for a task to happen on individual days? This is done using timeScaleData, see https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2003/aa206255(v=office.11) . When I did something similar (in VBA), I had to (1) get an array of time scale values, then (2) walk/iterate through that array and set work to those days:
set timeScaleValsArry = myTask.Assignments(1).TimeScaleData(startDay, endDay, pjAssignmentTimeScaledWork, daily)
for a = 1 to timeScaleValsArry.Count
timeScaleValsArry[a].value = hoursToWorkThatDay
next
Breaking down the elements above:
myTask is the task (of type task) I want to manipulate.
Assignments is an array representing each resource assigned to the task; for my purposes, I only ever had 1 resource assigned, hence the index of (1).
TimeScaleData is the function that returns the the array starting on the day startDay (whatever you want that to be), endDay, pjAssignmentTimeScaledWork which tells this function what data we want to work with (being work, but there are alternates ), and daily which is the frequency you want to work with (for instance you can go down to minutes, or up to years).
Then the returned array timeScaleValsArry is walked, and inside the loop the daily assignment for each value is manipulated. You'd need to customize this part to meet your needs; alternatively, you don't even need to loop if you always had three days: just hard code the array indices.
As far as language, clearly this is do-able in VBA. Doing this in C# as a VSTO addin has very similar syntax. I'd presume for JavaScript (what are you using, ScriptLab?) would also have similar syntax.

Complex Queries in Firestore / Realtime database and modeling for querying

I have a problem doing complex queries in Firestore database. I have read the documentation countless times so I know where the limitations are, but I wonder whether there is a way to structure the data so it supports my use cases. Let me explain what the use cases first:
I have a list of jobs, and users and I want to able to list/filter jobs according to some criteria and to list/filter users according to some criteria.
Job
JOB ID
- job type (1 of predefined values)
- salary (any number value)
- location (any value)
- long
- lat
- rating (1 - 5)
- views (any number value)
- timeAdded (any timestamp value)
- etc.
User
User ID
- experiences (0, 1 or more of predefined values)
- experience1
- jobCategory
- jobName
- timeEmployed
- experience2
- etc
- languages (0, 1 or more of predefined values)
- language1
- languageName
- proficency
- language2
- etc.
- location (any value)
- long
- lat
- rating (1 - 5)
- views (any number value)
- timeLastActive (any timestamp value)
- etc.
Filtering by field which can only have one value is fine. Even when I add sorting by "timeAdded" or a ragne filter.
1) The problem is when I introduce second range filter, such as jobs with "salary" higher then 15 bucks and at the same time "rating" higher then 4. Is there a way to get around this problem when I have N range filters?
2) Second problem is that I cannot use logical OR. Lets say, filter jobs, where "jobCategory" is Bartender or Server.
3) Another problem is to filter by fields, which can have more then 1 value, e.g. User can speak more than one language. Then if I want to filter users which speak English, it is not possible. Not to mention to filter users who speak e.g. English OR French.
I know I can model the data the way that I use the language as the name of the field, like -english = true, but when I introduce range filter to this, I need to create a Firestore index, which is very inconvenient since I can have around 20 languages and around 50 job types at the same time, and I would have to create indexes all the combinations together with different range filters.. is this assumption correct?
4) How would I filter jobs which up to 20 km from certain position? Radius and the position is on the user to choose.
5) What if I want to filter by all those fields at the same time? E.g. filter certain "jobCategory", location and radius, "salary" higher then something and "rating" higher then something, and sort it all by "timeAdded".
Is this possible with Firestore / Realtime database, can I model the data in some way to support this, or do I have to look for an alternative DB solution? I really like the real-time aspect of it. It will come handy when it is time to implement chat feature to the app. Is it solvable with Cloud functions? I am trying to avoid doing multiple requests, merging them together and sending that to client, since there can be any combination of filters.
If not doable with Firebase, do you know of any alternatives similar to Firestore with better querying options? I really hope I am just missing something :)
Thank you!

Graphite Percentage Calculation with groupby/Wildcards for alerting Target Function

I am trying to create a seyren alert for my page render metric stored in graphite.
My render stats are collected by ststsD and stored in graphite. The structure is following:
stats.counters.renderCompleted.display.<country>.<placement_id>.<page_version>.count
e.g.
stats.counters.renderCompleted.display.US.123456.v1_1_03.count
stats.counters.renderCompleted.display.US.123456.v1_1_09.count
stats.counters.renderCompleted.display.US.654321.v2_1_05.count
stats.counters.renderCompleted.display.US.654321.v2_1_07.count
stats.counters.renderCompleted.display.UK.123456.v1_1_09.count
...
...
I want to create a seyren alert with graphite function whenever the current render count for ANY PLACEMENT ANY VERSION (e.g. group by placement_id, page_version) falls below certain % of its (for that placement's and version's) previous day average.
I did search graphite functions but it's bit confusing probably because I don't have background in time-series data processing. Will truly appreciate any help. I tried with many combinations including the following, but not able to get it correct...
asPercent(sumSeriesWithWildCards(movingAverage(scaleToSeconds(
stats.counters.renderCompleted.display.US.*.*.count, 1),'10min'), 6),
sumSeriesWithWildCards(movingAverage(scaleToSeconds(timeShift(
stats.counters.renderCompleted.display.US.*.*.count, '1d'), 1), '10min'), 6))
Please note, I want to create only one alert (hence using WildCard function like sumSeriesWithWildCards) which should serve the purpose, not multiple alerts for individual placements and versions and we keep on adding these.
Thanks in advance.

create control-M job on the fly

Is it possible to dynamically create control-M jobs.
Here's what I want to do:
I want to create two jobs. First one I call a discovery job, the second one I call a template job.
The discovery job runs against some database and comes back with an array of parameters. I then want to start the template job for each element in the returned array passing in that element as a parameter. So if the discovery job returned [a1,a2,a3] I want to start the template job 3 times, first one with parameter a1, second with parameter a2 and third one with parameter a3.
Only when each of the template jobs finish successfully should the discovery job show as completed successfully. If one of the template job instances fails I should be able to manually retry that one instance and when it succeeds the Discovery job should become successful.
Is this possible ? And if so, how should this be done ?
Between the various components of Control-M this is possible.
The originating job will have an On/Do tab - this can perform subsequent actions based on the output of the first job. This can be set to work in various ways but it basically works on the principle of "do x if y happens". The 'y' can be job status (ok or not) exit code (0 or not) or text string in standard output (e.g. "system wants you to run 3 more jobs"). The 'x' can be a whole list of things too - demand in a job, add a specific condition, set variables.
You should check out the Auto Edit variables (I think they've changed the name of these in the latest versions) but these are your user defined variables (use the ctmvar utility to define/alter these). The variables can be defined for a specific job only or across your whole system.
If you don't get the degree of control you want then the next step would be to use the ctmcreate utility - this allows full on-the-fly job definition.
You can do it and the way I found that worked was to loop through a create script which then plugs in your variable name from your look-up. You can then do the same for the job number by using a counter to generate a job name such as adhoc0001, adhoc0002, etc. What I have done is to create n number of adhoc jobs as required by the query, order them into a new group and then once the group is complete send the downstream conditions on. If one fails then you can re-run it as normal. I use ctmcreate -input_file . Which works a treat.

Calculate product of a field across repeating elements in InfoPath

It is easy to calculate a sum, an average or a maximum accross set of fields using built-in xpath functions.
But is it possible to calculate a product?
Assuming I have repeating elements like
<my:table>
<my:row>
<my:value>10</my:value>
</my:row>
<my:row>
<my:value>20</my:value>
</my:row>
<my:row>
<my:value>30</my:value>
<my:row>
</my:table>
(the number of my:rows may vary).
i need to have a formula multiplying all my:values: 10*20*30 (and working with any number of rows).
Any ideas?
Please do not suggest code solutions, I need this for a restricted form.
Using conditional hack described here, I finally assembled the solution.
Inside my:row, create a running product field my:valueCumul, populated using a formula to refer to previous row, and leveraging the conditional hack to override NaN for the first row:
../my:value *
concat(
(count(../preceding-sibling::my:row[1]) = 0) * 1,
substring(../preceding-sibling::my:row[1]/my:valueCumul, 1, (count(../preceding-sibling::my:row[1]) = 1) * string-length(../preceding-sibling::my:row[1]/my:valueCumul))
)
Outside the table you can easily refer to my:valueCumul in the last row to get total product:
../my:row[count(../my:row)]/my:valueCumul
The nice features of this solution are:
Works in a browser form in any sharepoint environment
Is not impacted by "16 calculations" threshold
The formula is robust to row removal and shifts
You can't with the built in functions in InfoPath.
However, don't write off a code solution so fast. If you only access data elements in the form itself (nothing EXTERNAL) then you can leave the form as restricted security and the code will run with no problems - the user doesn't know the difference.
It is fairly trivial to attach to the right event, grab the nodes, and loop through them while multiplying. You don't even have to use managed code - use one of the script options. Comment back (or update your original post) if you run into any troubles and we can help resolve them.

Resources