0

SUMMARY

I have created a graph extension for the APInvoiceEntry graph (AP301000 screen), called APInvoiceEntry_Extension.

I created a new DB Table called APRegisterException, which stores exception information for SalesTax, Freight, Price, and Qty errors.There is a 1 to many relationship between APRegister and APRegisterException, indicating that a bill can have many different types of exceptions. For each of these exceptions, I created a button and an action to add Exceptions to the DAC within my extension graph.

THE PROBLEM

I am only able to add 1 new APRegisterExcetion record to the DAC. The DAC is not updating for multiple button clicks. Each of the following actions should create a new APRegisterException record, and add them to the Exceptions DAC within my graph.

public PXAction<APInvoice> ApplyPriceException;
public PXAction<APInvoice> ApplyQtyException;
public PXAction<PX.Objects.AP.APInvoice> ApplyFreightException;
public PXAction<PX.Objects.AP.APInvoice> ApplySalesTaxException;

note: the actions are executing, it's just the DAC that is not updating.

CODE

APREgisterException DAC

namespace BillsAndAdjustmentsExt
{
  [Serializable]
  public class APRegisterException : IBqlTable
  {
    #region APRegisterRefNbr
    [PXDBString(15, IsKey = true, IsUnicode = true, InputMask = "")]
    [PXUIField(DisplayName = "Ref Nbr")]
    public virtual string APRegisterRefNbr { get; set; }
    public abstract class aPRegisterRefNbr : IBqlField { }
    #endregion

    #region APTranLineNbr
    [PXDBInt()]
    [PXUIField(DisplayName = "Line Nbr")]
    public virtual int? APTranLineNbr { get; set; }
    public abstract class aPTranLineNbr : IBqlField { }
    #endregion

    #region ExceptionDesc
    [PXDBString(150, IsUnicode = true, InputMask = "")]
    [PXUIField(DisplayName = "Description")]
    public virtual string ExceptionDesc { get; set; }
    public abstract class exceptionDesc : IBqlField { }
    #endregion

    #region ExceptionType
    [PXDBString(3, IsUnicode = true, InputMask = "")]
    [PXUIField(DisplayName = "Exc. Type")]
    public virtual string ExceptionType { get; set; }
    public abstract class exceptionType : IBqlField { }
    #endregion

    #region ApprovedByID
    [PXDBString(15, IsUnicode = true, InputMask = "")]
    [PXUIField(DisplayName = "Approved By")]
    public virtual string ApprovedByID { get; set; }
    public abstract class approvedByID : IBqlField { }
    #endregion

    #region ApprovedDate
    [PXDBDate()]
    [PXUIField(DisplayName = "Approval Date")]
    public virtual DateTime? ApprovedDate { get; set; }
    public abstract class approvedDate : IBqlField { }
    #endregion
  }
}

EXTENSION GRAPH:

namespace PX.Objects.AP
{
  public class APInvoiceEntry_Extension : PXGraphExtension<APInvoiceEntry>
  {
    #region properties
    public APRegister _currentDoc
    {
      get
      {
        return Base.Document.Current;
      }
    }

    #endregion
   // note

    #region selects

    public PXSelectJoin<
              APRegisterException,
                  LeftJoin<APInvoice,
                      On<APRegisterException.aPRegisterRefNbr, Equal<APInvoice.refNbr>>>,
              Where<APRegisterException.aPRegisterRefNbr, Equal<Current<APInvoice.refNbr>>>> Exceptions;

    #endregion


    #region Event Handlers
    #endregion

    #region Actions

    public PXAction<APRegisterException> AdjustSalesTax; 
    [PXButton(CommitChanges = true)]
    [PXUIField(DisplayName = "Adj. Sales Tax")]
    protected void adjustSalesTax()
    {
       // put code here to adjust sales tax

    }

    public PXAction<APInvoice> ApplyPriceException;
    [PXButton(CommitChanges = true)]
    [PXUIField(DisplayName = "Apply Price Exc.")]
    protected void applyPriceException()
    {
        APTran row = Base.Transactions.Current;
        if(row == null)
        {
          throw new PXException("No rows selected");
        }      

        APRegisterException rException = new APRegisterException();
        rException.APRegisterRefNbr = row.RefNbr;   
        rException.APTranLineNbr = row.LineNbr;
        rException.ExceptionDesc = row.TranDesc;
        rException.ExceptionType = "PRC";
        Exceptions.Insert(rException);          
    }

    public PXAction<APInvoice> ApplyQtyException;
    [PXButton(CommitChanges = true)]
    [PXUIField(DisplayName = "Apply Qty Exc.")]
    protected void applyQtyException()
    {
        APTran row = Base.Transactions.Current;
        if(row == null)
        {
          throw new PXException("No rows selected");
        }

        APRegisterException rException = new APRegisterException();
        rException.APRegisterRefNbr = row.RefNbr;   
        rException.APTranLineNbr = row.LineNbr;
        rException.ExceptionDesc = row.TranDesc;
        rException.ExceptionType = "QTY";      
        Exceptions.Insert(rException); 

    }  


    public PXAction<PX.Objects.AP.APInvoice> ApplyFreightException;
    [PXButton(CommitChanges = true)]
    [PXUIField(DisplayName = "Apply Freight Exc.")]
    protected void applyFreightException()
    {
        string exceptionMessage = string.Empty;

        // insert freight exception code here
        if(_currentDoc.DocType != "INV" ) { exceptionMessage += "Document type must be 'Bill' to apply a freight exception. \n"; }   
        if(!string.IsNullOrEmpty(exceptionMessage))
        {
          throw new PXException("One or more errors occured trying to save this record. \n" + exceptionMessage);  
        }
        // set the current document to hold
        _currentDoc.Hold = true;

        // create the exception record and store it in cache
        APRegisterException rException = new APRegisterException();
        rException.APRegisterRefNbr = _currentDoc.RefNbr;
        rException.ExceptionDesc = "FREIGHT";
        rException.ExceptionType = "FRT";        

        Exceptions.Insert(rException); 
       // Base.Actions.PressSave();
    } 

    public PXAction<PX.Objects.AP.APInvoice> ApplySalesTaxException;
    [PXButton(CommitChanges = true)]
    [PXUIField(DisplayName = "Apply Sales Tax Exc.")]
    protected void applySalesTaxException()
    {  
        string exceptionMessage = string.Empty;

        if(_currentDoc.RefNbr == "<NEW>") { exceptionMessage += "Please save the invoice before applying a sales tax exception. \n"; }
        if(_currentDoc.DocType != "INV" ) { exceptionMessage += "Document type must be 'Bill' to apply a sales tax exception. \n"; }      
        //if(((APInvoice)_currentDoc).CuryTaxTotal == 0) { exceptionMessage += "Tax total must be greate than $0.00 to apply a sales tax exception. \n"; }

        if(!string.IsNullOrEmpty(exceptionMessage))
        {
          throw new PXException("One or more errors occured trying to save this record. \n" + exceptionMessage);  
        }
        // set the current document to hold
        _currentDoc.Hold = true;

        // create the exception record and store it in cache
        APRegisterException rException = new APRegisterException();
        rException.APRegisterRefNbr = _currentDoc.RefNbr;
        rException.ExceptionDesc = "SALES TAX";
        rException.ExceptionType = "TAX";        

        Exceptions.Insert(rException);      
       // Base.Actions.PressSave();
    }

    #endregion

  }
}
MAhipal Singh
  • 4,745
  • 1
  • 42
  • 57

2 Answers2

0

From reviewing your DAC, it seems that you have only one key field which is the APRegisterRefNbr. The key already exists in the cache, so it cannot insert. If you are looking for a one-to-many, I would look at doing a auto-numbered key, and then a reference back to the line that it is affecting. For example, you could set your database key to be a bigint (if this table is going to get huge) and identity for autonumber in SQL, and then add this to your DAC:

[PXDBLongIdentity(IsKey = true)]
[PXUIField(DisplayName = "APRegisterExceptionID", Enabled = false)]
public virtual Int64? APRegisterExceptionID{ get; set; }
public abstract class aPRegisterExceptionID: IBqlField { }

Then you have your unique ID, and can link back to the parent table using a PXSelector and PXParent.

#region APRegisterRefNbr  
[PXDBString(15)]
[PXSelector(typeof(APRegister.refNbr))]
[PXForeignReference(typeof(Field<APRegisterException.aPRegisterRefNbr>.IsRelatedTo<APRegister.refNbr>))]
[PXUIField(DisplayName = "APRegisterRefNbr")]
public virtual String APRegisterRefNbr  { get; set; }
public abstract class aPRegisterRefNbr  : IBqlField { }
#endregion

I have used a similar approach for many one-to-many relationship tables for components, and think it could work for you in this case.

KRichardson
  • 990
  • 7
  • 12
0
  1. You do not appear to have defined a parent child relationship for your DAC utilizing the PXParent and PXDBDefault attribute on the APRegisterException class, as well as needing adjust your keys to accomplish the described business use case.
  2. Include restriction to DocType in the declared 'Exceptions' view else different document types could pull exceptions associated to other documents.
  3. Include audit fields as well as tstamp and noteID on APRegisterException.

            [Serializable]
            public class APRegisterException : IBqlTable
            {
                        #region APRegisterRefNbr
                        [PXDBString(15, IsKey = true, IsUnicode = true, InputMask = "")]
                        [PXUIField(DisplayName = "Ref Nbr")]
                        [PXParent(typeof(Select<APInvoice, Where<APInvoice.refNbr, Equal<Current<APRegisterException.refNbr>>, And<APInvoice.docType, Equal<Current<APRegisterException.docType>>>>>))]
                        [PXDBDefault(typeof(APInvoice.refNbr))]
                        public virtual string APRegisterRefNbr { get; set; }
                        public abstract class aPRegisterRefNbr : IBqlField { }
                        #endregion
    
                        #region APDocType
                        [PXDBString(3, IsKey = true, IsUnicode = true, InputMask = "")]
                        [PXUIField(DisplayName = "Doc Type")]
        [PXDBDefault(typeof(APInvoice.docType))]
        public virtual string APDocType { get; set; }
        public abstract class aPDocType: IBqlField { }
        #endregion
    
        #region ExceptionDesc
        [PXDBString(150, IsUnicode = true, InputMask = "")]
        [PXUIField(DisplayName = "Description")]
        public virtual string ExceptionDesc { get; set; }
        public abstract class exceptionDesc : IBqlField { }
        #endregion
    
        #region ExceptionType
        [PXDBString(3, IsUnicode = true, InputMask = "", IsKey = true)]
        [PXUIField(DisplayName = "Exc. Type")]
        public virtual string ExceptionType { get; set; }
        public abstract class exceptionType : IBqlField { }
        #endregion
    
        #region ApprovedByID
        [PXDBString(15, IsUnicode = true, InputMask = "")]
        [PXUIField(DisplayName = "Approved By")]
        public virtual string ApprovedByID { get; set; }
        public abstract class approvedByID : IBqlField { }
                        #endregion
    
                        #region ApprovedDate
                        [PXDBDate()]
                        [PXUIField(DisplayName = "Approval Date")]
                        public virtual DateTime? ApprovedDate { get; set; }
                        public abstract class approvedDate : IBqlField { }
                        #endregion
            }
    
Joshua Van Hoesen
  • 1,684
  • 15
  • 30