Skip to main content
Solved

Has anyone come across this issue that some events are not triggered but some are?


aaghaei
Captain II
Forum|alt.badge.img+10

Hello all,

I am experiencing weird behavior with “DailyFieldReportEntry” graph events. When we have a CacheAttached Event in a graph typically it is the first one triggered by the platform to override DAC properties. As you can see in the below code on the same DAC I have two events. Acumatica triggers the RowSelected Event and everything works in my code as expected but oddly the CacheAttached Event is not triggered at all. But logically it should have been triggered before any other event. In fact, when I put a break on it to trace, it never is been hit at any point. Any idea why this is happening?

namespace Test
{
    public class TestDailyFieldReportEntryExt : PXGraphExtension<DailyFieldReportEntry_ApprovalWorkflow, DailyFieldReportEntry_Workflow, DailyFieldReportEntry>
    {
        public static bool IsActive() => true;

        protected virtual void _(Events.RowSelected<EPActivityApprove> e, PXRowSelected baseHandler)
        {
            //My Stuff
        }

        //My Properties 
        protected void _(Events.CacheAttached<EPActivityApprove.labourItemID> e) { }
    }
}

 

Best answer by Yuriy Zaletskyy

@aaghaei  It seems like there is a bug in Acumatica Framework regarding that specific field. Please check code below, and let me know if that helped:

    public class DailyFieldReportEntryExt : PXGraphExtension<DailyFieldReportEntry>
    {
        [PXMergeAttributes(Method = MergeMethod.Replace)]
        [POLineInventoryItem(Filterable = true)]
        protected virtual void EPActivityApprove_labourItemID_CacheAttached(PXCache sender)
        //protected void _(Events.CacheAttached<EPActivityApprove.labourItemID> e)
        {

        }

Take note, that I’ve commented out templated approach ( i.e. _(Events.CacheAttached )

and instead used full text syntax, which is not my favorite, but works better, then templated approach. 

P.S. I tried on 23 R1, but I have hope, that it will work in 22 R2 as well. I’m going to record video on youtube, which will shed more light on the issue.

View original
Did this topic help you find an answer to your question?

21 replies

darylbowman
Captain II
Forum|alt.badge.img+13

I have experienced this on a different screen. I never figured out why. Had to use a different event instead (RowUpdating instead of RowUpdated).

 

@Yuriy Zaletskyy


Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

As of CacheAttached in graph extension, it should not be executed. CacheAttached is purposed for replacing/extending attributes of DAC. I would be surprised, if CacheAttached would be executed. Outside graphExtension and Graphs, yeah, may be cases when CacheAttached will be executed. As of RowUpdated, RowUpdating not being executed, I seen cases when usage of three input parameters ( cache c, rowupdatedEventArgs e, RowUpdated baseDelegatePointer)prevented execution of some events. That happened, when baseDelegateEventPointer was never executed. Another case I seen, when AddHandler/RemoveHandler was executed. Below goes a link for samples of AddHandler: http://blog.zaletskyy.com/post/2023/06/15/how-to-add-handler-to-graph-dynamically


darylbowman
Captain II
Forum|alt.badge.img+13

@Yuriy Zaletskyy - Are you saying the CacheAttached event should be working even though it doesn't break there?


Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

@darylbowman correct. CacheAttached works for attributes, and not for execution of the body. It’s Aspect Oriented Programming feature of C# ( AOP ).

If you want to target CacheAttached, you may need to look into attributes, and 

PXEventSubscriberAttribute class.

Below goes code sample of how actual implementation for CacheAttached, which will be triggered by debugger:

public class BCCustomNumberingAttribute : PXEventSubscriberAttribute
	{
		protected String Dimension;
		protected Type Mask;
		protected Type Numbering;
		protected Type NumberingSelect;

		public BCCustomNumberingAttribute(String dimension, Type mask, Type numbering, Type select)
		{
			Dimension = dimension ?? throw new ArgumentException("dimension");
			Mask = mask ?? throw new ArgumentException("mask");
			Numbering = numbering ?? throw new ArgumentException("numbering");
			NumberingSelect = select ?? throw new ArgumentException("select");
		}

		public override void CacheAttached(PXCache sender)
		{
			base.CacheAttached(sender);

			PXCache bindingCache = sender.Graph.Caches[BqlCommand.GetItemType(Mask)]; // Initialize cache in advance to allow DimensionSelector from GuesCustomer fire events on persisting
			sender.Graph.RowPersisting.AddHandler(_BqlTable, PrioritizedRowPersisting);
		}

That is sample from Acumatica source code itself. 

But if you’ll apply that in graph, or graph extension, it will not be executed.

 

 


aaghaei
Captain II
Forum|alt.badge.img+10
  • Author
  • Captain II
  • 1203 replies
  • June 26, 2023

@Yuriy Zaletskyy thanks for the comments and @darylbowman thanks for chiming in. 

@Yuriy Zaletskyy I am using the CacheAttached Event within the Graph Extension to add a PXRestrictor to the DAC Properties. So I believe it should be triggered by the platform. Do I have a wrong understanding? Also as you can see from my original comment, I have no code inside the CacheAttached Event that I expect to be executed. All I am doing is Merging an attribute into the base attributes.


Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

As far as I know, PXRestrictor will be applied without execution of CacheAttached method. Acumatica uses CacheAttached only for reading of the attributes, not for execution of the body of CacheAttached itself.


aaghaei
Captain II
Forum|alt.badge.img+10
  • Author
  • Captain II
  • 1203 replies
  • June 26, 2023

@Yuriy Zaletskyy  My problem is that it is not applying the PXRestrictor. In fact the CacheAttached is not been hit at all to Realize there are properties to Merge with the base properties. This is the the Code:

 

namespace Test
{
    public class TestDailyFieldReportEntryExt : PXGraphExtension<DailyFieldReportEntry_ApprovalWorkflow, DailyFieldReportEntry_Workflow, DailyFieldReportEntry>
    {
        public static bool IsActive() => true;

        protected virtual void _(Events.RowSelected<EPActivityApprove> e, PXRowSelected baseHandler)
        {
            //My Stuff
        }

        #region CacheAttached InventoryID
        [PXMergeAttributes(Method = MergeMethod.Merge)]
        [PXRestrictor(
            typeof(Where<InventoryItem.itemStatus.IsNotIn<InventoryItemStatus.unknown, InventoryItemStatus.inactive, InventoryItemStatus.markedForDeletion>
                    .And<InventoryItem.itemType.IsEqual<INItemTypes.expenseItem>>>),
            HCLCSMessages.InvaidInventoryItem)]
        protected void _(Events.CacheAttached<EPExpenseClaimDetails.inventoryID> e) { }
        #endregion
    }
}

 


Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

Which screen you try to customize? Which Acumatica version you use?


Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

Hm.

I must admit, I was wrong about non execution of CacheAttached. In debugging session, CacheAttached was executed. But I had to extend another class. Instead of 

public class TestDailyFieldReportEntryExt : PXGraphExtension<DailyFieldReportEntry_ApprovalWorkflow, DailyFieldReportEntry_Workflow, DailyFieldReportEntry>

I used 

public class extforclass : PXGraphExtension<ExpenseClaimDetailEntry>

But I believe, your purpose is to modify Stock items for screen EP301020. I was able to achieve that in a following way:

 //public class TestDailyFieldReportEntryExt : PXGraphExtension<DailyFieldReportEntry_ApprovalWorkflow, DailyFieldReportEntry_Workflow, DailyFieldReportEntry>
    public class extforclass : PXGraphExtension<ExpenseClaimDetailEntry>
    {
        public static bool IsActive() => true;

        protected virtual void _(Events.RowSelected<EPActivityApprove> e, PXRowSelected baseHandler)
        {
            //My Stuff
        }

        #region CacheAttached InventoryID

        [PXMergeAttributes(Method = MergeMethod.Replace)]
        /*[PXRestrictor(
            typeof(Where<itemStatus.IsNotIn<InventoryItemStatus.unknown,
                    InventoryItemStatus.inactive, InventoryItemStatus.markedForDeletion>
                .And<InventoryItem.itemType.IsEqual<INItemTypes.expenseItem>>>),
            "HCLCSMessages.InvaidInventoryItem")]*/
        [POLineInventoryItem(Filterable = true)]
        protected void _(Events.CacheAttached<EPExpenseClaimDetails.inventoryID> e)
        {

        }
        #endregion
    }

I was able to get modified items at Inventory item section.

 


aaghaei
Captain II
Forum|alt.badge.img+10
  • Author
  • Captain II
  • 1203 replies
  • June 27, 2023

@Yuriy Zaletskyy Thanks for looking further into this odd thing.

  • I am testing on 22.212.0046.
  • The graph you are extending is the Expense Receipt graph. It works fine in the extension as you pointed out.
  • The Screen I try to customize is Daily Field Report (PJ304000)
  • The Primary Graph is DailyFieldReportEntry
  • The Primary DAC is DailyFieldReport
  • The tab I have this problem with is “Labor Time and Activities”
  • Its DAC is EPActivityApprove which lives in “PX.Objects.EP.EmployeeActivitiesApprove” and is a projection DAC from PMTimeActivty
  • Its Associated View in the graph context is EmployeeActivities that lives in DailyFieldReportEntryEmployeeActivityExtension Extension
  • The field its CachAttached is not triggered is LabourItemID

Below is the exact code I am trying to make it work but cannot.

namespace Test
{
    public class TestExt : PXGraphExtension<DailyFieldReportEntryEmployeeActivityExtension, DailyFieldReportEntry>
    {
        public static bool IsActive() => true;

        #region EPActivityApprove CacheAttached LabourItemID
        [PXMergeAttributes(Method = MergeMethod.Merge)]
        [PXRestrictor(
            typeof(Where<InventoryItem.itemStatus.IsNotIn<InventoryItemStatus.unknown, InventoryItemStatus.inactive, InventoryItemStatus.markedForDeletion>
                    .And<InventoryItem.itemType.IsEqual<INItemTypes.laborItem>>
                    .And<InventoryItem.inventoryCD.IsNotLike<HCLINInventoryCategory.inventoryCategoryPRIM>>>),
            "Invaid Inventory Item")]
        protected void _(Events.CacheAttached<EPActivityApprove.labourItemID> e) { }
        #endregion
    }
}

 


aaghaei
Captain II
Forum|alt.badge.img+10
  • Author
  • Captain II
  • 1203 replies
  • June 29, 2023

Hi @Yuriy Zaletskyy Did you possibly get a chance to look into the issue considering my last comments?


Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

Hi @aaghaei, I was able to reproduce the problem locally, but was overly busy for virtual dev con. Will try to find solution during tomorrow or Saturday.


aaghaei
Captain II
Forum|alt.badge.img+10
  • Author
  • Captain II
  • 1203 replies
  • June 29, 2023

@Yuriy Zaletskyy it is greatly appreciated. It has driven me crazy. Honestly I spent over 10 hours on the issue and playing with the 18 (!!!!!) out-of-box extensions on DFR but no luck. 


Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

@aaghaei  It seems like there is a bug in Acumatica Framework regarding that specific field. Please check code below, and let me know if that helped:

    public class DailyFieldReportEntryExt : PXGraphExtension<DailyFieldReportEntry>
    {
        [PXMergeAttributes(Method = MergeMethod.Replace)]
        [POLineInventoryItem(Filterable = true)]
        protected virtual void EPActivityApprove_labourItemID_CacheAttached(PXCache sender)
        //protected void _(Events.CacheAttached<EPActivityApprove.labourItemID> e)
        {

        }

Take note, that I’ve commented out templated approach ( i.e. _(Events.CacheAttached )

and instead used full text syntax, which is not my favorite, but works better, then templated approach. 

P.S. I tried on 23 R1, but I have hope, that it will work in 22 R2 as well. I’m going to record video on youtube, which will shed more light on the issue.


aaghaei
Captain II
Forum|alt.badge.img+10
  • Author
  • Captain II
  • 1203 replies
  • June 30, 2023

I cannot thank you enough @Yuriy Zaletskyy I was getting to the point of needing to be admitted to a psychiatric ward because of this Acumatica BUG. It has been a while since I am not using the old Event Model Syntaxes. I would have never thought of such a BUG as we rely on Acumatica Event Models for customizations heavily. 


Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

You by all means welcome. I also lost couple of hours on that issue in the past as well. I’m going to record a YouTube video, which will explain it in more details, and will ask you to like it and share on your social media. 


aaghaei
Captain II
Forum|alt.badge.img+10
  • Author
  • Captain II
  • 1203 replies
  • June 30, 2023

@Yuriy Zaletskyy you bet on it. Not sure if you also will be willing to inform Acumatica of reviewing the issue and hopefully fixing it to prevent driving other people crazy in similar situations. I could have done it myself but I am not a partner so unfortunately I can not do it. 


Yuriy Zaletskyy
Jr Varsity I
Forum|alt.badge.img+3

@aaghaei tag Acumatica employees for suchlike requests. I will report on this one, but if for whatever reason I will skip, just tag potentially Chris Hacket or other people.


sangland
Varsity I
Forum|alt.badge.img
  • Varsity I
  • 35 replies
  • July 18, 2023

Don’t know if it is relevant but for many Field Service screens you have to be an employee. When Business Events trigger import scenarios the event is run by a system admin user that needs to be liked to an employee. 


aaghaei
Captain II
Forum|alt.badge.img+10
  • Author
  • Captain II
  • 1203 replies
  • July 18, 2023

@sangland Thank you for chiming in. I am both an admin and an employee. If I am not an employee I won’t be able to even open the screen.


Forum|alt.badge.img+6
  • Captain II
  • 556 replies
  • September 9, 2024

As an aside, I encountered the same issue with the short form of CacheAttached not working where the long form declaration did:

This didn’t work:

    protected virtual void _(Events.CacheAttached<SOOrder.marginPct> e) { }

This worked:
    protected virtual void SOOrder_marginPct_CacheAttached(PXCache sender) { }
 

Now, this was done within a graph extension of Margin which is an extension of SOOrderEntry.

But, all of my SOLine short form CacheAttached declarations in the same extension did work.


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings