0
votes

I'm trying to add the Contract DAC and its new extension into my extension of the APInvoiceEntry Graph in order to do some validation and I'm really doing it wrong, but I don't know what exactly I'm screwing up, maybe the initialization of the Contracts DAC as well as the evaluating logic? It is trying to cast some of the Contracts logic as APTran and is sending an "unable to cast" error.

The end goal is to look at the selected project and branch in each line on Bills and Payments and have it evaluate based on the project ID and new BranchID field created in the ContractExt DAC extension.

The trace for the current error that I am getting is:

Unable to cast object of type 'PX.Objects.AP.APTran' to type 'PX.Objects.CT.Contract'. 

at PX.Objects.AP.APInvoiceEntry_Extension.APTran_RowUpdating(PXCache cache, PXRowUpdatingEventArgs e, PXRowUpdating InvokeBaseHandler) 
at PX.Data.PXCache.OnRowUpdating(Object item, Object newitem, Boolean externalCall) 
at PX.Data.PXCache`1.Update(IDictionary keys, IDictionary values) 
at PX.Data.PXGraph.ExecuteUpdate(String viewName, IDictionary keys, IDictionary values, Object[] parameters) 

This leads me to believe that I might not be bringing the Contract DAC in properly.

Code is as follows:

Graph:

namespace PX.Objects.AP
{
public class APInvoiceEntry_Extension : PXGraphExtension<APInvoiceEntry>
{
    public PXSelect<Contract, Where<Contract.contractID, Equal<Current<APTran.projectID>>>> Contract;
    protected void APTran_RowUpdating(PXCache cache, PXRowUpdatingEventArgs e, PXRowUpdating InvokeBaseHandler)
    {
        Contract conRow = (Contract)e.NewRow as Contract;
        ContractExt conRowE = PXCache<Contract>.GetExtension<ContractExt>(conRow);
        APTran row = e.NewRow as APTran;
        int? projectid = conRow.ContractID;
        int? baseprojectid = row.ProjectID;
        int? basebranchid = row.BranchID;
        int? branchid = conRowE.UsrBranch;
        if (
            //Check to make sure that selected Branch and Project match
            baseprojectid == projectid &&
            basebranchid != branchid
            )
        {
            throw new PXSetPropertyException("Branch and  project must match", PXErrorLevel.RowError);
        }
    }
}
}

DAC:

namespace PX.Objects.CT
{
public class ContractExt : PXCacheExtension<PX.Objects.CT.Contract>
{
    [Branch]
    public virtual int? UsrBranch { get; set; }
    public abstract class usrBranch : IBqlField { }
}}

This all compiles properly. The error pops as you would expect, like this: APTran Unable to Cast Error

1

1 Answers

1
votes

You are trying to cast the APTran row to a Contract when using (Contract)e.NewRow which is why you had the error. Doing a select as shown below should give you what you need.

public class APInvoiceEntry_Extension : PXGraphExtension<APInvoiceEntry>
{
    protected void APTran_RowUpdating(PXCache cache, PXRowUpdatingEventArgs e, PXRowUpdating InvokeBaseHandler)
    {
        Contract conRow = PXSelect<Contract, Where<Contract.contractID, Equal<Current<APTran.projectID>>>>.Select(Base);
        ContractExt conRowE = conRow.GetExtension<ContractExt>();
        APTran row = e.NewRow as APTran;
        int? projectid = conRow.ContractID;
        int? baseprojectid = row.ProjectID;
        int? basebranchid = row.BranchID;
        int? branchid = conRowE.UsrBranch;
        if (
            //Check to make sure that selected Branch and Project match
            baseprojectid == projectid &&
            basebranchid != branchid
            )
        {
            throw new PXSetPropertyException("Branch and  project must match", PXErrorLevel.RowError);
        }
    }
}

You can simply select your base DAC using PXSelect and then get the extension value as shown in the example above (which you already had in a different call - which works fine). If you want to display a DAC extension and the graph doesn't already have a view for the base DAC you would add a view, otherwise I just use PXSelect when needed.