Commit be393bc

mo khan <mo@mokhan.ca>
2010-02-23 04:29:08
* fixed the registration of the dispather synchronization context. + imported the payroll stuff.
1 parent 1860425
product/client/presentation.windows/bootstrappers/Bootstrapper.cs
@@ -1,8 +1,9 @@
-using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Diagnostics;
 using System.IO;
+using System.Threading;
+using System.Windows.Threading;
 using Autofac.Builder;
 using FluentNHibernate.Cfg;
 using FluentNHibernate.Cfg.Db;
@@ -57,16 +58,19 @@ namespace presentation.windows.bootstrappers
             builder.Register(x => create_application_context()).SingletonScoped();
 
             // presentation infrastructure
+            SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext());
             builder.Register<WpfApplicationController>().As<ApplicationController>().SingletonScoped();
             builder.Register<WpfPresenterFactory>().As<PresenterFactory>().SingletonScoped();
             builder.Register<SynchronizedEventAggregator>().As<EventAggregator>().SingletonScoped();
-            builder.Register(x => AsyncOperationManager.SynchronizationContext);
+            //builder.Register(x => AsyncOperationManager.SynchronizationContext);
+            builder.Register(x => SynchronizationContext.Current);
+
 
             // presenters
             builder.Register<StatusBarPresenter>().SingletonScoped();
-            builder.Register<CompensationPresenter>();
+            builder.Register<CompensationPresenter>().SingletonScoped();
+            builder.Register<SelectedFamilyMemberPresenter>().SingletonScoped();
             builder.Register<AddFamilyMemberPresenter>();
-            builder.Register<SelectedFamilyMemberPresenter>();
 
             // commanding
             builder.Register<ContainerCommandBuilder>().As<CommandBuilder>().SingletonScoped();
@@ -95,7 +99,7 @@ namespace presentation.windows.bootstrappers
         static ISession current_session(Autofac.IContext x)
         {
             var session = x.Resolve<IContext>().value_for(new TypedKey<ISession>());
-            if(null == session) Debugger.Break();
+            if (null == session) Debugger.Break();
             return session;
         }
 
product/client/presentation.windows/domain/payroll/Calendar.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace presentation.windows.domain.payroll
+{
+    static public class Calendar
+    {
+        static Func<Date> date = () => DateTime.Now.Date;
+        static Func<Date> default_date = () => DateTime.Now.Date;
+
+        static public void stop(Func<Date> new_date)
+        {
+            date = new_date;
+        }
+
+        static public void start()
+        {
+            date = default_date;
+        }
+
+        static public Date now()
+        {
+            return date();
+        }
+    }
+}
\ No newline at end of file
product/client/presentation.windows/domain/payroll/Compensation.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+using System.Linq;
+using gorilla.commons.utility;
+
+namespace presentation.windows.domain.payroll
+{
+    public class Compensation
+    {
+        Money salary = Money.Zero;
+        IList<Grant> grants = new List<Grant>();
+
+        public void increase_salary_to(Money newSalary)
+        {
+            salary = newSalary;
+        }
+
+        public void issue_grant(Money grant_value, UnitPrice price)
+        {
+            grants.Add(Grant.New(grant_value, price));
+        }
+
+        public Grant grant_for(Date date)
+        {
+            return grants.Single(x => x.was_issued_on(date));
+        }
+
+        public Money how_much_will_they_take_home_in(int year)
+        {
+            var total = Money.Zero;
+            grants
+                .Where(x => x.will_vest_in(year))
+                .each(x => total = total.Plus(x.vesting_amount()));
+            return total.Plus(salary);
+        }
+    }
+}
\ No newline at end of file
product/client/presentation.windows/domain/payroll/Date.cs
@@ -0,0 +1,39 @@
+using System;
+
+namespace presentation.windows.domain.payroll
+{
+    public class Date
+    {
+        long ticks;
+
+        Date(DateTime date)
+        {
+            ticks = date.Date.Ticks;
+        }
+
+        static public implicit operator Date(DateTime raw)
+        {
+            return new Date(raw);
+        }
+
+        public bool Equals(Date other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return other.ticks == ticks;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (Date)) return false;
+            return Equals((Date) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return ticks.GetHashCode();
+        }
+    }
+}
\ No newline at end of file
product/client/presentation.windows/domain/payroll/Grant.cs
@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using gorilla.commons.utility;
+
+namespace presentation.windows.domain.payroll
+{
+    public class Grant
+    {
+        Date issued_on;
+        IList<Unit> units_issued = new List<Unit>();
+
+        static public Grant New(Money purchase_amount, UnitPrice price)
+        {
+            var grant = new Grant
+                        {
+                            issued_on = Calendar.now(),
+                        };
+            price.purchase_units(purchase_amount).each(x => grant.add(x));
+            return grant;
+        }
+
+        public void change_unit_price_to(UnitPrice new_price)
+        {
+            units_issued.each(x => x.change_price(new_price));
+        }
+
+        public bool was_issued_on(Date date)
+        {
+            return issued_on.Equals(date);
+        }
+
+        public Money current_value()
+        {
+            var total = Money.Zero;
+            units_issued.each(x => total = total.Plus(x.current_value()));
+            return total;
+        }
+
+        void add(Unit unit)
+        {
+            units_issued.Add(unit);
+        }
+
+        public bool will_vest_in(int year)
+        {
+            return true;
+        }
+
+        public Money vesting_amount()
+        {
+            return current_value().divided_by(3);
+        }
+    }
+}
\ No newline at end of file
product/client/presentation.windows/domain/payroll/History.cs
@@ -0,0 +1,24 @@
+namespace presentation.windows.domain.payroll
+{
+    public class History
+    {
+        Date dateOfChange;
+        UnitPrice adjustedPrice;
+
+        History() {}
+
+        static public History New(UnitPrice newPrice)
+        {
+            return new History
+                   {
+                       dateOfChange = Calendar.now(),
+                       adjustedPrice = newPrice,
+                   };
+        }
+
+        public UnitPrice Adjustment()
+        {
+            return adjustedPrice;
+        }
+    }
+}
\ No newline at end of file
product/client/presentation.windows/domain/payroll/Money.cs
@@ -0,0 +1,65 @@
+using System;
+
+namespace presentation.windows.domain.payroll
+{
+    public class Money : IEquatable<Money>
+    {
+        public double value { get; private set; }
+        static public Money Zero = new Money(0);
+
+        Money(double value)
+        {
+            this.value = value;
+        }
+
+        static public implicit operator Money(double raw)
+        {
+            return new Money(raw);
+        }
+
+        public Money Plus(Money otherMoney)
+        {
+            return value + otherMoney.value;
+        }
+
+        public bool Equals(Money other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return other.value == value;
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            if (ReferenceEquals(this, obj)) return true;
+            if (obj.GetType() != typeof (Money)) return false;
+            return Equals((Money) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            return value.GetHashCode();
+        }
+
+        static public bool operator ==(Money left, Money right)
+        {
+            return Equals(left, right);
+        }
+
+        static public bool operator !=(Money left, Money right)
+        {
+            return !Equals(left, right);
+        }
+
+        public override string ToString()
+        {
+            return value.ToString("c");
+        }
+
+        public Money divided_by(int denominator)
+        {
+            return new Money(value/denominator);
+        }
+    }
+}
\ No newline at end of file
product/client/presentation.windows/domain/payroll/Unit.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+
+namespace presentation.windows.domain.payroll
+{
+    public class Unit
+    {
+        UnitPrice current_price;
+        IList<History> history = new List<History>();
+
+        static public Unit New(UnitPrice price)
+        {
+            var unit = new Unit();
+            unit.change_price(price);
+            return unit;
+        }
+
+        public void change_price(UnitPrice new_price)
+        {
+            current_price = new_price ?? 0;
+            history.Add(History.New(new_price));
+        }
+
+        public Money current_value()
+        {
+            return current_price.to_money();
+        }
+    }
+}
\ No newline at end of file
product/client/presentation.windows/domain/payroll/UnitPrice.cs
@@ -0,0 +1,34 @@
+using System.Collections.Generic;
+
+namespace presentation.windows.domain.payroll
+{
+    public class UnitPrice
+    {
+        double price;
+
+        UnitPrice(double price)
+        {
+            this.price = price;
+        }
+
+        static public implicit operator UnitPrice(double raw)
+        {
+            return new UnitPrice(raw);
+        }
+
+        public IEnumerable<Unit> purchase_units(Money amount)
+        {
+            for (var i = 0; i < number_of_units(amount); i++) yield return Unit.New(this);
+        }
+
+        double number_of_units(Money amount)
+        {
+            return amount.value/price;
+        }
+
+        public Money to_money()
+        {
+            return price;
+        }
+    }
+}
\ No newline at end of file
product/client/presentation.windows/presenters/AddFamilyMemberPresenter.cs
@@ -1,4 +1,5 @@
 using System;
+using Gorilla.Commons.Utility;
 using MoMoney.Service.Infrastructure.Threading;
 using presentation.windows.commands;
 using presentation.windows.commands.dto;
@@ -35,6 +36,7 @@ namespace presentation.windows.presenters
             {
                 close();
             });
+            date_of_birth = Clock.today();
         }
 
         public string first_name { get; set; }
product/client/presentation.windows/presenters/CompensationPresenter.cs
@@ -1,6 +1,9 @@
+using MoMoney.Service.Infrastructure.Eventing;
+using presentation.windows.events;
+
 namespace presentation.windows.presenters
 {
-    public class CompensationPresenter : TabPresenter
+    public class CompensationPresenter : TabPresenter, EventSubscriber<SelectedFamilyMember>
     {
         public string Header
         {
@@ -8,5 +11,7 @@ namespace presentation.windows.presenters
         }
 
         public void present() {}
+
+        public void notify(SelectedFamilyMember message) {}
     }
 }
\ No newline at end of file
product/client/presentation.windows/presenters/SelectedFamilyMemberPresenter.cs
@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using System.Linq;
+using System.Collections.ObjectModel;
 using MoMoney.Service.Infrastructure.Eventing;
 using presentation.windows.events;
 using presentation.windows.queries;
@@ -18,7 +17,7 @@ namespace presentation.windows.presenters
             this.event_aggregator = event_aggregator;
         }
 
-        public IList<PersonDetails> family_members { get; set; }
+        public ObservableCollection<PersonDetails> family_members { get; set; }
 
         public PersonDetails SelectedMember
         {
@@ -33,7 +32,7 @@ namespace presentation.windows.presenters
 
         public void present()
         {
-            builder.build<FindAllFamily>(x => family_members = x.fetch().ToList());
+            builder.build<FindAllFamily>(x => family_members = x.fetch().to_observable());
             update(x => x.family_members);
         }
 
product/client/presentation.windows/presenters/WpfBindingExtensinos.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace presentation.windows.presenters
+{
+    static public class WpfBindingExtensinos
+    {
+        static public ObservableCollection<T> to_observable<T>(this IEnumerable<T> items)
+        {
+            return new ObservableCollection<T>(items);
+        }
+    }
+}
\ No newline at end of file
product/client/presentation.windows/views/AddFamilyMemberDialog.xaml
@@ -1,9 +1,9 @@
 <Window x:Class="presentation.windows.views.AddFamilyMemberDialog"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" Title="Add A Family Member" ShowInTaskbar="False" WindowStartupLocation="CenterScreen">
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" Title="Add A Family Member" ShowInTaskbar="False" WindowStartupLocation="CenterScreen" Width="400" Height="170">
     <DockPanel>
         <StackPanel>
-        <Label>Add A Family Member</Label>
+        <Label FontWeight="Bold">Add A Family Member</Label>
         <DockPanel>
             <UniformGrid Rows="3">
                 <Label>first name</Label>
@@ -14,8 +14,10 @@
                 <Controls:DatePicker SelectedDate="{Binding Path=date_of_birth, Mode=TwoWay}"></Controls:DatePicker>
             </UniformGrid>
         </DockPanel>
-        <Button Command="{Binding Save}">_Save</Button>
-        <Button Command="{Binding Cancel}">_Cancel</Button>
+        <UniformGrid Rows="1" >
+            <Button Command="{Binding Save}" IsDefault="True">_Save</Button>
+            <Button Command="{Binding Cancel}" IsCancel="True">_Cancel</Button>
+        </UniformGrid>
         </StackPanel>
     </DockPanel>
 </Window>
product/client/presentation.windows/views/CompensationTab.xaml
@@ -1,30 +1,26 @@
-<UserControl x:Class="presentation.windows.views.CompensationTab"
-    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" MinWidth="800" MinHeight="600">
-    <DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
-        <StackPanel>
-            <TabControl TabStripPlacement="Left">
-                <TabItem Header="Base Pay">
-        <DockPanel>
-        <Label>Enter Salary:</Label>
-        <TextBox></TextBox>
-        </DockPanel>
-                </TabItem>
-                <TabItem Header="Bonus">
-        <DockPanel>
-        <Label>Enter Bonus:</Label>
-        <TextBox></TextBox>
-        </DockPanel>
-                    
-                </TabItem>
-                <TabItem Header="LTIP">
-        <DockPanel>
-        <Label>Enter Grant:</Label>
-        <TextBox></TextBox>
-        </DockPanel>
-                    
-                </TabItem>
-            </TabControl>
-        </StackPanel>
-    </DockPanel>
-</UserControl>
+<UserControl x:Class="presentation.windows.views.CompensationTab" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" MinWidth="800" MinHeight="600">
+	<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
+		<StackPanel>
+			<TabControl TabStripPlacement="Left">
+				<TabItem Header="Base Pay">
+					<DockPanel>
+						<Label>Enter Salary:</Label>
+						<TextBox></TextBox>
+					</DockPanel>
+				</TabItem>
+				<TabItem Header="Bonus">
+					<DockPanel>
+						<Label>Enter Bonus:</Label>
+						<TextBox></TextBox>
+					</DockPanel>
+				</TabItem>
+				<TabItem Header="LTIP">
+					<DockPanel>
+						<Label>Enter Grant:</Label>
+						<TextBox></TextBox>
+					</DockPanel>
+				</TabItem>
+			</TabControl>
+		</StackPanel>
+	</DockPanel>
+</UserControl>
\ No newline at end of file
product/client/presentation.windows/presentation.windows.csproj
@@ -122,6 +122,14 @@
     <Compile Include="ApplicationController.cs" />
     <Compile Include="bootstrappers\Bootstrapper.cs" />
     <Compile Include="bootstrappers\ConfigureMappings.cs" />
+    <Compile Include="domain\payroll\Calendar.cs" />
+    <Compile Include="domain\payroll\Compensation.cs" />
+    <Compile Include="domain\payroll\Date.cs" />
+    <Compile Include="domain\payroll\Grant.cs" />
+    <Compile Include="domain\payroll\History.cs" />
+    <Compile Include="domain\payroll\Money.cs" />
+    <Compile Include="domain\payroll\Unit.cs" />
+    <Compile Include="domain\payroll\UnitPrice.cs" />
     <Compile Include="events\SelectedFamilyMember.cs" />
     <Compile Include="orm\nhibernate\NHibernateUnitOfWorkFactory.cs" />
     <Compile Include="orm\nhibernate\NHibernateUnitOfWork.cs" />
@@ -146,6 +154,7 @@
     <Compile Include="commands\ContainerCommandBuilder.cs" />
     <Compile Include="commands\NamedCommand.cs" />
     <Compile Include="commands\ContainerAwareParameterizedCommandBuilder.cs" />
+    <Compile Include="presenters\WpfBindingExtensinos.cs" />
     <Compile Include="queries\ContainerAwareQueryBuilder.cs" />
     <Compile Include="queries\FindAllFamily.cs" />
     <Compile Include="queries\FindMemberIdentifiedBy.cs" />