Solved

Copy field from Requisitions to Purchase Orders via Create Orders action


Userlevel 2
Badge

Hi there,

 

I have tried the steps shown here to attempt passing the value of the custom fields from Requisitions over to the custom fields in Purchase Orders screen when Create Orders button is clicked. However, the custom fields in the created Purchase Order remain blank. Below is the DAC for both RQRequisitionLine and POLine:

RQRequisitionLine

        [PXDBString(50)]
[PXUIField(DisplayName = "Tax Purpose")]

public virtual string UsrTaxPurpose { get; set; }
public abstract class usrTaxPurpose : PX.Data.BQL.BqlString.Field<usrTaxPurpose> { }
#endregion

#region UsrProjectNo
[PXDBString(50)]
[PXUIField(DisplayName = "Project No")]

public virtual string UsrProjectNo { get; set; }
public abstract class usrProjectNo : PX.Data.BQL.BqlString.Field<usrProjectNo> { }
#endregion

#region UsrCategory
[PXDBString(50)]
[PXUIField(DisplayName = "Category")]

public virtual string UsrCategory { get; set; }
public abstract class usrCategory : PX.Data.BQL.BqlString.Field<usrCategory> { }

POLine

        [PXDBString]
[PXUIField(DisplayName = "Tax Purpose")]
[PXDefault(typeof(Search<RQRequisitionLineExt.usrTaxPurpose,
Where<POLine.rQReqNbr,
Equal<RQRequisitionLine.reqNbr>,
And<POLine.rQReqLineNbr,
Equal<RQRequisitionLine.lineNbr>>>>), PersistingCheck = PXPersistingCheck.Nothing)]
public virtual string UsrTaxPurpose { get; set; }
public abstract class usrTaxPurpose : BqlType<IBqlString, String>.Field<usrTaxPurpose> { }

[PXDBString]
[PXUIField(DisplayName = "Project No")]
[PXDefault(typeof(Search<RQRequisitionLineExt.usrProjectNo,
Where<POLine.rQReqNbr,
Equal<RQRequisitionLine.reqNbr>,
And<POLine.rQReqLineNbr,
Equal<RQRequisitionLine.lineNbr>>>>), PersistingCheck = PXPersistingCheck.Nothing)]
public virtual string UsrProjectNo { get; set; }
public abstract class usrProjectNo : BqlType<IBqlString, String>.Field<usrProjectNo> { }

[PXDBString]
[PXUIField(DisplayName = "Category")]
[PXDefault(typeof(Search<RQRequisitionLineExt.usrCategory,
Where<POLine.rQReqNbr,
Equal<RQRequisitionLine.reqNbr>,
And<POLine.rQReqLineNbr,
Equal<RQRequisitionLine.lineNbr>>>>), PersistingCheck = PXPersistingCheck.Nothing)]
public virtual string UsrCategory { get; set; }
public abstract class usrCategory : BqlType<IBqlString, String>.Field<usrCategory> { }

 

Please advise on this matter.

icon

Best answer by aaghaei 30 June 2023, 16:20

View original

13 replies

Userlevel 2
Badge

This is the error that I received when I tried to click the Create Orders button after implementing the code above:

 

Userlevel 7
Badge +17

Hi @ericklasimin61  I think you missed CURRENT from query. Please try like below and verify.

 

 

[PXDBString] [PXUIField(DisplayName = "Tax Purpose")] [PXDefault(typeof(Search<RQRequisitionLineExt.usrTaxPurpose,

Where<POLine.rQReqNbr, Equal<Current<RQRequisitionLine.reqNbr>>,

And<POLine.rQReqLineNbr, Equal<Current<RQRequisitionLine.lineNbr>>>>>),

PersistingCheck = PXPersistingCheck.Nothing)]

public virtual string UsrTaxPurpose { get; set; }

public abstract class usrTaxPurpose : BqlType<IBqlString, String>.Field<usrTaxPurpose> { }

Userlevel 2
Badge

Hi @Naveen Boga , thank you for your answer but adding Current doesn’t seem to fix the issue. Am I missing something else? I don’t think I need to set the Commit for those fields to True since they are not the trigger, right?

Userlevel 7
Badge +17

Hi @ericklasimin61  Are you seeing the same issue (Multipart -Identifier) after adding the CURRENT in the query?

Userlevel 2
Badge

The error does not appear, but the custom fields in the created PO does not reflect the values in Requisition screen.

Userlevel 2
Badge

Hi @Naveen Boga , do you have any idea on why the created PO does not reflect the values in Requisition screen?

Userlevel 7
Badge +9

I don’t think by relying solely on DAC properties you can make it work. I might be wrong as I was working on something but if I recall correctly, the row is inserted and then the RQ related fields are updated. As a result at the time of insertion the RQ related fields don’t have value yet and your PXFormula results logically should return null.

try overtired the method that creates the Po

Userlevel 7
Badge +17

Hi, @ericklasimin61  I investigated the problem you reported about the Multipart identifier and successfully resolved it.

 

Regarding the population of values, I noticed a problem in your code. Please review the code below and confirm if it is correct.

 

  public class POLineExt : PXCacheExtension<POLine>
{
[PXDBString]
[PXUIField(DisplayName = "Tax Purpose")]
[PXDefault(typeof(Search<RQRequisitionLineExt.usrTaxPurpose,
Where<RQRequisitionLine.reqNbr, Equal<Current<POLine.rQReqNbr>>,
And<RQRequisitionLine.lineNbr, Equal<Current<POLine.rQReqLineNbr>>>>>), PersistingCheck = PXPersistingCheck.Nothing)]

public virtual string UsrTaxPurpose { get; set; }
public abstract class usrTaxPurpose : PX.Data.BQL.BqlString.Field<usrTaxPurpose> { }
}

 

Userlevel 2
Badge

I don’t think by relying solely on DAC properties you can make it work. I might be wrong as I was working on something but if I recall correctly, the row is inserted and then the RQ related fields are updated. As a result at the time of insertion the RQ related fields don’t have value yet and your PXFormula results logically should return null.

try overtired the method that creates the Po

You are right, I commented the DAC properties and implemented the following code instead:


public class POOrderEntry_Extension : PXGraphExtension<POOrderEntry>
{
public delegate void PersistDelegate();
[PXOverride]

public void Persist(PersistDelegate persistDelegate)
{
POOrder pOOrder = Base.Document.Current;
if (pOOrder != null)
{
foreach (POLine pOLine in this.Base.Transactions.Select())
{
POLineExt pOLineExt = pOLine.GetExtension<POLineExt>();
if (pOLine != null)
{
RQRequisitionLine rQRequisitionLine = SelectFrom<RQRequisitionLine>.Where<RQRequisitionLine.reqNbr.IsEqual<@P.AsString>.And<RQRequisitionLine.lineNbr.IsEqual<@P.AsInt>>>.View.Select(this.Base, pOLine.RQReqNbr, pOLine.RQReqLineNbr);
RQRequisitionLineExt rQRequisitionLineExt = rQRequisitionLine.GetExtension<RQRequisitionLineExt>();

if (rQRequisitionLine != null)
{
pOLineExt.UsrTaxPurpose = rQRequisitionLineExt.UsrTaxPurpose;
pOLineExt.UsrProjectNo = rQRequisitionLineExt.UsrProjectNo;
pOLineExt.UsrCategory = rQRequisitionLineExt.UsrCategory;

}
}
}
}
persistDelegate();
}
}

The code works as intended, but any changes done to the custom fields in PO will not be persisted and instead, it will always be reverted back to the values from Requisitions screen.

 

Is there any way for the changes done in PO screen to persist instead?

Hello @ericklasimin61 ,

 

Instead of using persist delegate, Override any of the below methods and assign your custom values.
 

		protected virtual POLine InsertPOLine(POOrderEntry graph, RQRequisitionLine line, decimal? qty, decimal? unitCost, IBqlTable costOriginDac, string lineType, DateTime? bidPromisedDate)

OR,
 

        protected virtual void FillPOLineFromRequisitionLine(POLine poline, POOrderEntry graph, RQRequisitionLine rqLine, decimal? qty, decimal? unitCost, IBqlTable costOriginDac, string lineType)


 

Userlevel 2
Badge

Hello @ericklasimin61 ,

 

Instead of using persist delegate, Override any of the below methods and assign your custom values.
 

		protected virtual POLine InsertPOLine(POOrderEntry graph, RQRequisitionLine line, decimal? qty, decimal? unitCost, IBqlTable costOriginDac, string lineType, DateTime? bidPromisedDate)

OR,
 

        protected virtual void FillPOLineFromRequisitionLine(POLine poline, POOrderEntry graph, RQRequisitionLine rqLine, decimal? qty, decimal? unitCost, IBqlTable costOriginDac, string lineType)


 

Hi @venkatreddy43 , following your suggestion to override either of the methods:

InsertPOLine:

        protected virtual POLine InsertPOLine(POOrderEntry graph, RQRequisitionLine line, decimal? qty, decimal? unitCost, IBqlTable costOriginDac, string lineType, DateTime? bidPromisedDate)
{
if (qty <= 0)
return null;

POLine ooline = (POLine)graph.Transactions.Cache.CreateInstance();

ooline.OrderType = graph.Document.Current.OrderType;
ooline.OrderNbr = graph.Document.Current.OrderNbr;

ooline = PXCache<POLine>.CreateCopy(graph.Transactions.Insert(ooline));

ooline.LineType = lineType;
ooline.InventoryID = line.InventoryID;

if (ooline.InventoryID != null)
ooline.SubItemID = line.SubItemID;

ooline.TranDesc = line.Description;
ooline.UOM = line.UOM;
ooline.AlternateID = line.AlternateID;

if (unitCost != null)
ooline.ManualPrice = true;

ooline = graph.Transactions.Update(ooline);

if (line.SiteID != null)
graph.Transactions.Cache.RaiseExceptionHandling<POLine.siteID>(ooline, null, null);

ooline = PXCache<POLine>.CreateCopy(ooline);

FillPOLineFromRequisitionLine(ooline, graph, line, qty, unitCost, costOriginDac, lineType);

//Custom Code - Add values for custom fields
RQRequisitionLineExt rqLineExt = line.GetExtension<RQRequisitionLineExt>();
POLineExt pOLineExt = ooline.GetExtension<POLineExt>();
pOLineExt.UsrTaxPurpose = rqLineExt.UsrTaxPurpose;
pOLineExt.UsrProjectNo = rqLineExt.UsrProjectNo;
pOLineExt.UsrCategory = rqLineExt.UsrCategory;

if (bidPromisedDate != null)
ooline.PromisedDate = bidPromisedDate;

ooline = graph.Transactions.Update(ooline);
//Force Non-Project code since RQ has no support for Project yet.
ooline.ProjectID = PM.ProjectDefaultAttribute.NonProject();
PXUIFieldAttribute.SetError<POLine.subItemID>(graph.Transactions.Cache, ooline, null);
PXUIFieldAttribute.SetError<POLine.expenseSubID>(graph.Transactions.Cache, ooline, null);
return ooline;
}

 FillPOLineFromRequisitionLine:

        protected virtual void FillPOLineFromRequisitionLine(POLine poline, POOrderEntry graph, RQRequisitionLine rqLine, decimal? qty, decimal? unitCost, IBqlTable costOriginDac, string lineType)
{

if (rqLine.SiteID != null)
{
graph.Transactions.Cache.RaiseExceptionHandling<POLine.siteID>(poline, null, null);
poline.SiteID = rqLine.SiteID;
}

poline.OrderQty = qty;

if (unitCost != null)
poline.CuryUnitCost = unitCost;

//Custom Code - Add values for custom fields
RQRequisitionLineExt rqLineExt = rqLine.GetExtension<RQRequisitionLineExt>();
POLineExt pOLineExt = poline.GetExtension<POLineExt>();
pOLineExt.UsrTaxPurpose = rqLineExt.UsrTaxPurpose;
pOLineExt.UsrProjectNo = rqLineExt.UsrProjectNo;
pOLineExt.UsrCategory = rqLineExt.UsrCategory;

poline.RcptQtyAction = rqLine.RcptQtyAction;
poline.RcptQtyMin = rqLine.RcptQtyMin;
poline.RcptQtyMax = rqLine.RcptQtyMax;
poline.RcptQtyThreshold = rqLine.RcptQtyThreshold;
poline.RQReqNbr = rqLine.ReqNbr;
poline.RQReqLineNbr = rqLine.LineNbr.GetValueOrDefault();
poline.ManualPrice = true;

if (lineType != POLineType.GoodsForInventory)
{
if (rqLine.ExpenseAcctID != null)
poline.ExpenseAcctID = rqLine.ExpenseAcctID;

if (rqLine.ExpenseAcctID != null && rqLine.ExpenseSubID != null)
poline.ExpenseSubID = rqLine.ExpenseSubID;

poline.ProjectID = PM.ProjectDefaultAttribute.NonProject();
}

if (rqLine.PromisedDate != null)
poline.PromisedDate = rqLine.PromisedDate;

if (rqLine.RequestedDate != null)
poline.RequestedDate = rqLine.RequestedDate;

PXNoteAttribute.CopyNoteAndFiles(Lines.Cache, rqLine, graph.Transactions.Cache, poline);
}

Both failed to populate the values onto the custom fields. Can anyone advise on this matters?

Userlevel 7
Badge +9

I don’t think by relying solely on DAC properties you can make it work. I might be wrong as I was working on something but if I recall correctly, the row is inserted and then the RQ related fields are updated. As a result at the time of insertion the RQ related fields don’t have value yet and your PXFormula results logically should return null.

try overtired the method that creates the Po

You are right, I commented the DAC properties and implemented the following code instead:


public class POOrderEntry_Extension : PXGraphExtension<POOrderEntry>
{
public delegate void PersistDelegate();
[PXOverride]

public void Persist(PersistDelegate persistDelegate)
{
POOrder pOOrder = Base.Document.Current;
if (pOOrder != null)
{
foreach (POLine pOLine in this.Base.Transactions.Select())
{
POLineExt pOLineExt = pOLine.GetExtension<POLineExt>();
if (pOLine != null)
{
RQRequisitionLine rQRequisitionLine = SelectFrom<RQRequisitionLine>.Where<RQRequisitionLine.reqNbr.IsEqual<@P.AsString>.And<RQRequisitionLine.lineNbr.IsEqual<@P.AsInt>>>.View.Select(this.Base, pOLine.RQReqNbr, pOLine.RQReqLineNbr);
RQRequisitionLineExt rQRequisitionLineExt = rQRequisitionLine.GetExtension<RQRequisitionLineExt>();

if (rQRequisitionLine != null)
{
pOLineExt.UsrTaxPurpose = rQRequisitionLineExt.UsrTaxPurpose;
pOLineExt.UsrProjectNo = rQRequisitionLineExt.UsrProjectNo;
pOLineExt.UsrCategory = rQRequisitionLineExt.UsrCategory;

}
}
}
}
persistDelegate();
}
}

The code works as intended, but any changes done to the custom fields in PO will not be persisted and instead, it will always be reverted back to the values from Requisitions screen.

 

Is there any way for the changes done in PO screen to persist instead?

Please make two changes to the Persist. 1) check PXEntryStatus of the POLine to see if it is Inserted and 2) if the custom fields in Target DAC Ext (PO) are null then execute your code

This will help to avoid executing custom code on subsequent changes.

Hello @ericklasimin61 ,

 

Instead of using persist delegate, Override any of the below methods and assign your custom values.
 

		protected virtual POLine InsertPOLine(POOrderEntry graph, RQRequisitionLine line, decimal? qty, decimal? unitCost, IBqlTable costOriginDac, string lineType, DateTime? bidPromisedDate)

OR,
 

        protected virtual void FillPOLineFromRequisitionLine(POLine poline, POOrderEntry graph, RQRequisitionLine rqLine, decimal? qty, decimal? unitCost, IBqlTable costOriginDac, string lineType)


 

Hi @venkatreddy43 , following your suggestion to override either of the methods:

InsertPOLine:

        protected virtual POLine InsertPOLine(POOrderEntry graph, RQRequisitionLine line, decimal? qty, decimal? unitCost, IBqlTable costOriginDac, string lineType, DateTime? bidPromisedDate)
{
if (qty <= 0)
return null;

POLine ooline = (POLine)graph.Transactions.Cache.CreateInstance();

ooline.OrderType = graph.Document.Current.OrderType;
ooline.OrderNbr = graph.Document.Current.OrderNbr;

ooline = PXCache<POLine>.CreateCopy(graph.Transactions.Insert(ooline));

ooline.LineType = lineType;
ooline.InventoryID = line.InventoryID;

if (ooline.InventoryID != null)
ooline.SubItemID = line.SubItemID;

ooline.TranDesc = line.Description;
ooline.UOM = line.UOM;
ooline.AlternateID = line.AlternateID;

if (unitCost != null)
ooline.ManualPrice = true;

ooline = graph.Transactions.Update(ooline);

if (line.SiteID != null)
graph.Transactions.Cache.RaiseExceptionHandling<POLine.siteID>(ooline, null, null);

ooline = PXCache<POLine>.CreateCopy(ooline);

FillPOLineFromRequisitionLine(ooline, graph, line, qty, unitCost, costOriginDac, lineType);

//Custom Code - Add values for custom fields
RQRequisitionLineExt rqLineExt = line.GetExtension<RQRequisitionLineExt>();
POLineExt pOLineExt = ooline.GetExtension<POLineExt>();
pOLineExt.UsrTaxPurpose = rqLineExt.UsrTaxPurpose;
pOLineExt.UsrProjectNo = rqLineExt.UsrProjectNo;
pOLineExt.UsrCategory = rqLineExt.UsrCategory;

if (bidPromisedDate != null)
ooline.PromisedDate = bidPromisedDate;

ooline = graph.Transactions.Update(ooline);
//Force Non-Project code since RQ has no support for Project yet.
ooline.ProjectID = PM.ProjectDefaultAttribute.NonProject();
PXUIFieldAttribute.SetError<POLine.subItemID>(graph.Transactions.Cache, ooline, null);
PXUIFieldAttribute.SetError<POLine.expenseSubID>(graph.Transactions.Cache, ooline, null);
return ooline;
}

 FillPOLineFromRequisitionLine:

        protected virtual void FillPOLineFromRequisitionLine(POLine poline, POOrderEntry graph, RQRequisitionLine rqLine, decimal? qty, decimal? unitCost, IBqlTable costOriginDac, string lineType)
{

if (rqLine.SiteID != null)
{
graph.Transactions.Cache.RaiseExceptionHandling<POLine.siteID>(poline, null, null);
poline.SiteID = rqLine.SiteID;
}

poline.OrderQty = qty;

if (unitCost != null)
poline.CuryUnitCost = unitCost;

//Custom Code - Add values for custom fields
RQRequisitionLineExt rqLineExt = rqLine.GetExtension<RQRequisitionLineExt>();
POLineExt pOLineExt = poline.GetExtension<POLineExt>();
pOLineExt.UsrTaxPurpose = rqLineExt.UsrTaxPurpose;
pOLineExt.UsrProjectNo = rqLineExt.UsrProjectNo;
pOLineExt.UsrCategory = rqLineExt.UsrCategory;

poline.RcptQtyAction = rqLine.RcptQtyAction;
poline.RcptQtyMin = rqLine.RcptQtyMin;
poline.RcptQtyMax = rqLine.RcptQtyMax;
poline.RcptQtyThreshold = rqLine.RcptQtyThreshold;
poline.RQReqNbr = rqLine.ReqNbr;
poline.RQReqLineNbr = rqLine.LineNbr.GetValueOrDefault();
poline.ManualPrice = true;

if (lineType != POLineType.GoodsForInventory)
{
if (rqLine.ExpenseAcctID != null)
poline.ExpenseAcctID = rqLine.ExpenseAcctID;

if (rqLine.ExpenseAcctID != null && rqLine.ExpenseSubID != null)
poline.ExpenseSubID = rqLine.ExpenseSubID;

poline.ProjectID = PM.ProjectDefaultAttribute.NonProject();
}

if (rqLine.PromisedDate != null)
poline.PromisedDate = rqLine.PromisedDate;

if (rqLine.RequestedDate != null)
poline.RequestedDate = rqLine.RequestedDate;

PXNoteAttribute.CopyNoteAndFiles(Lines.Cache, rqLine, graph.Transactions.Cache, poline);
}

Both failed to populate the values onto the custom fields. Can anyone advise on this matters?

Try with below DAC extension syntax and check once.

RQRequisitionLineExt rqLineExt = PXCache<RQRequisitionLine>.GetExtension<RQRequisitionLineExt>(rqLine);

 

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved