Using filter with Customer screen in Acumatica API

2019-03-02 22:52发布

Looking at the API examples from Acumatica, I have written code to Export some data from the Customer screen based on a single filter. The filter should enforce that the Customer's email address equals a particular value (once that's working, I will also check a custom field with an encrypted password). Yet for some reason the Export function is returning what appears to be every customer record in our database. Can anyone tell what I am doing wrong with my filter, or anything else? Code and screenshot from debugger are below.

Thank you!

Public Function ValidateUser(ByVal emailAddress As String, ByVal password As String, ByRef customerFirstName As String, ByRef customerLastName As String, ByRef customerCountry As String, ByRef customerPhone As String, ByRef customerCell As String) As String

    Dim customer As AR303000Content = m_context.AR303000GetSchema()
    m_context.AR303000Clear()

    Dim emailFilter As Filter = New Filter()
    emailFilter.Field = customer.GeneralInfoMainContact.Email
    emailFilter.Condition = FilterCondition.Equals
    emailFilter.Value = emailAddress

    Dim searchfilters() As Filter = {emailFilter}
    Dim searchCommands() As Command = {customer.CustomerSummary.CustomerID, customer.CustomerSummary.CustomerName, customer.GeneralInfoMainContact.Phone1, customer.GeneralInfoMainContact.Phone2, customer.GeneralInfoMainAddress.Country}
    Dim searchResult As String()() = m_context.AR303000Export(searchCommands, searchfilters, 0, False, False)

    Dim numRecords = searchResult.Length
    Dim customerID As String = ""
    Dim customerName As String = ""
    If numRecords > 0 Then
        ' we found a user with that email address
        Dim i As Integer = 0
        For i = 1 To numRecords
            customerID = searchResult(i - 1)(0)
            customerName = searchResult(i - 1)(1)
            customerPhone = searchResult(i - 1)(2)
            customerCell = searchResult(i - 1)(3)
            customerCountry = searchResult(i - 1)(4)
        Next
    End If

    Dim spaceInName = customerName.IndexOf(" ")
    If spaceInName >= 0 Then
        customerFirstName = customerName.Substring(0, spaceInName)
        customerLastName = customerName.Substring(spaceInName + 1)
    End If

    Return customerID
End Function

Debugger showing 1512 records returned

标签: acumatica
1条回答
小情绪 Triste *
2楼-- · 2019-03-02 23:35

Filters generally only work on the primary view (e.g., main table - in this case BAccount+Customer). If you try to filter on data contained in secondary views, the system will silently ignore it. The e-mail address and contact record data is contained in the Contact table, and therefore you cannot filter by these fields.

I think this behaviour should be improved, and i'll file a suggestion internally to at least throw an exception if you try to filter on something that's not allowed. It will at least make troubleshooting this problem easier.

As an alternative, if you're using Submit() function to load a specific record, you can alter the underlying FieldName in the schema to have it match based on another field. This example below shows how to update a customer credit verification settings by looking up customer based on e-mail address:

Screen context = new Screen();
context.CookieContainer = new System.Net.CookieContainer();
context.Url = Url;
context.Login(Login, Password);

AR303000Content custSchema = context.AR303000GetSchema();

custSchema.CustomerSummary.CustomerID.FieldName += 
    ("!" + custSchema.CustomerSummary.ServiceCommands.FilterEmail.FieldName);

var commands = new Command[]
{
    new Value 
    {
        Value = "demo@gmail.com", 
        LinkedCommand = custSchema.CustomerSummary.CustomerID 
    },

    new Value 
    {
        Value = "Disabled", 
        LinkedCommand = custSchema.GeneralInfoCreditVerificationRulesCreditVerification.CreditVerification 
    },

    custSchema.Actions.Save,

    custSchema.GeneralInfoFinancialSettings.CustomerClass
};
var customer = context.AR303000Submit(commands)[0];

You can also use the Submit() function to retrieve data. Usually you place the fields you need in the commands array, but if you specifically need the CustomerID you'll need to use a trick to retrieve it since the CustomerID.FieldName value was altered to add the e-mail filter. Here's the sample:

private static string GetCustomerIDByEmail(string eMailAddress)
{
    Screen context = new Screen();
    context.CookieContainer = new System.Net.CookieContainer();
    context.Login("admin", "admin");

    Content custSchema = context.GetSchema();

    custSchema.CustomerSummary.CustomerID.FieldName +=
        ("!" + custSchema.CustomerSummary.ServiceCommands.FilterEmail.FieldName);

    var commands = new Command[]
    {
        new Value 
        {
            Value = eMailAddress,
            LinkedCommand = custSchema.CustomerSummary.CustomerID
        },

        // Manually define the Field by setting ObjectName and FieldName. We can't use custSchema.CustomerSummary.CustomerID field because it was altered to make it search by e-mail.
        new Field
        {
            ObjectName = "BAccount",
            FieldName = "AcctCD"
        }
    };

    var results = context.Submit(commands);

    if (results.Length == 0)
        return "Not found";
    else
        return results[0].CustomerSummary.CustomerID.Value;
}
查看更多
登录 后发表回答