Skip to main content
Solved

Cannot find a way to "grey out" a custom menu item on a grid in Bills and Adjustments screen


Joe Schmucker
Captain II
Forum|alt.badge.img+3

In 2021R1, I added a button to the Details grid in Bills and Adjustments.  Everything is working great.  I just cannot get the button to be greyed out when the other buttons are greyed out.

I can disable it so it will display a dialog that it is disabled if someone clicks it, but it just looks bad that it appears to be available.  

This code fires and enables/disables the button correctly, but I cannot change the visibility of it.

I suspect this might be something to do with a workflow on this screen?  However, in my installation of 2021R1, the workflow for this screen is not editable.  You can’t even create a new workflow.  I don’t even know if that would solve this for me, but either way, I’d like to grey out that button when it is not applicable.

Thanks!

Joe

 

Best answer by Joe Schmucker

It does not appear that you can add a new workflow to this screen

 

SO...I tried the other suggestion you provided above. I used the UsrAllocationID field as the StateColumn.

                <px:PXToolBarButton Key="cmdAllocateLine" Text="Allocate Line" DependOnGrid="grid" StateColumn="UsrAllocationID">
                  <AutoCallBack Target="ds" Command="AllocateLine" /></px:PXToolBarButton>

 

It worked!!  Since the Allocation ID field in the grid is disabled when the other fields are disabled, the button only lights up when you are able to select an allocation ID.

Seems like the VS code should work.  But I guess you have to do it the way they want you to do it.

Thanks guys for your support!

 

 

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

19 replies

Shawn Burt
Jr Varsity I
Forum|alt.badge.img+1
  • Jr Varsity I
  • 109 replies
  • April 12, 2022

make sure you are using the correct RowSelected event.

You want to use the one related to the data in the grid, ARTran I believe.

You are looking at the Invoice itself not the line detail. If you are needing data related to the Invoice you can still look at the Base.Document.Current to get that, but button in the grid should be modified within the context of the grids data.

That should resolve your issue.


Naveen Boga
Captain II
Forum|alt.badge.img+19
  • Captain II
  • 3381 replies
  • April 12, 2022

Hi @joe21  You can do visibility based on the State Column property.

 

Please refer below link and hope this helps.

 


Joe Schmucker
Captain II
Forum|alt.badge.img+3
  • Author
  • Captain II
  • 443 replies
  • April 12, 2022

@Shawn Burt  Just gave that a try but still not greyed out.  Thanks for the tip though.  It was an easy thing to try out!


Shawn Burt
Jr Varsity I
Forum|alt.badge.img+1
  • Jr Varsity I
  • 109 replies
  • April 12, 2022

if you are willing to share the project I can take a look. Naveen’s technique should work too but its been a while since I played with that. If I remember correctly it requires a unbound dac extension to store the state as it has to be boolean.


Joe Schmucker
Captain II
Forum|alt.badge.img+3
  • Author
  • Captain II
  • 443 replies
  • April 12, 2022

Yea.  I just looked at the link Naveen shared.  It looks like that solution is based on setting the state of the button based on a value in the selected line in the grid.  I just want the button to be greyed out when the document is not editable.  That way the button is visible on when the other buttons on that grid are visible, so I am depending on the document header for the status.  Here’s my code:

using ICSAllocations.DAC;
using ICSAllocations.Helper;
using PX.Data;
using PX.Data.BQL;
using PX.Data.BQL.Fluent;
using System;

namespace PX.Objects.AP
{
	// Acuminator disable once PX1016 ExtensionDoesNotDeclareIsActiveMethod extension should be constantly active
	public class APInvoiceEntry_Extension : PXGraphExtension<APInvoiceEntry>
	{

		public PXAction<APTran> AllocateLine;
		[PXButton(CommitChanges = true)]
		[PXUIField(DisplayName = "Allocate Line", Enabled = false, Visible = false)]
		protected void allocateLine()
		{

			//this.Base.Actions.PressSave();

			APTran currentItem = this.Base.Transactions.Current;

			if (currentItem == null) return;

			APTranExt itemExt = PXCache<APTran>.GetExtension<APTranExt>(currentItem);

			if (itemExt.UsrAllocationID == null) 
			{
				throw new Exception("You need to select an Allocation Template");
			}

			int itemCounter = 0;
			int itemCount = 0;
			decimal? balanceToAllocate = currentItem.CuryLineAmt;

			foreach (var detail in SelectFrom<ICAllocationAccounts>.InnerJoin<ICAllocationCode>.
				On<ICAllocationCode.allocationID.IsEqual<ICAllocationAccounts.allocationID>>.
				Where<ICAllocationCode.allocationID.IsEqual<@P.AsInt>>.
				View.Select(Base, itemExt.UsrAllocationID))
			{
				itemCount++;
			}

			this.Base.Transactions.Delete(currentItem);

			ICAllocationCode code = SelectFrom<ICAllocationCode>.
				Where<ICAllocationCode.allocationID.IsEqual<@P.AsInt>>.
				View.Select(Base, itemExt.UsrAllocationID);


			foreach (ICAllocationAccounts detail in SelectFrom<ICAllocationAccounts>.InnerJoin<ICAllocationCode>.
			On<ICAllocationCode.allocationID.IsEqual<ICAllocationAccounts.allocationID>>.
			Where<ICAllocationCode.allocationID.IsEqual<@P.AsInt>>.
			View.Select(Base, itemExt.UsrAllocationID))
			{

				itemCounter++;

				APTran newRow = this.Base.Transactions.Insert();

				newRow.InventoryID = currentItem.InventoryID;

				this.Base.Transactions.Cache.Update(newRow);

				if (itemCount == itemCounter)
				{
					newRow.CuryLineAmt = balanceToAllocate;
				}
				else
				{
					newRow.CuryLineAmt = Math.Round((decimal)((detail.Percent / 100) * currentItem.CuryLineAmt), 2);
					balanceToAllocate -= (decimal)newRow.CuryLineAmt;
				}

				if (currentItem.Qty != null && currentItem.Qty > 0)
				{
					newRow.Qty = Math.Round((decimal)((decimal)(detail.Percent / 100) * currentItem.Qty), 2);
				}

				if (code.DescriptionSource == DescriptionSourceType.FromDocument)
				{
					newRow.TranDesc = currentItem.TranDesc;
				}
				else
				{
					newRow.TranDesc = code.TranDescr;
				}

				newRow.BranchID = detail.BranchID;

				if(newRow.InventoryID == null)
				{
					newRow.SubID = detail.AccountSubID;
				}
				else
				{
					newRow.TranDesc = currentItem.TranDesc;
				}

				this.Base.Transactions.Cache.Update(newRow);
			}
		}

		#region Event Handlers
		//protected virtual void _(Events.RowSelected<APInvoice> e)
		//{
		//	APInvoice line = e.Row;
		//	if (line == null) return;

		//	if(line.VendorID != null && (line.Status == "H" || line.Status == "B"))
		//	{
		//		AllocateLine.SetEnabled(true);
		//		AllocateLine.SetVisible(true);
		//	}
		//	else
		//	{
		//		AllocateLine.SetEnabled(false);
		//		AllocateLine.SetVisible(false);
		//	}
		//}
		protected virtual void _(Events.RowSelected<APTran> e)
		{
			//APInvoice line = e.Row;
			//if (line == null) return;

			if (Base.Document.Current.VendorID != null && (Base.Document.Current.Status == "H" || Base.Document.Current.Status == "B"))
			{
				AllocateLine.SetEnabled(true);
				AllocateLine.SetVisible(true);
			}
			else
			{
				AllocateLine.SetEnabled(false);
				AllocateLine.SetVisible(false);
			}
		}

		#endregion
	}
}

This is from the ASPX

      <px:PXDSCallbackCommand Name="AllocateLine" Visible="false" CommitChanges="true" />
 

                <px:PXToolBarButton Key="cmdAllocateLine" Text="Allocate Line">
                  <AutoCallBack Target="ds" Command="AllocateLine" /></px:PXToolBarButton>
 

The program works.  Just the dang button visibility…

FYI, my code is what I have to do to get it to work based on my skill set.  If you cringe, feel free to make any suggestions.  HA!

 


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

Try this:

protected virtual void _(Events.RowSelected<APTran> e)
{
    APTran line = e.Row;
    if (line is null) return;

    APInvoice invoice = APTran.FK.Invoice.FindParent(e.Cache.Graph, line);
    if (invoice is null) return;

    AllocateLine.SetEnabled((invoice.VendorID is object && (invoice.Status == "H" || invoice.Status == "B")));
    AllocateLine.SetVisible((invoice.VendorID is object && (invoice.Status == "H" || invoice.Status == "B")));
}

 

Even better, I think this would accomplish the same thing using only e’s Graph:

protected virtual void _(Events.RowSelected<APTran> e)
{
    APTran line = e.Row;
    if (line is null) return;

    // Cast e's Graph as APInvoiceEntry and load parent Invoice
    var apInvoiceGraph = e.Cache.Graph as APInvoiceEntry;
    APInvoice invoice = apInvoiceGraph.Document.Current = apInvoiceGraph.Document.Search<APInvoice.docType, APInvoice.refNbr>(line.TranType, line.RefNbr);
    if (invoice is null) return;

    // Get APInvoiceEntry's Graph extension
    var apInvoiceGraphExt = apInvoiceGraph.GetExtension<APInvoiceEntry_Extension>();

    // Enable / disable custom Action
    apInvoiceGraphExt.AllocateLine.SetEnabled((invoice.VendorID is object && (invoice.Status == "H" || invoice.Status == "B")));
    apInvoiceGraphExt.AllocateLine.SetVisible((invoice.VendorID is object && (invoice.Status == "H" || invoice.Status == "B")));
}

 


Joe Schmucker
Captain II
Forum|alt.badge.img+3
  • Author
  • Captain II
  • 443 replies
  • April 12, 2022

@darylbowman  Button kicks a dialog that the button is disabled, so at least the code will not fire.

But unfortunately, the button is still allowing me to click it.  :-(

Thank you so much for the code though.  It is another way of doing it that I can keep for future reference.  

You guys have been super quick with stuff to try.  I can’t thank you all enough.  This is not the end of the world so it’s ok to just let it be.  I was thinking this was just another dumb thing I was missing, but I think that there is some overriding forces at work that I probably cannot work around.

You guys rule!

Thank you!


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

@joe21 Try the second option


Joe Schmucker
Captain II
Forum|alt.badge.img+3
  • Author
  • Captain II
  • 443 replies
  • April 12, 2022

@darylbowman HAHA!  I love the persistence!  I literally spent 2 hours trying to find a way to get this to work.  I love the fact there are others out there who refuse to give up!  Ha!

Got a compiler error.  From what I can see, this error seems erroneous.  I tried to build it anyway just to see if it was one of those Acumatica warnings that wasn’t actually going to stop the code from running but it doesn’t compile.

Please don’t waste any more of your time on this.  It is just a “presentation” issue that the customer can live with.  You are making me feel guilty!


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

My bad. Change

var apInvoiceGraphExt = invoice.GetExtension<APInvoiceEntry_Extension>();

to

var apInvoiceGraphExt = apInvoiceGraph.GetExtension<APInvoiceEntry_Extension>();

 

I don’t have that extension so VS didn’t catch that.


Joe Schmucker
Captain II
Forum|alt.badge.img+3
  • Author
  • Captain II
  • 443 replies
  • April 12, 2022

I did a RESTART APPLICATION to make sure all caches were re-instantiated.  I then went into debug and verified that the code was being hit.  The Status is “K” so the properties were being set to False.

Still, the evil button is visible.  

If my customer makes a big deal about this, would this be something I should submit as a “trouble ticket” to Acumatica?  I’ve got some great minds looking at this and maybe in 2021R1, it is just not possible to change that field status.  I have seen a few things in the new product that does not work the same way it did in older versions.


Naveen Boga
Captain II
Forum|alt.badge.img+19
  • Captain II
  • 3381 replies
  • April 12, 2022

Hi @joe21 You might tried all possible ways, have you tried with the Workflow automation steps from the customization project and verified?

 

 


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

Ok, so thinking back through this, your conditions are all Invoice specific, not row specific, so there should be no need to use APTran. Since it is disabled for all rows, I don’t think there would be a need to tie it into the grid either. Try this yet:

protected virtual void _(Events.RowSelected<APInvoice> e)
{
    APInvoice invoice = e.Row;
    if (invoice is null) return;

    // Cast e's Graph as APInvoiceEntry and load parent Invoice
    var apInvoiceGraph = e.Cache.Graph as APInvoiceEntry;
    invoice = apInvoiceGraph.Document.Current = apInvoiceGraph.Document.Search<APInvoice.docType, APInvoice.refNbr>(invoice.DocType, invoice.RefNbr);

    // Get APInvoiceEntry's Graph extension
    var apInvoiceGraphExt = apInvoiceGraph.GetExtension<APInvoiceEntry_Extension>();

    // Enable / disable custom Action
    apInvoiceGraphExt.AllocateLine.SetEnabled(invoice.VendorID is object && (invoice.Status == "H" || invoice.Status == "B"));
    apInvoiceGraphExt.AllocateLine.SetVisible(invoice.VendorID is object && (invoice.Status == "H" || invoice.Status == "B"));
}

Joe Schmucker
Captain II
Forum|alt.badge.img+3
  • Author
  • Captain II
  • 443 replies
  • Answer
  • April 12, 2022

It does not appear that you can add a new workflow to this screen

 

SO...I tried the other suggestion you provided above. I used the UsrAllocationID field as the StateColumn.

                <px:PXToolBarButton Key="cmdAllocateLine" Text="Allocate Line" DependOnGrid="grid" StateColumn="UsrAllocationID">
                  <AutoCallBack Target="ds" Command="AllocateLine" /></px:PXToolBarButton>

 

It worked!!  Since the Allocation ID field in the grid is disabled when the other fields are disabled, the button only lights up when you are able to select an allocation ID.

Seems like the VS code should work.  But I guess you have to do it the way they want you to do it.

Thanks guys for your support!

 

 


Joe Schmucker
Captain II
Forum|alt.badge.img+3
  • Author
  • Captain II
  • 443 replies
  • April 12, 2022

@darylbowman Exactly what I thought.  I tried it both ways.  The only way I could get it to work was with the StateColumn on the <px:PXToolBarButton aspx.

The way I have it set now actually works better because the button will only light up when there is an allocation ID selected.


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

@nmansinha - Any insight here? You’re a wizard with these things.


Joe Schmucker
Captain II
Forum|alt.badge.img+3
  • Author
  • Captain II
  • 443 replies
  • April 12, 2022
darylbowman wrote:

@nmansinha - Any insight here? You’re a wizard with these things.

Just want to make sure you don’t invest any more time into this.  The Naveen suggestion did solve my issue.  It actually works better than my original plan because the button is available not only based on the status of the document, but whether or not the Allocation ID field has a value.  

Still curious as to why our VS code was being ignored though.  :-)


darylbowman
Captain II
Forum|alt.badge.img+13
joe21 wrote:

Still curious as to why our VS code was being ignored though.  :-)

This


Forum|alt.badge.img+5
  • Jr Varsity II
  • 237 replies
  • April 13, 2022

I suspect your code was working but the workflow engine was re-enabling the action. You can modify the workflow via code(even ones that are disabled from editing in the customization editor).

Using a graph extension and overriding the Configure method allows you to do so. There is a relatively new training available on it:

https://openuni.acumatica.com/courses/development/t270-workflow-api/


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