This commit is contained in:
@@ -195,7 +195,10 @@ namespace Sockeye.Biz
|
||||
{
|
||||
var CustomerName = jCustomer["name"].Value<string>();
|
||||
if (multiSite)
|
||||
{
|
||||
CustomerName += " - " + jSite["name"].Value<string>();
|
||||
log.LogInformation($"RFImport MULTISITE CUSTOMER: {CustomerName}");
|
||||
}
|
||||
long CurrentCustomerId = 0;
|
||||
|
||||
//Create customer if we don't have one already
|
||||
@@ -222,9 +225,12 @@ namespace Sockeye.Biz
|
||||
if (jSite["hosted"].Value<bool>() == true)
|
||||
c.Tags.Add("hosted");
|
||||
|
||||
var adminEmail = jCustomer["adminEmail"].Value<string>();
|
||||
if (!string.IsNullOrWhiteSpace(adminEmail))
|
||||
c.Notes += "\nAdmin Email: " + adminEmail;
|
||||
//In rockfish there were support emails that were people allowed to be contacting us on behalf of the customer
|
||||
var supportEmail = jCustomer["supportEmail"].Value<string>();
|
||||
if (!string.IsNullOrWhiteSpace(supportEmail))
|
||||
c.Notes += "\nSupport Emails: " + supportEmail;
|
||||
//in Rockfish the admin email is the main license related contact and technically the only person responsible to contact us
|
||||
//usually the same as the purchase email
|
||||
c.EmailAddress = jCustomer["adminEmail"].Value<string>();
|
||||
CustomerBiz biz = CustomerBiz.GetBiz(ct);
|
||||
var NewObject = await biz.CreateAsync(c);
|
||||
|
||||
@@ -13,11 +13,11 @@ namespace Sockeye.Biz
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Process purchases that are from vendor notification
|
||||
/// Process vendor notifications
|
||||
/// Turn vendordata into fully filled out purchase
|
||||
/// attempt to match to existing customer or create one if necessary
|
||||
///
|
||||
/// A Separate job will make licenses
|
||||
/// A Separate job will make licenses from the new purchases where feasible
|
||||
///
|
||||
/// </summary>
|
||||
internal static class SockBotProcessVendorNotifications
|
||||
@@ -39,9 +39,6 @@ namespace Sockeye.Biz
|
||||
log.LogDebug("Process vendor notifications starting");
|
||||
await ProcessVendorNotificationDataIntoPurchases();
|
||||
|
||||
// log.LogDebug("Process licenses from purchases starting");
|
||||
// await ProcessPurchasesIntoLicenses();
|
||||
|
||||
lastSweep = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
@@ -53,58 +50,43 @@ namespace Sockeye.Biz
|
||||
{
|
||||
|
||||
//get a list of all actionable vendor notifications
|
||||
var ProcessablePurchaseIdList = await ct.Purchase
|
||||
var vnList = await ct.VendorNotification
|
||||
.AsNoTracking()
|
||||
.Where(z => z.Processed == false
|
||||
&& z.ProductId == null)
|
||||
.Where(z => z.Processed == null)
|
||||
.OrderBy(z => z.Id)
|
||||
.Select(z => z.Id)
|
||||
.ToListAsync();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (long purchaseId in ProcessablePurchaseIdList)
|
||||
foreach (var vn in vnList)
|
||||
{
|
||||
var biz = PurchaseBiz.GetBiz(ct);
|
||||
var p = await biz.GetAsync(purchaseId, false);
|
||||
if (p == null)
|
||||
var p = new Purchase();
|
||||
|
||||
log.LogDebug($"Processing vendor notification {vn.Id}-{vn.Created}");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(vn.VendorData))
|
||||
{
|
||||
//this is a serious issue log and server ops it
|
||||
var err = $"SockBotProcessPurchases error running job, purchase record id {purchaseId} could not be fetched {biz.GetErrorsAsString}";
|
||||
await NotifyEventHelper.AddOpsProblemEvent(err);
|
||||
var err = $"VendorNotification record {vn.Id}-{vn.Created} has no vendor data";
|
||||
await NotifyEventHelper.AddOpsProblemEvent("SockBotProcessVendorNotifications: " + err);
|
||||
log.LogError(err);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.LogDebug($"Processing purchase {p.Id}-{p.PurchaseDate}");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(p.VendorData))
|
||||
{
|
||||
var err = $"Purchase record with ID {purchaseId} has no vendor data for sales order {p.SalesOrderNumber}";
|
||||
await NotifyEventHelper.AddOpsProblemEvent("SockBotProcessPurchases: " + err);
|
||||
log.LogError(err);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
//Parse json vendordata
|
||||
|
||||
//Existing customer or create new one?
|
||||
//here maybe need to match by vendor provided customer ID??
|
||||
//sometimes a user will make a new account for a new purchase but intend it as an addon to v7
|
||||
//for v8 it should be straightforward, however if pricing chagnes and new product needs to be purchased they may create a new record
|
||||
//same dbid for v8 should do the trick
|
||||
//Parse json vendordata
|
||||
await ParseVendorNotificationData(vn, ct, log);
|
||||
|
||||
//save changes
|
||||
p.Processed = true;
|
||||
await biz.PutAsync(p);
|
||||
|
||||
//save changes
|
||||
p.Processed = true;
|
||||
await biz.PutAsync(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var err = "SockBotProcessPurchases error running job";
|
||||
var err = "SockBotProcessVendorNotifications error running job";
|
||||
//serious issue requires immediate notification
|
||||
await NotifyEventHelper.AddOpsProblemEvent(err, ex);
|
||||
log.LogError(ex, err);
|
||||
@@ -134,26 +116,50 @@ namespace Sockeye.Biz
|
||||
//CUSTOMER create or locate
|
||||
var jCustomerName = jData["order_notification"]["purchase"]["customer_data"]["reg_name"].Value<string>() ?? throw new System.FormatException($"Vendor data empty reg_name:{vn.VendorData}");
|
||||
var jCustomerEmail = jData["order_notification"]["purchase"]["customer_data"]["delivery_contact"]["email"].Value<string>() ?? throw new System.FormatException($"Vendor data empty email:{vn.VendorData}");
|
||||
|
||||
var jCustomerAccountNumber = jData["order_notification"]["purchase"]["customer_data"]["shopper_id"].Value<string>();//appears to be mycommerce customer id number hopefully static between orders
|
||||
|
||||
var customerBiz = CustomerBiz.GetBiz(ct);
|
||||
|
||||
Customer c = await ct.Customer.FirstOrDefaultAsync(z => z.Name == jCustomerName) ?? await ct.Customer.FirstOrDefaultAsync(z => z.EmailAddress == jCustomerEmail);
|
||||
//attempt to match to existing customer
|
||||
//account number is most ideal match, name second but could be multiple in sockeye from rockfish sites so name will start the same, finally email if nothing else
|
||||
Customer c = await ct.Customer.FirstOrDefaultAsync(z => z.AccountNumber == jCustomerAccountNumber) ?? await ct.Customer.FirstOrDefaultAsync(z => z.Name.StartsWith(jCustomerName)) ?? await ct.Customer.FirstOrDefaultAsync(z => z.EmailAddress == jCustomerEmail);
|
||||
if (c == null)
|
||||
{
|
||||
//New customer
|
||||
c = new Customer();
|
||||
|
||||
c.Name = jCustomerName;
|
||||
UpdateCustomerFromVendorData(jData, jCustomerEmail, c);
|
||||
c.EmailAddress = jCustomerEmail;
|
||||
c.AccountNumber = jCustomerAccountNumber;
|
||||
UpdateCustomerFromVendorData(jData, c);
|
||||
c = await customerBiz.CreateAsync(c);
|
||||
if (c == null)
|
||||
throw new System.ApplicationException($"Error creating new Customer: {customerBiz.GetErrorsAsString()} vendor data :{vn.VendorData}");
|
||||
}
|
||||
else
|
||||
{
|
||||
//existing customer, refresh it
|
||||
UpdateCustomerFromVendorData(jData, jCustomerEmail, c);
|
||||
//existing customer
|
||||
//here there could be several potential issues:
|
||||
//name differs because it was a separate site in rockfish, it's not cool to change the name
|
||||
//email differs, this can happen and is ok
|
||||
//account number differs if was empty then it's ok. If it wasn't empty and it differs this is a potential problem:
|
||||
//
|
||||
if (c.EmailAddress != jCustomerEmail)
|
||||
{
|
||||
c.EmailAddress = jCustomerEmail;//assume it was empty or has been recently updated
|
||||
}
|
||||
|
||||
if (c.AccountNumber != jCustomerAccountNumber)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(c.AccountNumber))
|
||||
c.AccountNumber=jCustomerAccountNumber;//this is ok, there wasn't an account number before so we're just adding it
|
||||
else{
|
||||
// this is problematic, it matched but for some reason the account numbers differ, there's no safe way to process this so alert and bail
|
||||
throw new System.ApplicationException($"Not processed due to error updating existing Customer: {c.Name} Account numbers differ, expected: {c.AccountNumber} vendor data:{vn.VendorData}");
|
||||
}
|
||||
}
|
||||
|
||||
//refresh
|
||||
UpdateCustomerFromVendorData(jData, c);
|
||||
c = await customerBiz.PutAsync(c);
|
||||
if (c == null)
|
||||
throw new System.ApplicationException($"Error updating existing Customer: {customerBiz.GetErrorsAsString()} vendor data :{vn.VendorData}");
|
||||
@@ -167,24 +173,23 @@ namespace Sockeye.Biz
|
||||
//ok, turn this into a fully realized Purchase record
|
||||
|
||||
//Product group
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var err = $"ParseVendorNotificationData: Purchase record {vn.Id}-{vn.PurchaseDate} triggered exception, see log";
|
||||
var err = $"ParseVendorNotificationData: Purchase record {vn.Id}-{vn.Created} triggered exception, see log";
|
||||
await NotifyEventHelper.AddOpsProblemEvent(err);//notify, this is serious
|
||||
log.LogError(ex, err);
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateCustomerFromVendorData(JObject jData, string jCustomerEmail, Customer c)
|
||||
private static void UpdateCustomerFromVendorData(JObject jData, Customer c)
|
||||
{
|
||||
c.EmailAddress = jCustomerEmail;
|
||||
c.Active = true;//if they just made a purchase they are active even if they weren't before
|
||||
c.DoNotContact = false;//if they just made a purchase they are contactable even if they weren't before
|
||||
c.AccountNumber = jData["order_notification"]["purchase"]["customer_data"]["shopper_id"].Value<string>();//appears to be mycommerce customer id number hopefully static between orders
|
||||
c.Address = c.PostAddress = jData["order_notification"]["purchase"]["customer_data"]["delivery_contact"]["address"]["street1"].Value<string>();
|
||||
c.City = c.PostCity = jData["order_notification"]["purchase"]["customer_data"]["delivery_contact"]["address"]["city"].Value<string>();
|
||||
c.Region = c.PostRegion = jData["order_notification"]["purchase"]["customer_data"]["delivery_contact"]["address"]["state"].Value<string>();
|
||||
@@ -201,6 +206,7 @@ namespace Sockeye.Biz
|
||||
c.Notes += "\n";
|
||||
c.Notes += $"Purchase contact:{firstName} {lastName}, language: {language}\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user