BPM to Create Revisions

I’m working on a BPM that creates a part revision and adds it to the PartRev table.

string ChildNumber;
int i;

foreach (var row in ChildParts.Part)
{

ChildNumber = row.PartNum;

Erp.Contracts.PartSvcContract partEntry = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.PartSvcContract>(this.Db, true);

using(var txscope = IceDataContext.CreateDefaultTransactionScope())        {
     
    partEntry.GetNewPartRev(ref dsPart, ChildNumber, "");
		i = dsPart.PartRev.Count()-1;	 
		ds.PartRev[i].RevisionNum = tmpRevisionNum;
		ds.PartRev[i].EffectiveDate = tmpEffectiveDate;
		ds.PartRev[i].Approved = tmpApproved;
		ds.PartRev[i].RevShortDesc = tmpRevShortDesc;
		ds.PartRev[i].DrawNum = tmpDrawNum;
		ds.PartRev[i].ECO = tmpECO;
		ds.PartRev[i].Configured = tmpConfigured;
		ds.PartRev[i].ECOGroup = tmpECOGroup;
		ds.PartRev[i].WebConfigured = tmpWebConfigured;
		ds.PartRev[i].Plant = tmpPlant;
		ds.PartRev[i].ShowInputPrice = tmpShowInputPrice;
		ds.PartRev[i].UseStaging = tmpUseStaging;
		ds.PartRev[i].ValRefDes = tmpValRefDes;
		ds.PartRev[i].RevDescription = tmpRevDescription;


this.PublishInfoMessage(ds.PartRev[i].RevisionNum, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "", "");


this.PublishInfoMessage(ds.PartRev[i].RevShortDesc, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "", "");

this.PublishInfoMessage(ds.PartRev[i].PartNum, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "", "");

// partEntry.Update(ref dsPart);
}                          
}

With this code I get the following error if I don’t comment out the Update line:
image

The publish message lines were added to simply make sure that the variables are populating with the correct information and putting it on the correct line (they are).

Any ideas why I would get the invalid revision number and rev description required errors when those are filled out?

@TDray It looks to me like you make dsPart and then load ds then try to update dsPart.

Wrap your code in ``` ``` so it will be an easier block to read.

Not sure what you want me to wrap the code in. I used the three tick marks when posting the code to separate it so not sure what more to do or how to do it.

I should have been clearer when first posting thought that the ChildParts.Part table is one I’m creating and filling that is pulling the part numbers of those that I need to create a revision for. I’m attempting to get a new part revision, populate the information for it, and then update this part. Is there something I’m missing?

You have to use the back tick (not apostrophe). The back tick is the key next to the 1 on the keyboard.

Have you tried doing this via running a trace + using widgets? This should be relatively straight forward to do in widget form.

You can even create loops using widgets (it still throws an error but it does save + correctly loops).

@TDray , I already fixed it for you a couple of days back. It’s all good!

Thank you. I was looking at the edit wondering what was wrong with it.

How do you create loops using widgets. I’m assuming you are saying there is a way to do for type of loops because if you are talking about just pointing widgets in a circle, wouldn’t that result in an infinite loop?

pointing widgets in a circle

Exactly but, like with any loop, you need some condition to break it once the goals have been met.

I.e.

  • Before doing logic, create variables that store:
    • Max Count of the items - ChildParts.Part.Count()
    • Count Completed - Initialise to 0
  • Do processing
  • After processing:
    • Increment CountCompleted by 1
    • Add Condition to check if CountCompleted < MaxCount
      • If Yes - connect beck to start of processing.
      • If No - do something else

When you do your logic using this, make sure to use the CountCompleted variable:
I.e. ChildParts.Part[CountCompleted]

Don’t you hate when you can’t see the obvious answer… Condition to check and use it to loop… Makes complete sense and not something I should have had to ask.

Now I just have to figure out how to do the widgets to get the result I want.

2 Likes

Have most of what I want to accomplish happening, but I have a small snag I’m hoping someone can help me out on.

I’m wanting certain parts to only allow revisions through this BPM and not directly. I can set up a BPM that stops the GetNewPartRev on those parts, but it also prevents this BPM from creating revisions. Is there a way to disable / re-enable a BPM from another BPM? Is there a way to have a BPM that prevents users from creating revisions but allows another BPM to do it? My assumption (which could be wrong) is that if I tried to limit it by user, it would also prevent the BPM because I assume BPMs run as the current user. Is that right? Is there another way around to prevent changes not coming from this BPM?

@TDray There is this that could work.

The callContextClient.AssemblyName is equal/not equal to wherever it is being called from.

Put in a info message or write to event log to see the assembly.

EG
image

1 Like

When I put in the info message, it is called by Erp.UI.Eng.WorkBenchEntry. This is the same regardless of whether it is called through the BPM or directly through the Engineering Work Bench, so this will not work as it doesn’t allow me to determine whether they are adding the revision through the Work Bench or the BPM is attempting to add it.

Maybe add a condition that checks the part numbers that you want then?

Or some other way (a custom UD column) that identifies the parts to be allowed to create new revisions?

E.g. Part.AllowNewRevisions_c

With regards to allowing this to work in BPM and manually, perhaps do this in a Post-Processing BPM with a condition that checks if it has been enabled from a pre-processing BPM?

Again in the Pre-Processing BPM you would need some form of identifier to know which part is allowed. Then you would enable the Post-Processing BPM via the Pre. Although you’d have to figure out the exact functionality yourself.

Look at the call context variables. I believe that there is a called from variable in there so you can see where it’s called from.

I’ve checked the Assembly Name, the Process ID, Client Type, Current User, and CGC Code and all are the same whether it is called by the user in the engineering work bench or called by the BPM.

Why don’t you set a BPM context variable in the BPM that’s calling it so that you can tell if it’s from the BPM or not.

1 Like

Thank you so much Banderson. This is exactly what I needed.

1 Like