Преглед на файлове

Added LicenseRenewal endpoint

Kenric Nugteren преди 1 година
родител
ревизия
ff33cab93a

+ 158 - 1
prs.licensing/Engine/LicensingEngine.cs

@@ -66,9 +66,166 @@ public class LicensingHandler : Handler<LicensingHandlerProperties>
         return request.Respond().Status(ResponseStatus.OK).Content(Serialization.Serialize(summary));
     }
 
+    private static List<Tuple<int, Func<DateTime, DateTime>>> renewalPeriods = new List<Tuple<int, Func<DateTime, DateTime>>> {
+        new(1, x => x.AddDays(-7)),
+        new(3, x => x.AddDays(-14)),
+        new(6, x => x.AddMonths(-1))
+    };
+
+    private int GetMonthDifference(DateTime date1, DateTime date2){
+        var months = (date2.Year - date1.Year) * 12 + (date2.Month - date1.Month);
+        
+        if(date2.Day >= date1.Day){
+            return months;
+        }
+        return months - 1;
+    }
+    private LicenseData GenerateLicense(LicenseRenewal renewal){
+        var renewalPeriodInMonths = GetMonthDifference(renewal.DateRenewed, renewal.NewExpiry);
+        var renewalAvailable = renewalPeriods
+            .Where(x => renewalPeriodInMonths >= x.Item1)
+            .MaxBy(x => x.Item1)
+            .Item2(renewal.NewExpiry);
+        
+        var newLicense = LicenseUtils.RenewLicense(renewal.OldLicense, renewal.DateRenewed, renewal.NewExpiry, renewalAvailable);
+        
+        return newLicense;
+    }
+    
+    private string NewCustomerCode(LicenseRenewal renewal){
+        var code = renewal.Company.CompanyName.ToUpper();
+        var codes = new Client<Customer>().Query(
+            new Filter<Customer>(x => x.Code).BeginsWith(code),
+            new Columns<Customer>(x => x.Code))?.Rows.Select(x => x.Get<Customer, string>(x => x.Code)).ToList();
+        
+        var tryCode = code;
+        var i = 0;
+        while(codes.Contains(tryCode)){
+            tryCode = $"{code}{i}";
+            ++i;
+        }
+        
+        return tryCode;
+    }
+    private Customer CreateNewCustomer(LicenseRenewal renewal){
+        Logger.Send(LogType.Information, "", "Creating new customer");
+        
+        var customer = new Customer {
+            Code = NewCustomerCode(renewal),
+            Name = $"{renewal.Company.CompanyName} - {renewal.Company.ABN}",
+            Delivery = renewal.Company.DeliveryAddress,
+            Email = renewal.Company.Email,
+            Postal = renewal.Company.PostalAddress
+        };
+        new Client<Customer>().Save(customer, "Created by License Renewal");
+        return customer;
+    }
+    private CustomerDocument CreateNewCustomerDocument(Guid customerID, string fileName, string data){
+        var document = new Document {
+            FileName = fileName,
+            Private = true,
+            TimeStamp = DateTime.Now,
+            Data = Encoding.UTF8.GetBytes(data)
+        };
+        document.CRC = CoreUtils.CalculateCRC(document.Data);
+        
+        new Client<Document>().Save(document, "");
+        
+        var documentType = new Client<DocumentType>()
+            .Query(new Filter<DocumentType>(x => x.Code).IsEqualTo("LICENSE"), new Columns<DocumentType>(x => x.ID))
+            .Rows.FirstOrDefault()?.Get<DocumentType, Guid>(x => x.ID) ?? Guid.Empty;
+        if(documentType == Guid.Empty){
+            Logger.Send(LogType.Error, "", "Document Type 'LICENSE' doesn't exist");
+        }
+        
+        var customerDocument = new CustomerDocument();
+        customerDocument.Type.ID = documentType;
+        customerDocument.EntityLink.ID = customerID;
+        customerDocument.DocumentLink.ID = document.ID;
+        
+        new Client<CustomerDocument>().Save(customerDocument, "Created by License Renewal");
+        return customerDocument;
+    }
+    private void CreateInvoice(Guid customerID, LicenseRenewal renewal){
+        var invoiceLines = new List<InvoiceLine>();
+        var notes = new List<string>();
+        foreach(var item in renewal.LicenseTracking){
+            var invoiceLine = new InvoiceLine {
+                Description = $"{item.License} - {item.Users} Users @ ${item.Rate:F2} per user",
+                ExTax = item.ExGST
+            };
+            invoiceLines.Add(invoiceLine);
+            notes.Add(invoiceLine.Description);
+        }
+        var discountLine = new InvoiceLine {
+            Description = $"${renewal.Discount:F2} discount",
+            ExTax = -renewal.Discount
+        };
+        invoiceLines.Add(discountLine);
+         notes.Add(discountLine.Description);
+        
+        var invoice = new Invoice {
+            Date = DateTime.Today,
+            Description = $"License Renewal - Stripe Transaction No. '{renewal.TransactionID}'"
+        };
+        invoice.CustomerLink.ID = customerID;
+        
+        new Client<Invoice>().Save(invoice, "Created by License Renewal");
+        
+        foreach(var line in invoiceLines){
+            line.InvoiceLink.ID = invoice.ID;
+        }
+        new Client<InvoiceLine>().Save(invoiceLines, "");
+        
+        var receipt = new Receipt {
+            Date = DateTime.Today,
+            Notes = string.Join('\n', notes)
+        };
+        new Client<Receipt>().Save(receipt, "");
+        
+        var invoiceReceipt = new InvoiceReceipt {
+            Notes = "Receipt for License Renewal",
+            Amount = renewal.Net
+        };
+        invoiceReceipt.InvoiceLink.ID = invoice.ID;
+        invoiceReceipt.ReceiptLink.ID = receipt.ID;
+        new Client<InvoiceReceipt>().Save(invoiceReceipt, "");
+    }
+
     private IResponseBuilder RenewLicense(IRequest request)
     {
-        return request.Respond().Status(ResponseStatus.NotFound);
+        
+        
+        var renewal = Serialization.Deserialize<LicenseRenewal>(request.Content);
+        if(renewal == null){
+            return request.Respond().Status(ResponseStatus.BadRequest);
+        }
+        
+        Logger.Send(LogType.Information, "", $"Request for license renewal from {renewal.Company.CompanyName}");
+        
+        var customerID = renewal.OldLicense.CustomerID;
+        if(customerID == Guid.Empty){
+            customerID = CreateNewCustomer(renewal).ID;
+            renewal.OldLicense.CustomerID = customerID;
+        }
+        
+        Logger.Send(LogType.Information, "", "Generating new license");
+        
+        var newLicense = GenerateLicense(renewal);
+        var newLicenseData = LicenseUtils.EncryptLicense(newLicense);
+        if(newLicenseData == null){
+            Logger.Send(LogType.Error, "", "Encryption of new license failed!");
+            return request.Respond().Status(ResponseStatus.InternalServerError);
+        }
+        
+        Logger.Send(LogType.Information, "", "Generating customer document");
+        var customerDocument = CreateNewCustomerDocument(customerID, $"{renewal.Company.CompanyName} - PRS License - {DateTime.Now:dd MMM yyyy}.txt", newLicenseData);
+        Logger.Send(LogType.Information, "", "Creating invoice");
+        CreateInvoice(customerID, renewal);
+        
+        return request.Respond()
+            .Status(ResponseStatus.OK)
+            .Content(Serialization.Serialize(new License { Data = newLicenseData } )); // Send just the encrypted data.
     }
     private IResponseBuilder Ping(IRequest request)
     {

+ 1 - 0
prs.server/Forms/DatabaseLicense/LicenseRenewalForm.xaml.cs

@@ -14,6 +14,7 @@ using System.Drawing;
 using Image = System.Windows.Controls.Image;
 using System.Diagnostics;
 using InABox.Configuration;
+using PRS.Shared;
 
 namespace PRSServer.Forms.DatabaseLicense
 {

+ 1 - 0
prs.server/Forms/DatabaseLicense/LicenseTrackingItemGrid.cs

@@ -7,6 +7,7 @@ using InABox.Client.Remote.Json;
 using InABox.Clients;
 using InABox.Core;
 using InABox.DynamicGrid;
+using PRS.Shared;
 using RestSharp;
 
 namespace PRSServer.Forms.DatabaseLicense

+ 1 - 1
prs.server/Forms/DatabaseLicense/LicenseRenewal.cs → prs.shared/Objects/LicenseRenewal.cs

@@ -6,7 +6,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 
-namespace PRSServer
+namespace PRS.Shared
 {
     public class LicenseRenewal : BaseObject
     {

+ 1 - 1
prs.server/Forms/DatabaseLicense/LicenseTrackingItem.cs → prs.shared/Objects/LicenseTrackingItem.cs

@@ -1,6 +1,6 @@
 using InABox.Core;
 
-namespace PRSServer.Forms.DatabaseLicense
+namespace PRS.Shared
 {
     public class LicenseTrackingItem : BaseObject
     {