123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Windows;
- using InABox.Clients;
- using InABox.Core;
- using InABox.DynamicGrid;
- using InABox.Wpf;
- using InABox.WPF;
- using System.Windows.Controls;
- using System.Drawing;
- using Image = System.Windows.Controls.Image;
- using System.Diagnostics;
- using InABox.Client.Remote.Json;
- using InABox.Configuration;
- using Microsoft.Win32;
- using PRS.Shared;
- using Stripe;
- namespace PRSServer.Forms.DatabaseLicense;
- /// <summary>
- /// Interaction logic for LicenseRenewal.xaml
- /// </summary>
- public partial class LicenseRenewalForm : ThemableWindow, IDynamicEditorHost
- {
-
- public static HttpJsonClient LicenseClient = new("https", "remote.prsdigital.com.au", 5000);
- //public static HttpJsonClient LicenseClient = new("http", "127.0.0.1", 8001);
-
- private static readonly EncryptedLocalConfiguration<LicenseRegistrationDetails> _config = new("g6+BoQpyti5bHsTZOY5Nbqq3Q3c90n0m3qZaQ3eAwkk=");
- private LicenseRegistrationDetails _licenseRegistrationDetails;
-
- private LicenseData? _currentLicense;
- public LicenseData? CurrentLicense
- {
- get => _currentLicense;
- set
- {
- _currentLicense = value;
- Modules.CurrentLicense = value;
- }
- }
-
- public int RenewalPeriod
- {
- get
- {
- if (int.TryParse(RenewalPeriodEditor.Value?.ToString(), out var period))
- {
- return period;
- }
- return 0;
- }
- set
- {
- RenewalPeriodEditor.Value = value;
- CalculateDiscounts();
- }
- }
-
- public DateTime RenewalDate
- {
- get
- {
- if(CurrentLicense == null)
- {
- return DateTime.MinValue;
- }
- if (CurrentLicense.Expiry > DateTime.Now)
- {
- return CurrentLicense.Expiry.Date;
- }
- return DateTime.Today;
- }
- }
- private DateTime _renewalAvailable;
- public DateTime RenewalAvailableFrom
- {
- get => _renewalAvailable;
- set
- {
- _renewalAvailable = value;
- if (!CanRenew)
- {
- RenewalAvailableLabel.Content = $"Renewal available from {value:dd MMM yyyy}";
- }
- }
- }
- public bool CanRenew => RenewalAvailableFrom.Date <= DateTime.Today || (CurrentLicense != null && CurrentLicense.Expiry <= DateTime.Now);
- public DateTime NewExpiration
- {
- get => RenewalDate.AddMonths(RenewalPeriod);
- }
- public List<LicenseTrackingItem> LicenseItems { get; private set; }
-
- public int Licenses { get; private set; }
-
- public double Gross { get; private set; }
- public double Discount { get; private set; }
-
- public double Net => Gross - Discount;
- public LicenseRenewalForm()
- {
- InitializeComponent();
- // This should get us the RegistrationID, which we need in order
- // to get the License Pricing from the Server
- _licenseRegistrationDetails = _config.Load(false);
-
- LastRenewal.EditorDefinition = new DateEditor();
- LastRenewal.Configure();
- LastRenewal.IsEnabled = false;
- CurrentExpiry.EditorDefinition = new DateEditor();
- CurrentExpiry.Configure();
- CurrentExpiry.IsEnabled = false;
- RenewalPeriodEditor.EditorDefinition = new ComboLookupEditor(typeof(RenewalPeriodLookups));
- RenewalPeriodEditor.Host = this;
- RenewalPeriodEditor.Configure();
- var lookups = new RenewalPeriodLookups(null).AsTable("RenewalPeriod");
- RenewalPeriodEditor.LoadLookups(lookups);
- NewExpiry.EditorDefinition = new DateEditor();
- NewExpiry.Configure();
- NewExpiry.IsEnabled = false;
- GrossLicenseFee.EditorDefinition = new CurrencyEditor();
- GrossLicenseFee.Configure();
- GrossLicenseFee.IsEnabled = false;
- DiscountEditor.EditorDefinition = new DoubleEditor();
- DiscountEditor.Configure();
- DiscountEditor.IsEnabled = false;
- NettLicenseFee.EditorDefinition = new CurrencyEditor();
- NettLicenseFee.Configure();
- NettLicenseFee.IsEnabled = false;
- Help.Content = new Image { Source = Properties.Resources.help.AsBitmapImage(Color.White) };
- Help.Click += Help_Click;
-
- }
- private void Help_Click(object sender, RoutedEventArgs e)
- {
- Process.Start(new ProcessStartInfo("https://prsdigital.com.au/wiki/index.php/License_Renewal") { UseShellExecute = true });
- }
- private void LoadData()
- {
- var result = Progress.ShowModal<bool>("Getting License", progress =>
- {
- try
- {
- progress.Report("Loading License");
- CurrentLicense = LoadCurrentLicense();
-
- progress.Report("Checking Server");
- if (!LicenseClient.Ping("ping"))
- return Result.Error("Server Unavailable");
-
- progress.Report("Retrieving Data");
- RetrieveFees();
-
- progress.Report("Scanning Data");
- LoadUserTracking();
-
- foreach (var item in LicenseItems)
- item.Rate = LicenseUtils.GetLicenseFee(item.Type);
-
- return Result.Ok(true);
- }
- catch (Exception e)
- {
- return Result.Error(e.Message);
- }
- });
- if (result.Get(out var success, out var error) && success)
- {
- UpdateWindow();
- }
- else
- {
- MessageWindow.ShowMessage(error ?? "Error", "Error");
- LicenseItems = new();
- IsEnabled = false;
- UpdateWindow();
- }
- }
-
- private void UpdateWindow()
- {
- // Always a minimum of one license required!
- Licenses = Math.Max(1, LicenseItems.OrderByDescending(x => x.Users).FirstOrDefault()?.Users ?? 0);
-
- Modules.Items = LicenseItems;
- Modules.Refresh(true, true);
-
- var lookups = new RenewalPeriodLookups(null).AsTable("RenewalPeriod");
- RenewalPeriodEditor.LoadLookups(lookups);
- RenewalPeriodEditor.Loaded = true;
-
- RenewalPeriod = LicenseUtils.TimeDiscountLevels().OrderBy(x => x).FirstOrDefault();
- PayWithStripe.IsEnabled = CanRenew;
- if (!PayWithStripe.IsEnabled)
- {
- PayTooltip.Visibility = Visibility.Visible;
- PayTooltip.Content = new Label { Content = $"Renewal available from {RenewalAvailableFrom:dd MMM yyyy}" };
- }
- else
- PayTooltip.Visibility = Visibility.Collapsed;
-
- LastRenewal.Loaded = true;
- CurrentExpiry.Loaded = true;
- NewExpiry.Loaded = true;
-
- //PayWithStripe.IsEnabled = false;
-
- PayTooltip.Visibility = Visibility.Visible;
- PayTooltip.Content = new Label { Content = "Loading..." };
-
- LastRenewal.Value = CurrentLicense?.LastRenewal ?? DateTime.MinValue;
- CurrentExpiry.Value = CurrentLicense?.Expiry ?? DateTime.MinValue;
- RenewalAvailableFrom = CurrentLicense?.RenewalAvailable ?? DateTime.MinValue;
- }
- private void Window_Loaded(object sender, RoutedEventArgs e)
- {
- LoadData();
- }
-
- private void RetrieveFees()
- {
- var summary = LicenseClient.PostRequest<LicenseFeeResponse>(
- new LicenseFeeRequest() { RegistrationID = CurrentLicense?.CustomerID ?? Guid.Empty },
- nameof(LicenseFeeRequest)
- );
- LicenseUtils.LoadSummary(summary);
- }
-
- private void LoadUserTracking()
- {
- var renewaldate = _currentLicense?.LastRenewal ?? DateTime.MinValue;
- var filter = !renewaldate.IsEmpty()
- ? new Filter<UserTracking>(x => x.Date).IsGreaterThanOrEqualTo(renewaldate).And(x => x.TotalWrite).IsNotEqualTo(0)
- : new Filter<UserTracking>(x => x.TotalWrite).IsNotEqualTo(0);
-
- var data = new Client<UserTracking>()
- .Query(
- filter,
- InABox.Core.Columns.None<UserTracking>().Add(x => x.User.ID)
- .Add(x => x.Type));
- var typesummary = data.Rows.GroupBy(r => r.Get<UserTracking, String>(c => c.Type)).ToArray();
- //Licenses = data.ExtractValues<UserTracking, Guid>(x => x.User.ID).Distinct().Count();
- var licensemap = LicenseUtils.LicenseMap();
- var result = new List<LicenseTrackingItem>();
- foreach (var map in licensemap)
- {
- var type = map.Value.EntityName();
- var item = result.FirstOrDefault(x => Equals(x.Type, type));
- if (item == null)
- {
- item = new LicenseTrackingItem()
- {
- Type = type,
- Caption = map.Value.GetCaption(),
- };
- result.Add(item);
- }
- var users = typesummary
- .FirstOrDefault(x => Equals(x.Key, map.Key.EntityName().Split('.').Last()))?
- .Select(r=>r.Get<UserTracking,Guid>(x=>x.User.ID))
- .Distinct()
- .Where(x=>!item.UserIDs.Contains(x));
- if (users != null)
- item.UserIDs.AddRange(users);
- }
- LicenseItems = result
- .OrderBy(x=>x.Caption)
- .ToList();
- }
- private static LicenseData? LoadCurrentLicense()
- {
- var license = new Client<License>().Query(
- new Filter<License>().All(),
- InABox.Core.Columns.None<License>().Add(x => x.Data))
- .Rows.FirstOrDefault()?.ToObject<License>();
- if(license == null)
- {
- MessageBox.Show("No current license found. Please see the documentation on how to proceed.");
- return null;
- }
- if(!LicenseUtils.TryDecryptLicense(license.Data, out var data, out var error))
- {
- MessageBox.Show("Current license is corrupt. Please see the documentation on how to proceed.");
- return null;
- }
- return data;
- }
- private void RenewalPeriod_OnEditorValueChanged(IDynamicEditorControl sender, Dictionary<string, object> values)
- {
- CalculateDiscounts();
- }
-
- private void CalculateDiscounts()
- {
- double CalcDiscount(double amount, int months)
- {
- return (amount * (LicenseUtils.GetUserDiscount(Licenses) / 100.0F)) +
- (amount * (LicenseUtils.GetTimeDiscount(months) / 100.0F));
- }
- var periodInMonths = RenewalPeriod;
-
- NewExpiry.Value = NewExpiration;
- double total = 0.0F;
- if (CurrentLicense?.IsDynamic == true)
- {
- foreach (var row in Modules.Data.Rows)
- total += row.Get<LicenseTrackingItem, double>(x => x.ExGST) * periodInMonths;
- Gross = total;
- Discount = CalcDiscount(total, periodInMonths);
- }
- else
- {
- foreach (var row in Modules.Data.Rows)
- total += Licenses * LicenseUtils.GetLicenseFee(row.Get<LicenseTrackingItem, String>(x => x.Type)) * periodInMonths;
- Gross = Math.Round(total) - 0.05;
- Gross = total;
- Discount = Math.Round(CalcDiscount(total, periodInMonths) * 20F) / 20F;
- }
-
-
- GrossLicenseFee.Value = Gross;
- DiscountEditor.Value = Discount;
- NettLicenseFee.Value = Net;
- PayWithStripe.IsEnabled = CanRenew && Net > 0;
- }
- private class RenewalPeriodLookups : LookupGenerator<object>
- {
- public RenewalPeriodLookups(object[] items) : base(items)
- {
- }
- protected override void DoGenerateLookups()
- {
- foreach (var period in LicenseUtils.TimeDiscountLevels())
- AddValue(period, string.Format("{0} month{1}", period, period > 1 ? "s" : ""));
- }
- }
-
- private void PayNowClick(object sender, RoutedEventArgs e)
- {
- if (!LicenseClient.Ping("ping"))
- {
- MessageBox.Show("The PRS server is not available right now. Please try again later.");
- return;
- }
- var grid = new LicenseRegistrationGrid();
- if (grid.EditItems(new LicenseRegistrationDetails[] { _licenseRegistrationDetails }))
- {
- _config.Save(_licenseRegistrationDetails);
- Result<string, string> result = Result.Error("Incomplete");
- var renewalRequest = CreateRenewal();
- Progress.ShowModal("Processing", progress =>
- {
- if (renewalRequest.Net > 0.0F)
- {
- // Process the Stripe Payment
- progress.Report("Processing Payment");
- result = ProcessStripePayment();
- if (!result.IsOK)
- return;
- }
- else
- result = Result.Ok("no payment required");
- progress.Report("Creating Renewal");
- if (result.Get(out var value, out var error))
- {
- result = RenewLicense(renewalRequest, value);
- }
- if(result.Get(out value, out error))
- {
- progress.Report("Saving License");
- SaveLicense(value);
- }
- });
- if (!result.Get(out var value, out var error))
- MessageWindow.ShowMessage(error, "Error");
- else
- {
- MessageWindow.ShowMessage("License Updated Successfully!","Success");
- Close();
- }
- }
-
- }
-
- private Result<string, string> ProcessStripePayment()
- {
- var result = "";
- var error = "";
-
- try
- {
- StripeConfiguration.ApiKey =
- "pk_live_51MRSuPIyPMVqmkXNiIu0BjTHWrfIvsWalXqYsebuTr27JF08jwk9KunHfvTrI30bojbQJgr0fWD3RkBXVnDsF75v00ryCeqOav";
- //StripeConfiguration.ApiKey = "sk_test_51MRSuPIyPMVqmkXN8TeGxDAGBeFx0pLzn3fsHBR8X1oMBKQVwGPEbuv6DNIu0qSmuflpmFfQ4N8c3vzdknKa7G0o00wTOXwCeW";
- var cardoptions = new TokenCreateOptions()
- {
- Card = new TokenCardOptions()
- {
- Number = _licenseRegistrationDetails.Card.CardNumber.Replace(" ", ""),
- ExpMonth = _licenseRegistrationDetails.Card.Month,
- ExpYear = _licenseRegistrationDetails.Card.Year,
- Cvc = _licenseRegistrationDetails.Card.Cvv
- }
- };
- var service = new TokenService();
- var token = service.Create(cardoptions);
-
- var chargeoptions = new ChargeCreateOptions()
- {
- Amount = Convert.ToInt64(Gross * 100),
- Currency = "AUD",
- Description = "PRS Renewal",
- Source = token.Id
- };
-
- var chargeservice = new ChargeService();
- var charge = chargeservice.Create(chargeoptions);
- if (charge.Paid)
- result = charge.Id;
- else
- error = string.Format("{0}: {1}", charge.FailureCode, charge.FailureMessage);
- }
- catch (Exception ex)
- {
- error = $"{ex.Message}";
- }
- if (!string.IsNullOrWhiteSpace(error))
- return Result.Error(error);
- return Result.Ok(result);
- }
-
- private LicenseRenewalRequest CreateRenewal()
- {
- return new LicenseRenewalRequest
- {
- Company = _licenseRegistrationDetails.Company,
- DateRenewed = RenewalDate,
- OldLicense = CurrentLicense,
- NewExpiry = NewExpiration,
- LicenseTracking = LicenseItems.ToArray(),
- Gross = Gross,
- Discount = Discount,
- Net = Net,
- Addresses = LicenseUtils.GetMacAddresses(),
- };
- }
- private Result<string, string> RenewLicense(LicenseRenewalRequest renewalRequest, String transactionID)
- {
- renewalRequest.TransactionID = transactionID;
- try
- {
- var result = LicenseClient.PostRequest<LicenseRenewalResult>(renewalRequest, nameof(LicenseRenewalRequest));
- return Result.Ok(result.License);
- }
- catch (Exception e)
- {
- return Result.Error(e.Message);
- }
- }
-
- private void SaveLicense(string license)
- {
- using var client = new Client<License>();
- var oldLicenses = client
- .Query(
- new Filter<License>().All(),
- InABox.Core.Columns.None<License>().Add(x => x.ID))
- .Rows.Select(x => x.ToObject<License>()).ToList();
- client.Delete(oldLicenses, "");
- client.Save(new License() { Data = license }, "");
- }
-
-
- #region IDynamicEditorHost
- public void LoadLookups(ILookupEditorControl editor)
- {
-
- }
- public BaseObject[] GetItems()
- {
- return new BaseObject[] { };
- }
- public Type GetEditorType() => typeof(BaseObject);
- public BaseEditor? GetEditor(DynamicGridColumn column)
- {
- return new NullEditor();
- }
-
- #endregion
- private void EnterKey_Click(object sender, RoutedEventArgs e)
- {
- if (EnterKey?.ContextMenu != null)
- EnterKey.ContextMenu.IsOpen = true;
- }
- private void CreateManualRequest(object sender, RoutedEventArgs e)
- {
- var request = new LicenseRequest()
- {
- CustomerID = CurrentLicense?.CustomerID ?? Guid.Empty,
- Addresses = LicenseUtils.GetMacAddresses(),
- IsDynamic = CurrentLicense?.IsDynamic ?? false,
- };
- SaveFileDialog sfd = new SaveFileDialog()
- {
- FileName = "license.request"
- };
- if (sfd.ShowDialog() == true)
- {
- System.IO.File.WriteAllText(sfd.FileName, LicenseUtils.EncryptLicenseRequest(request));
- MessageWindow.ShowMessage("Please email this file to support@prsdigital.com.au!","Request Created");
- }
- }
- private void LoadManualResponse(object sender, RoutedEventArgs e)
- {
- var ofd = new OpenFileDialog()
- {
- FileName = "license.key",
- Filter = "License Files (*.key)|*.key"
- };
- if (ofd.ShowDialog() == true && System.IO.File.Exists(ofd.FileName))
- {
- var text = System.IO.File.ReadAllText(ofd.FileName);
- if (LicenseUtils.TryDecryptLicense(text, out var data, out var _))
- {
- if (LicenseUtils.ValidateMacAddresses(data.Addresses))
- {
- SaveLicense(text);
- MessageWindow.ShowMessage("License Updated", "Success");
- Close();
- }
- else
- MessageWindow.ShowMessage("License Key is not valid!","Invalid Key");
- }
- else
- MessageWindow.ShowMessage("License Key is not valid!","Bad Key");
- }
- }
- }
|