How to Search Custom Field from Customer and Num Pad in Dynamics 365 Retail & Commerce POS
Microsoft Dynamics 365
Retail & Commerce
POS (Point of Sales)
How to Search Custom Field from Customer and Num Pad
Pre-Requisite
You must have a custom field in the channel table.
If you want to add a custom field. Please follow the link
https://sajidshaikhblog.blogspot.com/2023/08/how-to-extend-customer-list-view-adding.html
Commerce Runtime (CRT)
K:\RetailSDK\SampleExtensions\CommerceRuntime
Development
Open the commerce runtime project from the above source and select set as the startup project Runtime.Extensions.CustomerSearchSample
Create a new class with the name of CustomerSearchRequestHandler.cs. Because this class is not part of the project, you must create a file manually.
Code - CustomerSearchRequestHandler.cs
using Microsoft.Dynamics.Commerce.Runtime;
using Microsoft.Dynamics.Commerce.Runtime.Data;
using Microsoft.Dynamics.Commerce.Runtime.DataModel;
using Microsoft.Dynamics.Commerce.Runtime.DataServices.Messages;
using Microsoft.Dynamics.Commerce.Runtime.Messages;
using Microsoft.Dynamics.Commerce.Runtime.DataAccess.SqlServer;
using System;
using System.Collections.Generic;
namespace Contoso.Commerce.Runtime.CustomerSearchSample
{
public sealed class CustomerSearchRequestHandler : SingleRequestHandler<CustomersSearchRequest, CustomersSearchResponse> //SingleAsyncRequestHandler<CustomersSearchRequest>//
{
/// <summary>
/// Executes the workflow to retrieve customer information.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>The response.</returns>
protected override CustomersSearchResponse Process(CustomersSearchRequest request)
{
ThrowIf.Null(request, "request");
ThrowIf.Null(request.Criteria, "request.Criteria");
// Execute custom customer search logic here.
CustomersSearchResponse externalResponse = this.ExternalCustomerSearch(request);
return new CustomersSearchResponse(externalResponse.Customers.AsPagedResult());
}
public CustomersSearchResponse ExternalCustomerSearch(CustomersSearchRequest request)
{
List<CustomerSearchResult> customerSearchResult = new List<CustomerSearchResult>();
var databaseContext = new DatabaseContext(request.RequestContext);
ParameterSet configurationDataParameters = new ParameterSet
{
["@RefNoExt"] = request.Criteria.Keyword
};
//Get tender type Id for tokenized tender line from database.
var externalConfigDataset = databaseContext
.ExecuteQueryDataSet("SELECT PARTY from ax.CUSTTABLE where RefNoExt = @RefNoExt", configurationDataParameters);
if (externalConfigDataset.Tables[0].Rows.Count > 0)
{
CustomerSearchResult customersearchobj = new CustomerSearchResult()
{
PartyId = Convert.ToInt64(externalConfigDataset.Tables[0].Rows[0][0]),
};
customerSearchResult.Add(customersearchobj);
}
//Filter AccountNum
ParameterSet internalconfigurationDataParameters = new ParameterSet
{
["@AccountNum"] = "%" + request.Criteria.Keyword + "%"
};
var internalConfigDataset = databaseContext
.ExecuteQueryDataSet("SELECT PARTY from ax.CUSTTABLE where AccountNum Like @AccountNum", internalconfigurationDataParameters);
if (internalConfigDataset.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < internalConfigDataset.Tables[0].Rows.Count; i++)
{
CustomerSearchResult customersearchobj = new CustomerSearchResult()
{
PartyId = Convert.ToInt64(internalConfigDataset.Tables[0].Rows[i][0]),
};
customerSearchResult.Add(customersearchobj);
}
}
if (customerSearchResult.Count == 0 && request.Criteria.DataLevel == CommerceEntityDataLevel.Complete)
{
using (var databaseContext2 = new SqlServerDatabaseContext(request.RequestContext))
{
Customer customer = new Customer();
customer.FirstName = request.Criteria.Keyword;
customer.LastName = "";
customer.Name = customer.FirstName + " " + customer.LastName;
customer.CustomerType = CustomerType.Person;
customer.CustomerTypeValue = 1;
customer.CurrencyCode = request.RequestContext.GetChannelConfiguration().Currency;
customer.Language = request.RequestContext.GetChannelConfiguration().DefaultLanguageId;
var getCustomerCreateRequest = new CreateCustomerRequest();
getCustomerCreateRequest.NewCustomer = customer;
var getCustomerCreateResponse = request.RequestContext.Execute<CreateCustomerResponse>(getCustomerCreateRequest);
if (getCustomerCreateResponse.CreatedCustomer != null)
{
//customer.ExtensionProperties.Add(new CommerceProperty() { Key = "BoardingPass", Value = request.Criteria.Keyword });
ParameterSet parameters = new ParameterSet();
parameters.Add("RecId", getCustomerCreateResponse.CreatedCustomer.RecordId);
parameters.Add("RefNoExt", request.Criteria.Keyword);
databaseContext2.ExecuteStoredProcedureNonQuery("[ext].UPDATECUSTOMEREXTENEDPROPERTIES", parameters);
CustomerSearchResult customersearchobj = new CustomerSearchResult()
{
PartyId = Convert.ToInt64(getCustomerCreateResponse.CreatedCustomer.DirectoryPartyRecordId)
};
customerSearchResult.Add(customersearchobj);
}
}
}
var getGlobalCustomersDataRequest = new GetGlobalCustomersByCustomerSearchResultsDataRequest(customerSearchResult);
var getGlobalCustomersDataResponse = request.RequestContext.ExecuteAsync<EntityDataServiceResponse<GlobalCustomer>>(getGlobalCustomersDataRequest);
PagedResult<GlobalCustomer> customers = getGlobalCustomersDataResponse.Result.PagedEntityCollection;
foreach (GlobalCustomer i in customers)
{
using (var databaseContext1 = new DatabaseContext(request.RequestContext))
{
ParameterSet configurationDataParameters1 = new ParameterSet
{
["@AccountNum"] = i.AccountNumber
};
var configurationDataSet = databaseContext1
.ExecuteQueryDataSet("SELECT RefNoExt from ax.CUSTTABLE where AccountNum = @AccountNum", configurationDataParameters1);
if (configurationDataSet.Tables[0].Rows.Count > 0 && configurationDataSet.Tables[0].Rows[0][0] != null)
{
i.ExtensionProperties.Add(new CommerceProperty() { Key = "RefNoExt", Value = configurationDataSet.Tables[0].Rows[0][0].ToString() });
}
else
{
i.ExtensionProperties.Add(new CommerceProperty() { Key = "RefNoExt", Value = "" });
}
}
}
return new CustomersSearchResponse(customers);
}
}
}
This class will be modified with this code
Code - CustomerSearchByFieldsServiceRequestHandler.cs
namespace Contoso
{
namespace Commerce.Runtime.CustomerSearchSample
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Dynamics.Commerce.Runtime;
using Microsoft.Dynamics.Commerce.Runtime.DataModel;
using Microsoft.Dynamics.Commerce.Runtime.Services.Messages;
using Microsoft.Dynamics.Commerce.Runtime.DataServices.Messages;
using Microsoft.Dynamics.Commerce.Runtime.Messages;
using Microsoft.Dynamics.Commerce.Runtime.Data;
/// <summary>
/// Custom customer search by fields service request handler.
/// </summary>
public sealed class CustomerSearchByFieldsServiceRequestHandler : SingleAsyncRequestHandler<CustomerSearchByFieldsServiceRequest>
{
/// <summary>
/// Executes the workflow to retrieve customer information.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>The response.</returns>
protected override async Task<Response> Process(CustomerSearchByFieldsServiceRequest request)
{
ThrowIf.Null(request, "request");
ThrowIf.Null(request.SearchByFieldCriteria, "request.SearchByFieldCriteria");
if (request.SearchByFieldCriteria.Criteria.IsNullOrEmpty())
{
throw new ArgumentException("request.Criteria.Criteria can't be empty.");
}
// Execute the original customer search logic here.
var getCustomerSearchResultsDataRequest = new GetCustomerSearchResultsDataRequest(request.SearchByFieldCriteria, request.QueryResultSettings);
var getCustomerSearchResultsDataResponse = await request.RequestContext.ExecuteAsync<EntityDataServiceResponse<CustomerSearchResult>>(getCustomerSearchResultsDataRequest).ConfigureAwait(false);
PagedResult<CustomerSearchResult> originalSearchResults = getCustomerSearchResultsDataResponse.PagedEntityCollection;
// Execute the custom customer search logic here.
var customSearchResultsawait = await this.ExternalCustomerSearch(request.SearchByFieldCriteria, request).ConfigureAwait(false);
PagedResult<CustomerSearchResult> customSearchResults = customSearchResultsawait;
// Merge the search results.
IEnumerable<CustomerSearchResult> mergedSearchResults = originalSearchResults.Union(customSearchResults).OrderByDescending(c => c.SearchRanking);
// Get the global customer data for the customer search results.
var getGlobalCustomersDataRequest = new GetGlobalCustomersByCustomerSearchResultsDataRequest(mergedSearchResults);
var getGlobalCustomersDataResponse = await request.RequestContext.ExecuteAsync<EntityDataServiceResponse<GlobalCustomer>>(getGlobalCustomersDataRequest).ConfigureAwait(false);
PagedResult<GlobalCustomer> customers = getGlobalCustomersDataResponse.PagedEntityCollection;
foreach (GlobalCustomer i in customers)
{
var query = new SqlPagedQuery(QueryResultSettings.SingleRecord)
{
DatabaseSchema = "ax",
Select = new ColumnSet(new string[] { "RefNoExt" }),
From = "CustTable",
Where = "AccountNum = @AccountNum"
};
query.Parameters["@AccountNum"] = i.AccountNumber;
using (var databaseContext = new DatabaseContext(request.RequestContext))
{
var extensionResponse = await databaseContext.ReadEntityAsync<ExtensionsEntity>(query).ConfigureAwait(false);
ExtensionsEntity extensions = extensionResponse.FirstOrDefault();
var boardingPass = extensions != null ? extensions.GetProperty("RefNoExt") : null;
if (boardingPass != null)
{
i.ExtensionProperties.Add(new CommerceProperty() { Key = "RefNoExt", Value = boardingPass.ToString() });
}
else
{
i.ExtensionProperties.Add(new CommerceProperty() { Key = "RefNoExt", Value = "" });
}
}
}
return new CustomerSearchByFieldsServiceResponse(customers);
}
/// <summary>
/// A placeholder method that represents a call to an external service or a custom implementation
/// of customer search.
/// </summary>
/// <param name="criteria">The criteria containing which customer fields to search.</param>
/// <returns>The response.</returns>
//private PagedResult<CustomerSearchResult> ExternalCustomerSearch(CustomerSearchByFieldCriteria criteria, CustomerSearchByFieldsServiceRequest request)
private async Task<PagedResult<CustomerSearchResult>> ExternalCustomerSearch(CustomerSearchByFieldCriteria criteria, CustomerSearchByFieldsServiceRequest request)
{
// This sample method will only append an additional customer search result if the search criteria contains
string externalSearchKeyword = "";
List<CustomerSearchResult> customerSearchResult = new List<CustomerSearchResult>();
if (string.IsNullOrEmpty(externalSearchKeyword))
{
string removeSteric = criteria?.Criteria?.FirstOrDefault()?.SearchTerm.Replace("*", "");
string removeSlash = removeSteric.Substring(1, removeSteric.Length - 1);
externalSearchKeyword = removeSlash.Replace("\\", "").Replace("\"", "");
var query = new SqlPagedQuery(QueryResultSettings.SingleRecord)
{
DatabaseSchema = "ax",
Select = new ColumnSet(new string[] { "PARTY" }),
From = "CustTable",
Where = "RefNoExt = @RefNoExt"
};
query.Parameters["@RefNoExt"] = externalSearchKeyword;
using (var databaseContext = new DatabaseContext(request.RequestContext))
{
var extensionResponse = await databaseContext.ReadEntityAsync<ExtensionsEntity>(query).ConfigureAwait(false);
ExtensionsEntity extensions = extensionResponse.FirstOrDefault();
var party = extensions != null ? extensions.GetProperty("PARTY") : null;
if (party != null)
{
CustomerSearchResult customersearchobj = new CustomerSearchResult()
{
PartyId = Convert.ToInt64(party),
};
customerSearchResult.Add(customersearchobj);
}
}
}
return customerSearchResult.AsPagedResult();
}
}
}
}
Build the project Runtime.Extensions.CustomerSearchSample.
Copy dll from
K:\RetailSDK\SampleExtensions\CommerceRuntime\Extensions.CustomerSearchSample\bin\Debug\netstandard2.0
Paste dll to
K:\RetailServer\WebRoot\bin\Ext
Now refresh, log in and search your custom field data
Now go to the transaction screen and search
Video Link
The End
Comments
Post a Comment