Prevent Over Picking (EMWW) / or stop Shipping too many pieces

On the handheld, you can pick more than the requested number of pieces (without a notification or warning). This process accommodates multiple releases on SO Lines. EMWW is an app, so I don’t think I can do anything to change that (and I am not sure how to run a trace for the app on the handheld). If anyone know how to prevent picking more than requested, please let me know.

The next step is for our packers to pull the picked order into the Customer Shipment Entry (actions - picked orders). I have run a trace on this process and a number of business objects are firing. I am having trouble pulling in the OrderDtl.TotalShipped because it is not a database field (so I am not sure how to grab it).
image
I think this field would be the most accurate way to determine if any previous releases were shipped complete or as partials to accurately determine what has already shipped.

On Customer Shipment entry, there is a field (also not a database field) called ShipDtl.SellingShippedQty
image
However, this field pulls in the Picked Quantity and matches the “This Shipment” quantity, so it disregards what was previously shipped on for this order line.

The trouble I am having is many of the fields I need to compare are NOT database fields (so you have to catch them on the tt or ds table on the correct BO, but If I cannot prevent over-picking on the handheld (EMWW), then I want to prevent it on the Shipment when shipping tries to close the pack. By the time shipping tries to close the pack, there is no longer data in the tt or ds table because the shipping line has already been written.

I have tried Data and Method Directives without success. Does anyone have tips on the right path for me to take to resolve this issue.

I looked at this topic and I could not get it to work when there are multiple SO releases.

Any help would be greatly appreciated.

@BKen I use this pre processing on CustShip.UpdateMaster. I think something similar should work for this.

image

/* check shipping qty */
string xmsg = string.Empty;

foreach (var ttShipDtlRow in ds.ShipDtl.Where(sdr => sdr.Added() || sdr.Updated())) 
                                    
{
    if (ttShipDtlRow.SellingShippedQty + ttShipDtlRow.SellingShipmentQty > ttShipDtlRow.SellingReqQty)
    {
        xmsg = $"Previously Shipped Qty of {ttShipDtlRow.SellingShippedQty:N0} plus {ttShipDtlRow.SellingShipmentQty:N0} is {ttShipDtlRow.SellingShippedQty + ttShipDtlRow.SellingShipmentQty:N0} \nOrder/Line/Release Quantity: {ttShipDtlRow.SellingReqQty:N0}";
        CallContext.Current.ExceptionManager.AddBLException(xmsg);
    }
    
}

1 Like

Nice Greg, that should work just fine.

I think @BKen also has to make sure that is web config for whatever app server he is on is set to throw errors in headers too right? Otherwise that error message doesn’t pop up I believe.

I swear I remember reading that in the implementation guide.

One should only pass errors through to clients in DEV environments. This is where observability systems are better than legacy debugging techniques.

Improper Error Handling | OWASP Foundation
Improper handling of errors can introduce a variety of security problems for a web site. The most common problem is when detailed internal error messages such as stack traces, database dumps, and error codes are displayed to the user (hacker). These messages reveal implementation details that should never be revealed. Such details can provide hackers important clues on potential flaws in the site and such messages are also disturbing to normal users.

@Mark_Wonsil

This one in the CRM implementation guide is awesome. No raising of security concerns. Just assuming that the user and the organization has the know-how to read this and know all the intricacies behind opening port 443 to inbound/outbound traffic.

Epicor has started hiding error messages for the last couple of years. Several have written here that error messages have become more cryptic and that we have to look in the server logs. This practice is true for the .NET client as well as REST.

BTW, I blew up the document and see that that wasn’t just error messages but BPM informational messages for KWW, so the security note only applies to not passing error messages to the handheld but OK for business logic checks.

Mark, so if I am understanding you correctly, is this okay or not okay- the addition of the headers?

I would say that allowing the ContextHeader is fine - just don’t pass any information in it that would help an attacker, i.e. error messages, implementation details, etc.

I see, so in terms of @gpayne 's BPM you are saying, feel free to send a message, but since you are exposing this in the context header you may wish to limit what you are sending…

1 Like

Greg,
I must be doing something wrong. Here is my method directive:


I am not sure when it happened, but I think the tt moved to ds.

I have this Method directive enabled, but nothing is happening on a sales order that has 1 line with 2 releases. I am picking more than each release, but each pick is less than the line total.
1st customer shipment:
image

2nd customer shipment:
image

I suspect that on customer shipment entry, when you go to Actions - Picked Orders and pull in a picked order, that it overwrites “Shipped To Date” field. Perhaps it is accurate on how many have been shipped to date for the Order Release, but not for the Order Line.

And you are also saying that while you think Epicor is doing a better job at hiding sensitive details in their headers/exceptions, you are still somewhat concerned with what this guide is telling us to do because there could be places where Epicor hasn’t done a great job at hiding those details, right?

I created an informational message firing for a true or false condition after the ds.ShipDtl.SellingShipmentQty field of the change row is not equal to the 0 expression, but all the fields I pulled are NULL. Is this because the tt or ds table has already written to the database and are now blank?
image

I would say we’re highjacking @bken’s thread here. :wink: Security is a shared responsibility and I think Epicor is setting good defaults but giving users the ability to accept additional risk if they choose to.

1 Like

Last post, sorry @BKen , the big qualm I have with epicor is that they don’t point out the risks that you are taking when you add these things to the web config. They just assume that everyone is as smart as @Mark_Wonsil and know what they are doing by adding these to their webconfig…

so the whole part of “if they choose to” assumes that they know what they are doing.

When in reality most people only know that they want to see their BPM messages and this guides them to believe that’s all this is doing.

They’re generally smarter I have found! I’m just old…

I wonder what the correlation coefficient is.

@BKen I wonder since you are getting a line that already exists that it is neither added or updated at this point. We make them manually so that would not happen for me. I would take all of the conditions off and maybe make the exception into just an info message and print the values inside the foreach to see what was happening.

@BKen The tt went to ds in 700 I think. The screenshot is from 10.2.400 and the code is from 11.1.200.

1 Like

So our Shipping group will sometimes pull in Picked Order and sometimes will manually add lines to Customer Shipment Entry. I want to prevent overshipment for all scenarios, so I am thinking about doing a data directive with a condition on when the pack goes from Open to Any, but I am not sure how to query for “non-database” fields. I can fill table by query, but the non-database fields do not get pulled over.
How do I get this field pulled into a directive?
image

I want to get this field from the Order Line because it will accommodate all releases (the customer shipment entry fields do not factor in all releases when a Picked Order gets pulled in).