Commit be393bc
Changed files (16)
product
client
presentation.windows
bootstrappers
domain
presenters
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" />