|
@@ -66,9 +66,166 @@ public class LicensingHandler : Handler<LicensingHandlerProperties>
|
|
return request.Respond().Status(ResponseStatus.OK).Content(Serialization.Serialize(summary));
|
|
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)
|
|
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)
|
|
private IResponseBuilder Ping(IRequest request)
|
|
{
|
|
{
|