diff --git a/server/biz/GlobalBizSettingsBiz.cs b/server/biz/GlobalBizSettingsBiz.cs index 53b05a5..8f0c0cb 100644 --- a/server/biz/GlobalBizSettingsBiz.cs +++ b/server/biz/GlobalBizSettingsBiz.cs @@ -351,6 +351,12 @@ namespace Sockeye.Biz p.VendorData += ",\n"; p.VendorData += jVendorNotificationItem["data"].Value(); await ct.SaveChangesAsync(); + +#if (DEBUG) + //Test dev stuff +#warning DEV TEST ORDER PROCESSING REMOVE THIS WHEN DONE + await SockBotProcessPurchases.ParseVendorNotificationData(p, ct); +#endif } }// all vendor notifications loop @@ -758,7 +764,7 @@ namespace Sockeye.Biz tlr.RejectReason = jTrialRequestItem["rejectReason"].Value(); tlr.LicenseId = TrialKeyId; var biz = TrialLicenseRequestBiz.GetBiz(ct); - await biz.CreateAsync(tlr,true); + await biz.CreateAsync(tlr, true); } diff --git a/server/generator/SockBotProcessPurchases.cs b/server/generator/SockBotProcessPurchases.cs index b9c0c1d..03d6a90 100644 --- a/server/generator/SockBotProcessPurchases.cs +++ b/server/generator/SockBotProcessPurchases.cs @@ -4,6 +4,7 @@ using System.Net.Http; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; using Sockeye.Models; using Sockeye.Util; @@ -36,13 +37,26 @@ 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 licenses from purchases starting"); + // await ProcessPurchasesIntoLicenses(); + + lastSweep = DateTime.UtcNow; + } + + private static async Task ProcessVendorDataIntoPurchases() + { + return; + using (AyContext ct = Sockeye.Util.ServiceProviderProvider.DBContext) { - //get a list of all active server ID's + //get a list of all actionable purchases var ProcessablePurchaseIdList = await ct.Purchase .AsNoTracking() - .Where(z => z.Processed == false) + .Where(z => z.Processed == false + && z.ProductId == null) .OrderBy(z => z.Id) .Select(z => z.Id) .ToListAsync(); @@ -62,7 +76,7 @@ namespace Sockeye.Biz } else { - log.LogDebug($"Processing order {p.SalesOrderNumber}"); + log.LogDebug($"Processing purchase {p.Id}-{p.PurchaseDate}"); if (string.IsNullOrWhiteSpace(p.VendorData)) { @@ -73,13 +87,13 @@ namespace Sockeye.Biz } -//Parse json vendordata + //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 + //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 @@ -97,11 +111,699 @@ namespace Sockeye.Biz } } - lastSweep = DateTime.UtcNow; } + internal static async Task ParseVendorNotificationData(Purchase p, AyContext ct, ILogger log) + { + + if (string.IsNullOrWhiteSpace(p.VendorData)) return; + + try + { + var jData = JObject.Parse(p.VendorData); + var salesOrderNumber = jData["order_notification"]["purchase"]["purchase_id"].Value(); + } + catch (Exception ex) + { + var err = $"ParseVendorNotificationData: Purchase record {p.Id}-{p.PurchaseDate} triggered exception, see log"; + await NotifyEventHelper.AddOpsProblemEvent(err);//notify, this is serious + log.LogError(ex, err); + } + } + + + #region SAMPLE VENDOR PURCHASE NOTIFICATIONS + /* + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////v7 export to xls add on///////////////////////////// + { +"creation_date": "2023-01-20T00:18:33Z", +"id": 357520816, +"order_notification": { +"purchase": { + "customer_data": { + "billing_contact": { + "address": { + "city": "Cambridge", + "country": "Canada", + "country_id": "CA", + "postal_code": "N1T 1J3", + "state": "Ontario", + "state_id": "ON", + "street1": "181 Shearson Crescent" + }, + "company": "Cambridge Elevating Inc", + "email": "richard.wright@cambridgeelevating.com", + "first_name": "Richard", + "last_name": "Wright" + }, + "customer_payment_data": { + "currency": "USD", + "payment_method": "MasterCard" + }, + "delivery_contact": { + "address": { + "city": "Cambridge", + "country": "Canada", + "country_id": "CA", + "postal_code": "N1T 1J3", + "state": "Ontario", + "state_id": "ON", + "street1": "181 Shearson Crescent" + }, + "company": "Cambridge Elevating Inc", + "email": "richard.wright@cambridgeelevating.com", + "first_name": "Richard", + "last_name": "Wright" + }, + "language": "English", + "language_iso": "en", + "reg_name": "Cambridge Elevating Inc", + "shopper_id": "62545677", + "subscribe_newsletter": false, + "user_id": "richard.wright@cambridgeelevating.com-5" + }, + "is_test": false, + "payment_complete_date": "2023-01-20T00:18:33Z", + "payment_status": "complete", + "payment_status_id": "PCA", + "purchase_date": "2023-01-20T00:18:31Z", + "purchase_id": 843101393, + "purchase_item": [ + { + "accounting": { + "currency": "USD", + "product_net": 6.65, + "discount": 0.0, + "product_vat": 0.86, + "shipping": 0.0, + "shipping_vat": 0.0, + "eu_vat": -0.86, + "margin_net": -2.5, + "your_revenue": 4.15 + }, + "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": 7953, + "product_id": 300740327, + "product_name": "optional add-on plug-in Export to XLS 1 year subscription license", + "product_single_price": 6.65, + "purchase_item_key": [], + "quantity": 1, + "running_no": 1, + "shipping_price": 0.0, + "shipping_vat_pct": 0.0, + "subscription": { + "expiration_date": "2024-01-20T18:36:22Z", + "id": "771160083-3", + "interval": "Yearly without end", + "original_notification_no": "7779", + "original_purchase_id": "771160083", + "original_running_no": "3", + "renewal_discount_count": "", + "renewal_discount_start": "", + "renewal_type": "auto", + "retention_discount_count": "", + "retention_discount_percent": "", + "start_date": "2022-01-20T00:00:00", + "status": "ToProcess", + "status_id": "TOP" + }, + "vat_pct": 13.0 + } + ], + "purchase_origin": "Subscription", + "sequential_invoice_no": "e5-DE-2023-00000163106" +} +} +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////// V7 Scheduleable user ////////////////////// + +{ +"creation_date": "2023-01-20T00:18:32Z", +"id": 357520809, +"order_notification": { +"purchase": { + "customer_data": { + "billing_contact": { + "address": { + "city": "Cambridge", + "country": "Canada", + "country_id": "CA", + "postal_code": "N1T 1J3", + "state": "Ontario", + "state_id": "ON", + "street1": "181 Shearson Crescent" + }, + "company": "Cambridge Elevating Inc", + "email": "richard.wright@cambridgeelevating.com", + "first_name": "Richard", + "last_name": "Wright" + }, + "customer_payment_data": { + "currency": "USD", + "payment_method": "MasterCard" + }, + "delivery_contact": { + "address": { + "city": "Cambridge", + "country": "Canada", + "country_id": "CA", + "postal_code": "N1T 1J3", + "state": "Ontario", + "state_id": "ON", + "street1": "181 Shearson Crescent" + }, + "company": "Cambridge Elevating Inc", + "email": "richard.wright@cambridgeelevating.com", + "first_name": "Richard", + "last_name": "Wright" + }, + "language": "English", + "language_iso": "en", + "reg_name": "Cambridge Elevating Inc", + "shopper_id": "62545677", + "subscribe_newsletter": false, + "user_id": "richard.wright@cambridgeelevating.com-5" + }, + "is_test": false, + "payment_complete_date": "2023-01-20T00:18:32Z", + "payment_status": "complete", + "payment_status_id": "PCA", + "purchase_date": "2023-01-20T00:18:31Z", + "purchase_id": 843101383, + "purchase_item": [ + { + "accounting": { + "currency": "USD", + "product_net": 577.5, + "discount": 0.0, + "product_vat": 75.08, + "shipping": 0.0, + "shipping_vat": 0.0, + "eu_vat": -75.08, + "margin_net": -29.05, + "your_revenue": 548.45 + }, + "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": 7952, + "product_id": 300807973, + "product_name": "Up to 15 AyaNova schedulable resource 1 year subscription license", + "product_single_price": 577.5, + "purchase_item_key": [], + "quantity": 1, + "running_no": 1, + "shipping_price": 0.0, + "shipping_vat_pct": 0.0, + "subscription": { + "expiration_date": "2024-01-20T18:36:22Z", + "id": "771160083-1", + "interval": "Yearly without end", + "original_notification_no": "7777", + "original_purchase_id": "771160083", + "original_running_no": "1", + "renewal_discount_count": "", + "renewal_discount_start": "", + "renewal_type": "auto", + "retention_discount_count": "", + "retention_discount_percent": "", + "start_date": "2022-01-20T00:00:00", + "status": "ToProcess", + "status_id": "TOP" + }, + "vat_pct": 13.0 + } + ], + "purchase_origin": "Subscription", + "sequential_invoice_no": "e5-DE-2023-00000163105" +} +} +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// NOT A LICENSE PRODUCT - CUSTOMIZATION SERVICES FOR REPORT TEMPLATE + +{ +"creation_date": "2023-01-18T15:45:50Z", +"id": 357446088, +"order_notification": { +"purchase": { + "customer_data": { + "billing_contact": { + "address": { + "city": "Brunswick", + "country": "USA", + "country_id": "US", + "postal_code": "38014", + "state": "Tennessee", + "state_id": "TN", + "street1": "PO Box 374" + }, + "company": "Tri-Star Medical Technologies LLC", + "email": "stan@tri-starmedical.com", + "first_name": "Stan", + "last_name": "Hilton" + }, + "customer_payment_data": { + "currency": "USD", + "payment_method": "Visa" + }, + "delivery_contact": { + "address": { + "city": "Brunswick", + "country": "USA", + "country_id": "US", + "postal_code": "38014", + "state": "Tennessee", + "state_id": "TN", + "street1": "PO Box 374" + }, + "company": "Tri-Star Medical Technologies LLC", + "email": "stan@tri-starmedical.com", + "first_name": "Stan", + "last_name": "Hilton" + }, + "language": "English", + "language_iso": "en", + "reg_name": "Tri-Star Medical Technologies LLC", + "shopper_id": "65821033", + "subscribe_newsletter": false, + "user_id": "stan@tri-starmedical.com-1" + }, + "is_test": false, + "payment_complete_date": "2023-01-18T15:45:49Z", + "payment_status": "complete", + "payment_status_id": "PCA", + "purchase_date": "2023-01-18T15:45:48Z", + "purchase_id": 842819563, + "purchase_item": [ + { + "accounting": { + "currency": "USD", + "product_net": 50.0, + "discount": 0.0, + "product_vat": 4.63, + "shipping": 0.0, + "shipping_vat": 0.0, + "eu_vat": -4.63, + "margin_net": -5.14, + "your_revenue": 44.86 + }, + "additional_information": [], + "currency": "USD", + "delivery_type": "Electronically", + "discount": 0.0, + "extended_download_price": 0.0, + "manual_order_price": 0.0, + "notification_no": 7945, + "product_id": 300525428, + "product_name": "AyaNova customization services", + "product_single_price": 50.0, + "purchase_item_key": [], + "quantity": 1, + "running_no": 1, + "shipping_price": 0.0, + "shipping_vat_pct": 0.0, + "vat_pct": 9.25 + } + ], + "purchase_origin": "online", + "sequential_invoice_no": "e5-US-2023-00000083100" +} +} +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////// TEST PURCHASE USING SPECIAL TEST CREDIT CARD NUMBER PROVIDED BY MYCOMMERCE +{ +"creation_date": "2023-01-18T04:24:28Z", +"id": 357424814, +"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": "65817245", + "subscribe_newsletter": false, + "user_id": "gzmailadmin@gmail.com-36" + }, + "is_test": true, + "payment_complete_date": "2023-01-18T04:24:28Z", + "payment_status": "testpaymentarrived", + "payment_status_id": "TCA", + "purchase_date": "2023-01-18T04:24:28Z", + "purchase_id": 842769483, + "purchase_item": [ + { + "additional_information": [], + "currency": "USD", + "delivery_type": "Electronically", + "discount": 0.0, + "extended_download_price": 0.0, + "manual_order_price": 0.0, + "notification_no": 0, + "product_id": 300525428, + "product_name": "AyaNova customization services", + "product_single_price": 50.0, + "purchase_item_key": [], + "quantity": 1, + "running_no": 1, + "shipping_price": 0.0, + "shipping_vat_pct": 0.0, + "vat_pct": 12.0 + } + ], + "purchase_origin": "online" +} +} +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////// RAVEN PERPETUAL + +{ +"creation_date": "2023-01-14T06:17:59Z", +"id": 357214426, +"order_notification": { +"purchase": { + "customer_data": { + "billing_contact": { + "address": { + "city": "Frankfort", + "country": "USA", + "country_id": "US", + "postal_code": "46041", + "state": "Indiana", + "state_id": "IN", + "street1": "47 N Jackson St." + }, + "company": "ACCS", + "email": "internet@accs.net", + "first_name": "Marcus", + "last_name": "Hodges" + }, + "customer_payment_data": { + "currency": "USD", + "payment_method": "Visa" + }, + "delivery_contact": { + "address": { + "city": "Frankfort", + "country": "USA", + "country_id": "US", + "postal_code": "46041", + "state": "Indiana", + "state_id": "IN", + "street1": "47 N Jackson St." + }, + "company": "ACCS", + "email": "internet@accs.net", + "first_name": "Marcus", + "last_name": "Hodges" + }, + "language": "English", + "language_iso": "en", + "reg_name": "ACCS", + "shopper_id": "65783365", + "subscribe_newsletter": false, + "user_id": "internet@accs.net" + }, + "is_test": false, + "payment_complete_date": "2023-01-14T06:17:59Z", + "payment_status": "complete", + "payment_status_id": "PCA", + "purchase_date": "2023-01-14T06:17:58Z", + "purchase_id": 841935113, + "purchase_item": [ + { + "accounting": { + "currency": "USD", + "product_net": 72.0, + "discount": 0.0, + "product_vat": 5.04, + "shipping": 0.0, + "shipping_vat": 0.0, + "eu_vat": -5.04, + "margin_net": -6.03, + "your_revenue": 65.97 + }, + "additional_information": [ + { + "additional_id": "AGREENOREFUNDS", + "additional_value": "YES" + }, + { + "additional_id": "AGREEPAYMETHODVALIDCANCEL", + "additional_value": "YES" + }, + { + "additional_id": "AGREEEXPIRESIFNOTPAID", + "additional_value": "YES" + }, + { + "additional_id": "DATABASEID", + "additional_value": "7ktPA+Eaq+LM4vNMkQdbwBkUMDzzFYXmH+m21n3w5Rk=" + } + ], + "currency": "USD", + "delivery_type": "Electronically", + "discount": 0.0, + "extended_download_price": 0.0, + "manual_order_price": 0.0, + "notification_no": 7944, + "product_id": 301028317, + "product_name": "AyaNova perpetual single user license includes one year maintenance plan ", + "product_single_price": 24.0, + "purchase_item_key": [], + "quantity": 3, + "running_no": 1, + "shipping_price": 0.0, + "shipping_vat_pct": 0.0, + "subscription": { + "expiration_date": "2024-01-14T06:17:59Z", + "id": "841935113-1", + "interval": "Yearly without end", + "renewal_discount_count": "", + "renewal_discount_start": "", + "renewal_type": "auto", + "retention_discount_count": "", + "retention_discount_percent": "", + "start_date": "2023-01-14T00:00:00", + "status": "ToProcess", + "status_id": "TOP" + }, + "vat_pct": 7.0, + "your_product_id": "perpetual" + } + ], + "purchase_origin": "online", + "sequential_invoice_no": "e5-US-2023-00000064245" +} +} +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////// RAVEN MONTHLY SUBSCRIPTION +{ +"creation_date": "2023-01-07T01:54:11Z", +"id": 356798113, +"order_notification": { +"purchase": { + "customer_data": { + "billing_contact": { + "address": { + "city": "UNIONVILLE", + "country": "Canada", + "country_id": "CA", + "postal_code": "L3R 9W6", + "state": "Ontario", + "state_id": "ON", + "street1": "4261 HWY 7 E, Unit A14 #399" + }, + "company": "sportseffect", + "email": "service@sportseffect.com", + "first_name": "Mark", + "last_name": "Hopkins" + }, + "customer_payment_data": { + "currency": "CAD", + "payment_method": "Visa" + }, + "delivery_contact": { + "address": { + "city": "UNIONVILLE", + "country": "Canada", + "country_id": "CA", + "postal_code": "L3R 9W6", + "state": "Ontario", + "state_id": "ON", + "street1": "4261 HWY 7 E, Unit A14 #399" + }, + "company": "sportseffect", + "email": "service@sportseffect.com", + "first_name": "Mark", + "last_name": "Hopkins" + }, + "language": "English", + "language_iso": "en", + "reg_name": "sportseffect", + "shopper_id": "65387076", + "subscribe_newsletter": false, + "user_id": "service@sportseffect.com" + }, + "is_test": false, + "payment_complete_date": "2023-01-07T01:54:11Z", + "payment_status": "complete", + "payment_status_id": "PCA", + "purchase_date": "2023-01-07T01:54:09Z", + "purchase_id": 840549123, + "purchase_item": [ + { + "accounting": { + "currency": "USD", + "product_net": 23.8, + "discount": 0.0, + "product_vat": 3.09, + "shipping": 0.0, + "shipping_vat": 0.0, + "eu_vat": -3.09, + "margin_net": -4.03, + "your_revenue": 19.77 + }, + "additional_information": [ + { + "additional_id": "AGREENOREFUNDS", + "additional_value": "YES" + }, + { + "additional_id": "AGREEPAYMETHODVALIDCANCEL", + "additional_value": "YES" + }, + { + "additional_id": "AGREEEXPIRESIFNOTPAID", + "additional_value": "YES" + }, + { + "additional_id": "DATABASEID", + "additional_value": "New subscription" + } + ], + "currency": "USD", + "delivery_type": "Electronically", + "discount": 0.0, + "extended_download_price": 0.0, + "manual_order_price": 0.0, + "notification_no": 7937, + "product_id": 301028467, + "product_name": "AyaNova subscription one user monthly", + "product_single_price": 11.9, + "purchase_item_key": [], + "quantity": 2, + "running_no": 1, + "shipping_price": 0.0, + "shipping_vat_pct": 0.0, + "subscription": { + "expiration_date": "2023-02-07T00:15:13Z", + "id": "833674953-1", + "interval": "Monthly without end", + "original_notification_no": "7925", + "original_purchase_id": "833674953", + "original_running_no": "1", + "renewal_discount_count": "", + "renewal_discount_start": "", + "renewal_type": "auto", + "retention_discount_count": "", + "retention_discount_percent": "", + "start_date": "2022-12-07T00:00:00", + "status": "ToProcess", + "status_id": "TOP" + }, + "vat_pct": 13.0, + "your_product_id": "subscriptionmonthly" + } + ], + "purchase_origin": "Subscription", + "sequential_invoice_no": "e5-DE-2023-00000055949" +} +} +} + + */ + + #endregion sample vendor notifications + //order notification json schema on this page down + //https://account.mycommerce.com/home/wiki/7479997 //json format + //https://account.mycommerce.com/home/wiki/7479805 //overall info diff --git a/server/models/Purchase.cs b/server/models/Purchase.cs index 6c6a108..2feb761 100644 --- a/server/models/Purchase.cs +++ b/server/models/Purchase.cs @@ -12,20 +12,40 @@ namespace Sockeye.Models public long Id { get; set; } public uint Concurrency { get; set; } public long? CustomerId { get; set; } - public long? LicenseId { get; set; }//when licensed will be set to this license id - THINKING ON THIS ONE public bool Licenseable { get; set; } = false;//indicates it is ready for the licensing job to license this purchase (if has no license id) + public long? LicenseId { get; set; }//when null and also when pgroup is a licenseable type means it shoudl be processed by SockBotProcessPurchases license gen [NotMapped] public string CustomerViz { get; set; } [Required] public long VendorId { get; set; } [NotMapped] public string VendorViz { get; set; } - public long? ProductId { get; set; }//optional because a new vendor notification won't have a product set yet also pgroup will be NotSet + public long? ProductId { get; set; }//When null means it's new and should be processed by SockbotProcessPurchases job into proper purchase record [Required] public ProductGroup PGroup { get; set; } [NotMapped] public string ProductViz { get; set; } public string SalesOrderNumber { get; set; } + + /* + "accounting": { + "currency": "USD", + "product_net": 577.5, + "discount": 0.0, + "product_vat": 75.08, + "shipping": 0.0, + "shipping_vat": 0.0, + "eu_vat": -75.08, + "margin_net": -29.05, + "your_revenue": 548.45 + */ + public string Currency { get; set; }//All values sb US dollars, but just in case + public decimal ProductNet { get; set; } = 0;//total billed for the product before taxes + public decimal Discount { get; set; } = 0; + public decimal VendorFee { get; set; } = 0;//margin_net charged by myCommerce; their fee for processing the order + public decimal Revenue { get; set; } = 0;//amount we are paid for the order (product net - discount - vendorfee) + + + [Required] public DateTime PurchaseDate { get; set; } public DateTime? ExpireDate { get; set; } @@ -35,7 +55,7 @@ namespace Sockeye.Models public bool RenewNoticeSent { get; set; } = false; public int Quantity { get; set; } = 1; public string VendorData { get; set; } - public bool Processed { get; set; } = false;//indicates it was processed from raw vendor data into proper values, false means it should be processed + 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 Tags { get; set; } //workaround for notification diff --git a/server/util/AySchema.cs b/server/util/AySchema.cs index a906201..598e70d 100644 --- a/server/util/AySchema.cs +++ b/server/util/AySchema.cs @@ -900,7 +900,8 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); 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, " - + "purchasedate TIMESTAMPTZ NOT NULL, expiredate TIMESTAMPTZ, canceldate TIMESTAMPTZ, couponcode text, notes text, " + + "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, " + "wiki TEXT, tags VARCHAR(255) ARRAY )"); @@ -1207,6 +1208,11 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); 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, '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'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseDiscount', 'Discount' FROM atranslation t where t.baselanguage = 'en'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorFee', 'Vendor fee' FROM atranslation t where t.baselanguage = 'en'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseRevenue', 'Revenue' FROM atranslation t where t.baselanguage = 'en'"); //spanish translations await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'Purchase', 'Purchase' FROM atranslation t where t.baselanguage = 'es'"); @@ -1221,6 +1227,11 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); 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, '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'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseDiscount', 'Discount' FROM atranslation t where t.baselanguage = 'es'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorFee', 'Vendor fee' FROM atranslation t where t.baselanguage = 'es'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseRevenue', 'Revenue' FROM atranslation t where t.baselanguage = 'es'"); //french translations await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'Purchase', 'Purchase' FROM atranslation t where t.baselanguage = 'fr'"); @@ -1235,6 +1246,11 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); 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, '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'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseDiscount', 'Discount' FROM atranslation t where t.baselanguage = 'fr'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorFee', 'Vendor fee' FROM atranslation t where t.baselanguage = 'fr'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseRevenue', 'Revenue' FROM atranslation t where t.baselanguage = 'fr'"); //german translations @@ -1250,6 +1266,11 @@ $BODY$ LANGUAGE PLPGSQL STABLE"); 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, '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'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseDiscount', 'Discount' FROM atranslation t where t.baselanguage = 'de'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseVendorFee', 'Vendor fee' FROM atranslation t where t.baselanguage = 'de'"); + await ExecQueryAsync("INSERT INTO atranslationitem(translationid,key,display) SELECT t.id, 'PurchaseRevenue', 'Revenue' FROM atranslation t where t.baselanguage = 'de'"); #endregion purchase