Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OaaS/HeuristicLab.Services.Optimization.Billing/BillingEngine/BillingEngine.cs @ 9619

Last change on this file since 9619 was 9619, checked in by spimming, 10 years ago

#1888:

  • Added new BillingService methods
  • Disabled proxy generation and lazy loading!
  • Extended see method with additional test data
  • Added properties to order and invoice model
  • initial commit of BillingEngine module
File size: 6.1 KB
Line 
1
2using System;
3using System.Collections.Generic;
4using System.Configuration;
5using System.Diagnostics;
6using System.Linq;
7using System.Threading;
8using HeuristicLab.Services.Optimization.Billing.Business;
9using HeuristicLab.Services.Optimization.Billing.Interfaces;
10using HeuristicLab.Services.Optimization.Billing.Model;
11namespace HeuristicLab.Services.Optimization.Billing.BillingEngine {
12  public class BillingEngine {
13    private bool stop;
14    private AutoResetEvent waitHandle;
15    private TimeSpan interval;
16    private DateTime currentDate;
17
18    private IOptimizationBilling billingService;
19    public IOptimizationBilling BillingService {
20      get {
21        if (billingService == null) {
22          billingService = new BillingService();
23        }
24        return billingService;
25      }
26      set { billingService = value; }
27    }
28
29    private IInvoiceFormattingEngine invoiceFormattingEngine;
30    public IInvoiceFormattingEngine InvoiceFormattingEngine {
31      get {
32        if (invoiceFormattingEngine == null) {
33          invoiceFormattingEngine = new PlainTextInvoiceFormattingEngine();
34        }
35        return invoiceFormattingEngine;
36      }
37      set { invoiceFormattingEngine = value; }
38    }
39
40    public BillingEngine() {
41      stop = false;
42      interval = TimeSpan.Parse(ConfigurationManager.AppSettings["BillingEngineInterval"]);
43      waitHandle = new AutoResetEvent(true);
44    }
45
46    public void StopBillingEngine() {
47      stop = true;
48      waitHandle.Set();
49    }
50
51    public void Run() {
52      while (!stop) {
53        try {
54          Trace.WriteLine("[BillingEngine] Start billing cycle");
55          //currentDate = DateTime.Parse(DateTime.Now.ToShortDateString());
56          currentDate = DateTime.Now.Date;
57          Trace.WriteLine(string.Format("[BillingEngine] Current date: {0}", currentDate));
58          IList<Order> activeOrders = BillingService.GetOrdersByState(OrderState.Active);
59          Trace.WriteLine(string.Format("[BillingEngine] Processing {0} active orders.", activeOrders.Count));
60          foreach (Order order in activeOrders) {
61            if (!order.NextBillableDay.HasValue) {
62              // there has never been an invoice generated from this order
63              order.NextBillableDay = currentDate;
64            }
65
66            if (order.NextBillableDay >= currentDate) {
67              // TODO: Embed everything in a transaction
68
69              // Collect Usage Data
70              //IList<UsageRecord> usageRecrods = BillingService.GetUsageRecords(order.User.Name, order.LastBillableDay.Value, currentDate);
71
72              // Collect Invoice Data
73              Invoice invoice = new Invoice();
74              invoice.Order = order;
75              invoice.User = order.User;
76              invoice.Due = currentDate.AddMonths(1);
77              invoice.InvoiceDate = currentDate;
78              invoice.Status = InvoiceStatus.Open;
79              invoice.InvoiceLines = new List<InvoiceLine>();
80              foreach (OrderLine orderLine in order.OrderLines) {
81                InvoiceLine invoiceLine = new InvoiceLine();
82                invoiceLine.Invoice = invoice;
83                invoiceLine.Product = orderLine.Product;
84                invoiceLine.ProductPrice = orderLine.ProductPrice;
85                invoiceLine.Quantity = invoiceLine.Quantity;
86                invoice.InvoiceLines.Add(invoiceLine);
87              }
88
89              InvoiceLine usageCharges = new InvoiceLine();
90              usageCharges.Invoice = invoice;
91              usageCharges.Product = billingService.GetProductByName("Oaas Usage Charges").First();
92              usageCharges.ProductPrice = 999.99;
93              usageCharges.Quantity = 1;
94              invoice.InvoiceLines.Add(usageCharges);
95
96              // Bill Post Processing: Apply Discounts or Promotions
97              // eg. add discounts
98              // sum up items to sub-total, calc. tax -> total current charges
99
100              // Invoice Formatting Engine: Generate Invoice
101              invoice.InvoiceDocument = InvoiceFormattingEngine.Generate(invoice);
102
103              UpdateBillingState(order);
104              billingService.UpdateOrder(order);
105            }
106          }
107
108          Trace.WriteLine("[BillingEngine] Finished billing cycle");
109        }
110        catch (Exception e) {
111          Trace.WriteLine(string.Format("[BillingEngine] The following exception occured: {0}", e.ToString()));
112        }
113        waitHandle.WaitOne(interval);
114      }
115      waitHandle.Close();
116    }
117
118    private void UpdateBillingState(Order order) {
119      if (order.ActiveUntil != null && order.ActiveUntil == order.NextBillableDay) {
120        order.NextBillableDay = null;
121        order.State = OrderState.Finished;
122      }
123
124      DateTime nextBillingDay = CalculateNextBillingDate(order);
125
126      if (order.ActiveUntil != null && order.ActiveUntil < nextBillingDay) {
127        order.NextBillableDay = nextBillingDay;
128      }
129    }
130
131    private DateTime CalculateNextBillingDate(Order order) {
132      DateTime nextBillingDay = currentDate;
133
134      if (order.BillingPeriod == BillingPeriod.Weekly) {
135        nextBillingDay = nextBillingDay.AddDays(7);
136      } else if (order.BillingPeriod == BillingPeriod.Monthly) {
137        if (order.BillingType == BillingType.Pre) {
138          nextBillingDay = nextBillingDay.AddDays(DateTime.DaysInMonth(nextBillingDay.Year, nextBillingDay.Month) + 1);
139        } else if (order.BillingType == BillingType.Post) {
140          if (nextBillingDay.Month == 12) {
141            nextBillingDay = nextBillingDay.AddDays(DateTime.DaysInMonth(nextBillingDay.Year + 1, 1) + 1);
142          } else {
143            nextBillingDay = nextBillingDay.AddDays(DateTime.DaysInMonth(nextBillingDay.Year, nextBillingDay.Month + 1) + 1);
144          }
145        }
146      } else if (order.BillingPeriod == BillingPeriod.Yearly) {
147        if (order.BillingType == BillingType.Pre) {
148          nextBillingDay = new DateTime(DateTime.Now.Year + 1, 1, 1);
149        } else if (order.BillingType == BillingType.Post) {
150          nextBillingDay = new DateTime(DateTime.Now.Year + 1, 12, 31);
151        }
152      }
153
154      return nextBillingDay;
155    }
156  }
157}
Note: See TracBrowser for help on using the repository browser.