I have created a few fields in BAccountExt as shown below and placed them under a custom tab in Customers screen:
- UsrValue1 - string
- UsrValue2 - string
- UsrValidValue - boolean (field disabled to disallow manual update)
- UsrValue1ValidatedDateTime
The flow of this customization is when validateValue action button is pressed, it will trigger validation on UsrValue1 and UsrValue2 via API and return the status (true/false). The status will then be saved to UsrValidValue field, and the validation date time will be recorded in UsrValue1ValidatedDateTime field.
The action button code is as shown below:
protected void validateValue()
{
bool flag = true;
Customer customer = (Customer)Base.CurrentCustomer.Current;
if (customer != null)
{
// Retrieve customer's BAccount from the current context
BAccount customerAccount = Helper.GetCustomer(customer.BAccountID);
BAccountExt customerAccountExt = customerAccount.GetExtension<BAccountExt>();
// Retrieve company's BAccount from the current context
BAccount companyAccount = Helper.GetCompanyAccountFromContext();
if (companyAccount == null)
{
// Acuminator disable once PX1050 HardcodedStringInLocalizationMethod [Justification]
throw new PXException("Company account not found.");
}
string apiBaseUrl = companyAccount.GetExtension<BAccountExt>().UsrApiBaseUrl;
string idValue = companyAccount.GetExtension<BAccountExt>().UsrIDValue;
if (string.IsNullOrEmpty(apiBaseUrl) || string.IsNullOrEmpty(idValue))
{
// Acuminator disable once PX1050 HardcodedStringInLocalizationMethod [Justification]
throw new PXException("API base URL or ID value is null or empty.");
}
// Retrieve access token
string accessToken = null;
try
{
var accessTokenTask = TokenManager.GetAccessTokenAsync(companyAccount, flag); // Override token manager for Customers screen
accessToken = accessTokenTask.GetAwaiter().GetResult();
}
catch (Exception ex)
{
PXTrace.WriteError(ex);
// Acuminator disable once PX1050 HardcodedStringInLocalizationMethod [Justification]
throw new PXException("Failed to retrieve access token.");
}
finally
{
string value1 = customer.GetExtension<BAccountExt>().UsrValue1;
string value2 = customer.GetExtension<BAccountExt>().UsrValue2;
try
{
var apiCallSuccessTask = ValidateValueHelper.ValidateValue(apiBaseUrl, value1, value2, accessToken);
var apiCallSuccess = apiCallSuccessTask.GetAwaiter().GetResult();
customerAccountExt.UsrValidValue = apiCallSuccess; // Update checkbox if success
PXTrace.WriteInformation($"Value validation result: {apiCallSuccess}");
}
catch (Exception ex)
{
PXCache<BAccount>.GetExtension<BAccountExt>(customerAccount).UsrValidValue = false; // Update checkbox if failed
// Acuminator disable once PX1050 HardcodedStringInLocalizationMethod [Justification]
throw new PXException("Value is invalid. Please review and validate again.");
}
finally
{
customerAccountExt.UsrValue1ValidatedDateTime = DateTime.Now; // Always update the validation date/time
// Update the cache
this.Base.Caches[typeof(BAccount)].Update(customerAccount);
this.Base.CurrentCustomer.Update(customer);
// Save changes to the database
this.Base.Actions.PressSave();
PXTrace.WriteInformation($"Record saved.");
}
}
}
}I confirmed from trace that the code passes through all checkpoints:
API Response Status Code: OK
Value is valid
Value validation result: True
Record saved.
Despite all that, the values remained unchanged in Customers screen. Please advise on this.