| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 | 
							- using System;
 
- using System.Collections.Generic;
 
- using System.Linq;
 
- using System.Text;
 
- using System.Threading.Tasks;
 
- using com.sun.xml.@internal.fastinfoset.sax;
 
- using Comal.Classes;
 
- using GenHTTP.Api.Protocol;
 
- using GenHTTP.Modules.IO;
 
- using InABox.Clients;
 
- using InABox.Core;
 
- using NPOI.HSSF.Util;
 
- using PRS.Shared;
 
- using PRSServices;
 
- using RequestMethod = GenHTTP.Api.Protocol.RequestMethod;
 
- namespace PRSLicensing;
 
- public class LicensingHandler : Handler<LicensingHandlerProperties>
 
- {
 
-     private LicensingHandlerProperties? _properties;
 
-     
 
-     public override void Init(LicensingHandlerProperties properties)
 
-     {
 
-         _properties = properties;
 
-     }
 
-     private IResponseBuilder RetrieveFees(IRequest request)
 
-     {
 
-         if (_properties == null)
 
-             return request.Respond().Status(ResponseStatus.BadRequest);
 
-         
 
-         var lsr = Serialization.Deserialize<LicenseFeeRequest>(request.Content);
 
-         if (lsr == null)
 
-             return request.Respond().Status(ResponseStatus.BadRequest);
 
-         
 
-         Logger.Send(LogType.Information, "", $"License Enquiry Received ({lsr.RegistrationID})");
 
-         var productids = _properties.EngineProperties.Mappings.Select(x => x.Product.ID).ToArray();
 
-         if (!productids.Any())
 
-         { 
 
-             Logger.Send(LogType.Error,"","Engine Product Mapping List is Empty");
 
-             return request.Respond().Status(ResponseStatus.BadRequest);
 
-         }
 
-         
 
-         var query = new MultiQuery();
 
-         
 
-         query.Add(
 
-             new Filter<Product>(x=>x.ID).InList(productids),
 
-             new Columns<Product>(x=>x.ID)
 
-                 .Add(x=>x.NettCost)
 
-                 .Add(x=>x.Charge.Chargeable)
 
-                 .Add(x=>x.Charge.PriceType)
 
-                 .Add(x=>x.Charge.Markup)
 
-                 .Add(x=>x.Charge.Price)
 
-             );
 
-         
 
-         if (lsr.RegistrationID != Guid.Empty)
 
-             query.Add(
 
-                 new Filter<CustomerProduct>(x=>x.Customer.ID).IsEqualTo(lsr.RegistrationID).And(x=>x.Product.ID).InList(productids),
 
-                 new Columns<CustomerProduct>(x=>x.Product.ID)
 
-                     .Add(x=>x.Product.NettCost)
 
-                     .Add(x=>x.Charge.Chargeable)
 
-                     .Add(x=>x.Charge.PriceType)
 
-                     .Add(x=>x.Charge.Markup)
 
-                     .Add(x=>x.Charge.Price)
 
-             );
 
-         
 
-         query.Query();
 
-         var products = query.Get<Product>().Rows.Select(x => x.ToObject<Product>()).ToArray();
 
-         
 
-         var customerproducts = lsr.RegistrationID != Guid.Empty
 
-             ? query.Get<CustomerProduct>().Rows.Select(x => x.ToObject<CustomerProduct>()).ToArray()
 
-             : new CustomerProduct[] { };
 
-         var result = new LicenseFeeResponse();
 
-         foreach (var mapping in _properties.EngineProperties.Mappings)
 
-         {
 
-             var customer = customerproducts.FirstOrDefault(x => x.Product.ID == mapping.Product.ID);
 
-             if (customer != null)
 
-             {
 
-                 result.LicenseFees[mapping.License] = customer.Charge.PriceType == ProductPriceType.CostPlus
 
-                     ? customer.Product.NettCost * (100F + customer.Charge.Markup) / 100F
 
-                     : customer.Charge.Price;
 
-             }
 
-             else
 
-             {
 
-                 var product = products.FirstOrDefault(x => x.ID == mapping.Product.ID);
 
-                 result.LicenseFees[mapping.License] = product != null
 
-                     ? product.Charge.PriceType == ProductPriceType.CostPlus
 
-                         ? product.NettCost * (100F + product.Charge.Markup) / 100F
 
-                         : product.Charge.Price
 
-                     : 0.0F;
 
-             }
 
-         }
 
-         foreach (var timediscount in _properties.EngineProperties.TimeDiscounts)
 
-             result.TimeDiscounts[timediscount.Months] = timediscount.Discount;
 
-         
 
-         foreach (var userdiscount in _properties.EngineProperties.UserDiscounts)
 
-             result.UserDiscounts[userdiscount.Users] = userdiscount.Discount;
 
-         
 
-         return request.Respond().Status(ResponseStatus.OK).Content(Serialization.Serialize(result));
 
-     }
 
-     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(LicenseRenewalRequest renewalRequest){
 
-         var renewalPeriodInMonths = GetMonthDifference(renewalRequest.DateRenewed, renewalRequest.NewExpiry);
 
-         var renewalAvailable = renewalPeriods
 
-             .Where(x => renewalPeriodInMonths >= x.Item1)
 
-             .MaxBy(x => x.Item1)
 
-             .Item2(renewalRequest.NewExpiry);
 
-         
 
-         var newLicense = LicenseUtils.RenewLicense(renewalRequest.OldLicense, renewalRequest.DateRenewed, renewalRequest.NewExpiry, renewalAvailable, renewalRequest.Addresses);
 
-         return newLicense;
 
-     }
 
-     
 
-     private string NewCustomerCode(LicenseRenewalRequest renewalRequest)
 
-     {
 
-         // Try to build a 5 character abbreviation of the company name
 
-         // is ACME Incorporated should become ACMIN
 
-         // while P T Barnum should become PTBAR and so on
 
-         String code = "";
 
-         var codecomps = renewalRequest.Company.CompanyName
 
-             .ToUpper()
 
-             .Split(' ')
 
-             .ToList();
 
-         while (code.Length < 5 && codecomps.Any())
 
-         {
 
-             var chunk = new string(codecomps.First().Take(Math.Min(3,5-code.Length)).ToArray());
 
-             code += chunk;
 
-             codecomps.RemoveAt(0);
 
-         }
 
-         
 
-         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() ?? new List<string>();
 
-         
 
-         var i = 1;
 
-         while(codes.Contains($"{code}{i:D3}"))
 
-             i++;            
 
-         
 
-         return $"{code}{i:D3}";
 
-     }
 
-     
 
-     private Customer CreateNewCustomer(LicenseRenewalRequest renewalRequest){
 
-         Logger.Send(LogType.Information, "", "Creating new customer");
 
-         
 
-         var customer = new Customer {
 
-             Code = NewCustomerCode(renewalRequest),
 
-             Name = renewalRequest.Company.CompanyName,
 
-             ABN = renewalRequest.Company.ABN,
 
-             Delivery = renewalRequest.Company.DeliveryAddress,
 
-             Email = renewalRequest.Company.Email,
 
-             Postal = renewalRequest.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, LicenseRenewalRequest renewalRequest){
 
-         var invoiceLines = new List<InvoiceLine>();
 
-         var notes = new List<string>();
 
-         foreach(var item in renewalRequest.LicenseTracking){
 
-             var invoiceLine = new InvoiceLine {
 
-                 Description = $"{item.Caption} - {item.Users} Users @ ${item.Rate:F2} per user",
 
-                 ExTax = item.ExGST
 
-             };
 
-             invoiceLines.Add(invoiceLine);
 
-             notes.Add(invoiceLine.Description);
 
-         }
 
-         var discountLine = new InvoiceLine {
 
-             Description = $"${renewalRequest.Discount:F2} discount",
 
-             ExTax = -renewalRequest.Discount
 
-         };
 
-         invoiceLines.Add(discountLine);
 
-         notes.Add(discountLine.Description);
 
-         
 
-         var invoice = new Invoice {
 
-             Date = DateTime.Today,
 
-             Description = $"PRS License Renewal",
 
-         };
 
-         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 = $"PRS Renewal Invoice #{invoice.Number} ({renewalRequest.TransactionID})"
 
-         };
 
-         new Client<Receipt>().Save(receipt, "");
 
-         
 
-         var invoiceReceipt = new InvoiceReceipt {
 
-             Notes = "Receipt for License Renewal",
 
-             Amount = renewalRequest.Net
 
-         };
 
-         invoiceReceipt.InvoiceLink.ID = invoice.ID;
 
-         invoiceReceipt.ReceiptLink.ID = receipt.ID;
 
-         new Client<InvoiceReceipt>().Save(invoiceReceipt, "");
 
-     }
 
-     
 
-     private IResponseBuilder RenewLicense(IRequest request)
 
-     {
 
-         
 
-         var renewal = Serialization.Deserialize<LicenseRenewalRequest>(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);
 
-         LicenseRenewalResult result = new()
 
-         {
 
-             License = newLicenseData
 
-         };
 
-         return request.Respond()
 
-             .Status(ResponseStatus.OK)
 
-             .Content(Serialization.Serialize(result)); // Send just the encrypted data.
 
-     }
 
-     
 
-     private IResponseBuilder Ping(IRequest request)
 
-     {
 
-         return request.Respond().Status(ResponseStatus.OK);
 
-     }
 
-     private IResponseBuilder HandleGET(IRequest request)
 
-     {
 
-         var endpoint = request.Target.Current?.Value.ToLower() ?? "";
 
-         
 
-         if (endpoint == nameof(Ping).ToLower())
 
-             return Ping(request);
 
-         
 
-         return request.Respond().Status(ResponseStatus.NotFound);
 
-     }
 
-     private IResponseBuilder HandlePOST(IRequest request)
 
-     {
 
-         var endpoint = request.Target.Current?.Value.ToLower() ?? "";
 
-         
 
-         if (endpoint.Equals(nameof(LicenseFeeRequest).ToLower()))
 
-             return RetrieveFees(request);
 
-         
 
-         if (endpoint.Equals(nameof(LicenseRenewalRequest).ToLower()))
 
-             return RenewLicense(request);
 
-         
 
-         return request.Respond().Status(ResponseStatus.NotFound);
 
-     }
 
-     public override ValueTask<IResponse?> HandleAsync(IRequest request)
 
-     {
 
-         try
 
-         {
 
-             switch (request.Method.KnownMethod)
 
-             {
 
-                 case RequestMethod.GET:
 
-                     return new ValueTask<IResponse?>(HandleGET(request).Build());
 
-                 case RequestMethod.POST:
 
-                     return new ValueTask<IResponse?>(HandlePOST(request).Build());
 
-                 default:
 
-                     Logger.Send(LogType.Error, ClientFactory.UserID, $"Request method {request.Method.RawMethod} unknown");
 
-                     return new ValueTask<IResponse?>(request.Respond().Status(ResponseStatus.MethodNotAllowed).Build());
 
-             }
 
-         }
 
-         catch (Exception eListen)
 
-         {
 
-             Logger.Send(LogType.Error, ClientFactory.UserID, eListen.Message);
 
-             return new ValueTask<IResponse?>(request.Respond().Status(ResponseStatus.InternalServerError).Build());
 
-         }
 
-     }
 
- }
 
 
  |