using System; using System.Linq; using System.Net.Http; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Sockeye.Models; using Sockeye.Util; namespace Sockeye.Biz { /// /// Process purchases that are from vendor notification /// Turn vendordata into fully filled out purchase /// attempt to match to existing customer or create one if necessary /// /// A Separate job will make licenses /// /// internal static class SockBotProcessPurchases { private static ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger("SockBotProcessPurchases"); private static DateTime lastSweep = DateTime.MinValue; private static TimeSpan PROCESS_EVERY_INTERVAL = new TimeSpan(0, 5, 10);//every 5 minutes roughly meaning 15 minutes down is highest fail state //////////////////////////////////////////////////////////////////////////////////////////////// // DoSweep // public static async Task DoWorkAsync() { //This will get triggered roughly every minute, but we don't want to check that frequently if (DateTime.UtcNow - lastSweep < PROCESS_EVERY_INTERVAL) return; if (ServerBootConfig.MIGRATING) return;//don't do this during migration (migration is one time only so can remove after up and running) log.LogDebug("Process purchases starting"); using (AyContext ct = Sockeye.Util.ServiceProviderProvider.DBContext) { //get a list of all active server ID's var ProcessablePurchaseIdList = await ct.Purchase .AsNoTracking() .Where(z => z.Processed == false) .OrderBy(z => z.Id) .Select(z => z.Id) .ToListAsync(); try { foreach (long purchaseId in ProcessablePurchaseIdList) { var biz = PurchaseBiz.GetBiz(ct); var p = await biz.GetAsync(purchaseId, false); if (p == null) { //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); log.LogError(err); } else { log.LogDebug($"Processing order {p.SalesOrderNumber}"); 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 //save changes p.Processed = true; await biz.PutAsync(p); } } } catch (Exception ex) { var err = "SockBotProcessPurchases error running job"; //serious issue requires immediate notification await NotifyEventHelper.AddOpsProblemEvent(err, ex); log.LogError(ex, err); } } lastSweep = DateTime.UtcNow; } ///////////////////////////////////////////////////////////////////// }//eoc }//eons