This commit is contained in:
@@ -50,33 +50,18 @@ namespace Sockeye.Api.Controllers
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
try
|
||||
{
|
||||
//do stuff with the notification
|
||||
(string username, string password) = Sockeye.Util.AutoOrderProcessingUtil.GetUsernameAndPasswordFromAuthorizeHeader(Authorization);
|
||||
// Now use username and password with whatever authentication process you want
|
||||
{
|
||||
(string username, string password) = Sockeye.Util.AutoOrderProcessingUtil.GetUsernameAndPasswordFromAuthorizeHeader(Authorization);
|
||||
if (username == "Y24PYYDQSA1L12905N5MKU" && password == "MA8GMQK2PC3FDNT1RTR68R")
|
||||
{
|
||||
//put the jobject notification into the db as json string freeform notification information
|
||||
//to be processed by other code later. i.e. just capture it as is cleanly and don't bother trying to do anything fancy here this should be tight and focused and side effect free
|
||||
|
||||
|
||||
//although...on second thought it could just make a purchase record with some sort of state of unprocessed so a job could swing by and process it or we could
|
||||
//do that manually so then there would be no need for extra UI and stuff, and it wont' conflict with the need to process immediately and lightly here
|
||||
//i.e. two stage: one is to make the record barebones for purchase then a job comes along and turns it into a real purchase
|
||||
//also add error handling here iwth proper notification see trial request code so we get notified on error
|
||||
//and don't return OK / 200 unless the order is stored successfully in db as shareit will retry until it's successful several times, see the link below for deets
|
||||
//Need to be able to make a manual purchase record with almost nothing more than the vendor notifciation text so can recover if auto system fails and for testing
|
||||
|
||||
{
|
||||
//save it to the database
|
||||
var Purchase = new Purchase();
|
||||
Purchase.PurchaseDate = DateTime.UtcNow;//this is kind of fucky, what if the order takes more than a day to arrive? I guess fixup from the vendordata later
|
||||
Purchase.VendorId = 1;//MyCommerce/shareit is vendor 1, for now that's all that's needed
|
||||
Purchase.VendorData = j.ToString();
|
||||
await ct.Purchase.AddAsync(Purchase);
|
||||
var vn = new VendorNotification();
|
||||
vn.Created = DateTime.UtcNow;
|
||||
vn.VendorId = 1;//MyCommerce/shareit is vendor 1, for now that's all that's needed
|
||||
vn.VendorData = j.ToString();
|
||||
await ct.VendorNotification.AddAsync(vn);
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -84,7 +69,7 @@ namespace Sockeye.Api.Controllers
|
||||
await NotifyEventHelper.AddOpsProblemEvent("OrderController/shareit - Exception processing vendor notification, see log");
|
||||
return StatusCode(503);//ask it to retry again later
|
||||
}
|
||||
return Ok("ok");//shareit robot looks for an OK response to know if it should resend or not https://account.mycommerce.com/home/wiki/7479805
|
||||
return Ok("ok");//shareit notifier looks for an OK response to know if it should resend or not https://account.mycommerce.com/home/wiki/7479805
|
||||
}
|
||||
//------------
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Sockeye.DataList
|
||||
|
||||
var RoleSet = BizRoles.GetRoleSet(DefaultListAType);
|
||||
AllowedRoles = RoleSet.ReadFullRecord | RoleSet.Change;
|
||||
DefaultColumns = new List<string>() { "PurchaseDate", "PurchaseSalesOrderNumber", "Customer", "Product", "PurchaseProcessed" };
|
||||
DefaultColumns = new List<string>() { "PurchaseDate", "PurchaseSalesOrderNumber", "Customer", "Product", "PurchaseProcessed", "PurchaseVendorNotificationId" };
|
||||
DefaultSortBy = new Dictionary<string, string>() { { "PurchaseDate", "-" } };
|
||||
FieldDefinitions = new List<DataListFieldDefinition>();
|
||||
|
||||
@@ -50,6 +50,16 @@ namespace Sockeye.DataList
|
||||
SqlValueColumnName = "avendor.name"
|
||||
});
|
||||
|
||||
FieldDefinitions.Add(new DataListFieldDefinition
|
||||
{
|
||||
TKey = "PurchaseVendorNotificationId",
|
||||
FieldKey = "PurchaseVendorNotificationId",
|
||||
SockType = (int)SockType.VendorNotification,
|
||||
UiFieldDataType = (int)UiFieldDataType.Integer,
|
||||
SqlIdColumnName = "apurchase.vendornotificationid",
|
||||
SqlValueColumnName = "apurchase.vendornotificationid"
|
||||
});
|
||||
|
||||
FieldDefinitions.Add(new DataListFieldDefinition
|
||||
{
|
||||
TKey = "Product",
|
||||
|
||||
39
server/DataList/VendorNotificationDataList.cs
Normal file
39
server/DataList/VendorNotificationDataList.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
using Sockeye.Biz;
|
||||
|
||||
namespace Sockeye.DataList
|
||||
{
|
||||
internal class VendorNotificationDataList : DataListProcessingBase
|
||||
{
|
||||
public VendorNotificationDataList(long translationId)
|
||||
{
|
||||
DefaultListAType = SockType.VendorNotification;
|
||||
SQLFrom = @"FROM avendornotification ";
|
||||
|
||||
var RoleSet = BizRoles.GetRoleSet(DefaultListAType);
|
||||
AllowedRoles = RoleSet.ReadFullRecord | RoleSet.Change;
|
||||
DefaultColumns = new List<string>() { "VendorNotificationCreated", "VendorNotificationProcessed" };
|
||||
DefaultSortBy = new Dictionary<string, string>() { { "VendorNotificationCreated", "-" } };
|
||||
FieldDefinitions = new List<DataListFieldDefinition>();
|
||||
|
||||
FieldDefinitions.Add(new DataListFieldDefinition
|
||||
{
|
||||
TKey = "VendorNotificationCreated",
|
||||
FieldKey = "VendorNotificationSalesOrderNumber",
|
||||
SockType = (int)SockType.VendorNotification,
|
||||
UiFieldDataType = (int)UiFieldDataType.DateTime,
|
||||
SqlIdColumnName = "avendornotification.id",
|
||||
SqlValueColumnName = "avendornotification.created",
|
||||
IsRowId = true
|
||||
});
|
||||
|
||||
FieldDefinitions.Add(new DataListFieldDefinition
|
||||
{
|
||||
TKey = "VendorNotificationProcessed",
|
||||
FieldKey = "VendorNotificationProcessed",
|
||||
UiFieldDataType = (int)UiFieldDataType.DateTime,
|
||||
SqlValueColumnName = "avendornotification.processed"
|
||||
});
|
||||
}
|
||||
}//eoc
|
||||
}//eons
|
||||
@@ -59,6 +59,8 @@ namespace Sockeye.Biz
|
||||
return await ct.SubscriptionServer.AnyAsync(z => z.Id == id);
|
||||
case SockType.Purchase:
|
||||
return await ct.Purchase.AnyAsync(z => z.Id == id);
|
||||
case SockType.VendorNotification:
|
||||
return await ct.VendorNotification.AnyAsync(z => z.Id == id);
|
||||
case SockType.Product:
|
||||
return await ct.Product.AnyAsync(z => z.Id == id);
|
||||
case SockType.GZCase:
|
||||
|
||||
@@ -61,6 +61,8 @@ namespace Sockeye.Biz
|
||||
return new SubscriptionServerBiz(ct, userId, translationId, roles);
|
||||
case SockType.Purchase:
|
||||
return new PurchaseBiz(ct, userId, translationId, roles);
|
||||
case SockType.VendorNotification:
|
||||
return new VendorNotificationBiz(ct, userId, translationId, roles);
|
||||
case SockType.Product:
|
||||
return new ProductBiz(ct, userId, translationId, roles);
|
||||
case SockType.GZCase:
|
||||
|
||||
@@ -512,7 +512,7 @@ namespace Sockeye.Biz
|
||||
});
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////
|
||||
//LICENSE
|
||||
//
|
||||
roles.Add(SockType.Vendor, new BizRoleSet()
|
||||
@@ -598,6 +598,23 @@ namespace Sockeye.Biz
|
||||
Select = AuthorizationRoles.All
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//VENDOR NOTIFICATION
|
||||
//
|
||||
roles.Add(SockType.VendorNotification, new BizRoleSet()
|
||||
{
|
||||
Change = AuthorizationRoles.BizAdmin
|
||||
| AuthorizationRoles.Service
|
||||
| AuthorizationRoles.Sales
|
||||
| AuthorizationRoles.Accounting,
|
||||
ReadFullRecord = AuthorizationRoles.BizAdminRestricted
|
||||
| AuthorizationRoles.ServiceRestricted
|
||||
| AuthorizationRoles.Tech
|
||||
| AuthorizationRoles.SalesRestricted
|
||||
,
|
||||
Select = AuthorizationRoles.All
|
||||
});
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//PRODUCT
|
||||
//
|
||||
@@ -648,23 +665,23 @@ namespace Sockeye.Biz
|
||||
|
||||
//GENERATE CLIENT COMPATIBLE JSON FROM ROLES OUTPUT TO DEBUG LOG
|
||||
//And seperately, set the JSON variable so can copy from debug variable "value" property for lastRoles here to compare
|
||||
|
||||
|
||||
|
||||
/*
|
||||
string json = Newtonsoft.Json.JsonConvert.SerializeObject(roles, Newtonsoft.Json.Formatting.None);
|
||||
System.Diagnostics.Debugger.Log(1, "JSONFRAGMENTFORCLIENT", "BizRoles.cs -> biz-role-rights.js Client roles JSON fragment:\n\n");
|
||||
System.Diagnostics.Debugger.Log(1, "JSONFRAGMENTFORCLIENT", json + "\n\n");
|
||||
var lastRoles = "{\"Customer\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"CustomerNote\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"CustomerNotifySubscription\":{\"Change\":10,\"ReadFullRecord\":65797,\"Select\":131071},\"HeadOffice\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"Global\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"GlobalOps\":{\"Change\":16384,\"ReadFullRecord\":8192,\"Select\":0},\"User\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"UserOptions\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"ServerState\":{\"Change\":16384,\"ReadFullRecord\":131071,\"Select\":0},\"LogFile\":{\"Change\":0,\"ReadFullRecord\":24576,\"Select\":0},\"Backup\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"FileAttachment\":{\"Change\":2,\"ReadFullRecord\":3,\"Select\":0},\"ServerJob\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"OpsNotificationSettings\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"ServerMetrics\":{\"Change\":16384,\"ReadFullRecord\":24576,\"Select\":0},\"Translation\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"DataListSavedFilter\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"FormUserOptions\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"FormCustom\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"PickListTemplate\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"BizMetrics\":{\"Change\":2,\"ReadFullRecord\":98369,\"Select\":0},\"Notification\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"NotifySubscription\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"Report\":{\"Change\":3,\"ReadFullRecord\":131071,\"Select\":131071},\"Memo\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Reminder\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Review\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Integration\":{\"Change\":49514,\"ReadFullRecord\":49514,\"Select\":49514},\"License\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"TrialLicenseRequest\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"SubscriptionServer\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"Purchase\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"Product\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"GZCase\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071}}";
|
||||
Dictionary<SockType, BizRoleSet> lastRolesDeserialized = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<SockType, BizRoleSet>>(lastRoles);
|
||||
if (lastRolesDeserialized.Count != roles.Count)
|
||||
{
|
||||
|
||||
{
|
||||
((ILogger)Sockeye.Util.ApplicationLogging.CreateLogger("BizRoles.cs")).LogWarning("BizRoles::Constructor - roles were modified from last snapshot for client!!!");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
string json = Newtonsoft.Json.JsonConvert.SerializeObject(roles, Newtonsoft.Json.Formatting.None);
|
||||
System.Diagnostics.Debugger.Log(1, "JSONFRAGMENTFORCLIENT", "BizRoles.cs -> biz-role-rights.js Client roles JSON fragment:\n\n");
|
||||
System.Diagnostics.Debugger.Log(1, "JSONFRAGMENTFORCLIENT", json + "\n\n");
|
||||
var lastRoles = "{\"Customer\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"CustomerNote\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"CustomerNotifySubscription\":{\"Change\":10,\"ReadFullRecord\":65797,\"Select\":131071},\"HeadOffice\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"Global\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"GlobalOps\":{\"Change\":16384,\"ReadFullRecord\":8192,\"Select\":0},\"User\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"UserOptions\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":0},\"ServerState\":{\"Change\":16384,\"ReadFullRecord\":131071,\"Select\":0},\"LogFile\":{\"Change\":0,\"ReadFullRecord\":24576,\"Select\":0},\"Backup\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"FileAttachment\":{\"Change\":2,\"ReadFullRecord\":3,\"Select\":0},\"ServerJob\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"OpsNotificationSettings\":{\"Change\":16384,\"ReadFullRecord\":8195,\"Select\":0},\"ServerMetrics\":{\"Change\":16384,\"ReadFullRecord\":24576,\"Select\":0},\"Translation\":{\"Change\":2,\"ReadFullRecord\":1,\"Select\":131071},\"DataListSavedFilter\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"FormUserOptions\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"FormCustom\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"PickListTemplate\":{\"Change\":2,\"ReadFullRecord\":131071,\"Select\":0},\"BizMetrics\":{\"Change\":2,\"ReadFullRecord\":98369,\"Select\":0},\"Notification\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"NotifySubscription\":{\"Change\":131071,\"ReadFullRecord\":131071,\"Select\":0},\"Report\":{\"Change\":3,\"ReadFullRecord\":131071,\"Select\":131071},\"Memo\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Reminder\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Review\":{\"Change\":124927,\"ReadFullRecord\":124927,\"Select\":124927},\"Integration\":{\"Change\":49514,\"ReadFullRecord\":49514,\"Select\":49514},\"License\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"TrialLicenseRequest\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"SubscriptionServer\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"Purchase\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"Product\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071},\"GZCase\":{\"Change\":32842,\"ReadFullRecord\":65797,\"Select\":131071}}";
|
||||
Dictionary<SockType, BizRoleSet> lastRolesDeserialized = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<SockType, BizRoleSet>>(lastRoles);
|
||||
if (lastRolesDeserialized.Count != roles.Count)
|
||||
{
|
||||
|
||||
{
|
||||
((ILogger)Sockeye.Util.ApplicationLogging.CreateLogger("BizRoles.cs")).LogWarning("BizRoles::Constructor - roles were modified from last snapshot for client!!!");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -379,7 +379,7 @@ namespace Sockeye.Biz
|
||||
l.Add(new FormField { TKey = "PurchaseCancelDate", FieldKey = "PurchaseCancelDate" });
|
||||
l.Add(new FormField { TKey = "PurchaseCouponCode", FieldKey = "PurchaseCouponCode" });
|
||||
l.Add(new FormField { TKey = "PurchaseNotes", FieldKey = "PurchaseNotes" });
|
||||
l.Add(new FormField { TKey = "PurchaseVendorData", FieldKey = "PurchaseVendorData" });
|
||||
l.Add(new FormField { TKey = "PurchaseVendorNotificationId", FieldKey = "PurchaseVendorNotificationId" });
|
||||
l.Add(new FormField { TKey = "PurchaseProcessed", FieldKey = "PurchaseProcessed" });
|
||||
|
||||
l.Add(new FormField { TKey = "Tags", FieldKey = "Tags" });
|
||||
@@ -391,6 +391,7 @@ namespace Sockeye.Biz
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region SubscriptionServer
|
||||
{
|
||||
List<FormField> l = new List<FormField>();
|
||||
|
||||
@@ -336,28 +336,19 @@ namespace Sockeye.Biz
|
||||
},
|
||||
*/
|
||||
|
||||
var jData = JObject.Parse(jVendorNotificationItem["data"].Value<string>());
|
||||
var salesOrderNumber = jData["order_notification"]["purchase"]["purchase_id"].Value<string>();
|
||||
var p = await ct.Purchase.FirstOrDefaultAsync(z => z.SalesOrderNumber == salesOrderNumber);
|
||||
if (p == null)
|
||||
{
|
||||
//this is only test orders no real orders hit here
|
||||
// log.LogError($"RFImport Vendor notifications can't match sales order number {salesOrderNumber}");
|
||||
// log.LogError(jData["order_notification"].ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(p.VendorData))
|
||||
p.VendorData += ",\n";
|
||||
p.VendorData += jVendorNotificationItem["data"].Value<string>();
|
||||
await ct.SaveChangesAsync();
|
||||
var vn = new VendorNotification();
|
||||
vn.Created = DateUtil.EpochToDateNullIsMin(jVendorNotificationItem["dtCreated"].Value<long>());
|
||||
vn.VendorId = 1;
|
||||
vn.VendorData = jVendorNotificationItem["data"].Value<string>();
|
||||
vn.Processed = vn.Created;//indicate it's been processed
|
||||
await ct.SaveChangesAsync();
|
||||
|
||||
#if (DEBUG)
|
||||
//Test dev stuff
|
||||
//Test dev stuff
|
||||
#warning DEV TEST ORDER PROCESSING REMOVE THIS WHEN DONE
|
||||
await SockBotProcessPurchases.ParseVendorNotificationData(p, ct);
|
||||
await SockBotProcessVendorNotifications.ParseVendorNotificationData(vn, ct, log);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}// all vendor notifications loop
|
||||
}
|
||||
|
||||
@@ -263,8 +263,8 @@ namespace Sockeye.Biz
|
||||
await SockBotSubscriptionServerHealthChecks.DoWorkAsync();
|
||||
if (!KeepOnWorking()) return;
|
||||
|
||||
//SOCKBOT - PROCESS PURCHASES
|
||||
await SockBotProcessPurchases.DoWorkAsync();
|
||||
//SOCKBOT - PROCESS VENDOR NOTIFICATIONS
|
||||
await SockBotProcessVendorNotifications.DoWorkAsync();
|
||||
if (!KeepOnWorking()) return;
|
||||
|
||||
//JOB SWEEPER
|
||||
|
||||
@@ -193,8 +193,7 @@ namespace Sockeye.Biz
|
||||
.AddText(obj.CouponCode)
|
||||
.AddText(obj.Wiki)
|
||||
.AddText(obj.Tags)
|
||||
.AddText(obj.Notes)
|
||||
.AddText(obj.VendorData);
|
||||
.AddText(obj.Notes);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -270,7 +269,7 @@ namespace Sockeye.Biz
|
||||
{
|
||||
vc.Add(await ct.Vendor.AsNoTracking().Where(x => x.Id == o.VendorId).Select(x => x.Name).FirstOrDefaultAsync(), "vendor", o.VendorId);
|
||||
}
|
||||
o.VendorViz = vc.Get("vendor", o.CustomerId);
|
||||
o.VendorViz = vc.Get("vendor", o.VendorId);
|
||||
|
||||
|
||||
if (!vc.Has("product", o.ProductId))
|
||||
@@ -441,7 +440,7 @@ namespace Sockeye.Biz
|
||||
{
|
||||
|
||||
//# NEW PURCHASE VENDOR NOTIFICATION
|
||||
if (ayaEvent == SockEvent.Created && (!string.IsNullOrWhiteSpace(o.VendorData)))
|
||||
if (ayaEvent == SockEvent.Created)
|
||||
{
|
||||
//Get product name and get customer name to notify
|
||||
var productName = await ct.Product.AsNoTracking().Where(x => x.Id == o.ProductId).Select(x => x.Name).FirstOrDefaultAsync();
|
||||
|
||||
@@ -75,7 +75,9 @@ namespace Sockeye.Biz
|
||||
[CoreBizObject, ReportableBizObject]
|
||||
Product = 97,
|
||||
[CoreBizObject, ReportableBizObject]
|
||||
GZCase = 98
|
||||
GZCase = 98,
|
||||
[CoreBizObject, ReportableBizObject]
|
||||
VendorNotification = 99
|
||||
|
||||
|
||||
|
||||
|
||||
416
server/biz/VendorNotificationBiz.cs
Normal file
416
server/biz/VendorNotificationBiz.cs
Normal file
@@ -0,0 +1,416 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Linq;
|
||||
using Sockeye.Util;
|
||||
using Sockeye.Api.ControllerHelpers;
|
||||
using Sockeye.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Sockeye.Biz
|
||||
{
|
||||
internal class VendorNotificationBiz : BizObject, IJobObject, ISearchAbleObject, IReportAbleObject, IExportAbleObject, INotifiableObject
|
||||
{
|
||||
internal VendorNotificationBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
|
||||
{
|
||||
ct = dbcontext;
|
||||
UserId = currentUserId;
|
||||
UserTranslationId = userTranslationId;
|
||||
CurrentUserRoles = UserRoles;
|
||||
BizType = SockType.VendorNotification;
|
||||
}
|
||||
|
||||
internal static VendorNotificationBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null)
|
||||
{
|
||||
if (httpContext != null)
|
||||
return new VendorNotificationBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items));
|
||||
else
|
||||
return new VendorNotificationBiz(ct, 1, ServerBootConfig.SOCKEYE_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdmin);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//EXISTS
|
||||
internal async Task<bool> ExistsAsync(long id)
|
||||
{
|
||||
return await ct.VendorNotification.AnyAsync(z => z.Id == id);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//CREATE
|
||||
//
|
||||
internal async Task<VendorNotification> CreateAsync(VendorNotification newObject)
|
||||
{
|
||||
await ValidateAsync(newObject, null);
|
||||
if (HasErrors)
|
||||
return null;
|
||||
else
|
||||
{
|
||||
await ct.VendorNotification.AddAsync(newObject);
|
||||
await ct.SaveChangesAsync();
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, newObject.Id, BizType, SockEvent.Created), ct);
|
||||
await SearchIndexAsync(newObject, true);
|
||||
await HandlePotentialNotificationEvent(SockEvent.Created, newObject);
|
||||
return newObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//GET
|
||||
//
|
||||
internal async Task<VendorNotification> GetAsync(long id, bool logTheGetEvent = true)
|
||||
{
|
||||
var ret = await ct.VendorNotification.AsNoTracking().SingleOrDefaultAsync(z => z.Id == id);
|
||||
if (logTheGetEvent && ret != null)
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, id, BizType, SockEvent.Retrieved), ct);
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//UPDATE
|
||||
//
|
||||
internal async Task<VendorNotification> PutAsync(VendorNotification putObject)
|
||||
{
|
||||
var dbObject = await GetAsync(putObject.Id, false);
|
||||
if (dbObject == null)
|
||||
{
|
||||
AddError(ApiErrorCode.NOT_FOUND, "id");
|
||||
return null;
|
||||
}
|
||||
if (dbObject.Concurrency != putObject.Concurrency)
|
||||
{
|
||||
AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
|
||||
return null;
|
||||
}
|
||||
|
||||
await ValidateAsync(putObject, dbObject);
|
||||
if (HasErrors) return null;
|
||||
ct.Replace(dbObject, putObject);
|
||||
try
|
||||
{
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!await ExistsAsync(putObject.Id))
|
||||
AddError(ApiErrorCode.NOT_FOUND);
|
||||
else
|
||||
AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
|
||||
return null;
|
||||
}
|
||||
await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, putObject.Id, BizType, SockEvent.Modified), ct);
|
||||
await SearchIndexAsync(putObject, false);
|
||||
await HandlePotentialNotificationEvent(SockEvent.Modified, putObject, dbObject);
|
||||
return putObject;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//DELETE
|
||||
//
|
||||
internal async Task<bool> DeleteAsync(long id)
|
||||
{
|
||||
using (var transaction = await ct.Database.BeginTransactionAsync())
|
||||
{
|
||||
|
||||
VendorNotification dbObject = await GetAsync(id, false);
|
||||
if (dbObject == null)
|
||||
{
|
||||
AddError(ApiErrorCode.NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
await ValidateCanDeleteAsync(dbObject);
|
||||
if (HasErrors)
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
var IDList = await ct.Review.AsNoTracking().Where(x => x.SockType == SockType.VendorNotification && x.ObjectId == id).Select(x => x.Id).ToListAsync();
|
||||
if (IDList.Count() > 0)
|
||||
{
|
||||
ReviewBiz b = new ReviewBiz(ct, UserId, UserTranslationId, CurrentUserRoles);
|
||||
foreach (long ItemId in IDList)
|
||||
if (!await b.DeleteAsync(ItemId, transaction))
|
||||
{
|
||||
AddError(ApiErrorCode.CHILD_OBJECT_ERROR, null, $"Review [{ItemId}]: {b.GetErrorsAsString()}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ct.VendorNotification.Remove(dbObject);
|
||||
await ct.SaveChangesAsync();
|
||||
|
||||
//Log event
|
||||
await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObject.Id, dbObject.Name, ct);
|
||||
await Search.ProcessDeletedObjectKeywordsAsync(dbObject.Id, BizType, ct);
|
||||
await FileUtil.DeleteAttachmentsForObjectAsync(BizType, dbObject.Id, ct);
|
||||
await transaction.CommitAsync();
|
||||
await HandlePotentialNotificationEvent(SockEvent.Deleted, dbObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//SEARCH
|
||||
//
|
||||
private async Task SearchIndexAsync(VendorNotification obj, bool isNew)
|
||||
{
|
||||
var SearchParams = new Search.SearchIndexProcessObjectParameters(UserTranslationId, obj.Id, BizType);
|
||||
DigestSearchText(obj, SearchParams);
|
||||
if (isNew)
|
||||
await Search.ProcessNewObjectKeywordsAsync(SearchParams);
|
||||
else
|
||||
await Search.ProcessUpdatedObjectKeywordsAsync(SearchParams);
|
||||
}
|
||||
|
||||
public async Task<Search.SearchIndexProcessObjectParameters> GetSearchResultSummary(long id, SockType specificType)
|
||||
{
|
||||
var obj = await GetAsync(id, false);
|
||||
var SearchParams = new Search.SearchIndexProcessObjectParameters();
|
||||
DigestSearchText(obj, SearchParams);
|
||||
return SearchParams;
|
||||
}
|
||||
|
||||
public void DigestSearchText(VendorNotification obj, Search.SearchIndexProcessObjectParameters searchParams)
|
||||
{
|
||||
if (obj != null)
|
||||
searchParams.AddText(obj.VendorData);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//VALIDATION
|
||||
//
|
||||
|
||||
private async Task ValidateAsync(VendorNotification proposedObj, VendorNotification currentObj)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private async Task ValidateCanDeleteAsync(VendorNotification inObj)
|
||||
{
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//REPORTING
|
||||
//
|
||||
public async Task<JArray> GetReportData(DataListSelectedRequest dataListSelectedRequest, Guid jobId)
|
||||
{
|
||||
var idList = dataListSelectedRequest.SelectedRowIds;
|
||||
JArray ReportData = new JArray();
|
||||
while (idList.Any())
|
||||
{
|
||||
var batch = idList.Take(IReportAbleObject.REPORT_DATA_BATCH_SIZE);
|
||||
idList = idList.Skip(IReportAbleObject.REPORT_DATA_BATCH_SIZE).ToArray();
|
||||
|
||||
//query for this batch, comes back in db natural order unfortunately
|
||||
var batchResults = await ct.VendorNotification.AsNoTracking().Where(z => batch.Contains(z.Id)).ToArrayAsync();
|
||||
|
||||
//order the results back into original
|
||||
//What is happening here:
|
||||
//for performance the query is batching a bunch at once by fetching a block of items from the sql server
|
||||
//however it's returning in db order which is often not the order the id list is in
|
||||
//so it needs to be sorted back into the same order as the ide list
|
||||
//This would not be necessary if just fetching each one at a time individually (like in workorder get report data)
|
||||
|
||||
var orderedList = from id in batch join z in batchResults on id equals z.Id select z;
|
||||
batchResults = null;
|
||||
|
||||
foreach (VendorNotification w in orderedList)
|
||||
{
|
||||
if (!ReportRenderManager.KeepGoing(jobId)) return null;
|
||||
await PopulateVizFields(w);
|
||||
var jo = JObject.FromObject(w);
|
||||
|
||||
ReportData.Add(jo);
|
||||
}
|
||||
orderedList = null;
|
||||
}
|
||||
vc.Clear();
|
||||
return ReportData;
|
||||
}
|
||||
private VizCache vc = new VizCache();
|
||||
|
||||
|
||||
//populate viz fields from provided object
|
||||
private async Task PopulateVizFields(VendorNotification o)
|
||||
{
|
||||
|
||||
if (!vc.Has("vendor", o.VendorId))
|
||||
{
|
||||
vc.Add(await ct.Vendor.AsNoTracking().Where(x => x.Id == o.VendorId).Select(x => x.Name).FirstOrDefaultAsync(), "vendor", o.VendorId);
|
||||
}
|
||||
o.VendorViz = vc.Get("vendor", o.VendorId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// IMPORT EXPORT
|
||||
//
|
||||
|
||||
public async Task<JArray> GetExportData(DataListSelectedRequest dataListSelectedRequest, Guid jobId)
|
||||
{
|
||||
return await GetReportData(dataListSelectedRequest, jobId);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//JOB / OPERATIONS
|
||||
//
|
||||
public async Task HandleJobAsync(OpsJob job)
|
||||
{
|
||||
//Hand off the particular job to the corresponding processing code
|
||||
//NOTE: If this code throws an exception the caller (JobsBiz::ProcessJobsAsync) will automatically set the job to failed and log the exeption so
|
||||
//basically any error condition during job processing should throw up an exception if it can't be handled
|
||||
switch (job.JobType)
|
||||
{
|
||||
case JobType.BatchCoreObjectOperation:
|
||||
await ProcessBatchJobAsync(job);
|
||||
break;
|
||||
default:
|
||||
throw new System.ArgumentOutOfRangeException($"VendorNotificationBiz.HandleJob-> Invalid job type{job.JobType.ToString()}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async Task ProcessBatchJobAsync(OpsJob job)
|
||||
{
|
||||
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Running);
|
||||
await JobsBiz.LogJobAsync(job.GId, $"LT:StartJob {job.SubType}");
|
||||
List<long> idList = new List<long>();
|
||||
long FailedObjectCount = 0;
|
||||
JObject jobData = JObject.Parse(job.JobInfo);
|
||||
if (jobData.ContainsKey("idList"))
|
||||
idList = ((JArray)jobData["idList"]).ToObject<List<long>>();
|
||||
else
|
||||
idList = await ct.VendorNotification.AsNoTracking().Select(z => z.Id).ToListAsync();
|
||||
bool SaveIt = false;
|
||||
|
||||
//---------------------------------
|
||||
//case 4192
|
||||
TimeSpan ProgressAndCancelCheckSpan = new TimeSpan(0, 0, ServerBootConfig.JOB_PROGRESS_UPDATE_AND_CANCEL_CHECK_SECONDS);
|
||||
DateTime LastProgressCheck = DateTime.UtcNow.Subtract(new TimeSpan(1, 1, 1, 1, 1));
|
||||
var TotalRecords = idList.LongCount();
|
||||
long CurrentRecord = -1;
|
||||
//---------------------------------
|
||||
|
||||
foreach (long id in idList)
|
||||
{
|
||||
try
|
||||
{
|
||||
//--------------------------------
|
||||
//case 4192
|
||||
//Update progress / cancel requested?
|
||||
CurrentRecord++;
|
||||
if (DateUtil.IsAfterDuration(LastProgressCheck, ProgressAndCancelCheckSpan))
|
||||
{
|
||||
await JobsBiz.UpdateJobProgressAsync(job.GId, $"{CurrentRecord}/{TotalRecords}");
|
||||
if (await JobsBiz.GetJobStatusAsync(job.GId) == JobStatus.CancelRequested)
|
||||
break;
|
||||
LastProgressCheck = DateTime.UtcNow;
|
||||
}
|
||||
//---------------------------------
|
||||
|
||||
SaveIt = false;
|
||||
ClearErrors();
|
||||
VendorNotification o = null;
|
||||
//save a fetch if it's a delete
|
||||
if (job.SubType != JobSubType.Delete)
|
||||
o = await GetAsync(id, false);
|
||||
switch (job.SubType)
|
||||
{
|
||||
// case JobSubType.TagAddAny:
|
||||
// case JobSubType.TagAdd:
|
||||
// case JobSubType.TagRemoveAny:
|
||||
// case JobSubType.TagRemove:
|
||||
// case JobSubType.TagReplaceAny:
|
||||
// case JobSubType.TagReplace:
|
||||
// SaveIt = TagBiz.ProcessBatchTagOperation(o.Tags, (string)jobData["tag"], jobData.ContainsKey("toTag") ? (string)jobData["toTag"] : null, job.SubType);
|
||||
// break;
|
||||
case JobSubType.Delete:
|
||||
if (!await DeleteAsync(id))
|
||||
{
|
||||
await JobsBiz.LogJobAsync(job.GId, $"LT:Errors {GetErrorsAsString()} id {id}");
|
||||
FailedObjectCount++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new System.ArgumentOutOfRangeException($"ProcessBatchJobAsync -> Invalid job Subtype{job.SubType}");
|
||||
}
|
||||
if (SaveIt)
|
||||
{
|
||||
o = await PutAsync(o);
|
||||
if (o == null)
|
||||
{
|
||||
await JobsBiz.LogJobAsync(job.GId, $"LT:Errors {GetErrorsAsString()} id {id}");
|
||||
FailedObjectCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//delay so we're not tying up all the resources in a tight loop
|
||||
await Task.Delay(Sockeye.Util.ServerBootConfig.JOB_OBJECT_HANDLE_BATCH_JOB_LOOP_DELAY);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await JobsBiz.LogJobAsync(job.GId, $"LT:Errors id({id})");
|
||||
await JobsBiz.LogJobAsync(job.GId, ExceptionUtil.ExtractAllExceptionMessages(ex));
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
//case 4192
|
||||
await JobsBiz.UpdateJobProgressAsync(job.GId, $"{++CurrentRecord}/{TotalRecords}");
|
||||
//---------------------------------
|
||||
|
||||
await JobsBiz.LogJobAsync(job.GId, $"LT:BatchJob {job.SubType} {idList.Count}{(FailedObjectCount > 0 ? " - LT:Failed " + FailedObjectCount : "")}");
|
||||
await JobsBiz.UpdateJobStatusAsync(job.GId, JobStatus.Completed);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// NOTIFICATION PROCESSING
|
||||
//
|
||||
public async Task HandlePotentialNotificationEvent(SockEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null)
|
||||
{
|
||||
if (ServerBootConfig.MIGRATING) return;
|
||||
ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger<VendorNotificationBiz>();
|
||||
|
||||
log.LogDebug($"HandlePotentialNotificationEvent processing: [SockType:{this.BizType}, AyaEvent:{ayaEvent}]");
|
||||
|
||||
bool isNew = currentObj == null;
|
||||
|
||||
proposedObj.Name = $"VENDOR NOTIFICATION created:{((VendorNotification)proposedObj).Created} id:{proposedObj.Id.ToString()}";
|
||||
//STANDARD EVENTS FOR ALL OBJECTS
|
||||
await NotifyEventHelper.ProcessStandardObjectEvents(ayaEvent, proposedObj, ct);
|
||||
|
||||
|
||||
}//end of process notifications
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
}//eoc
|
||||
|
||||
|
||||
}//eons
|
||||
|
||||
@@ -20,9 +20,9 @@ namespace Sockeye.Biz
|
||||
/// A Separate job will make licenses
|
||||
///
|
||||
/// </summary>
|
||||
internal static class SockBotProcessPurchases
|
||||
internal static class SockBotProcessVendorNotifications
|
||||
{
|
||||
private static ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger("SockBotProcessPurchases");
|
||||
private static ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger("SockBotProcessVendorNotifications");
|
||||
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
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -36,8 +36,8 @@ namespace Sockeye.Biz
|
||||
|
||||
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");
|
||||
await ProcessVendorDataIntoPurchases();
|
||||
log.LogDebug("Process vendor notifications starting");
|
||||
await ProcessVendorNotificationDataIntoPurchases();
|
||||
|
||||
// log.LogDebug("Process licenses from purchases starting");
|
||||
// await ProcessPurchasesIntoLicenses();
|
||||
@@ -45,14 +45,14 @@ namespace Sockeye.Biz
|
||||
lastSweep = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
private static async Task ProcessVendorDataIntoPurchases()
|
||||
private static async Task ProcessVendorNotificationDataIntoPurchases()
|
||||
{
|
||||
return;
|
||||
|
||||
using (AyContext ct = Sockeye.Util.ServiceProviderProvider.DBContext)
|
||||
{
|
||||
|
||||
//get a list of all actionable purchases
|
||||
//get a list of all actionable vendor notifications
|
||||
var ProcessablePurchaseIdList = await ct.Purchase
|
||||
.AsNoTracking()
|
||||
.Where(z => z.Processed == false
|
||||
@@ -115,25 +115,25 @@ namespace Sockeye.Biz
|
||||
|
||||
|
||||
|
||||
internal static async Task ParseVendorNotificationData(Purchase p, AyContext ct, ILogger log)
|
||||
internal static async Task ParseVendorNotificationData(VendorNotification vn, AyContext ct, ILogger log)
|
||||
{
|
||||
|
||||
if (string.IsNullOrWhiteSpace(p.VendorData)) return;
|
||||
if (string.IsNullOrWhiteSpace(vn.VendorData)) return;
|
||||
|
||||
try
|
||||
{
|
||||
var jData = JObject.Parse(p.VendorData);
|
||||
var jData = JObject.Parse(vn.VendorData);
|
||||
|
||||
//fundamentally validate the object is a purchase notification
|
||||
if (jData["order_notification"]["purchase"]["purchase_id"] == null)
|
||||
{
|
||||
//this is not the expected format data, stop processing and alert:
|
||||
throw new System.FormatException($"Vendor data unexpected format:{p.VendorData}");
|
||||
throw new System.FormatException($"Vendor data unexpected format:{vn.VendorData}");
|
||||
}
|
||||
|
||||
//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:{p.VendorData}");
|
||||
var jCustomerEmail = jData["order_notification"]["purchase"]["customer_data"]["delivery_contact"]["email"].Value<string>() ?? throw new System.FormatException($"Vendor data empty email:{p.VendorData}");
|
||||
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 customerBiz = CustomerBiz.GetBiz(ct);
|
||||
@@ -148,7 +148,7 @@ namespace Sockeye.Biz
|
||||
UpdateCustomerFromVendorData(jData, jCustomerEmail, c);
|
||||
c = await customerBiz.CreateAsync(c);
|
||||
if (c == null)
|
||||
throw new System.ApplicationException($"Error creating new Customer: {customerBiz.GetErrorsAsString()} vendor data :{p.VendorData}");
|
||||
throw new System.ApplicationException($"Error creating new Customer: {customerBiz.GetErrorsAsString()} vendor data :{vn.VendorData}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -156,7 +156,7 @@ namespace Sockeye.Biz
|
||||
UpdateCustomerFromVendorData(jData, jCustomerEmail, c);
|
||||
c = await customerBiz.PutAsync(c);
|
||||
if (c == null)
|
||||
throw new System.ApplicationException($"Error updating existing Customer: {customerBiz.GetErrorsAsString()} vendor data :{p.VendorData}");
|
||||
throw new System.ApplicationException($"Error updating existing Customer: {customerBiz.GetErrorsAsString()} vendor data :{vn.VendorData}");
|
||||
}
|
||||
|
||||
var salesOrderNumber = jData["order_notification"]["purchase"]["purchase_id"].Value<string>();
|
||||
@@ -166,11 +166,14 @@ namespace Sockeye.Biz
|
||||
|
||||
//ok, turn this into a fully realized Purchase record
|
||||
|
||||
//Product group
|
||||
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var err = $"ParseVendorNotificationData: Purchase record {p.Id}-{p.PurchaseDate} triggered exception, see log";
|
||||
var err = $"ParseVendorNotificationData: Purchase record {vn.Id}-{vn.PurchaseDate} triggered exception, see log";
|
||||
await NotifyEventHelper.AddOpsProblemEvent(err);//notify, this is serious
|
||||
log.LogError(ex, err);
|
||||
}
|
||||
@@ -204,6 +207,268 @@ namespace Sockeye.Biz
|
||||
#region SAMPLE VENDOR PURCHASE NOTIFICATIONS
|
||||
/*
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////// V7 MULTIPLE PRODUCTS IN ONE ORDER/////////////////////////////
|
||||
|
||||
{
|
||||
"creation_date": "2023-01-22T23:21:49Z",
|
||||
"id": 357678128,
|
||||
"order_notification": {
|
||||
"purchase": {
|
||||
"customer_data": {
|
||||
"billing_contact": {
|
||||
"address": {
|
||||
"city": "Courtenay",
|
||||
"country": "Canada",
|
||||
"country_id": "CA",
|
||||
"postal_code": "V9J9T6",
|
||||
"state": "British Columbia",
|
||||
"state_id": "BC",
|
||||
"street1": "05-3610 Christie Parkway"
|
||||
},
|
||||
"company": "GZTestCo",
|
||||
"email": "gzmailadmin@gmail.com",
|
||||
"first_name": "Test",
|
||||
"last_name": "Testerson"
|
||||
},
|
||||
"customer_payment_data": {
|
||||
"currency": "USD",
|
||||
"payment_method": "Other"
|
||||
},
|
||||
"delivery_contact": {
|
||||
"address": {
|
||||
"city": "Courtenay",
|
||||
"country": "Canada",
|
||||
"country_id": "CA",
|
||||
"postal_code": "V9J9T6",
|
||||
"state": "British Columbia",
|
||||
"state_id": "BC",
|
||||
"street1": "05-3610 Christie Parkway"
|
||||
},
|
||||
"company": "GZTestCo",
|
||||
"email": "gzmailadmin@gmail.com",
|
||||
"first_name": "Test",
|
||||
"last_name": "Testerson"
|
||||
},
|
||||
"language": "English",
|
||||
"language_iso": "en",
|
||||
"reg_name": "GZTestCo",
|
||||
"shopper_id": "65860321",
|
||||
"subscribe_newsletter": false,
|
||||
"user_id": "gzmailadmin@gmail.com-38"
|
||||
},
|
||||
"is_test": true,
|
||||
"payment_complete_date": "2023-01-22T23:21:48Z",
|
||||
"payment_status": "testpaymentarrived",
|
||||
"payment_status_id": "TCA",
|
||||
"purchase_date": "2023-01-22T23:21:47Z",
|
||||
"purchase_id": 843671213,
|
||||
"purchase_item": [
|
||||
{
|
||||
"additional_information": [
|
||||
{
|
||||
"additional_id": "ADDITIONAL1",
|
||||
"additional_value": "YES"
|
||||
},
|
||||
{
|
||||
"additional_id": "ADDITIONAL2",
|
||||
"additional_value": "YES"
|
||||
},
|
||||
{
|
||||
"additional_id": "ADDITIONAL3",
|
||||
"additional_value": "YES"
|
||||
}
|
||||
],
|
||||
"currency": "USD",
|
||||
"delivery_type": "Electronically",
|
||||
"discount": 0.0,
|
||||
"extended_download_price": 0.0,
|
||||
"manual_order_price": 0.0,
|
||||
"notification_no": 0,
|
||||
"product_id": 300740317,
|
||||
"product_name": "Up to 5 AyaNova schedulable resource 1 year subscription license",
|
||||
"product_single_price": 695.0,
|
||||
"purchase_item_key": [],
|
||||
"quantity": 1,
|
||||
"running_no": 1,
|
||||
"shipping_price": 0.0,
|
||||
"shipping_vat_pct": 0.0,
|
||||
"subscription": {
|
||||
"expiration_date": "2024-01-22T23:21:48Z",
|
||||
"id": "843671213-1",
|
||||
"interval": "Yearly without end",
|
||||
"renewal_discount_count": "",
|
||||
"renewal_discount_start": "",
|
||||
"renewal_type": "auto",
|
||||
"retention_discount_count": "",
|
||||
"retention_discount_percent": "",
|
||||
"start_date": "2023-01-23T00:00:00",
|
||||
"status": "ToProcess",
|
||||
"status_id": "TOP"
|
||||
},
|
||||
"vat_pct": 12.0
|
||||
},
|
||||
{
|
||||
"additional_information": [
|
||||
{
|
||||
"additional_id": "ADDITIONAL1",
|
||||
"additional_value": "YES"
|
||||
},
|
||||
{
|
||||
"additional_id": "ADDITIONAL2",
|
||||
"additional_value": "YES"
|
||||
},
|
||||
{
|
||||
"additional_id": "ADDITIONAL3",
|
||||
"additional_value": "YES"
|
||||
}
|
||||
],
|
||||
"currency": "USD",
|
||||
"delivery_type": "Electronically",
|
||||
"discount": 0.0,
|
||||
"extended_download_price": 0.0,
|
||||
"manual_order_price": 0.0,
|
||||
"notification_no": 0,
|
||||
"product_id": 300740314,
|
||||
"product_name": "optional add-on AyaNova RI (responsive interface) 1 year subscription license",
|
||||
"product_single_price": 199.0,
|
||||
"purchase_item_key": [],
|
||||
"quantity": 1,
|
||||
"running_no": 2,
|
||||
"shipping_price": 0.0,
|
||||
"shipping_vat_pct": 0.0,
|
||||
"subscription": {
|
||||
"expiration_date": "2024-01-22T23:21:48Z",
|
||||
"id": "843671213-2",
|
||||
"interval": "Yearly without end",
|
||||
"renewal_discount_count": "",
|
||||
"renewal_discount_start": "",
|
||||
"renewal_type": "auto",
|
||||
"retention_discount_count": "",
|
||||
"retention_discount_percent": "",
|
||||
"start_date": "2023-01-23T00:00:00",
|
||||
"status": "ToProcess",
|
||||
"status_id": "TOP"
|
||||
},
|
||||
"vat_pct": 12.0
|
||||
},
|
||||
{
|
||||
"additional_information": [
|
||||
{
|
||||
"additional_id": "ADDITIONAL1",
|
||||
"additional_value": "YES"
|
||||
}
|
||||
],
|
||||
"currency": "USD",
|
||||
"delivery_type": "Electronically",
|
||||
"discount": 0.0,
|
||||
"extended_download_price": 0.0,
|
||||
"manual_order_price": 0.0,
|
||||
"notification_no": 0,
|
||||
"product_id": 300740321,
|
||||
"product_name": "optional add-on AyaNova WBI (web browser interface) 1 year subscription license",
|
||||
"product_single_price": 99.0,
|
||||
"purchase_item_key": [],
|
||||
"quantity": 1,
|
||||
"running_no": 3,
|
||||
"shipping_price": 0.0,
|
||||
"shipping_vat_pct": 0.0,
|
||||
"subscription": {
|
||||
"expiration_date": "2024-01-22T23:21:48Z",
|
||||
"id": "843671213-3",
|
||||
"interval": "Yearly without end",
|
||||
"renewal_discount_count": "",
|
||||
"renewal_discount_start": "",
|
||||
"renewal_type": "auto",
|
||||
"retention_discount_count": "",
|
||||
"retention_discount_percent": "",
|
||||
"start_date": "2023-01-23T00:00:00",
|
||||
"status": "ToProcess",
|
||||
"status_id": "TOP"
|
||||
},
|
||||
"vat_pct": 12.0
|
||||
},
|
||||
{
|
||||
"additional_information": [
|
||||
{
|
||||
"additional_id": "ADDITIONAL1",
|
||||
"additional_value": "YES"
|
||||
}
|
||||
],
|
||||
"currency": "USD",
|
||||
"delivery_type": "Electronically",
|
||||
"discount": 0.0,
|
||||
"extended_download_price": 0.0,
|
||||
"manual_order_price": 0.0,
|
||||
"notification_no": 0,
|
||||
"product_id": 300740322,
|
||||
"product_name": "optional add-on AyaNova MBI (minimal browser interface) 1 year subscription license",
|
||||
"product_single_price": 99.0,
|
||||
"purchase_item_key": [],
|
||||
"quantity": 1,
|
||||
"running_no": 4,
|
||||
"shipping_price": 0.0,
|
||||
"shipping_vat_pct": 0.0,
|
||||
"subscription": {
|
||||
"expiration_date": "2024-01-22T23:21:48Z",
|
||||
"id": "843671213-4",
|
||||
"interval": "Yearly without end",
|
||||
"renewal_discount_count": "",
|
||||
"renewal_discount_start": "",
|
||||
"renewal_type": "auto",
|
||||
"retention_discount_count": "",
|
||||
"retention_discount_percent": "",
|
||||
"start_date": "2023-01-23T00:00:00",
|
||||
"status": "ToProcess",
|
||||
"status_id": "TOP"
|
||||
},
|
||||
"vat_pct": 12.0
|
||||
},
|
||||
{
|
||||
"additional_information": [
|
||||
{
|
||||
"additional_id": "ADDITIONAL1",
|
||||
"additional_value": "YES"
|
||||
}
|
||||
],
|
||||
"currency": "USD",
|
||||
"delivery_type": "Electronically",
|
||||
"discount": 0.0,
|
||||
"extended_download_price": 0.0,
|
||||
"manual_order_price": 0.0,
|
||||
"notification_no": 0,
|
||||
"product_id": 300740323,
|
||||
"product_name": "optional add-on AyaNova QBI(QuickBooks interface) 1 year subscription license",
|
||||
"product_single_price": 99.0,
|
||||
"purchase_item_key": [],
|
||||
"quantity": 1,
|
||||
"running_no": 5,
|
||||
"shipping_price": 0.0,
|
||||
"shipping_vat_pct": 0.0,
|
||||
"subscription": {
|
||||
"expiration_date": "2024-01-22T23:21:48Z",
|
||||
"id": "843671213-5",
|
||||
"interval": "Yearly without end",
|
||||
"renewal_discount_count": "",
|
||||
"renewal_discount_start": "",
|
||||
"renewal_type": "auto",
|
||||
"retention_discount_count": "",
|
||||
"retention_discount_percent": "",
|
||||
"start_date": "2023-01-23T00:00:00",
|
||||
"status": "ToProcess",
|
||||
"status_id": "TOP"
|
||||
},
|
||||
"vat_pct": 12.0
|
||||
}
|
||||
],
|
||||
"purchase_origin": "online"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////v7 export to xls add on/////////////////////////////
|
||||
{
|
||||
@@ -60,6 +60,7 @@ namespace Sockeye.Models
|
||||
public virtual DbSet<Vendor> Vendor { get; set; }
|
||||
public virtual DbSet<Product> Product { get; set; }
|
||||
public virtual DbSet<Purchase> Purchase { get; set; }
|
||||
public virtual DbSet<VendorNotification> VendorNotification { get; set; }
|
||||
public virtual DbSet<TrialLicenseRequest> TrialLicenseRequest { get; set; }
|
||||
public virtual DbSet<GZCase> GZCase { get; set; }
|
||||
public virtual DbSet<SubscriptionServer> SubscriptionServer { get; set; }
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Sockeye.Models
|
||||
public string Notes { get; set; }
|
||||
public bool RenewNoticeSent { get; set; } = false;
|
||||
public int Quantity { get; set; } = 1;
|
||||
public string VendorData { get; set; }
|
||||
public long? VendorNotificationId { get; set; }
|
||||
public bool Processed { get; set; } = false;//indicates it was fully processed and need not be processed by purchase or license generating jobs (all imported data set to processed)
|
||||
public string Wiki { get; set; }
|
||||
public List<string> Tags { get; set; }
|
||||
|
||||
64
server/models/VendorNotification.cs
Normal file
64
server/models/VendorNotification.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Newtonsoft.Json;
|
||||
using Sockeye.Biz;
|
||||
|
||||
namespace Sockeye.Models
|
||||
{
|
||||
public class VendorNotification : ICoreBizObjectModel
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public uint Concurrency { get; set; }
|
||||
[Required]
|
||||
public DateTime Created { get; set; } = DateTime.UtcNow;
|
||||
[Required]
|
||||
public long VendorId { get; set; }
|
||||
[NotMapped]
|
||||
public string VendorViz { get; set; }
|
||||
public string VendorData { get; set; }
|
||||
public DateTime? Processed { get; set; } = null;//indicates it was fully processed and need not be processed by purchase generating job (all imported data set to processed)
|
||||
|
||||
//workaround for notification
|
||||
[NotMapped, JsonIgnore]
|
||||
public string Name { get; set; }
|
||||
|
||||
public VendorNotification()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[NotMapped, JsonIgnore]
|
||||
public SockType SType { get => SockType.VendorNotification; }
|
||||
public List<string> Tags { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
}//eoc
|
||||
}//eons
|
||||
|
||||
/*
|
||||
|
||||
## How to make test sales and product links in ShareIt
|
||||
|
||||
fake sale of v8 to get license emails to update rockfish to auto read in the deets
|
||||
FAKE CREDIT CARD
|
||||
I have generated a test credit card number for your account. Please use the following as the credit card number making sure to use the word test and the 12 digit number with no spaces.
|
||||
You can use any valid information you would like for the other fields.
|
||||
test134661442658
|
||||
Expiration Date: any date in the future
|
||||
CVS code: 123
|
||||
Example typical database ID:
|
||||
tZy9aSHjacFf9a9v3EtzUqM1amq/eMvJa2nXswLle74=
|
||||
Links to purchase
|
||||
$50 customization charge https://order.mycommerce.com/cart/new?vendorid=14466&PRODUCT%5B300525428%5D=1
|
||||
Use this for custom report work minimum $50 for small changes
|
||||
|
||||
subscription month to month https://order.mycommerce.com/cart/new?vendorid=14466&PRODUCT%5B301028467%5D=1
|
||||
subscription yearly https://order.mycommerce.com/cart/new?vendorid=14466&PRODUCT%5B301028468%5D=1
|
||||
Perpetual single license: https://order.mycommerce.com/cart/new?vendorid=14466&PRODUCT%5B301028314%5D=1
|
||||
*** TESTING THIS ONE FIRST Perpetual single one year maintenance ACTIVE DISCOUNT PRICE: https://order.mycommerce.com/cart/new?vendorid=14466&PRODUCT%5B301028315%5D=1
|
||||
Perpetual single one year maintenance NEW FULL PRICE: https://order.mycommerce.com/cart/new?vendorid=14466&PRODUCT%5B301028317%5D=1
|
||||
v7 single for comparison 300740315 https://order.mycommerce.com/cart/new?vendorid=14466&PRODUCT%5B300740315%5D=1
|
||||
Address to use for testing
|
||||
05-3610 Christie Parkway Courtenay B.C. Canada V9J 9T6
|
||||
|
||||
*/
|
||||
@@ -897,16 +897,20 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
+ "vendorid BIGINT NOT NULL REFERENCES avendor(id), pgroup INTEGER NOT NULL DEFAULT 0, licenseinterval INTERVAL, maintinterval INTERVAL, vendorcode TEXT NOT NULL UNIQUE, ourcode TEXT NOT NULL UNIQUE, "
|
||||
+ "wiki TEXT, tags VARCHAR(255) ARRAY )");
|
||||
|
||||
await ExecQueryAsync("CREATE TABLE avendornotification (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, created TIMESTAMPTZ NOT NULL, vendorid BIGINT NOT NULL REFERENCES avendor(id), "
|
||||
+ "vendordata TEXT, processed TIMESTAMPTZ)");
|
||||
|
||||
await ExecQueryAsync("CREATE TABLE apurchase (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, customerid BIGINT REFERENCES acustomer(id) ON DELETE CASCADE, "
|
||||
+ "vendorid BIGINT NOT NULL REFERENCES avendor(id), productid BIGINT REFERENCES aproduct(id), pgroup INTEGER NOT NULL DEFAULT 4, salesordernumber TEXT NOT NULL, "
|
||||
+ "productnet DECIMAL(38,18) NOT NULL default 0, discount DECIMAL(38,18) NOT NULL default 0, vendorfee DECIMAL(38,18) NOT NULL default 0, revenue DECIMAL(38,18) NOT NULL default 0, "
|
||||
+ "currency TEXT NOT NULL DEFAULT 'USD', purchasedate TIMESTAMPTZ NOT NULL, expiredate TIMESTAMPTZ, canceldate TIMESTAMPTZ, couponcode text, notes text, "
|
||||
+ "renewnoticesent BOOL NOT NULL DEFAULT false, quantity INTEGER NOT NULL DEFAULT 1, "
|
||||
+ "vendordata TEXT, processed BOOL NOT NULL DEFAULT false, "
|
||||
+ "vendornotificationid BIGINT REFERENCES avendornotification(id), processed BOOL NOT NULL DEFAULT false, "
|
||||
+ "wiki TEXT, tags VARCHAR(255) ARRAY )");
|
||||
|
||||
|
||||
|
||||
|
||||
await ExecQueryAsync("CREATE TABLE agzcase (id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, caseid BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, "
|
||||
+ "created TIMESTAMPTZ NOT NULL, closed TIMESTAMPTZ, name TEXT NOT NULL, notes TEXT, "
|
||||
+ "wiki TEXT, tags VARCHAR(255) ARRAY, customerid BIGINT REFERENCES acustomer(id) )");
|
||||
@@ -1053,7 +1057,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerDatacenter', 'Data center' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerTimeZone', 'Time zone' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastUpdated', 'Last updated' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerSubExpire', 'Subscription expires' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerSubExpire', 'Subscription expires' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastHealthStatus', 'Health status' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastHealthCheck', 'Last health check' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerTrialContact', 'Trial contact' FROM atranslation t where t.baselanguage = 'en'");
|
||||
@@ -1079,7 +1083,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerDatacenter', 'Data center' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerTimeZone', 'Time zone' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastUpdated', 'Last updated' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerSubExpire', 'Subscription expires' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerSubExpire', 'Subscription expires' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastHealthStatus', 'Health status' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastHealthCheck', 'Last health check' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerTrialContact', 'Trial contact' FROM atranslation t where t.baselanguage = 'es'");
|
||||
@@ -1105,7 +1109,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerDatacenter', 'Data center' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerTimeZone', 'Time zone' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastUpdated', 'Last updated' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerSubExpire', 'Subscription expires' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerSubExpire', 'Subscription expires' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastHealthStatus', 'Health status' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastHealthCheck', 'Last health check' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerTrialContact', 'Trial contact' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
@@ -1131,7 +1135,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerDatacenter', 'Data center' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerTimeZone', 'Time zone' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastUpdated', 'Last updated' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerSubExpire', 'Subscription expires' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerSubExpire', 'Subscription expires' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastHealthStatus', 'Health status' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerLastHealthCheck', 'Last health check' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'SubServerTrialContact', 'Trial contact' FROM atranslation t where t.baselanguage = 'de'");
|
||||
@@ -1206,7 +1210,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseNotes', 'Notes' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseRenewNoticeSent', 'Renew notice sent' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseQuantity', 'Quantity' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorData', 'Vendor data' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorNotificationId', 'Vendor data' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseProcessed', 'Processed' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseCurrency', 'Currency' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseProductNet', 'Product net' FROM atranslation t where t.baselanguage = 'en'");
|
||||
@@ -1225,7 +1229,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseNotes', 'Notes' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseRenewNoticeSent', 'Renew notice sent' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseQuantity', 'Quantity' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorData', 'Vendor data' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorNotificationId', 'Vendor data' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseProcessed', 'Processed' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseCurrency', 'Currency' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseProductNet', 'Product net' FROM atranslation t where t.baselanguage = 'es'");
|
||||
@@ -1244,7 +1248,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseNotes', 'Notes' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseRenewNoticeSent', 'Renew notice sent' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseQuantity', 'Quantity' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorData', 'Vendor data' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorNotificationId', 'Vendor data' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseProcessed', 'Processed' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseCurrency', 'Currency' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseProductNet', 'Product net' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
@@ -1264,7 +1268,7 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseNotes', 'Notes' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseRenewNoticeSent', 'Renew notice sent' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseQuantity', 'Quantity' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorData', 'Vendor data' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorNotificationId', 'Vendor data' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseProcessed', 'Processed' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseCurrency', 'Currency' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseProductNet', 'Product net' FROM atranslation t where t.baselanguage = 'de'");
|
||||
@@ -1274,6 +1278,38 @@ $BODY$ LANGUAGE PLPGSQL STABLE");
|
||||
|
||||
#endregion purchase
|
||||
|
||||
#region VENDOR NOTIFICATION
|
||||
|
||||
//english translations
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotification', 'Vendor notification' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationList', 'Vendor notifications' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationCreated', 'Created' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationVendorData', 'Vendor data' FROM atranslation t where t.baselanguage = 'en'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationProcessed', 'Processed' FROM atranslation t where t.baselanguage = 'en'");
|
||||
|
||||
//spanish translations
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotification', 'Vendor notification' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationList', 'Vendor notifications' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationCreated', 'Created' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationVendorData', 'Vendor data' FROM atranslation t where t.baselanguage = 'es'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationProcessed', 'Processed' FROM atranslation t where t.baselanguage = 'es'");
|
||||
|
||||
//french translations
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotification', 'Vendor notification' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationList', 'Vendor notifications' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationCreated', 'Created' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationVendorData', 'Vendor data' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationProcessed', 'Processed' FROM atranslation t where t.baselanguage = 'fr'");
|
||||
|
||||
//german translations
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotification', 'Vendor notification' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationList', 'Vendor notifications' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationCreated', 'Created' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationVendorData', 'Vendor data' FROM atranslation t where t.baselanguage = 'de'");
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'VendorNotificationProcessed', 'Processed' FROM atranslation t where t.baselanguage = 'de'");
|
||||
|
||||
#endregion vendor notification
|
||||
|
||||
#region GZCASE
|
||||
//english translations
|
||||
await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'GZCase', 'Case' FROM atranslation t where t.baselanguage = 'en'");
|
||||
|
||||
Reference in New Issue
Block a user