Replicator Activity in sequential Mode for Approval WorkFlow in SharePoint 2010 - sharepoint-2010

I am trying to create a Dcoument Approval WorkFlow, with Custom Task Edit infopath forms
Flow is ,When A Document is added into the List , it is assingned to User A , who is Orignator's Manager.
When User A Approves the document , it Assigned to User B for Approval.User B is fixed.
When User B has approved the document , then User B himself will assign the document to User C(Which means User C is dynamic and will be there at runtime).
When User C Approves it , A Task should be created for User , and work Flow should continue till User C Completes his Task.
Is Any of the Users , rejects the Task, The Workflow Should Stop.
How I implmented it ;
I created one Sequence Activity , as follows :
-create Task
-whileTaskNotComplete (onTaskChanged)
Complete Task
then Placed this Activity under Replicator Activity.
I am not sure how to set Replicator initialized and Child initialzed values .
I know replicator needs to be run for 3 times, but the last iterations value is not fixed, it is provided at runtime under second iteration.and under onTaskChange event of Activity.
How can I pass this value to workflow or next iteration?
second thing when i am setting any value for Apporver under replicator initialized method , it is assigning all the Tasks to same Approver which is set under initialized method.
could you please help me , I referred the videos http://www.shillier.com/Videos/MultipleTasks.wmv, but it is for Parallel mode , I need in sequential mode.
Thanks in advance.
Azra

I would start splitting it up in a state machine:
1 Start
2 Create and Assign Task
3 Wait for approval
4 End
in the "Wait for approval" you check for your conditions and then set a global variable for the next approver in line (make sure it's persisted) and set the state to "Create and Assign Task". Until you are done with your list.
1->2->3->(->2)->4

Related

Can a telegram bot block a specific user?

I have a telegram bot that for any received message runs a program in the server and sends its result back. But there is a problem! If a user sends too many messages to my bot(spamming), it will make server so busy!
Is there any way to block the people whom send more than 5 messages in a second and don't receive their messages anymore? (using telegram api!!)
Firstly I have to say that Telegram Bot API does not have such a capability itself, Therefore you will need to implement it on your own and all you need to do is:
Count the number of the messages that a user sends within a second which won't be so easy without having a database. But if you have a database with a table called Black_List and save all the messages with their sent-time in another table, you'll be able to count the number of messages sent via one specific ChatID in a pre-defined time period(In your case; 1 second) and check if the count is bigger than 5 or not, if the answer was YES you can insert that ChatID to the Black_List table.
Every time the bot receives a message it must run a database query to see that the sender's chatID exists in the Black_List table or not. If it exists it should continue its own job and ignore the message(Or even it can send an alert to the user saying: "You're blocked." which I think can be time consuming).
Note that as I know the current telegram bot API doesn't have the feature to stop receiving messages but as I mentioned above you can ignore the messages from spammers.
In order to save time, You should avoid making a database connection
every time the bot receives an update(message), instead you can load
the ChatIDs that exist in the Black_List to a DataSet and update the
DataSet right after the insertion of a new spammer ChatID to the
Black_List table. This way the number of the queries will reduce
noticeably.
I have achieved it by this mean:
# Using the ttlcache to set a time-limited dict. you can adjust the ttl.
ttl_cache = cachetools.TTLCache(maxsize=128, ttl=60)
def check_user_msg_frequency(message):
print(ttl_cache)
msg_cnt = ttl_cache[message.from_user.id]
if msg_cnt > 3:
now = datetime.now()
until = now + timedelta(seconds=60*10)
bot.restrict_chat_member(message.chat.id, message.from_user.id, until_date=until)
def set_user_msg_frequency(message):
if not ttl_cache.get(message.from_user.id):
ttl_cache[message.from_user.id] = 1
else:
ttl_cache[message.from_user.id] += 1
With these to functions above, you can record how many messages sent by any user in the period. If a user's messages sent more than expected, he would be restricted.
Then, every handler you called should call these two functions:
#bot.message_handler(commands=['start', 'help'])
def handle_start_help(message):
set_user_msg_frequency(message)
check_user_msg_frequency(message)
I'm using pyTelegramBotAPI this module to handle.
I know I'm late to the party, but here is another simple solution that doesn't use a Db:
Create a ConversationState class to attach to each telegram Id when they start to chat with the bot
Then add a LastMessage DateTime variable to the ConversationState class
Now every time you receive a message check if enought time has passed from the LasteMessage DateTime, if not enought time has passed answer with a warning message.
You can also implement a timer that deletes the conversation state class if you are worried about performance.

Maximo 7.6 APPR POs via Integration

We have an integration where in PO will be created in an external application and then will be interfaced to Maximo.
POs which are aproved only will be inbound to Maximo , however Maximo doesnt allow addition of POLINES in APPR status ,so via integration , we are receiving the PO in WAPPR status.
We have to approve the PO instantly so that any successive PO updates / Receipt transactions process to Maximo.
I'm aware that an escalation can do the task of approving POs, however I would like the status change to happen instantly.
I have tried following options
1)Create a workflow to approve PO and set it to auto initiate. This doesnt work as workflow set to auto-initiate doesnt get triggered for objects created through integration
2)Tried setting up automation script to initiate workflow
from psdi.mbo import MboConstants
from psdi.server import MXServer
print("**************Script to Approve Inbound POs *******");
stat=mbo.getString("STATUS")
if ( stat != ''):
print ( " Status is not null ");
print ( stat);
if ( stat=='WAPPR'):
print ("Status is WAPPR");
MXServer.getMXServer().lookup("WORKFLOW").initiateWorkflow("[my WF]",mbo);
print(" Workflow has been initiated and PO will be approved");
my WF contains an Action , which performs Change Status to set status as APPR.
This creates an entry in the POSTATUS table, however new Status reads as WAPPR instead of APPR
3)Automation script to set value for Status
from psdi.mbo import MboConstants
from psdi.server import MXServer
print("**************Script to Approve POs Inbound *******");
stat=mbo.getString("STATUS")
if ( stat != ''):
print ( " Status is not null ");
print ( stat);
if ( stat=='WAPPR'):
print ("Status is WAPPR");
mbo.setValue("STATUS","APPR",MboConstants.NOVALIDATION );
print(" Status approved");
This was set up with Object Launch point , Object as PO and on Save operation , After commit.
This also dint work.
Please let me know whether there are any other options
Not sure if you're workflow triggering script is working or if it is needed.
The problem is you analysis of the change status. Because a new PO record is created, there is also a new status 'change', which is the change from 'nothing' to the first status for PO that is 'WAPPR' . For PO there is no 'NEW' status. So the record you're seeing in the POSTATUS table is not from your script, but from the create action of the interface.
For status changes you should use the default application action. This will change the status on the record AND create an entry in the correct status table (POSTATUS in this case). Go to->System Configuration->Platform configuration->Actions. Create new action. Set object to PO, Type to 'Change Status' and value to 'APPR'.
Use this action in your workflow. Or directly in the escalation.
Don't worry to much about escalations that run every 5min. You can even use a new status 'NEW' as synonym for 'WAPPR' to distinguish between normal records and the just interfaced ones. That way you can also hide them from your users in the PO application.
Hope that helps.

Initialization of query failed - BW_REPORTING_FPM001 error

I am implementing Trial Balance(Version 2) FPM/Webdynpro App from Fiori Apps Library
following App Implementation : Trial Balance guide for S/4 Hana 1610.
When I launch the Trial Balance App.It says "Initialization of query 2CCFITRIALBALQ0001 Failed"(PFA for the error ).
Please let me know how to Initialize or Activate BEx Query.
Regards,
Sayed
The issue is resolved following the below steps :
1) Set a BW-client: Transaction SE37 RS_MANDT_UNIQUE_SET. If you use only one client, then fill I_MANDT with this one. If you use multiple clients, choose one of these.
2) Set user parameters RSWAD_DEV_MDVERSION = ‘072’ and RSWAD_SKIP_JAVA = ‘X’ for user DDIC(Its setting in transaction SU01 under parameter tab)
3) Logon to system with user DDIC in the client you used in step 1 and perform transaction RSTCO_ADMIN in order to activate the technical objects, which are needed for the engine. The parameters set in step 2 avoid, that unnecessary objects (related to BI tools based on JAVA) are activated here.
4) If you don't look at the OLAP-statistics you should deactivate these: Transaction SE38 - execute Report SAP_RSADMIN_MAINTAIN: with OBJECT = RSDDSTAT_GLOBAL_OFF and VALUE = X in insert mode. If you need the statistics, you can switch these on by running the program with that object but VALUE = space in update mode.
5) If you want to use OData-Services run report EQ_RS_AUTO_SETUP (transaction SE38)
6) If you want to use the BW time hierarchies, go to transaction RSRHIERARCHYVIRT and mark the hierarchies you need - for this you have to wait until the job triggered in step 3 has finished successfully
7) Call function module RSEC_GENERATE_BI_ALL.
Regards,
Rehan Sayed

getgroup() is very slow

I am using the function getgroup() to read all of the groups of a user in the active directory.
I'm not sure if I'm doing something wrong but it is very very slow. Each time it arrives at this point, it takes several seconds. I'm also accessing the rest of Active directory using the integrated function of "Accountmanagement" and it executes instantly.
Here's the code:
For y As Integer = 0 To AccountCount - 1
Dim UserGroupArray As PrincipalSearchResult(Of Principal) = UserResult(y).GetGroups()
UserInfoGroup(y) = New String(UserGroupArray.Count - 1) {}
For i As Integer = 0 To UserGroupArray.Count - 1
UserInfoGroup(y)(i) = UserGroupArray(i).ToString()
Next
Next
Later on...:
AccountChecker_Listview.Groups.Add(New ListViewGroup(Items(y, 0), HorizontalAlignment.Left))
For i As Integer = 0 To UserInfoGroup(y).Count - 1
AccountChecker_Listview.Items.Add(UserInfoGroup(y)(i)).Group = AccountChecker_Listview.Groups(y)
Next
Item(,) contains my normal Active directory data that I display Item(y, 0) contain the username.
y is the number of user accounts in AD. I also have some other code for the other information in this loop but it's not the issue here.
Anyone know how to make this goes faster or if there is another solution?
I'd recommend trying to find out where the time is spent. One option is to use a profiler, either the one built into Visual Studio or a third-party profiler like Redgate's Ants Profiler or the Yourkit .Net Profiler.
Another is to trace the time taken using the System.Diagnostics.Stopwatch class and use the results to guide your optimization efforts. For example time the function that retrieves data from Active Directory and separately time the function that populates the view to narrow down where the bottleneck is.
If the bottleneck is in the Active Directory lookup you may want to consider running the operation asynchronously so that the window is not blocked and populates as new data is retrieved. If it's in the listview you may want to consider for example inserting the data in a batch operation.

Autosys: Concept of Kick Start Attribute and how to use

i have a daily( 09:00am) box containing 10 jobs inside it. All child jobs are sequentially scheduled to run.
On Monday, jobs 1,2 &3 completed and job4 failed. And coz of this, the downstream is stalled and the box is running infinetly( until some actions taken manually)
But the requirement is to run this box again on Tue 09:00am. I heard of Kickstart attribute to kick off the box on next scheduled time irrespective of last run status.
Can someone tell about this kick_start attribute? Also suggest me any other way to schedule this box daily.
TIA
Never heard of the kick_start attribute and could not find it in the R11.3.5 reference guide.
I would look at the box_terminator: y that will fail the box if a job in it fails and the job_terminator: y that will terminate and fail a job if the box it is in fails.
box_criteria is another attribute that may help as you can define what success or failure looks like. For example if you don't care if job4 fails, define box_criteria: s(job3).
Course that only sets your box to FA where it will run the next time it's starting conditions are met. It does nothing to run the downstream for the current run.
Have fun and test, test, test.