Skip to main content

Hi All,

We would like to display an error to the user if the Project Budget exceeds while adding the details in Purchase Order and stop them from removing it from hold.

Acumatica does some calculation on page load and displays a warning when the budget is exceeded as shown below:

 

This is the budget in the project:

 

For the Project, Project Task, Cost Code and Account Group combination, the budget in project is 1500 but in PO is 1501, so it is displaying the warning message.

There are other logic as well which I do not know yet and it is complex if I have to replicate the logic.

My job is to see if the budget is exceeded or not if it is exceeding, I need to give a message to user and stop from proceeding further.

Things I have tried:

  1. Tried to implement the logic by myself but I am missing certain scenarios like the line item in PO can be marked as closed/cancelled, so they need to be treated differently.
  2. Catch the warning and show it as an error but the warning message is inconsistent. There are many instances where the warning was not shown although the budget exceeded and after reload it comes back.

From my analysis the code from Acumatica is in class BudgetControlGraph. Is there a way I could re-use the logic or replicate it for my requirement and How?

 

Hi  Just wondering if you managed to find a solution for this as requirement has come up for a client, thanks


Hi @rajeshmishra90,

You can override the persist method for POOrderEntry graph and fetch the budget based on Projects and show the exception based on data fetched.

you can try below code snippet.

// Override the method that handles the removal of the hold status
public delegate void PersistDelegate();
>PXOverride]
public void Persist(PersistDelegate baseMethod)
{
// Get the current Purchase Order record
POOrder currentOrder = Base.Document.Current;
if (currentOrder != null)
{
// Check if the budget is exceeded
bool isBudgetExceeded = CheckProjectBudgetExceeded(currentOrder);

// If the budget is exceeded, display an error and stop the process
if (isBudgetExceeded)
{
throw new PXException("The project budget has been exceeded. You cannot proceed.");
}
}

// Call the base method to proceed with saving the order
baseMethod();
}

private bool CheckProjectBudgetExceeded(POOrder currentOrder)
{
// Flag to track whether the budget is exceeded
bool isExceeded = false;

foreach (POLine line in Base.Transactions.Select())
{
// Skip lines that are closed or cancelled
if (line.Closed == true || line.Cancelled == true)
continue;

// Fetch the budget for the project, task, cost code, and account group combination
PMBudget projectBudget = PXSelect<PMBudget,
Where<PMBudget.projectID, Equal<Required<PMBudget.projectID>>,
And<PMBudget.projectTaskID, Equal<Required<PMBudget.projectTaskID>>,
And<PMBudget.costCodeID, Equal<Required<PMBudget.costCodeID>>,
And<PMBudget.accountGroupID, Equal<Required<PMBudget.accountGroupID>>>>>>>
.Select(Base, line.ProjectID, line.TaskID, line.CostCodeID, line.ExpenseAcctID);

if (projectBudget != null)
{
// Calculate the total committed amount (in this case, the amount from PO lines)
decimal totalAmount = line.CuryLineAmt ?? 0m;

// Compare the committed amount with the budgeted amount
if (projectBudget.CuryAmount.GetValueOrDefault() < totalAmount)
{
isExceeded = true;
break;
}
}
}

return isExceeded;
}

Hope, it helps!

Note: I have not tried above code as working , you can change logic as per your scenario.


Thanks so much will give it a crack!


Hello @rajeshmishra90 ,

 

Have you tried extending the BudgetControlGraph of the POOrderEntry and override RowSelected event to set the error on field?

public class POOrderEntryExt : BudgetControlGraph<POOrderEntry>

 

Here is the sample code may help you.
 

public class POOrderEntryExtExt : PXGraphExtension<POOrderEntryExt, POOrderEntry>
{
public static bool IsActive() => POOrderEntryExt.IsActive();

protected virtual void _(Events.RowSelected<POOrder> e, PXRowSelected baseEvent)
{
baseEvent?.Invoke(e.Cache, e.Args);
// Validate and return if no Budget Control is required
// TODO: Add code to validate

foreach (PMBudgetControlLine budgetControlLine in Base1.BudgetControlLines.Cache.Inserted)
{
if (budgetControlLine.RemainingAmount < 0)
{
e.Cache.RaiseExceptionHandling<POOrder.curyOrderTotal>(e.Row, e.Row.CuryOrderTotal,
new PXSetPropertyException(e.Row, PX.Objects.PM.Messages.BudgetControlDocumentWarning, PXErrorLevel.RowError));
return;
}
}
}
}

 

Note: I have not tested the above code.


@rajeshmishra90 , Hope the above code work for you.


Reply