Auto Toggle Make Direct Sales Kit line

I have a working BPM that changes a sales kit line release to be Make Direct that I built using this post:

I am aware that toggling the Make flag does not carry out the methods that happen when you manually check/uncheck the flag in the UI. What, if anything, do I need to “undo” when marking Make Direct false programmatically?

Back story if you care…
I have much appreciation for those (@hmwillett , @timshuwy , @Randy) who covered how to automatically enable the Make Direct flag on an order and properly drive suggestions, etc. However, I have a business case that I want to undo this selectively. Long story short, we started using sales kits in some instances but we want to treat the manufactured lines in the sales kit like a make direct line 98% of the time. That part is working fine. But occasionally we end up with a unit in stock (that is not normal) and they want to use that to fulfill the line on the sales kit. Today, I have to disable the BPM and use the DMT to toggle the Make flag to false and let them reserve/allocate before re-enabling the BPM. This seems to work OK but I don’t want to have to be involved for these scenarios. So I thought I could create a UBAQ to do this and give it to the sales people to toggle the flag. I’m having some trouble getting the PartSug and PartDtl to sync up with these changes like they need to. Upon a new row added, everything works properly. But changing an existing row, I am expecting a suggestion to exist in the PartSug table to create a job and it’s not happening. Worse, if I toggle it back to true, my original PartSug entry tied to the order doesn’t come back either. It seems like changing the Make flag doesn’t stick either and it is getting changed back after I force it. I seem to recall that’s why I used the DMT in the first place… the change would stick. Any ideas?

It’s kind of a mess and been a few years since I looked, but if you do it without the BO, you have to keep the OrderRel, PartSug, and PartDtl tables in sync. Maybe PartWip too (don’t remember).

I don’t recall what the issue was when I used the BO SalesOrder.ChangeMake, but if you can get that to work, I would start there as it should cover all of that for you.

1 Like

I should probably put more effort into getting the ChangeMake method to work first. I agree. I am probably over-complicating things.

Question, are you only making sales kits make direct or all of your parts?

I can tell you what logic I used to make Unfirm on Order Entry be set properly, especially related to Kits. Now in my case there wasn’t a need for a BO and the BO may handle Kits for you. But if the BO doesn’t then you are still responsible to updating the Children.

if (IsOrderCreditHold(iOrderNum))
{
  foreach (var ttOrderRelRow in ttOrderRel.ToList())
  {
    using (var txScope = IceContext.CreateDefaultTransactionScope())
    {

        var row = Db.OrderRel.Where(w => w.Company == Session.CompanyID && w.OrderNum == ttOrderRelRow.OrderNum
                && w.OrderLine == ttOrderRelRow.OrderLine && w.OrderRelNum == ttOrderRelRow.OrderRelNum).FirstOrDefault();


        row.FirmRelease = false;
        ttOrderRelRow.FirmRelease = false;
        Ice.Diagnostics.Log.WriteEntry($"[ Updating FirmRelease ] OrderNum: {row.OrderNum} - OrderLine: {row.OrderLine} - OrderRel: {row.OrderRelNum}");
        Db.Validate(row);

        var kitChildrenRows =
          (from od in Db.OrderDtl
            join or in Db.OrderRel on new { od.Company, od.OrderNum, od.OrderLine } equals new { or.Company, or.OrderNum, or.OrderLine }
            where od.Company == Session.CompanyID
              && od.OrderNum == ttOrderRelRow.OrderNum
              && od.KitParentLine == ttOrderRelRow.OrderLine
              && or.OrderRelNum == ttOrderRelRow.OrderRelNum
              && od.KitFlag == "C"
            select or
          ).ToList();

          foreach (var kitChildRow in kitChildrenRows)
          {
            kitChildRow.FirmRelease = false;
            Ice.Diagnostics.Log.WriteEntry($"[ Updating FirmRelease Kit Child ] OrderNum: {kitChildRow.OrderNum} - OrderLine: {kitChildRow.OrderLine} - OrderRel: {kitChildRow.OrderRelNum}");
            Db.Validate(kitChildRow);
          }
          
          
          Ice.Diagnostics.Log.WriteEntry($"DEBUG LISTING ALL");
        var kitChildrenRowsx =
          (from od in Db.OrderDtl
            join or in Db.OrderRel on new { od.Company, od.OrderNum, od.OrderLine } equals new { or.Company, or.OrderNum, or.OrderLine }
            where od.Company == Session.CompanyID
              && od.OrderNum == ttOrderRelRow.OrderNum
              && or.OrderRelNum == ttOrderRelRow.OrderRelNum
            select or
          ).ToList();

          foreach (var kitChildRow in kitChildrenRowsx)
          {
         
            Ice.Diagnostics.Log.WriteEntry($"[ Debug ] OrderNum: {kitChildRow.OrderNum} - OrderLine: {kitChildRow.OrderLine} - OrderRel: {kitChildRow.OrderRelNum}");
       
          }
          
        txScope.Complete();
    }
  }
}

In my case I had to do it on the POST After Credit Hold was applied, hence UI Refresh.
image

Definitely: Go with ChangeMake

1 Like

Would love to see the refresh UI code…

I am having trouble getting my head around a “make direct sales kit”… how does that work? Sales Kits are not normally made on a job and if you ship the kit from a job, then the components of the kit would not be properly shipped.

2 Likes

If you do a simple GetByID in the POST Epicor will handle the Refresh for you. I started doing that going forward.

It just does this

using (Erp.Contracts.SalesOrderSvcContract orderSvc = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.SalesOrderSvcContract>(Db))
{
  SalesOrderTableset OrderDs = orderSvc.GetByID(iOrderNum);
  this.dsHolder.Attach(OrderDs);
}
4 Likes

We are moving toward stock but for the time being, almost all Manufactured parts are Make Direct - save for some kanban items do as needed.

I know. It’s ridiculous.
Our company has a long tradition of tying jobs to customers. So we have done mostly make direct for manufactured parts. However, we have a diverse customer base and several of them require us to supply 1 part number for their PO as a complete “kit”. For years, we would make a custom part number with a customer specific MOM - usually consisting of a copy of a standard part but with a few extra options/accessories lumped in. This skewed finances and eventually caused finance to have to make adjustments for those transactions because all the revenue was coming in on one product group instead of splitting to the various groups. That’s where the sales kit came in. But of course sales kits don’t do make direct jobs. And we started out by not tying them to customers. But everyone couldn’t figure out which was which and after briefly trying to trick our dashboards into tying an order to the job (even when it was stock), I set out to try to make the sales kit direct. So it works by tricking the system into making the release directly to the order but then I also have a BPM on the backside that when the operation is reported complete, it will change the demand link back to stock just in time for it to be picked for shipment.

Ahh… the old “Manufacturing wants to know who they are making it for” trick… Years ago I had to remove the customer and order information from our production reports, travelers, etc, because we had to stop the shop from prioritizing certain customers “because they are more important”. It seemed that the production line thought they knew better than the planners, and would override their decisions to make one item ahead of another.
My view is that production should make what they are told to make BY PART NUMBER and not by customer or order.
FYI… at Epicor, our developers do not know which customers are asking for a feature. All they know is that someone in Product Management said that we need a feature, and they produce it.

5 Likes

Why not set the default to make direct at the company level then?

Will that work for a sales kit?

Thanks Haso, I think @hmwillett is using that in kinetic as well.

1 Like

Not to derail the thread, but welcome to my struggle. :wink:

1 Like

Oh God–giving me PTSD from my time as a planner. Looking at you BOBBIE. :expressionless:

1 Like

OK. Questionable business process practices aside, I was able to get the ChangeMake method to work on my UBAQ so I think I’m good to go. I ended up doing a pre-processing on the Update method and sent the values to callContext variables and enabled a post processing directive. Then on the post-processing I ran the ChangeMake and MasterUpdate methods to implement the change. Seems to work OK. Thanks everyone!!

1 Like