Automatic AR Write Off

I’m working on a BPM that when an invoice for a specific customer is posted, it automatically writes it off to an intercompany GL account. I’m struggling with getting it to post. I followed the code in the trace, but there was never anything that showed up in the trace for the posting process, so when the invoice is posted, nothing happens regarding the write off.
Anyone know the code to post it?

//var _writeTaskLog = new System.Lazy<Ice.Core.WriteTaskLog>(() => new Ice.Core.WriteTaskLog(this.Db));


var tt = ttInvcHead.FirstOrDefault();

if( tt != null )
{
  int iNum = tt.InvoiceNum;
  decimal iAmt = tt.InvoiceAmt;
  decimal iBal = tt.InvoiceBal;
  string writeOffAcct = "01-01-2020-00-0000";
  string writeOffAcctPipe = "2020|01|01|00|0000";
  
  using(var arBO = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.ARAdjustmentSvcContract>(Db))
  {
    ARAdjustmentTableset arTS = new ARAdjustmentTableset();
    
    // Load the invoice information in to the arTS tableset
    arTS = arBO.GetByID(iNum);
    
    // Get a new AR Write Off Record
    arBO.GetNewCashDtl1(ref arTS, iNum);
    
    //_writeTaskLog.Value.WriteToTaskLog("CheckNum: " + arTS.CashDtl[0].HeadNum.ToString(),tasknum);
    
    // Change the adjustment amount to the invoice balance
    bool reload = false;
    
    arTS.CashDtl[0].DocDispTranAmt = -iBal;
    arTS.CashDtl[0].DocTranAmt = -iBal;
    arTS.CashDtl[0].DispTranAmt = -iBal;
    arTS.CashDtl[0].Comment = "Auto Write Off by BPM";
    arTS.CashDtl[0].TranType = "ADJUST";
    arTS.CashDtl[0].RowMod = "A";
    arTS.CashDtlTGLC[0].GLAccount = writeOffAcctPipe;
    arTS.CashDtlTGLC[0].RowMod = "A";
    arTS.CashDtlTGLC[0].SegValue1 = "2020";
    arTS.CashDtlTGLC[0].SegValue2 = "01";
    arTS.CashDtlTGLC[0].SegValue3 = "01";
    arTS.CashDtlTGLC[0].SegValue4 = "00";
    arTS.CashDtlTGLC[0].SegValue5 = "0000";
   
    arBO.ChangeAdjAmount(ref arTS, out reload);
    
    // Change GL Account to the write off account
    string ipCompany = Session.CompanyID;
    string ipCOACode = "ISIMain";
    string ipGLAccount = writeOffAcctPipe;
    
    arBO.ChangeGLAcctDisp(ipCompany, ipCOACode, ipGLAccount);
    
    // Validate the transaction set is accurate
    arBO.ValidateTransaction(ref arTS);
  }
}

Or if someone knows a different way, I’m open to suggestions.
Was trying to go the GL Control route for the customer where I set the Receivables context to the write off account, but was stuck with the invoice out in AR Aging.

No matter what you do the invoice will sit in some aging as open until it is either adjusted out or a receipt is posted against it.

My suggestion would be to have the customer AR account set to an intercompany account. This will allow you to see the IC invoices separated from the trade invoices and see all of the intercompany bookings.

As necessary you can write off the Intercompany invoices to the appropriate account.

No automation but it’s clean.

Charlie Smith

CRS Consulting Svcs

(860) 919-1708

CTCharlie@outlook.com

Thanks for your response Charlie.

This is exactly the process I’m attempting to automate–I’m not trying to “fake it” by setting flags; I’m trying to use the ARAdjustments BO to actually make it happen. I’ve got most of it pieced together, I’m just struggling with the posting portion.

I got it working.
Apparently, tracing doesn’t work with Kinetic screens?
I traced with the classic and got the posting information.

  using(var postBO = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.ARInvAdjPostSvcContract>(Db))
  {
    ARInvAdjPostTableset postTS = new ARInvAdjPostTableset();
    
    postTS = postBO.GetNewParameters();
    
    string agentID = "SystemTaskAgent";
    int agentSchedNum = 0;
    int agentTaskNum = 0;
    string maintProgram = "Erp.UIProc.ARInvAdjPost";
    
    postTS.ARInvAdjPostParam[0].ActType = "AR_Invoice_Adjustment";
    postTS.ARInvAdjPostParam[0].HeadNum = headNum;
    postTS.ARInvAdjPostParam[0].InvoiceNum = iNum;
    postTS.ARInvAdjPostParam[0].GLAccount = writeOffAcctPipe;
    postTS.ARInvAdjPostParam[0].TranAmt = -iBal;
    postTS.ARInvAdjPostParam[0].DocTranAmt = -iBal;
    postTS.ARInvAdjPostParam[0].Comment = "Auto Write Off by BPM";
    postTS.ARInvAdjPostParam[0].BookID = "ISI";
    postTS.ARInvAdjPostParam[0].COACode = "ISIMain";
    postTS.ARInvAdjPostParam[0].RowMod = "A";
    
    postBO.SubmitToAgent(postTS, agentID, agentSchedNum, agentTaskNum, maintProgram);
  }
2 Likes

I am trying to use the code, but I keep getting the below error

Can you please advise?

Did you add the ARInvAdjPost reference in the Usings and References section?

1 Like

I added using Erp.Contracts.ARInvAdjPostSvcContract;
but keep getting the same error.

I have solved this issue, but get another one
The type or namespace name ‘ARInvAdjPostTableset’ could not be found (are you missing a using directive or an assembly reference?)

can you advise on this?

Add this to the usings:

using Erp.Tabelsets;

Not able to find it

What should I do?

Never mind, I solved this.
Thank you very much for your help.

Type it in up here.

Sorry for bothering you again, the process was running properly until I started receiving the below error

Any Idea?

Note: I am running multiple Adjustments using a for loop.

Looks like you may need to save the record before you loop back up to edit the next.

No, the issue is that the Adjustment failed due to an error, and then it’s locked in someplace in the database. What is needed is to know the table that holds the error record and remove it.
Is there a table that saves the invoice adjustments?

There is already a tool in Epicor to resolve the data locked transactions.
image