main
1using System.Collections.Generic;
2using Gorilla.Commons.Utility;
3
4namespace presentation.windows.server.domain.payroll
5{
6 public class Grant
7 {
8 Date issued_on;
9 History<UnitPrice> price_history = new History<UnitPrice>();
10 Units units = Units.Empty;
11 List<Vest> expirations = new List<Vest>();
12
13 static public Grant New(Money purchase_amount, UnitPrice price, Fraction portion, Frequency frequency)
14 {
15 var grant = new Grant
16 {
17 issued_on = Calendar.now(),
18 };
19 grant.change_unit_price_to(price);
20 grant.purchase(purchase_amount);
21 grant.apply_vesting_frequency(portion, frequency);
22 return grant;
23 }
24
25 Grant() {}
26
27 public virtual void change_unit_price_to(UnitPrice new_price)
28 {
29 price_history.record(new_price);
30 }
31
32 public virtual bool was_issued_on(Date date)
33 {
34 return issued_on.Equals(date);
35 }
36
37 public virtual Money balance()
38 {
39 return balance(Calendar.now());
40 }
41
42 public virtual Money balance(Date on_date)
43 {
44 return unit_price(on_date).total_value_of(units_remaining(on_date));
45 }
46
47 Units units_remaining(Date on_date)
48 {
49 var remaining = Units.Empty;
50 foreach (var expiration in expirations)
51 {
52 remaining = remaining.combined_with(expiration.unvested_units(units, on_date));
53 }
54 return remaining;
55 }
56
57 void purchase(Money amount)
58 {
59 units = units.combined_with(current_unit_price().purchase_units(amount));
60 }
61
62 UnitPrice current_unit_price()
63 {
64 return unit_price(Calendar.now());
65 }
66
67 UnitPrice unit_price(Date on_date)
68 {
69 return price_history.recorded(on_date);
70 }
71
72 void apply_vesting_frequency(Fraction portion, Frequency frequency)
73 {
74 var next_date = issued_on.minus_days(1);
75 portion.each(x =>
76 {
77 next_date = frequency.next(next_date);
78 expirations.Add(new Vest(portion, next_date));
79 });
80 }
81 }
82}