Cust Shipment BPM

Hi

I need to create a BPM which will check the OurShipQty on the shipment line and compare to the JobProd Qty on the Job Head. If the qtys fall outside of 2% tolerance then error.

For example on a 10kg Job Production. If I try to ship 9.7kgs it would error. If I ship 9.8kgs it will accept.

I have written a baq which works - the expression is below:

How can I add this into a bpm - I tried the query option but there’s no option for using an expression in tablet criteria

You won’t be able to do any calculations in the BPM BAQ, it’s kind of limited (as you have found).

You do have couple of options though. If you have access to that field in the BPM you can use an expression in a condition block. (if you tell me where you are putting your BPM, I can help a little more with that)

If you don’t have access to those fields, you can call that BAQ using the dynamicQueryContract, but that’s going to be a fair amount of code to get that work. So it all depends on what your current skill level is.

if the BAQ designer in BPM won’t allow the expressions the same way you may have to resort to doing the query by hand in LINQ

Apologies, what do you mean by Linq?

image325026.png

image745634.png

image711792.png

image209680.png

image079666.png

It’s a query syntax used by C# similar to SQL but it can be used on many different datasources not just a database, which is nice. It’s more advanced but let’s you do some of the tricky stuff

I think you can do this without link of the the dynamic query.

use this condition

use this formula to check
image

Keep in mind that if you do this, you will not be able to ship anything partial (if you do an exception instead of an info message)

The Method is on the CustShip.Update pre-processing.

Hi @carlawhite,
i have done few BPM’s on this area using code, i have altered my code to suite what you want, please let me know if this will work in your environment.


the code as text:

var ttShipHead_xRow = (from ttShipHead_Row in ttShipHead
where ttShipHead_Row.Company == Session.CompanyID
&& (ttShipHead_Row.Updated()||ttShipHead_Row.Added())
select ttShipHead_Row).FirstOrDefault();

if (ttShipHead_xRow != null)
{
	foreach (var ShipDtl_iterator in (from ShipDtl_Row in Db.ShipDtl
	where ShipDtl_Row.Company == ttShipHead_xRow.Company
	&& 	ShipDtl_Row.PackNum == ttShipHead_xRow.PackNum
	select ShipDtl_Row).ToList())
		
		if (ShipDtl_iterator != null)
		{
		foreach (var JobHead_iterator in (from JobHead_Row in Db.JobHead
		where JobHead_Row.Company == ShipDtl_iterator.Company
		&& JobHead_Row.JobNum == ShipDtl_iterator.JobNum
		select JobHead_Row).ToList())		
			if (JobHead_iterator != null)
			{
				if(JobHead_iterator.ProdQty > ShipDtl_iterator.OurJobShipQty*1.02m || JobHead_iterator.ProdQty < ShipDtl_iterator.OurJobShipQty*0.98m)
				{
			CallContext.Current.ExceptionManager.AddBLException("Dispached Qty: "+ShipDtl_iterator.OurJobShipQty+" of Pack Line: "+ShipDtl_iterator.PackLine+" From Job No.: "+ShipDtl_iterator.JobNum+" is not within the allowed Job ship Qty tolerance.");
				}
			}
		}	
}

Note: as @Banderson said this will stop dispatching everything outside this tolerance.

HTH

1 Like

Hi thanks ever so much for your advice. I used your code, and placed it where stated, it works - however, its runs the BPM at time of clicking Shipped on the shiphead

This is too late for our process- it needs to be when the OurJobShipQty is changed. or line is saved.

I tried manipulating your code and placing it on shipdtl in transaction- but still cannot get it working.

thanks in advance

Hi Carla,
putting it in there will guarantee that nothing will be shipped if any line is not satisfying this condition, i can change it to other methods, but according to my test experiment, user will be able to pass it by updating other fields or going to the shipping head before hit Save on the ShipDtl UI screen, you can try it and all what you need is to start from ttshipDtl and replace the foreach loop as there is no need to loop through each line of the ttShipHead Pack Id.

@carlawhite
try this, i have re coded it, but used In-Tran data directive on ShipDtl, so it will be triggered on both actions as well as changing Row (notification) event which should give users the early warning as you want

var ttShipDtl_xRow = (from ttShipDtl_Row in ttShipDtl
where ttShipDtl_Row.Company == Session.CompanyID
&& (ttShipDtl_Row.Updated()||ttShipDtl_Row.Added())
select ttShipDtl_Row).FirstOrDefault();

if (ttShipDtl_xRow != null)
{
		var JobHead = (from JobHead_Row in Db.JobHead
		where JobHead_Row.Company == ttShipDtl_xRow.Company
		&& JobHead_Row.JobNum == ttShipDtl_xRow.JobNum
		select JobHead_Row).FirstOrDefault();		
			if (JobHead != null)
			{
				if(JobHead.ProdQty > ttShipDtl_xRow.OurJobShipQty*1.02m || JobHead.ProdQty < ttShipDtl_xRow.OurJobShipQty*0.98m)
				{
			CallContext.Current.ExceptionManager.AddBLException("Dispached Qty: "+ttShipDtl_xRow.OurJobShipQty+" of Pack Line No.: "+ttShipDtl_xRow.PackLine+" From Job No.: "+ttShipDtl_xRow.JobNum+" is not within the allowed Job ship Qty tolerance.");
				}
			}
		
}

Note: we do not ship from manufacturing in my environment but i advise you to use the code to validate against Part No. as well, because Epicor will allow MFG-CUS Transaction from any Existed Job No.

HTH

1 Like

This has worked beautifully - many thanks for your support much appreciated!

1 Like

Hi
I have a problem- I changed the Exception to a Message instead as I did not want to stop the process - just notify.

When get invoices the message pops up on each pack line that is being invoiced! I didn’t envisage this happening.

you can add a widget condition saying when ttShipDtl_xRow.OurJobShipQty changed from any to another and see how Epicor will behave on both BO (i.e. Cust Shipment and Invoicing)

cheers- I tried this and it still runs at invoicing

do you know what BO Invoice changing in the ShipDtl Records, what fields or/and value ? i do not perform any financial transaction you see

hi
I figured it out :slight_smile: I added the condition widget and checked to see if ReadytoInvoice was false then execute code.

Many thanks

1 Like