PO Blanket

Hello,
We have a situation with what we call PO blanket and I was wondering if someone already went thru a similar scenario and how was it solved: if with customization, service connect, BPMs, Data Directives, or if exist any out-of-the-box functionality within 10.1.400 that we might be missing.
The general idea is that Purchasing creates a PO 123 (i.e.) and enters the Total QTY of 5000 on line 1, release 1 (123-1-1) for a given component, prints the PO, and sends it to the supplier. Later, Purchasing may add a release for a partial QTY of 200 (or whatever is wanted at a given time) and the idea is to automatically update the original QTY of 5000 in 123-1-1 as Total QTY minus Partial QTY (5000 – 200) = 4800 and auto generate a new PO 123-1-2 for 200 while maintaining the remaining balance of 4800 in the original PO 123-1-1
Some assumptions are that the PO Blanket can contain more than one line and therefore will be multiple part numbers in each PO Blanket.

Your suggestions will be appreciated!
Daniel Dell’Aquila

We’ve done this with BPMs but there is no built in facility

Jose,

Thank you for your response. Is there any code that would you be willing to share that could shorten our development?

You can do blanket PO’s out of the box, it’s just HOW you do it that makes all the difference.

If I recall correctly, you MUST lock the line qty and add the first release as the total PO qty and END date of the blanket PO. Then every time you add a release line, the qty of the first release (which Is really the last) will automatically adjust.

Hi Daniel,
I don’t have anything handy it was done for a customer eons ago

I just confirmed it.

If you just lock your line qty, All releases added after will subtract from the “initial” release (which as I noted, will be the final release)

1 Like

This is pretty cool @Chris_Conn didn’t know this. I wonder when this was added

+1 for Chris? Hot damn!

FYI - If you DONT put that first release as the LAST shipment (by date), you are going to be fighting Epicor as it will try to close your lines everytime you ship a release.

2 Likes

Chris,

Thank you for your response. But I might be doing something wrong because when we add the second release, the qty adds up to the total in the Line 1, and the Release 1 remains the same. We see the Lock QTY in the release tab, but not in the Line tab. For example Line 1 release 1 is for 5000, we add release 2 for 200, and line one shows 5200 and release 1 stays 5000. Can you send me some screen shots?

Chris,

I believe the functionality that you just described is for Sales Orders (SO), and I am looking for Purchase Orders (PO) instead.

Daniel,

You are correct, I was indeed talking about a SO. I assumed they were the same but in fact they are not. Sorry to get you hopes up. I’ll save Jose the trouble: Chris -= 1;

I’ll take -2 for getting my hopes up!

Oh! Please don’t worry! After all you are the only ones who responded to my request!

Thanks a bunch!

1 Like

This is how I would approach it

On the line create a custom UD field called BlanketLine_c boolean and the user check this checkbox when they want this line to behave like a Blanket as stated above.
Then put a BPM on POUpdate with a condition that says if there is an Added PORelease or Updated Release then it flags a field in BPMDataContext to let a PostProcessing Method know that it needs to fire and to reduce the first release by the quantity of the newly added release or modified release. You may want to store the initial PO Line QTY in a separate UD field that will never change so that you can reference it when doing the math.
Because you are modifying several parts of the PO DataSet though you’ll have to do a GetByID at the very in in PostProcess to re-load the dataset and avoid “Record has been modified issues”

This is kind of what we did, although I believe we simply have a UD field for the initial quantity, which is set by BPM to be equal to line quantity when the line is first saved. Then purchaser can just reference that quantity after adding a release and make sure that Release 1 and Line Qty are correctly set after adding additional releases - it’s a little more manual, but they haven’t complained yet in the last 4 years.

Chris -

Any possibility you could share some simple coding to get me started? I understand most of this but guidance as to method or data BPMs, etc would be helpful.

Nevermind … I have worked it out.

Thanks

We have upgraded to Epior 10.2.600 and now this customization is not working. I am trying to adjust release 1 on the PO so that the line quantity is essentially “locked”. I keep getting an error:

“Attempt to lock records with no transaction in effect detected.”

I assume it is due to the fact that I am trying to update a record that I have locked already. How can I work around this?

Below is my code:

//Name: UpdateRelOne
//Table:  PORelease
//Type: In-Transaction Data Directive
//Blanket PO functionality - treating like a locked line and master release for Release 1. Subsequent releases will decrement/increment Release 1, but leave the Line quantity the same.
//Converted from ABL to C# 08/26/2019 MLW


decimal Rel1Qty = decimal.Zero;
decimal XREL1Qty = decimal.Zero;
decimal OpenPerc;
decimal LineQty;
MessageText = "";

var NewPORel = (from NPORrow in ttPORel
                select NPORrow).ToList();

foreach (var PORIter in NewPORel)
{

//MessageText = PORIter.PONum.ToString() + "==" + PORIter.POLine.ToString() + "==" + PORIter.PORelNum.ToString() + "==" + PORIter.RelQty.ToString() + "==" + PORIter.XRelQty.ToString() +  "==" + PORIter.ReqChgQty.ToString() +  "==" + PORIter.RowMod.ToString();

  var MatchPOHed = (from MPOHrow in Db.POHeader
                    where MPOHrow.Company == PORIter.Company && MPOHrow.PONum == PORIter.PONum && MPOHrow.CheckBox02 == true
                    select MPOHrow).FirstOrDefault();
  if(MatchPOHed != null)
  {
    var MastPORel = (from MRelrow in Db.PORel
                    where MRelrow.Company == PORIter.Company && MRelrow.PONum == PORIter.PONum && MRelrow.POLine == PORIter.POLine && MRelrow.PORelNum == 1
                    select MRelrow).FirstOrDefault(); 
    /* Adjust Release 1 based on action to other releases */
   if (MastPORel != null && PORIter.RelQty != 0)
   {
      //MessageText = MessageText + "\n\r" + MastPORel.PONum.ToString() + "==" + MastPORel.POLine.ToString() + "==" + MastPORel.PORelNum.ToString() + "==" + MastPORel.RelQty.ToString() + "==" + MastPORel.XRelQty.ToString();
      
      if (PORIter.RowMod == "A" && PORIter.PORelNum != 1)
      {
        Rel1Qty = MastPORel.RelQty - PORIter.RelQty;
        XREL1Qty = MastPORel.XRelQty - PORIter.XRelQty;
        MessageText = PORIter.RowMod.ToString() + "==" + Rel1Qty + "==" + XREL1Qty ;
      }
      if (PORIter.RowMod == "U" && PORIter.PORelNum != 1)
      {
        Rel1Qty = MastPORel.RelQty - (PORIter.RelQty - PORIter.ReqChgQty);
        XREL1Qty = MastPORel.XRelQty - (PORIter.XRelQty - ((PORIter.XRelQty / PORIter.RelQty) * PORIter.ReqChgQty));
        MessageText = PORIter.RowMod.ToString() + "==" + Rel1Qty + "==" + XREL1Qty ;
      }
      if (PORIter.RowMod == "D" && PORIter.PORelNum != 1)
      {
        Rel1Qty = MastPORel.RelQty + PORIter.RelQty;
        XREL1Qty = MastPORel.XRelQty + PORIter.XRelQty;
        MessageText = PORIter.RowMod.ToString() + "==" + Rel1Qty + "==" + XREL1Qty ;
      }
     if (Rel1Qty < 0)
      {
         CallContext.Current.ExceptionManager.AddBLException("Too large a quantity has been entered. Review the first release to see balance open on blanket.");
      }
     else
      {
         MastPORel.RelQty = Rel1Qty;
         MastPORel.XRelQty = XREL1Qty;
      }
   }
  }
Db.Validate();
}