Code for lot creations and part tran

,

Hi all,
I am still working on getting auto receive to split a lot with quantities over 1 into single piece lots with their own lot number when they are auto receive to inventory. I’ve been using the Epicor Support Bot in ChatGPT to get my head around this process. I think I am so close but don’t know why I’m getting the error below.

I have an In-Transaction Data Directive on the PartTran table to catch the transaction and split the lots.

Tran is required.
Asm is required.
Pack ID is required.
Line is required.
PO is required.
Line is required.
Release is required.
Order is required.
Line is required.
Rel is required.
Description is required.
Rev is required.
Supplier Number is required.
PO Receipt Qty is required.
Packing Slip is required.
Invoice is required.
Dimension is required.
Fiscal Period is required.
Journal is required.
DMR Number is required.
Action Number is required.
RMA is required.
Journal is required.
Call is required.
Line is required.
Line is required.
Customer is required.
RMA Line is required.
Rcv is required.

// Create an instance of the PartTran and LotSelectUpdate business objects
var partTranBO = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.PartTranSvcContract>(Db);
var lotSelectUpdateBO = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.LotSelectUpdateSvcContract>(Db);  // LotSelectUpdateSvc to manage lots

// Get the original transaction details
var originalTran = ttPartTran.FirstOrDefault();

if (originalTran != null && !string.IsNullOrEmpty(originalTran.JobNum))
{
    string jobNum = originalTran.JobNum;
    int tranQty = (int)originalTran.TranQty;
    DateTime sysDate = DateTime.Now; // Get the current system date for the transaction

    // Loop through each piece and create a new PartTran record for each lot
    for (int i = 1; i <= tranQty; i++)
    {
        // Step 1: Create a new lot using GetNewPartLot from LotSelectUpdateSvc
        Erp.Tablesets.LotSelectUpdateTableset lotDataSet = new Erp.Tablesets.LotSelectUpdateTableset();

        // Create a new lot using the PartNum from the original transaction
        lotSelectUpdateBO.GetNewPartLot(ref lotDataSet, originalTran.PartNum);  // Pass the part number as required

        // Access the new lot row
        var newLot = lotDataSet.PartLot[0];  // Access the new lot created

        // Assign a custom lot number (e.g., Job-1, Job-2)
        newLot.LotNum = $"{jobNum}-{i}";

        // Save the new lot to the system
        lotSelectUpdateBO.Update(ref lotDataSet);  // This creates the lot in the system

        // Step 2: Create a new PartTran transaction
        Erp.Tablesets.PartTranTableset newTranDataSet = new Erp.Tablesets.PartTranTableset();

        // Call the BO to create a new transaction and pass the required parameters
        partTranBO.GetNewPartTran(ref newTranDataSet, sysDate, 0);  // 0 could be a placeholder for a specific line, update as needed

        // Access the newly created PartTran row
        var newTran = newTranDataSet.PartTran[0];

        // Copy values from the original transaction and set up the new lot number
        newTran.JobNum = originalTran.JobNum;
        newTran.PartNum = originalTran.PartNum;
        newTran.WareHouseCode = originalTran.WareHouseCode;
        newTran.BinNum = originalTran.BinNum;
        newTran.Plant = originalTran.Plant;
        newTran.TranType = originalTran.TranType;
        newTran.TranDate = originalTran.TranDate;

        // Step 3: Assign the created lot number to the transaction
        newTran.LotNum = newLot.LotNum;  // Use the lot number created in Step 1

        // Set the transaction quantity to 1 for each lot
        newTran.TranQty = 1;

        // Step 4: Save the new PartTran record to the database via the BO Update method
        partTranBO.Update(ref newTranDataSet);
    }
}

I don’t know that this is your problem giving you an error: but if you want it to execute for anything over qty 1, you should change this:

for (int i = 1; i <= tranQty; i++)

either start with i = 0 or make it be i < tranQty.

The error makes me think you have a row in your dataset that isn’t getting filled upon Update. Can you log it and maybe do a row count on your dataset when it’s trying to update?

1 Like

Those are all integer fields. I wonder if it wants you to feed them all 0s.

EDIT: Nevermind. A few aren’t integers.

We do something similar here’s our code not sure If it will help but I know ours works fine in terms of creating the new lots etc



if (ErpCallContext.ContainsKey("Auto_Receipt_JobOper_Context"))
{
  //InfoMessage.Publish("Fires this");
  //this line looks for the checkbox in company config that says the lot number should be defaulted to job number. If that's true, then we don't need this and the job number as lot is fine. If it's not checked (which is the case for all of SG at the moment) it will continue
  if (!Db.XbSyst.Where(z=>z.Company == this.Session.CompanyID).Select(z=>z.JobLotDflt).FirstOrDefault())
  {
        //there is some call context values that we can use for logging.
        var JobOper = (ErpCallContext.GetValue("Auto_Receipt_JobOper_Context") as JobOper);
        //this is only going to fire on added or updated rows
        foreach (var rcpt in this.ttPartTran.Where(z=>z.RowMod == "U" || z.RowMod == "A"))
        {
          //this if looking at the current lotnum in the record. When doing transactions, the system creates the part tran row first, then updates that row. We are only going to fire this when there is a lot number present so that 1. the empty row isn't affected and 2. if the part is not lot tracked, we don't need to fire this to create a lotnum.
          if (!string.IsNullOrEmpty(rcpt.LotNum) && rcpt.JobNum == rcpt.LotNum && rcpt.InventoryTrans == true)
          {
            using(  var lotSvc = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.LotSelectUpdateSvcContract>(Db))
            {
              if (rcpt.TranQty > 0)
              {
                string newLotNum;                
                lotSvc.GenerateNewLotNum(rcpt.PartNum, out newLotNum);
                rcpt.LotNum = newLotNum;
                PartLot p = new PartLot();
                p.PartLotDescription = $"SubconJobRec {rcpt.JobNum}/{JobOper.OprSeq}";
                p.PartLotDescription = p.PartLotDescription.Length > 30 ? p.PartLotDescription.Substring(0,30):p.PartLotDescription;
                p.Company = rcpt.Company;
                p.PartNum = rcpt.PartNum;
                p.LotNum = rcpt.LotNum;
                p.FirstRefDate = DateTime.Now;
                p.OnHand = true;
                Db.PartLot.Insert(p);
                Db.Validate();
                Ice.Diagnostics.Log.WriteEntry($"tran {newLotNum} partnum {rcpt.PartNum} rowmod {rcpt.RowMod} jobnum {rcpt.JobNum} opseq {JobOper.OprSeq}");
              }
              else //this finds the last lot number used if the recieved checkbox in unchecked and the transaction is negative.
              {
                string oldLotNum;
                oldLotNum = Db.PartTran.Where(z=>z.Company == this.Session.CompanyID && z.PartNum == rcpt.PartNum && rcpt.TranType == "MFG-STK" && z.TranQty >0 && rcpt.JobNum == z.JobNum).OrderByDescending(z=>z.TranNum).FirstOrDefault().LotNum;
                if (!string.IsNullOrEmpty(oldLotNum))
                {
                  rcpt.LotNum = oldLotNum;
                }
                
              }
              
            }
          }
        }
  }        
}
1 Like

Hi,
Thanks for the idea, but I’m still getting the error. How would I log it? I can turn on tracing but I don’t see the BPM or transaction on the trace log.