BPM ARInvoice Error - Update Tax Category

Hi,
I am trying to update the AR Invoice line tax category using the BOs that Epicor calls based on the trace I did on the AR Invoice entry screen. I need to do this so that all tax calculations are done by Epicor. Can’t understand why I am getting an error stating “InvcDtl not found”. I also created a JSON file and ran ARInvoiceSvc/UpdateMaster via the API help page, and got the same error. Does anyone have any ideas as to why this is happening?

Thank you in advance,
Peter

Perhaps this is a situation to use UpdateExt rather than Master? I’ve seen a few posts on the forum that users get strange results, and have to switch to that method. Don’t ask me for the reason why :smiley:

Before calling OnChangeofLineTaxCat, the tableset should already contain 2 InvcDtl records for the invoice line you are going to modify, this is what the UI does, it sends the unmodified and modified rows.

dp definitely would not work, I don’t know what dp2 contains.

Thank you for your responses. Sorry, I mistype the dp2. It is only dp.
The dp is set via GetByID and it returns only a single unmodified record per invoice line. The interesting thing is that if I just run the OnChangeofLineTaxCat, I also got “InvcDtl not found” error also. I have tried doing this via In-Transaction and Standard Data Directive BPM and pre and post-processing method directing BPM with the same issue.

I have tried Update BO but it gave me “NullReferenceExemption” type error (attached). From what I understand, UpdateExt calls Update anyway so I didn’t try it in the BMP. However, I tried UpdateExt via the API help page and got “Row has been modified by another user and couldn’t be updated.” even though there wasn’t any active user is in the invoice record.

Background of my task:
We added a user defined field to InvcHead (DefaultTaxCategoryID_c) and when this is applied to the invoice head, we need to also apply to all the invoice line. So I am trying to do this via Data Directive on InvcHead and also method directive.

UpdateBOError.txt (4.9 KB)

In the update ext attempt, did you put in “U” for the row mod field?

Yes, the RowMod is set to U

You need to pass in both the unmodified row as well as the modified row to UpdateMaster.

You can use bo GetRows or BufferCopy – I need to write-up more info on this but Epicor has helpers to clone a row.

var dsReceipt = bo.GetByID(vendorNum, purPoint, packSlip);
 
// 
// Example how to Copy a few Tableset rows to New Tableset
//
var dsNew = new Erp.Tablesets.ReceiptTableset { 
    RcvHead = { 
        Epicor.Data.BufferCopy.Clone(dsReceipt.RcvHead[0]) 
    },
    RcvMisc = {
        Epicor.Data.BufferCopy.Clone(dsReceipt.RcvMisc.Where(x => x.MiscSeq == seqNum).FirstOrDefault()),
        Epicor.Data.BufferCopy.Clone(dsReceipt.RcvMisc.Where(x => x.MiscSeq == seqNum).FirstOrDefault())
        //new Erp.Tablesets.RcvMiscRow { EnableToBuildYourOwn }
    }
};
 
dsNew.RcvMisc[0].RowMod = "U";
 
 
// 
// Example how to Copy a LINQ Row to Tableset
//
 
// Erp.Tablesets.ReceiptTableset 
var dsNew3 = new Erp.Tablesets.ReceiptTableset {
    RcvHead = { 
        Epicor.Data.BufferCopy.Copy<Erp.Tables.RcvHead, Erp.Tablesets.RcvHeadRow>(Db.RcvHead.Where(s => s.Company == Session.CompanyID 
                    && s.PackSlip == packSlip 
                    && s.VendorNum == vendorNum 
                    && s.PurPoint == purPoint).FirstOrDefault())
    },
    // Erp.Tablesets.RcvMiscTable
    RcvMisc = {
        // Erp.Tablesets.RcvMiscRow
        Epicor.Data.BufferCopy.Copy<Erp.Tables.RcvMisc, Erp.Tablesets.RcvMiscRow>(Db.RcvMisc.Where(s => s.Company == Session.CompanyID 
                    && s.PackSlip == packSlip 
                    && s.VendorNum == vendorNum 
                    && s.PurPoint == purPoint
                    && s.MiscSeq == seqNum).FirstOrDefault()),
        // Erp.Tablesets.RcvMiscRow     
        Epicor.Data.BufferCopy.Copy<Erp.Tables.RcvMisc, Erp.Tablesets.RcvMiscRow>(Db.RcvMisc.Where(s => s.Company == Session.CompanyID 
                    && s.PackSlip == packSlip 
                    && s.VendorNum == vendorNum 
                    && s.PurPoint == purPoint
                    && s.MiscSeq == seqNum).FirstOrDefault())
    }
};
 
dsNew3.RcvMisc[0].RowMod = "U";
 
bo.OnChangeMiscDocActualAmt(vendorNum, purPoint, packSlip, seqNum, _value, ref dsNew);
bo.Update(ref dsNew);
 
 
// 
// Example how to Copy a LINQ Row to a LINQ Row (Erp.Tables.RcvMisc)
//
 
// Epicor Clone and Copy both will create a new GUID when the target is a LINQ Row
var LINQtoLINQExample = Epicor.Data.BufferCopy.Clone(Db.RcvMisc.Where(s => s.Company == Session.CompanyID 
    && s.PackSlip == packSlip 
    && s.VendorNum == vendorNum 
    && s.PurPoint == purPoint
    && s.MiscSeq == seqNum).FirstOrDefault());
 
// If you want to Preserve the GUID you must use Copy with 3rd param true
Erp.Tables.RcvMisc linqRowExample2 = new Erp.Tables.RcvMisc();
Epicor.Data.BufferCopy.Copy(xrow, linqRowExample2, true);

Example of me Updating InvcHead

foreach (var row in dsInvcHeadList.InvcHeadList)
{
Ice.Diagnostics.Log.WriteEntry($"dsInvcHeadList: {row.InvoiceNum}");

    using (var bo = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.ARInvoiceSvcContract>(this.Db))
    {
    
        var dsInvoice = bo.GetByID(row.InvoiceNum);
        var originalRow = dsInvoice.InvcHead.NewRow();
        BufferCopy.Copy(dsInvoice.InvcHead[0], originalRow);
        
        dsInvoice.InvcHead.Add(originalRow);
        Ice.Diagnostics.Log.WriteEntry($"dsInvoice: {dsInvoice.InvcHead[0].InvoiceNum}");
        string recalcAmts = callContextBpmData.ShortChar01; // asked in customization
        dsInvoice.InvcHead[0].ApplyDate = dtGroupApplyDate;
        dsInvoice.InvcHead[0].RowMod = "U";
        bo.OnChangeofApplyDateEx(row.InvoiceNum, dtGroupApplyDate, recalcAmts, ref dsInvoice);
        dsInvoice.InvcHead[0].RowMod = "U";

        /// <param name="ds"></param>
        /// <param name="cGroupID">current GroupID on Invoice</param>
        /// <param name="cTableName">Indicates the tableName that triggered the update</param>
        /// <param name="runCheckAmortSched">Indicates whether the chkAmortSchedCore method should be called</param>
        /// <param name="runChkLtrOfCredit">Indicates whether the chkLtrOfCredit method should be called</param>
        /// <param name="genAmortSched">Indicates whether Amortization schedules should be either restored or generated</param>
        /// <param name="lRASchedExists">value of current InvcDtl.RASchedExists field</param>
        /// <param name="ipInvoiceNum">current invoice num used to call chkLtrOfCredCore</param>
        /// <param name="ipInvoiceLine">current invoice line</param>
        /// <param name="cARLOCID">current ARLOCID used to call chkLtrOfCredCore</param>
        /// <param name="suppressUserPrompts">Indicates if user prompts should be suppressed</param>
        /// <param name="dTotalCharges">InvcHead.InvoiceAmt used in call to CheckLtrOfCredit</param>
        /// <param name="lGetDefaultAccount">Set the global variable to get the default account if the product code or part are dirty</param>
        /// <param name="grpTotalInvAmt">InvGrp.BaseAmount to update in UI</param>
        /// <param name="opGenMessage">possible output message from chkAmortSchedCore</param>
        /// <param name="opLtrCrdMsg">possible output message from chkLtrOfCredCore</param>
        /// <param name="lUpdateRan">Indicates that the Update process did run</param>

        decimal grpTotalInvAmt = 0;
        string opGenMessage = "";
        string opLtrCrdMsg = "";
        bool lUpdateRan = false;
        bool genAmortSched = false;
        
        bo.UpdateMaster(ref dsInvoice, dsInvoice.InvcHead[0].GroupID, "InvcHead", false, false, ref genAmortSched, false, dsInvoice.InvcHead[0].InvoiceNum, 1, "", false, dsInvoice.InvcHead[0].InvoiceAmt, false, out grpTotalInvAmt, out opGenMessage, out opLtrCrdMsg, out lUpdateRan);
        
     }
 }

Mainly focus on:

        var dsInvoice = bo.GetByID(row.InvoiceNum);
        var originalRow = dsInvoice.InvcHead.NewRow();
        BufferCopy.Copy(dsInvoice.InvcHead[0], originalRow);
        
        dsInvoice.InvcHead.Add(originalRow);

More Reading:

Thank you very much! Adding the original row resolved the issue I was having.