IssueReturn PerformMaterialMovement REST call not showing in PartTran

As @Mark_Wonsil always says I would highly recommend you write a function that will take the 2 or 3 parameters you actually need and do the Issue Return from there server side thus abstracting the complexity.

Abstracting complex logic into a server-side function has several advantages over directly hitting complex endpoints from the client:

  1. Simplified Client Code: By abstracting the logic, your client code becomes much simpler. You can encapsulate all the intricate details and business rules on the server side, leaving the client with a clean, straightforward interface.
  2. Centralized Error Handling: Handling errors and exceptions can be more effectively managed in a centralized location on the server. This ensures consistent error responses and simplifies debugging and maintenance.
  3. Enhanced Security: By reducing the exposure of complex endpoints and business logic, you minimize the risk of security vulnerabilities. The client only interacts with a well-defined and narrow interface, reducing the attack surface. Specially if you use Acess Scope
  4. Maintainability: Changes to business logic or workflows can be made on the server without requiring updates to the client code. This makes it easier to maintain and evolve the application.
  5. Performance Optimization: Server-side functions are faster because all the complex logic already happens server side. Any additional BO calls etc don’t have to stand up and break down a TCP Stack or a Db Connection.
  6. Data Integrity: Ensuring data integrity and consistency is easier when managed on the server. You can enforce validation rules, transactional integrity, and other critical business rules more effectively.

I have a function that does this already, see below:

Library Function ID
MtlFunctions IssueMaterial

Request Parameters

Parameter Name type
JobNum String
AsmSeq Int
MtlSeq Int
PCID String
PartNum String
LotNum String
Qty Decimal
BinNum String

Output Parameters

Parameter Name type Remarks
Success Boolean
InfoMessage String
ErrorMessage String

Functionality:

StringBuilder myInfo = new StringBuilder();
try
{
     this.CallService<Erp.Contracts.IssueReturnSvcContract>(ir =>{
      Erp.Tablesets.SelectedJobAsmblTableset asmDS = new Erp.Tablesets.SelectedJobAsmblTableset();
      SelectedJobAsmblRow asmDSRow = (SelectedJobAsmblRow)asmDS.SelectedJobAsmbl.NewRow();
      asmDSRow.Company = this.Session.CompanyID;
      asmDSRow.JobNum = this.JobNum;
      asmDSRow.AssemblySeq = this.AsmSeq;
      asmDSRow.RowMod = "A";
      asmDS.SelectedJobAsmbl.Add(asmDSRow);
      string callProcess = "IssueMaterial";
      string message;
      IssueReturnTableset issueReturnDS = ir.GetNewJobAsmblMultiple("STK-MTL", Guid.Empty, callProcess, ref asmDS, out message);      

      var myRow = issueReturnDS.IssueReturn.FirstOrDefault();
      myRow.RowMod = "U";
      string pcMessage;
      ir.OnChangeToJobNum(ref issueReturnDS, callProcess, out pcMessage);
      myRow.RowMod = "U";
      ir.OnChangeToAssemblySeq(ref issueReturnDS, callProcess);
      myRow.RowMod = "U";
      myRow.ToJobSeq = this.MtlSeq;
      ir.OnChangingToJobSeq(this.MtlSeq, ref issueReturnDS);
      myRow.RowMod = "U";
      
      ir.OnChangeToJobSeq(ref issueReturnDS,  callProcess, out message); 
      
      if (string.IsNullOrEmpty(this.PCID))
      {
        myRow.PartNum = this.PartNum;
        myRow.RowMod = "U";
        ir.OnChangePartNum(ref issueReturnDS, callProcess);
        myRow.RowMod = "U";
        ir.OnChangeLotNum(this.LotNum, ref issueReturnDS);
        myRow.RowMod = "U";
        myRow.FromBinNum = this.BinNum;
        ir.OnChangingFromBinNum(ref issueReturnDS, out message);
        ir.OnChangeFromBinNum(ref issueReturnDS);
      }
      else
      {
        myRow.RowMod = "U";
        string questionMsg;
        ir.OnChangeFromPCID(this.PCID, false, false, callProcess, out questionMsg, ref issueReturnDS, out message);
      }
      myRow.RowMod = "U";
      ir.OnChangeTranQty(this.Qty, ref issueReturnDS);
      bool requiredUserInput;
      myRow.TranReference = "Issued via Job-Mat web app";
      ir.PrePerformMaterialMovement(ref issueReturnDS, out requiredUserInput);
      
      string NeqQtyAction;
      string NeqQtyMessage;
      string PCBinAction; 
      string PCBinMessage;
      string OutBinAction;
      string OutBinMessage;
      ir.MasterInventoryBinTests(ref issueReturnDS, out NeqQtyAction, out NeqQtyMessage, out PCBinAction, out PCBinMessage, out OutBinAction, out OutBinMessage);
      
      bool NegQtyAction = false;
      string legalNumberMessage;
      string partTrakPKs;
      ir.PerformMaterialMovement(NegQtyAction, ref issueReturnDS, out legalNumberMessage, out partTrakPKs);
      myInfo.Append($"{this.PartNum} issued to job {this.JobNum}");

      
      Success = true;
      InfoMessage = myInfo.ToString();
      
    });
}
catch (Exception ex)
{
  Success = false;
  InfoMessage = myInfo.ToString();
  ErrorMessage = ex.ToString();
}
finally
{
      var Dbcontext = Ice.Services.ContextFactory.CreateContext<ErpContext>();
    
      Erp.Internal.Lib.ErpCallContext.Add("PBOnHand-Post",""); // PartBin
      Erp.Internal.Lib.ErpCallContext.Add("PQDemand-Post",""); // Part Quantity
      Erp.Internal.Lib.ErpCallContext.Add("PLOnHand-Post",""); // Part Lot
      
      Erp.Internal.Lib.DeferredUpdate libDeferredUpdate = new Erp.Internal.Lib.DeferredUpdate(Dbcontext);
      libDeferredUpdate.UpdPQDemand();
      
      Erp.Internal.Lib.ErpCallContext.RemoveValue("PBOnHand-Post");
      Erp.Internal.Lib.ErpCallContext.RemoveValue("PQDemand-Post");
      Erp.Internal.Lib.ErpCallContext.RemoveValue("PLOnHand-Post");
}

3 Likes