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);