Can anybody tell me how to check if a Customer Status is Active or Inactive in Acumatica. I am using the following code but can't figure out what the real value for should be:
if (row != null){
if (row.Status == <status.Active>){
//DO SOMETHING
}
else{
//DO SOMETHING ELSE
}
}
With what can I replace the if I want to check if the Customer status is Active or not?
Thanks,
G
I think if you have something like :
if (row.status == Customer.status.Active)
It should work. You will need to have a using/reference for the AR objects.
You can see what the attributes are on the status field by opening the customer form in Design mode. By doing that, you can see what field in the DAC it actually is and what is available in the dropdown for that field. Here are the attributes for the status field.
new string[] { Active, Hold, CreditHold, Inactive, OneTime },
new string[] { CR.Messages.Active, CR.Messages.Hold,CR.Messages.CreditHold, CR.Messages.Inactive, CR.Messages.OneTime }) { }
}}
[PXDBString(1, IsFixed = true)]
[PXDefault(status.Active)]
[PXUIField(DisplayName = "Status")]
[status.List()]
// below are the values for the CR.Messages if you care to see
public const string Active = "Active";
public const string Hold = "On Hold";
public const string HoldPayments = "Hold Payments";
public const string Inactive = "Inactive";
public const string OneTime = "One-Time";
public const string CreditHold = "Credit Hold";
Further review of the source code shows that the customer status field is actually a field in the BAccount table called Status. It is a single character field and the value for Active = 'A', Inactive = 'I'. (there are more values)
So, if you are simply wanting to know if the customer is Active, similar to what Max posted, you would simply do this in one of the event handlers where the current row is defined as row:
if (row.status == 'A') // if customer status is Active...
{
//do something
}
There may be a constant you can use, which would be better.
Related
I have problems with my dialog field. I have button that opens dialog tab with field. It was supposed to show on that field lookup exact records(i guess i need select there by one field value). Right now i have this code:
DialogField Journal = dialog.addField(extendedTypeStr(JournalId));
This dialog line adds a field with all values on that EDT. I have 3 journal types - NEW, UPDATE, DELETE. Right now on that field lookup it shows me all 3 journal types. I want to make custom lookup that shows exact type , example - if i click that button on journal that has type "NEW", then it should show only "NEW" type of journal types on lookup. I heard there is something like dialog.addLookup or something. Can someone help me?
You already added your dialog field (in the dialog() method). Now add the dialogRunPost() method that is executed after the form GUI is initialized. At that point you can fetch the underlying FormStringControl behind the dialog field. Subscribing to the FormStringControl.OnLookup event allows you to override the lookup.
I did not have some journal data available, so I created a similar example with customers. My example dialog (MyDialog) takes a source customer (customerCaller) and shows a dialog with a custom lookup that only shows customers with the same customer group.
My example is also a standalone, runnable class and is not called from a form. Comments have been added to indicate where this affects the code.
Full example
public class MyDialog extends Runbase
{
// fields
protected Args args;
protected CustTable customerCaller;
protected DialogField dfCustomerId;
// construct
public static MyDialog newArgs(Args _args)
{
MyDialog ret = new MyDialog();
ret.args = _args;
return ret;
}
// initialize
public boolean init()
{
boolean ret = super();
// validate and fetch caller
if (args.record() && args.record().TableId == tableNum(CustTable))
//if (args.caller() && args.caller().dataset() == tableNum(CustTable)) --> when called from form
{
customerCaller = args.record();
//customerCaller = args.caller().record();
}
else
{
throw error(Error::missingRecord('My Dialog'));
}
return ret;
}
// build dialog
public Object dialog()
{
Dialog ret = super();
// optional reference to visualize the input
ret.addText('Caller customer group = ' + customerCaller.CustGroup);
// add field
dfCustomerId = ret.addField(extendedTypeStr(CustAccount)); // default lookup = all CustTable.AccountNum values
return ret;
}
public void dialogPostRun(DialogRunbase dialog)
{
super(dialog);
// subscribe to lookup event
FormStringControl fscCustomerId = dfCustomerId.control();
fscCustomerId .OnLookup += eventhandler(this.customerId_OnLookup);
}
// custom lookup for customer id
protected void customerId_OnLookup(FormControl _sender, FormControlEventArgs _e)
{
// cancel default
FormControlCancelableSuperEventArgs eventArgs = _e;
eventArgs.CancelSuperCall();
// define lookup query (list all customers with same customer group as input customer)
Query query = new Query();
QueryBuildDataSource qbds = SysQuery::findOrCreateDataSource(query, tableNum(CustTable));
SysQuery::findOrCreateRange(qbds, fieldNum(CustTable, CustGroup)).value(SysQuery::value(customerCaller.CustGroup));
// do lookup
SysTableLookup lookup = SysTableLookup::newParameters(tableNum(CustTable), _sender);
lookup.parmQuery(query);
lookup.addLookupfield(fieldNum(CustTable, AccountNum), true);
lookup.addLookupfield(fieldNum(CustTable, CustGroup));
lookup.performFormLookup();
}
// run dialog
public static void main(Args _args)
{
// I am running this dialog directly (not from a form), generating some random input
CustTable customer;
select firstonly customer where customer.CustGroup != '';
_args.record(customer);
// end of random input
MyDialog md = MyDialog::newArgs(_args);
md.init();
if (md.prompt())
{
md.run();
}
}
}
Result
I have a custom action on screen CR304000 - OpportunityMaint in the Quotes tab of the grid view that marks a field called IsPrimary in the CRQuote DAC as true for the current record in the Quotes view. These project Quotes are associated with the current opportunity as well as with a related PMQoute in the PMQuoteMaint BLC. The PMQuoteMaint BLC has a view called Activties that has all the CRActivities associated with the PMQuote. I created a custom field in the CRActivity called IsPrimary and added it to the Activities view in the PMQuoteMaint BLC grid.
My goal was to override the Action in the OpportunityMaint to update the IsPrimary field in CRActivity to true or false depending on what the Action in OpportunityMaint is toggling. However, my IsPrimary field in PMQuoteMaint is not toggling. My code attempts to get Current Quote OpportunityMain and then create a PMQuoteMaint graph and set the Current record. Then iterate though Activies view and set the IsPrimary field accordingly. Like I said, not having success because I'm not sure that my code is successfully retrieving the correct Activities.
There might be a better way to access CRActivity associated with a PMQuote, but I'm not sure. Any help would be appreciated. Here is code:
public virtual IEnumerable PrimaryQuote(PXAdapter adapter)
{
foreach (CROpportunity opp in adapter.Get())
{
if (Quotes.Current?.IsPrimary != true)
{
var selectExistingPrimary = new PXSelect<CRQuote, Where<CRQuote.quoteID,
Equal<Required<CRQuote.quoteID>>>>(this);
CRQuote primary = selectExistingPrimary.Select(opp.DefQuoteID);
if (primary != null && primary.QuoteID != Quotes.Current.QuoteID && primary.Status ==
PM.PMQuoteStatusAttribute.Closed)
{
throw new PXException(PM.Messages.QuoteIsClosed, opp.OpportunityID,
primary.QuoteNbr);
}
var quoteID = Quotes.Current.QuoteID;
var opportunityID = this.Opportunity.Current.OpportunityID;
this.Persist();
PXDatabase.Update<Standalone.CROpportunity>(
new PXDataFieldAssign<Standalone.CROpportunity.defQuoteID>(quoteID),
new PXDataFieldRestrict<Standalone.CROpportunity.opportunityID>(PXDbType.VarChar,
255, opportunityID, PXComp.EQ)
);
this.Cancel.Press();
CROpportunity rec = this.Opportunity.Search<CROpportunity.opportunityID>
(opportunityID);
yield return rec;
}
yield return opp;
}
``` My OverRide
public PXAction<CROpportunity> primaryQuote;
[PXUIField(DisplayName = Messages.MarkAsPrimary)]
[PXButton]
public virtual IEnumerable PrimaryQuote(PXAdapter adapter)
{
// this is currently selected record in quotes grid
var currQuoteNbr = Base.Quotes.Current.QuoteNbr;
bool isPrimary2;
foreach (CRQuote quote in Base.Quotes.Select())
{
var quoteNbr = quote.QuoteNbr;
if(quoteNbr.Trim() == currQuoteNbr.Trim())
{
isPrimary2 = true;
}
else
{
isPrimary2 = false;
}
PXTrace.WriteInformation(string.Format("Quote: {0} Value:
{1}",quoteNbr.ToString(),isPrimary2.ToString()));
var PMQuoteMaintGraph = PXGraph.CreateInstance<PMQuoteMaint>();
PMQuoteMaintGraph.Quote.Current = PMQuoteMaintGraph.Quote.Search<PMQuote.quoteNbr>
(quoteNbr.Trim()); // this is the current quote
foreach (CRActivity activity in PMQuoteMaintGraph.Activities.Select())
{
CRActivityExt itemExt = PXCache<CRActivity>.GetExtension<CRActivityExt>(activity);
itemExt.UsrPrimary = isPrimary2;
PMQuoteMaintGraph.Activities.Cache.Persist(PXDBOperation.Update);
PXDatabase.Update<CRActivity>(new PXDataFieldAssign<CRActivityExt.usrPrimary>
(isPrimary2));
}
}
return Base.primaryQuote.Press(adapter);
}
with code from Load value from popup to InventoryID field question am able to set the InventoyID from popup to the InventoryID field but the default behavior of Acumatica is missing, like after InventoryID is set from poup, am selecting Item Class then a pop up is firing and asking for confirmation, generally this happen only when we update Item Class for already created Item.
[PXButton]
[PXUIField(DisplayName = "Generate")]
public IEnumerable GenerateInv(PXAdapter adapter)
{
string inventoryCD = "ACUMATICA";
InventoryItem item = PXCache<InventoryItem>.CreateCopy(Base.Item.Current);
OrderedDictionary keys = new OrderedDictionary(StringComparer.OrdinalIgnoreCase)
{
{
typeof(InventoryItem.inventoryCD).Name,
adapter.View.Cache.GetValue(adapter.View.Cache.Current,
typeof(InventoryItem.inventoryCD).Name)
}
};
OrderedDictionary vals = new OrderedDictionary(StringComparer.OrdinalIgnoreCase)
{
{
typeof(InventoryItem.inventoryCD).Name, inventoryCD
}
};
adapter.View.Cache.Update(keys, vals);
if (adapter.Searches != null && adapter.Searches.Length > 0)
{
adapter.Searches[0] = inventoryCD;
}
return adapter.Get();
}
You can try to skip the message window by overriding the Field Verifying on the stock item page for InventoryItem.ItemClassID. You should use some condition to indicate you are running your customer process so the standard message will appear for normal use on the stock items page.
public virtual void InventoryItem_ItemClassID_FieldVerifying(PXCache cache, PXFieldVerifyingEventArgs e, PXFieldVerifying del)
{
try
{
del?.Invoke(cache, e);
}
catch (PXDialogRequiredException)
{
var someSkipMessageWindowCondition = true;
if (someSkipMessageWindowCondition)
{
return;
}
throw;
}
}
Because of the use of the private property doResetDefaultsOnItemClassChange in the Base graph, the process will function as if the message box was answered YES to default the field values from the new item class. If you do not want the values to change using the new class you will need to cancel the field defaultings for the fields found in InventoryItem_ItemClassID_FieldUpdated in the Base graph. This will point out which fields are being updated when doResetDefaultsOnItemClassChange == true.
A better answer to your question would be automatically answering NO which I am unsure how to do. Would be nice to know how do perform that function if someone else knows how to make that call.
I am trying to set a custom field I created in the INTranSplit table. I fetch the target record, set the custom field, update the view holding the records for the page, and perform a PressSave(). At some point during the save, the code sets the INTranSplit.TranDate to null and throws an exception.
Here is my code:
public PXAction<EMPWorkOrder> addSerialNbr;
[PXUIField(DisplayName = "Add Serial Number")]
protected void AddSerialNbr()
{
AvailableSNFilter serialNbrRow = AvailableSNs.Current;
if (serialNbrRow.AvailableSNs != null)
{
//Gets record from DAC created from a SQL View
GetAvailableSerialNumbers targetSN = (GetAvailableSerialNumbers)PXSelectorAttribute.Select<AvailableSNFilter.availableSNs>(AvailableSNs.Cache, serialNbrRow);
//Fetches the INTranSplit record
INTranSplit tran = PXSelect<INTranSplit, Where<INTranSplit.refNbr, Equal<Required<GetAvailableSerialNumbers.refNbr>>, And<INTranSplit.lotSerialNbr,
Equal<Required<GetAvailableSerialNumbers.lotSerialNbr>>, And<INTranSplit.inventoryID, Equal<Required<GetAvailableSerialNumbers.inventoryID>>
,And<INTranSplit.lotSerialNbr, NotEqual<Required<INTranSplit.lotSerialNbr>>>>>>>
.Select(this, targetSN.RefNbr, targetSN.LotSerialNbr, targetSN.InventoryID, string.Empty);//, targetSN.SplitLineNbr);
INTranSplitExt tranExt = PXCache<INTranSplit>.GetExtension<INTranSplitExt>(tran);
//Sets the custom field
tranExt.UsrWOID = CurrentDocument.Current.Id;
WorkOrderSerialNumbers.Update(tran);
serialNbrRow.AvailableSNs = string.Empty;
AvailableSNs.Update(serialNbrRow);
this.Actions.PressSave();
}
else
{
Document.Ask("AvailableSN Null", MessageButtons.OK);
}
}
The error I get is this:
Error #14: Updating 'IN Transaction Split' record raised at least one error. Please review the errors.
Error: 'Transaction Date' cannot be empty.
I stepped through the process and found that the TranDate is not null until after the code enters the PressSave() function.
Is there any way to solve this issue?
Make sure you are including the parent views and setting current for INRegister and INTran as TranDate in the INTranSplit is based on INRegister.
I created a new field, UsrAcknowledged, boolean, checkbox, and placed it on the SOLine details grid. I want every line on the details grid to be checked when the Email Sales Order/Quote process is run under Actions for SOOrder. My code is as follows under the SOOrderEntry_Extension:PXGraphExtension
public CRActivityList<SOOrder> Activity;
public PXAction<SOOrder> notification;
[PXUIField(DisplayName = "Notifications", Visible = false)]
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.DataEntryF)]
protected virtual IEnumerable Notification(PXAdapter adapter,
[PXString]
string notificationCD
)
{
foreach (SOOrder order in adapter.Get<SOOrder>())
{
var parameters = new Dictionary<string, string>();
parameters["SOOrder.OrderType"] = order.OrderType;
parameters["SOOrder.OrderNbr"] = order.OrderNbr;
Activity.SendNotification(ARNotificationSource.Customer, notificationCD, order.BranchID, parameters);
//order.OrderDesc = "Desc";
foreach (SOLine line in PXSelect<SOLine>.Select(Base, order.OrderNbr))
{
SOLineExt rowExt = line.GetExtension<SOLineExt>();
rowExt.UsrAcknowledged = true;
line.OrderQty = 5;
}
yield return order;
}
}
//order.Desc = "Desc" was an initial simple test just to see if my code was achieving the desired results and the proder desciption was changed as planned.
My code compiles and the email process runs as planned with a green check for successful, but neither the Acknowledged check box nor the Order Quantity are changed. I don't really care about the ord qty, it was just another test.
Any suggestions for what I can change to update the Acknowledged checkbox to checked during the Email Sales Order/Quote under Actions on the SO Order Entry screen would be appreciated
I would say you need to call Base.Transactions.Update(line) after you update your row values inside your foreach.