0

I created one new extension field in Contacts screen (location id --- int) and in customer location screen when I click on the "+" button it should redirect to contacts screen and the header session "Customer and Location ID" should default but Location ID is not defaulting.

Here is the img example:

Location Id not defaulting

And this is the code what I wrote:

    public PXDBAction<Location> addContact;
    [PXUIField(DisplayName = Messages.AddContact)]
    [PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntry)]
    public virtual void AddContact()
    {

        var row = Base.Location.Current;
        if (row == null || row.BAccountID == null) return;

        ContactExt extension = PXCache<Contact>.GetExtension<ContactExt>(Base.Contact.Current); //Base.Contact.Current

        ContactMaint graph = PXGraph.CreateInstance<ContactMaint>();
        graph.Clear();

        Location get = Base.Location.Current;
        Contact retbatch = graph.Contact.Insert(new Contact());

        retbatch.BAccountID = get.BAccountID;
        extension.UsrLocationCD = get.LocationID;

        if (!Base.IsContractBasedAPI)
            PXRedirectHelper.TryRedirect(graph, PXRedirectHelper.WindowMode.NewWindow);

        graph.Save.Press();
    }

Newly created extension field logic:

public class ContactExt : PXCacheExtension<PX.Objects.CR.Contact> /*, IBqlTable*/
{

    #region UsrLocationCD
    [PXDBInt()]
    [PXUIField(DisplayName = "Location ID")]

    [PXSelector(
      typeof(Search<Location.locationID, Where<Location.bAccountID,
           Equal<Current<Contact.bAccountID>>>>),
        SubstituteKey = typeof(Location.locationCD), ValidateValue = false)]

    public virtual int? UsrLocationCD { get; set; }
    public abstract class usrLocationCD : PX.Data.BQL.BqlInt.Field<usrLocationCD> { }
    #endregion

}

This is the Breakpoint img:

Debugging Img of contacts related code

And like this similar functionality should happens in Opportunities screen

Img example:

Values are defaulting in Opportunities screen

And this is the similar code (Opportunities screen):

    public PXDBAction<Location> addOpportunity;
    [PXUIField(DisplayName = Messages.AddNewOpportunity)]
    [PXButton(ImageKey = PX.Web.UI.Sprite.Main.AddNew)]
    public virtual void AddOpportunity()
    {
        var row = CurrentBAccount.Current;
        if (row == null || row.BAccountID == null) return;


        OpportunityMaint graph = PXGraph.CreateInstance<OpportunityMaint>();
        graph.Clear();

        Location get = Base.Location.Current;
        CROpportunity retbatch = graph.Opportunity.Insert(new CROpportunity());

        retbatch.BAccountID = get.BAccountID;
        retbatch.LocationID = get.LocationID;

        if (!Base.IsContractBasedAPI)
            PXRedirectHelper.TryRedirect(graph, PXRedirectHelper.WindowMode.NewWindow);

        graph.Save.Press();
    } 

this is the Breakpoint img:

Debugging Img of Opportunities related code

functionality is working in Opportunities screen

Where is the mistake in the "Contacts screen" logic and how to overcome this issue?

I'm new to this acumatica.

James Z
  • 12,209
  • 10
  • 24
  • 44
Ashok
  • 13
  • 6

2 Answers2

0

Similar to What is the proper way to update values of DAC's retrieved via PXResultset?

Generally speaking, you didn't actually update the cache (the underlying data object that is sync'd with the database). Think in terms of layers of information:

  • The database is the actual repository of store data
  • The cache is the working copy of the database data in memory. This is what we work with, most commonly as "views" (public PXSelect<> MyView;) typically defined at the top of a graph.
  • Working objects in memory are where we work out what values need to be.

Acumatica naturally retrieves data from the database into a cache object via PXGraph for standard CRUD operations. You add data (MyView.Insert(myData);) to the cache and update data in the cache (MyView.Update(myData);), but it is not pushed to the database until you Save (Persist). When you retrieve an extension (the extra fields of the database table that are defined in the DAC Extension) then you just have an object in memory(ContactExt contactExt = contact.GetExtenstion();) This is the same concept as when you use Contact contact = Contacts.Current();

Once you retrieve data from the database, it is in the cache. When you add data "to the database", you really are working with objects in memory (the cache) until you persist that data. When you manipulate data (extension.UsrLocationCD = get.LocationID;) then the object in memory is updated, but not the actual cache (which will be persisted to the database when you press save).

To push the updated data in your working objects (extension.UsrLocationCD = get.LocationID;) then you need to push it to the cache. This is done in a number of ways. In this case, I'd just use Update on the view.

graph.Contact.Update(extension);

You also could use:

graph.Caches[typeof(Contact)].Update(extension); 

Ultimately, you need to persist your data, and that is done already at the bottom of your code sample with graph.Save.Press();.

Your code with the view updated:

public PXDBAction<Location> addContact;
[PXUIField(DisplayName = Messages.AddContact)]
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntry)]
public virtual void AddContact()
{

    var row = Base.Location.Current;
    if (row == null || row.BAccountID == null) return;

    ContactExt extension = PXCache<Contact>.GetExtension<ContactExt>(Base.Contact.Current); //Base.Contact.Current

    ContactMaint graph = PXGraph.CreateInstance<ContactMaint>();
    graph.Clear();

    Location get = Base.Location.Current;
    Contact retbatch = graph.Contact.Insert(new Contact());

    retbatch.BAccountID = get.BAccountID;
    extension.UsrLocationCD = get.LocationID;

    // Update the cache
    graph.Contact.Update(extension);

    if (!Base.IsContractBasedAPI)
        PXRedirectHelper.TryRedirect(graph, PXRedirectHelper.WindowMode.NewWindow);

    graph.Save.Press();
}
Brian Stevens
  • 1,826
  • 1
  • 7
  • 16
0

The small modification (calling to extension field) helped me to default the value at the contacts screen.

    public PXDBAction<Location> addContact;
    [PXUIField(DisplayName = Messages.AddContact)]
    [PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntry)]
    public virtual void AddContact()
    {
        var row = Base.Location.Current;
        if (row == null || row.BAccountID == null) return;

        ContactMaint graph = PXGraph.CreateInstance<ContactMaint>();
        graph.Clear();

        Location get = Base.Location.Current;
        Contact retbatch = graph.Contact.Insert(new Contact());

//This is what I changed the extension field call

        ContactExt extension = retbatch.GetExtension<ContactExt>();

        retbatch.BAccountID = get.BAccountID;
        extension.UsrLocationCD = get.LocationID;

//And I updated to the graph Cache

        graph.Contact.Cache.Update(retbatch);

        if (!Base.IsContractBasedAPI)
            PXRedirectHelper.TryRedirect(graph, 
          PXRedirectHelper.WindowMode.NewWindow);
     }

Working after modify the code

Ashok
  • 13
  • 6