Hi everyone,

I need to call a sub-process from a C# script task, I found this code:

var showAdressProcessUId = new Guid("abfbf7ee-e499-45e9-9d22-b9e91a46683d");
var manager = UserConnection.ProcessSchemaManager;
var schema =  (ProcessSchema)manager.GetInstanceByUId(showAdressProcessUId);
var moduleProcess = schema.CreateProcess(UserConnection);
moduleProcess.SetPropertyValue("PageInstanceId", PageInstanceId);
moduleProcess.SetPropertyValue("ActiveTreeGridCurrentRowId", ActiveTreeGridCurrentRowId);
moduleProcess.SetPropertyValue("TreeGridSelectedRowsIds", TreeGridSelectedRowsIds);
moduleProcess.SetPropertyValue("SchemaName", "Contact");
moduleProcess.SetPropertyValue("RouteMode", false);
moduleProcess.Execute(UserConnection);

From ShowContactAddressOnMapProcess

If I use it for my process:

var _sendMailId = new Guid("84e96844-b0ae-4edc-8b5e-20d1ba13fb8b");
var _manager = UserConnection.ProcessSchemaManager;
var _schema = (ProcessSchema)_manager.GetInstanceByUId(_sendMailId);
var _moduleProcess = _schema.CreateProcess(UserConnection);
_moduleProcess.SetPropertyValue("Test1", "Something");
_moduleProcess.Execute(UserConnection);

Throws this exception :

Terrasoft.Common.InvalidObjectStateException: missing property "Test1" of type "ProcessComponentSet".

 

I would need to know how it works or another way to do it, I need to call a sub-process inside a for loop.



Thanks.

Like 0

Like

6 comments

Dear Ezequiel,

It is nor recommended to use sub-processes and the processes in general for such purpose. Technically you can call a business process from a business process. But if you correct the code above and execute it  the system will freeze and the processes will block each other. All users meanwhile will not be able to use the system properly.

Please adjust the business-purpose you want to achieve in order to avoid using business-processes or find another architecture solution.

Oliver

Hi, 

I see, I'm trying to send an email inside the loop, but I can't find in any of the existing process how to send an email with a template though a script task.

If someone knows how to do it or has an example, I would appreciate it if you could explain it or show it to me.

Thanks.

Dear Ezequiel,

There is "Send email" BP element you can use to reach your goal. Just select in a message input "Template message" and you will be able to choose what template to use.

 

 

Peter Vdovukhin,

Yes I know, but like I said I need to use it in a for loop, with that I could use it if I had the code to call a sub-process from a script task.

Dear Ezequiel,

As you wrote to bpm'online support, let's continue our conversation there. After resolving your task I will post an answer here.

Here is a simple example I have successfully tested:

A first business process contains only script task with such code:

for(int i = 0; i < 2; i++) {

    var _sendMailId = new Guid("cc1b3e27-4d11-4957-ac40-b22ff5b11aff");

    var _manager = UserConnection.ProcessSchemaManager;

    var _schema = (ProcessSchema)_manager.GetInstanceByUId(_sendMailId);

    var _moduleProcess = _schema.CreateProcess(UserConnection);

    _moduleProcess.SetPropertyValue("UsrTestParameter", "Letter number " + i);

    _moduleProcess.Execute(UserConnection);

}

A second business process with GUID = cc1b3e27-4d11-4957-ac40-b22ff5b11aff contains only Send email element that has a text parameter UsrTestParameter and use this parameter for email subject. The second business process HAS to be compiled to be called from the first business process.

Show all comments

Hi,

   I would like to be able to iterate over all contacts (filtered of course) and generate a new GUID for a new custom column (I don't want to re-use the internal Id field externally thus created a second field)

A naive first try is to simply use a 'Modify data' actions, specify the filter and set the Formula of the column I like to modify to "Guid.newGuid()". When running the process all filtered Contacts get the same new GUID filled into the column in stead of a unique GUID per contact.

How can I make sure that each Contact get a unique value ? 

Thank you,

Ron

Like 0

Like

4 comments
Best reply

Thank you for this reply Oliver. It does give inspiration on how to solve this.

It does seem an overly complex means to do something to all objects individually :(

I can live with it, but if anyone can think of another solution that would still be welcome.

Best regards,

Ron Geens

Dear Ron,

Indeed, if you modify the data the formula will generate new Guid and will simply insert this Guid into all contacts according to filter.

The best option will be generating new Guid for each Contact individually per Business-process iteration. You can either make a timer for starting a business-process, reading one contact (that has no guid yet) and making new guid for it. Although, business-process will be executed with errors once all contacts will get guids. 

You can also create a trigger (starting signal) for modify data/add data with filter "YourFieldwithGuid is not filled in" and again simply read contact and generate the guid. In this case the business-process will be launched only if needed and will not be falling with errors.

You can simply combine these options and make it work. Simply set up the business-process to generate guid for each existing Contact and then adjust the business-process to generate for each new contact or contact having no guid in your field.

With best regards,

Oliver Wingston

Thank you for this reply Oliver. It does give inspiration on how to solve this.

It does seem an overly complex means to do something to all objects individually :(

I can live with it, but if anyone can think of another solution that would still be welcome.

Best regards,

Ron Geens

Dear Ronald,

I can suggest the alternative. You may use the custom query similar to the following to add 1 to every following record GuId:

declare @num int = 0;
update TableName 
set ColumnName = @num, @num=@num+1

Lisa

Lisa Brown,

Thank you Lisa, but I am only a user of the BPM processflows, not a programmer.

No idea where your code would have to be put.

Show all comments

Is it possible to remove or somehow disable processes that are in "Run process" context menu according to some conditions? For example, I'd like to disable a process on section page and allow it on edit page but only if the object has a particular status. If it's not possible - how else can I achieve similar functionality?

Like 0

Like

4 comments

You need to create replacing modules for the case page and for the case section. Then write the code that will match your needs there. Please find the example below.

define("CaseSection", ["BaseFiltersGenerateModule", "CheckBoxFixedFilterStyle", "StorageUtilities",
			"ServiceDeskConstants", "CasePageUtilitiesV2", "css!CheckBoxFixedFilterStyle"],
		function(BaseFiltersGenerateModule, CheckBoxFixedFilterStyle, StorageUtilities, ServiceDeskConstants) {
			return {
				entitySchemaName: "Case",
				contextHelpId: "1001",
				mixins: {},
				attributes: {
					"UsrIsProcessButtonVisible": {
						dataValueType: this.Terrasoft.DataValueType.BOOLEAN,
						type: this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
						value: false
					}
				},
				messages: {},
				methods: {
					init: function() {
						this.callParent(arguments);
						this.set("UsrIsProcessButtonVisible");
					}
				},
				diff: /**SCHEMA_DIFF*/[
					{
						"operation": "merge",
						"name": "ProcessButton",
						"values": {
							"visible": {"bindTo": "UsrIsProcessButtonVisible"}
						}
					},
					{
						"operation": "merge",
						"name": "DataGridRunProcessAction",
						"values": {
							"visible": {"bindTo": "UsrIsProcessButtonVisible"}
						}
					}
				]/**SCHEMA_DIFF*/
			};
		});

 

define("CasePage", [], function() {
	return {
		entitySchemaName: "Case",
		attributes: {
			"UsrIsProcessButtonVisible": {
				dataValueType: this.Terrasoft.DataValueType.BOOLEAN,
				type: this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				value: false
			}
		},
		modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
		methods: {
			onEntityInitialized: function() {
				this.callParent(arguments);
				this.set("UsrIsProcessButtonVisible");
			}
		},
		dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "merge",
				"name": "ProcessButton",
				"values": {
					"visible": {"bindTo": "UsrIsProcessButtonVisible"}
				}
			}
		]/**SCHEMA_DIFF*/
	};
});

 

Thank you. And do you know if it's possible to disable or hide single context menu item? For example if I have two processes I may want to disable one but not the other.

You need to override methods from the ProcessEntryPointUtilities mixin in the CaseSection and CasePage modules. For example, for the button on a grid record you'll need to override the addRecordRunProcessMenuItems method in the CaseSection module. 

http://prntscr.com/jzm8w0

Thank you very much.

Show all comments

Hi community!

Could you give me an example of how to call a business process from a script task with parameter passing

Thanks you!

King regards!

Ezequiel

Like 0

Like

1 comments

Dear Ezequiel,

The task was already discussed in another Community post here - https://community.bpmonline.com/questions/call-business-process-script-task. Feel free to check the solution provided there. 

Lisa

Show all comments

We need to track tasks that we perform for each account.  we are doing some manually through tasks,  now we are doing some via automation - we still need to record them so they show in the TimeLine - BTW, the timeline feature is great!

Like 0

Like

3 comments

Dear Brian,

If you want to add the activities by the business process without completing them manually, then you can use Add data element: https://academy.bpmonline.com/documents/technic-bpms/7-12/add-data-process-element#XREF_27515

This element can add one record or a selection in the background mode. And you can set up the status to be completed: 

Best regards,

Lily

Lily Johnson,

Thanks, this worked... but to note for others I added several more fields to fill out the activity for it to show up and record what I wanted.

I wanted the nice activity notification to appear like it does for a Task so I also went a step further.  I left the Activity.Status field as "Not Started", added on a 2 sec timer and then closed the Activity by setting the Activity.Status = Completed.  This gives the user a notification letting them know when the process is completed, records the activity and closes the process automatically.  I do this added work for notification because the process varies in time, but the user needs to get a note while their waiting.

Brian Morgan,

In case you need to notify a user, please think of the extending the process or create a new one like it is discussed in this topic: 

https://community.bpmonline.com/questions/how-notification-can-be-sent-business-process-different-users

Best regards,

Lily

Show all comments

I created a test process, now I want to delete it.

I can't find an option to delete it?

Like 0

Like

2 comments

Dear Brian,

If you want to delete a process completely from the system, then you need to go to System designer -> Advanced settings -> Configuration tab:

But you can simply deactivate the process and it won't interrupt your work:

Best regards,

Lily Johnson

thanks, this worked.

now this thread will serve as documentation for others.

Show all comments

Hi everyone, 

I'm running on bpm'online last version 7.12.0

I've added a few actions to my sections and pages. Let's take "Order" for instance.

I could bind a business process to those added on section. For example, for a BP called "customProcess", here's the code in OrderSectionV2

 

	oneSelected: function() {
				var selectedRows = this.get("SelectedRows");
				return selectedRows ? (selectedRows.length == 1) : false;
			},
 
customProcessAction: function() {
				//Call Business Process
				var selectedOrder = this.get("SelectedRows").toString();
				var args = {
					sysProcessName: "customProcess",
					parameters: {
						OrderId: selectedOrder
					}
				};
				// Running business process.
				ProcessModuleUtilities.executeProcess(args);
			},
 
getSectionActions: function() {
				var actionMenuItems = this.callParent(arguments);
				actionMenuItems.addItem(this.getButtonMenuItem({
					Type: "Terrasoft.MenuSeparator",
					Caption: ""
				}));
				actionMenuItems.addItem(this.getButtonMenuItem({ 
					"Caption": {bindTo: "Resources.Strings.customProcessCaption"},
					"Click": {bindTo: "customProcessAction"},
					"Enabled": {bindTo: "oneSelected"}
				}));
				return actionMenuItems;
			}

By applying the same logic on OrderPageV2, it's not working. The action appears but it doesn't do anything when clicking on it.

I hope you'll be able to help me.

Thank you, best regards. 

 

Like 0

Like

2 comments

Please take a course by the link below and debug the code.

https://developers.google.com/web/tools/chrome-devtools/javascript/

Then put breakpoints into the selected places and find the value that you missed.

http://prntscr.com/jdqezc

Additionally, please investigate the code below

var selectedOrder = this.get("SelectedRows").toString();

Where from you expect to get the SelectedRows value on the page? If  you were in a section, the SelectedRows would contain the rows that were selected in the section. But if you are on a page, what the SelectedRows variable should contain?

Probably you need to pass an Id of the page record instead of the SelectedRows. 

Additionally, please investigate the place where you expect to see the menu action. If you need to see it on a section or on a page when a section is open on a left side, then you need to place the script in a section module (for example OpportunitySectionV2). If you need to see the menu action on a page, then you need to place the script in a page module. If you need to see it everywhere, then you probably need to place the script both in a section module and in a page module. But the logic should be different. 

 

 

 

Thank you for your quick answer.

Eugene Podkovka writes:

Where from you expect to get the SelectedRows value on the page? If  you were in a section, the SelectedRows would contain the rows that were selected in the section. But if you are on a page, what the SelectedRows variable should contain?

The code is for a section indeed and was just an example.

 

Eugene Podkovka writes:

Additionally, please investigate the place where you expect to see the menu action. If you need to see it on a section or on a page when a section is open on a left side, then you need to place the script in a section module (for example OpportunitySectionV2). If you need to see the menu action on a page, then you need to place the script in a page module. If you need to see it everywhere, then you probably need to place the script both in a section module and in a page module. But the logic should be different. 

Yes I figured that was the issue here. I do need to see it everywhere ! 

I'll try to make it work and ask for your help again if I have issues. Thank you very much.

Show all comments



Hello community!

Is possible make a formula but get the title of the fields. For example:

The idea is create a string with the Title of the field and the value.

Regards,

 

Like 0

Like

1 comments

Is there a way to send an attachment inside of a business process?

  • The attachment location/directory is data driven, different for each contact
Like 0

Like

4 comments

Dear John,

 

Here's the method that can be used to implement sending the attachments within business process:

		public static bool SendMail(string mailto, string caption, string message, Guid FileId, string SchemaName, UserConnection userConn) {
			SchemaName+="File";
			string smtpServer = Terrasoft.Core.Configuration.SysSettings.GetValue(userConn, "SFsmtpServer").ToString();
			string from = Terrasoft.Core.Configuration.SysSettings.GetValue(userConn, "SFFrom").ToString();
			string password = Terrasoft.Core.Configuration.SysSettings.GetValue(userConn, "SFPassword").ToString();
			Stream FileA = null;
			string Fname = "";
			var esq = new EntitySchemaQuery(userConn.EntitySchemaManager, SchemaName);
			esq.AddAllSchemaColumns();
			esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "Id",FileId));
			var coll = esq.GetEntityCollection(userConn);
			foreach(var ent in coll) {
				FileA = ent.GetStreamValue("Data");
				Fname = ent.GetTypedColumnValue&lt;string&gt;("Name");
				break;
			}
			try {
				MailMessage mail = new MailMessage();
				mail.From = new MailAddress(from);
				mail.To.Add(new MailAddress(mailto));
				mail.Subject = caption;
				mail.Body = message;
				mail.IsBodyHtml = true;
				if (FileA != null)
					mail.Attachments.Add(new Attachment(FileA, Fname));
				SmtpClient client = new SmtpClient();
				client.Host = smtpServer;
				client.Port = 587;
 
				client.EnableSsl = true;
				client.Credentials = new NetworkCredential(from.Split('@')[0], password);
				client.DeliveryMethod = SmtpDeliveryMethod.Network;
 
				client.Send(mail);
				mail.Dispose();
				return true;
			} catch(Exception e) {
				throw new Exception("Mail.Send: " + e.Message);
			}
		}

Please note that in this case the file is taken from Attachments and Files tab of the record. If you want to take the file from the external resource you'll need to develop the additional integration.

Lisa

 

Lisa Brown,

Is posible select the sender mailConfiguration? This code take the default email. I need select a shared configuration.

Lisa Brown,

Please feel free to use ESQ to find the mailbox that you need.

https://academy.bpmonline.com/documents/technic-sdk/7-11/use-entitysche…

All user mailboxes are in the MailboxSyncSettings table.

Eugene Podkovka,

Hi, using the script above, is it possible to let the user edit the email message before sending? (like you can do when you use the [ Send email ]?

Show all comments

Hello community!

I have a business proces that when run manually works perfect but if use the schedule code, the code schedule the proces perfect but when ejecute return a error about the null object.

Can you help me to find the error?

The bussines proces to ejecute (think that error is about the userConnection):

var userConnection = (UserConnection)HttpContext.Current.Session[ "UserConnection" ];
 
var delete = new Delete(userConnection)
        .From("BGlobalSurveyLinks"); 
delete.Execute();
 
var insert = new Insert(userConnection).Into("BGlobalSurveyLinks")
	 .Set("Name", Column.Const(surveyLink))
	.Set("Description", Column.Const(surveyTitle)); 
insert.Execute();

The schedule code (that work perfect becouse the BP execute every 5 minutes):

var userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"];
string schedulerJobGroupName = "BGlobal";//- any name
string jobProcessName = "BGlobalSincronize"; //- the name of the process
string schedulerJobName = "Schedule"; //- any name
AppScheduler.RemoveJob(schedulerJobName, schedulerJobGroupName);
var job = AppScheduler.CreateProcessJob(schedulerJobName, schedulerJobGroupName, jobProcessName, userConnection.Workspace.Name, userConnection.CurrentUser.Name);
var trigger = new SimpleTriggerImpl(schedulerJobName + "Trigger", schedulerJobGroupName, DateTime.UtcNow.AddMinutes(5));
AppScheduler.Instance.ScheduleJob(job, trigger);
return true;

 

Like 0

Like

1 comments

The business process doesn't work because you don't send "userConnection" in a correct format. Please upgrade your instance to 7.11 and use an out-of-the-box scheduler that was embedded into a business process designer.

https://www.bpmonline.com/release-7-11

 

Show all comments