Commit a994056

mo <email@solidware.ca>
2011-03-31 03:12:10
sorted out the federal tax calculation.
1 parent d22bdcb
product/desktop.ui/model/TaxesForIndividual.cs
@@ -1,6 +1,6 @@
 using System;
-using System.Collections.Generic;
 using solidware.financials.windows.ui.presenters;
+using solidware.financials.windows.ui.views.controls;
 
 namespace solidware.financials.windows.ui.model
 {
@@ -10,24 +10,17 @@ namespace solidware.financials.windows.ui.model
         {
             FederalTaxes = federalTaxes;
             Id = id;
-            ProvincialTaxesGrid = new List<TaxRow>
-                                  {
-                                      new TaxRow {Name = "john doe", Tax = 23456.09m},
-                                      new TaxRow {Name = "sally doe", Tax = 9456.09m},
-                                  };
+            TotalIncome = Money.Null;
         }
 
         public Guid Id { get; private set; }
-        public decimal TotalIncome { get; private set; }
-        public decimal TotalFamilyIncome { get; private set; }
-        public IEnumerable<TaxRow> ProvincialTaxesGrid { get; private set; }
+        public Observable<Money> TotalIncome { get; private set; }
         public FederalTaxesViewModel FederalTaxes { get; set; }
 
         public void AddIncome(decimal amount)
         {
-            TotalIncome += amount;
-            FederalTaxes.ChangeTotalIncomeTo(TotalIncome);
-            update(x => x.TotalIncome);
+            TotalIncome.Value += amount;
+            FederalTaxes.ApplyTaxesTo(TotalIncome.Value);
         }
     }
 }
\ No newline at end of file
product/desktop.ui/presenters/AddNewIncomeViewModel.cs
@@ -1,4 +1,5 @@
 using System;
+using gorilla.utility;
 using solidware.financials.infrastructure;
 using solidware.financials.messages;
 using solidware.financials.windows.ui.events;
@@ -19,9 +20,11 @@ namespace solidware.financials.windows.ui.presenters
         {
             Add = builder.build<AddIncomeCommand, IfFamilyMemberIsSelected<AddNewIncomeViewModel>>(this);
             Cancel = builder.build<CancelCommand>(this);
+            date = Clock.now();
         }
 
         public virtual decimal amount { get; set; }
+        public virtual DateTime date { get; set; }
         public IObservableCommand Add { get; set; }
         public IObservableCommand Cancel { get; set; }
         public virtual Action close { get; set; }
@@ -42,10 +45,12 @@ namespace solidware.financials.windows.ui.presenters
                 bus.publish(new AddIncomeCommandMessage
                             {
                                 Amount = presenter.amount,
-                                PersonId = applicationState.PullOut<SelectedFamilyMember>().id
+                                PersonId = applicationState.PullOut<SelectedFamilyMember>().id,
+                                Date = presenter.date,
                             });
                 presenter.close();
             }
         }
+
     }
 }
\ No newline at end of file
product/desktop.ui/presenters/FederalTaxesViewModel.cs
@@ -1,6 +1,5 @@
 using System;
 using solidware.financials.windows.ui.model;
-using solidware.financials.windows.ui.views.controls;
 
 namespace solidware.financials.windows.ui.presenters
 {
@@ -9,39 +8,15 @@ namespace solidware.financials.windows.ui.presenters
         public FederalTaxesViewModel(Guid id)
         {
             Id = id;
-            FederalTaxesGrid = CreateSampleTable();
+            Taxes = Money.Null;
         }
 
         public Guid Id { get; private set; }
-        public decimal FederalTaxes { get; set; }
-        public decimal FederalFamilyTaxes { get; private set; }
-        public DataGridTable FederalTaxesGrid { get; private set; }
+        public views.controls.Observable<Money> Taxes { get; set; }
 
-        public void ChangeTotalIncomeTo(decimal totalIncome)
+        public void ApplyTaxesTo(Money totalIncome)
         {
-            FederalTaxes = new FederalTaxes().CalculateFederalTaxesFor(totalIncome);
-            FederalTaxesGrid.AddRow(x =>
-            {
-                x.AddToCell(new Column<string>("Name"), "blah");
-                x.AddToCell(new Column<decimal>("Tax"), totalIncome);
-            });
-            update(x => x.FederalTaxes);
-        }
-
-        DataGridTable CreateSampleTable()
-        {
-            var table = new DataGridTable();
-            var nameColumn = table.CreateColumn<string>("Name");
-            var tax = table.CreateColumn<decimal>("Tax");
-
-            table.AddRow(x =>
-            {
-                x.AddToCell(nameColumn, "mo");
-                x.AddToCell(tax, 12345.67m);
-            });
-            table.AddRow(x => x.AddToCell(nameColumn, "allison"));
-            table.FindRowFor(nameColumn, "allison").AddToCell(tax, 98765.43m);
-            return table;
+            Taxes.Value = new FederalTaxes().CalculateFederalTaxesFor(totalIncome);
         }
     }
 }
\ No newline at end of file
product/desktop.ui/presenters/Money.cs
@@ -0,0 +1,57 @@
+using gorilla.utility;
+using solidware.financials.windows.ui.views.controls;
+
+namespace solidware.financials.windows.ui.presenters
+{
+    public class Money
+    {
+        static public readonly Money Zero = new Money(0m);
+        static public Observable<Money> Null { get { return new ObservableProperty<Money>(Zero); } }
+
+        public Money(decimal money)
+        {
+            this.money = money;
+        }
+        static public implicit operator decimal(Money money)
+        {
+            return money.money;
+        }
+
+        static public implicit operator Money(decimal money)
+        {
+            return new Money(money);
+        }
+
+        public Money Plus(Money other)
+        {
+            return new Money(money + other.money);
+        }
+
+        public bool Equals(Money other)
+        {
+            if (ReferenceEquals(null, other)) return false;
+            if (ReferenceEquals(this, other)) return true;
+            return other.money == money;
+        }
+
+        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 money.GetHashCode();
+        }
+
+        public override string ToString()
+        {
+            return "{0:C}".format(money);
+        }
+
+        decimal money;
+    }
+}
\ No newline at end of file
product/desktop.ui/presenters/TaxSummaryPresenter.cs
@@ -1,10 +1,12 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using solidware.financials.infrastructure;
 using solidware.financials.infrastructure.eventing;
 using solidware.financials.messages;
 using solidware.financials.windows.ui.events;
 using solidware.financials.windows.ui.model;
+using solidware.financials.windows.ui.views.controls;
 
 namespace solidware.financials.windows.ui.presenters
 {
@@ -17,11 +19,8 @@ namespace solidware.financials.windows.ui.presenters
         {
             this.builder = builder;
             this.bus = bus;
-        }
-
-        public void present()
-        {
-            bus.publish<FindAllIncome>();
+            FamilyIncome = Money.Null;
+            TotalFamilyFederalTaxes = Money.Null;
         }
 
         public string Header
@@ -30,11 +29,19 @@ namespace solidware.financials.windows.ui.presenters
         }
 
         public TaxesForIndividual Selected { get; set; }
-        public FederalTaxesViewModel FederalTaxes { get { return Selected.FederalTaxes; } }
+        public Observable<Money> FamilyIncome { get; set; }
+        public Observable<Money> TotalFamilyFederalTaxes { get; set; }
+
+        public void present()
+        {
+            bus.publish<FindAllIncome>();
+        }
 
         public void notify(IncomeMessage message)
         {
+            FamilyIncome.Value += message.Amount;
             TaxesFor(message.PersonId).AddIncome(message.Amount);
+            TotalFamilyFederalTaxes.Value = family.Values.Sum(x => x.FederalTaxes.Taxes.Value);
         }
 
         public void notify(SelectedFamilyMember message)
product/desktop.ui/presenters/WpfBindingExtensinos.cs → product/desktop.ui/presenters/WpfBindingExtensions.cs
@@ -1,13 +1,19 @@
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
+using solidware.financials.windows.ui.views.controls;
 
 namespace solidware.financials.windows.ui.presenters
 {
-    static public class WpfBindingExtensinos
+    static public class WPFBindingExtensions
     {
         static public ObservableCollection<T> to_observable<T>(this IEnumerable<T> items)
         {
             return new ObservableCollection<T>(items);
         }
+
+        static public Observable<T> ToObservable<T>(this T item)
+        {
+            return new ObservableProperty<T>(item);
+        }
     }
 }
\ No newline at end of file
product/desktop.ui/views/controls/Column.cs
@@ -2,7 +2,12 @@
 
 namespace solidware.financials.windows.ui.views.controls
 {
-    public class Column<T> : IEquatable<Column<T>>
+    public interface IColumn
+    {
+        string Title { get; }
+    }
+
+    public class Column<T> : IEquatable<Column<T>>, IColumn
     {
         public string Title { get; private set; }
 
@@ -46,12 +51,12 @@ namespace solidware.financials.windows.ui.views.controls
             return (Title != null ? Title.GetHashCode() : 0);
         }
 
-        public static bool operator ==(Column<T> left, Column<T> right)
+        static public bool operator ==(Column<T> left, Column<T> right)
         {
             return Equals(left, right);
         }
 
-        public static bool operator !=(Column<T> left, Column<T> right)
+        static public bool operator !=(Column<T> left, Column<T> right)
         {
             return !Equals(left, right);
         }
product/desktop.ui/views/controls/DataGridTable.cs
@@ -11,6 +11,11 @@ namespace solidware.financials.windows.ui.views.controls
             return FindRowMatching(row => row.ValueStoredIn(column).Equals(expectedValue));
         }
 
+        public virtual bool HasRowFor<ColumnType>(Column<ColumnType> column, ColumnType expected)
+        {
+            return this.Any(row => row.ValueStoredIn(column).Equals(expected));
+        }
+
         public virtual Row FindRowMatching(Func<Row, bool> condition)
         {
             return this.First(condition);
product/desktop.ui/views/controls/IObservable.cs
@@ -1,9 +0,0 @@
-using System.ComponentModel;
-
-namespace solidware.financials.windows.ui.views.controls
-{
-    public interface IObservable : INotifyPropertyChanged
-    {
-        object Value { get; }
-    }
-}
\ No newline at end of file
product/desktop.ui/views/controls/ObjectExtensions.cs
@@ -22,9 +22,9 @@ namespace solidware.financials.windows.ui.views.controls
         {
             if (value is T)
                 return (T)value;
-            if(value is IObservable)
+            if(value is Observable)
             {
-                return (T)((IObservable)value).Value;
+                return (T)((Observable)value).Value;
             }
             return (T)Convert.ChangeType(value, typeof (T));
         }
product/desktop.ui/views/controls/Observable.cs
@@ -1,39 +1,16 @@
-using System.ComponentModel;
+using System;
+using System.ComponentModel;
 
 namespace solidware.financials.windows.ui.views.controls
 {
-    public class Observable<T> : IObservable
+    public interface Observable<T> : Observable
     {
-        private T value;
-
-        public Observable() { }
-
-        public Observable(T value)
-        {
-            this.value = value;
-        }
-
-        public T Value
-        {
-            get { return value; }
-            set
-            {
-                this.value = value;
-                PropertyChanged(this, new PropertyChangedEventArgs("Value"));
-            }
-        }
-
-        object IObservable.Value { get { return value; } }
-
-        public static implicit operator T(Observable<T> val)
-        {
-            return val.value;
-        }
+        T Value { get; set; }
+        void WhenChanged(Action observer);
+    }
 
-        public event PropertyChangedEventHandler PropertyChanged = delegate { };
-        public override string ToString()
-        {
-            return value.ToString();
-        }
+    public interface Observable : INotifyPropertyChanged
+    {
+        object Value { get; }
     }
 }
\ No newline at end of file
product/desktop.ui/views/controls/ObservableProperty.cs
@@ -0,0 +1,49 @@
+using System;
+using System.ComponentModel;
+
+namespace solidware.financials.windows.ui.views.controls
+{
+    public class ObservableProperty<T> : Observable<T>
+    {
+        T value;
+
+        public ObservableProperty() : this(default(T)) {}
+
+        public ObservableProperty(T value)
+        {
+            this.value = value;
+        }
+
+        public T Value
+        {
+            get { return value; }
+            set
+            {
+                this.value = value;
+                PropertyChanged(this, new PropertyChangedEventArgs("Value"));
+            }
+        }
+
+        public void WhenChanged(Action observer)
+        {
+            PropertyChanged += (o, e) => observer();
+        }
+
+        object Observable.Value
+        {
+            get { return value; }
+        }
+
+        static public implicit operator T(ObservableProperty<T> val)
+        {
+            return val.value;
+        }
+
+        public event PropertyChangedEventHandler PropertyChanged = (o, e) => {};
+
+        public override string ToString()
+        {
+            return value.ToString();
+        }
+    }
+}
\ No newline at end of file
product/desktop.ui/views/controls/Row.cs
@@ -4,7 +4,7 @@ using gorilla.utility;
 
 namespace solidware.financials.windows.ui.views.controls
 {
-    public class Row : Dictionary<string, IObservable> 
+    public class Row : Dictionary<string, Observable> 
     {
         DataGridTable table;
 
@@ -20,16 +20,16 @@ namespace solidware.financials.windows.ui.views.controls
 
         public virtual void AddToCell<T>(Column<T> column, T value)
         {
-            AddToCell(column, (IObservable)new Observable<T>(value));
+            AddToCell(column, (Observable)new ObservableProperty<T>(value));
         }
 
-        public virtual void AddToCell<T>(Column<T> column, IObservable value)
+        public virtual void AddToCell<T>(Column<T> column, Observable value)
         {
             this[column] = value;
             table.each(row =>
             {
                 if (!row.HasValueStoredIn(column))
-                    row[column] = new Observable<T>(default(T));
+                    row[column] = new ObservableProperty<T>(default(T));
             });
         }
 
product/desktop.ui/views/controls/SmartGrid.cs
@@ -1,13 +1,9 @@
-using System;
 using System.Collections;
-using System.Collections.Generic;
 using System.Linq;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
 using System.Windows.Input;
-using System.Windows.Media;
-using gorilla.utility;
 
 namespace solidware.financials.windows.ui.views.controls
 {
@@ -16,21 +12,9 @@ namespace solidware.financials.windows.ui.views.controls
         static SmartGrid()
         {
             IsReadOnlyProperty.OverrideMetadata(typeof (SmartGrid), new FrameworkPropertyMetadata((o, e) => ((SmartGrid) o).ConfigureColumns()));
-            ValueConvertersProperty.OverrideMetadata(typeof (SmartGrid), new FrameworkPropertyMetadata((o, e) => ((SmartGrid) o).ConfigureColumns()));
             CommandManager.RegisterClassCommandBinding(typeof (SmartGrid), new CommandBinding(ApplicationCommands.Paste, (o, e) => ((SmartGrid) o).OnExecutedPaste()));
         }
 
-        static public readonly DependencyProperty ReadOnlyColumnsProperty = DependencyProperty.Register("ReadOnlyColumns", typeof (IEnumerable<string>), typeof (SmartGrid));
-        static public readonly DependencyProperty HeaderColumnsProperty = DependencyProperty.Register("HeaderColumns", typeof (IEnumerable<string>), typeof (SmartGrid));
-
-        static public readonly DependencyProperty ValueConvertersProperty = DependencyProperty.Register("ValueConverters", typeof (IEnumerable<KeyValuePair<string, IValueConverter>>),
-                                                                                                        typeof (SmartGrid));
-
-        static public readonly DependencyProperty ReadOnlyItemsProperty = DependencyProperty.Register("ReadOnlyItems", typeof (IEnumerable<IDictionary<string, object>>), typeof (SmartGrid));
-
-        static readonly SolidColorBrush HeaderColour = Brushes.LightGray;
-        static readonly SolidColorBrush ReadOnlyColour = Brushes.WhiteSmoke;
-
         public SmartGrid()
         {
             SelectionUnit = DataGridSelectionUnit.CellOrRowHeader;
@@ -44,95 +28,11 @@ namespace solidware.financials.windows.ui.views.controls
                           };
         }
 
-        public virtual IEnumerable<IDictionary<string, object>> ReadOnlyItems
-        {
-            get { return (IEnumerable<IDictionary<string, object>>) GetValue(ReadOnlyItemsProperty) ?? Enumerable.Empty<IDictionary<string, object>>(); }
-            set { SetValue(ReadOnlyItemsProperty, value); }
-        }
-
-        public IEnumerable<string> ReadOnlyColumns
-        {
-            get { return (IEnumerable<string>) GetValue(ReadOnlyColumnsProperty) ?? Enumerable.Empty<string>(); }
-            set
-            {
-                SetValue(ReadOnlyColumnsProperty, value);
-                if (Columns != null && Columns.Count > 0)
-                {
-                    ConfigureColumns();
-                }
-            }
-        }
-
-        public IEnumerable<string> HeaderColumns
-        {
-            get { return (IEnumerable<string>) GetValue(HeaderColumnsProperty) ?? Enumerable.Empty<string>(); }
-            set
-            {
-                SetValue(HeaderColumnsProperty, value);
-                if (Columns != null && Columns.Count > 0)
-                {
-                    ConfigureColumns();
-                }
-            }
-        }
-
-        public IEnumerable<KeyValuePair<string, IValueConverter>> ValueConverters
-        {
-            get { return (IEnumerable<KeyValuePair<string, IValueConverter>>) GetValue(ValueConvertersProperty) ?? Enumerable.Empty<KeyValuePair<string, IValueConverter>>(); }
-            set
-            {
-                SetValue(ValueConvertersProperty, value);
-                if (Columns != null && Columns.Count > 0)
-                {
-                    ConfigureColumns();
-                }
-            }
-        }
-
         void ConfigureColumns()
         {
             foreach (var column in Columns)
             {
-                var header = column.Header.ToString();
-                column.IsReadOnly = IsReadOnly || ReadOnlyColumns.Contains(header);
-
-                Brush background = null;
-                if (HeaderColumns.Contains(header))
-                {
-                    background = HeaderColour;
-                }
-                else if (ReadOnlyColumns.Contains(header))
-                {
-                    background = ReadOnlyColour;
-                }
-                if (background != null)
-                {
-                    if (column.CellStyle == null) column.CellStyle = new Style();
-                    SetPropertyIfNotPresent(column, BackgroundProperty, background);
-                    SetPropertyIfNotPresent(column, ForegroundProperty, Brushes.Black);
-                }
-
-                var textColumn = column as DataGridTextColumn;
-                if (textColumn == null) continue;
-                var binding = textColumn.Binding as Binding;
-                if (binding == null) continue;
-                if (binding.Converter != null) continue; // Converter has already been bound and cannot be changed.
-
-                var valueConverter = ValueConverters.SingleOrDefault(x => x.Key == header).Value;
-
-                if (valueConverter != null)
-                {
-                    binding.Converter = valueConverter;
-                }
-            }
-        }
-
-        static void SetPropertyIfNotPresent(DataGridColumn column, DependencyProperty dependencyProperty, Brush brush)
-        {
-            var existing = column.CellStyle.Setters.OfType<Setter>().FirstOrDefault(x => x.Property == dependencyProperty);
-            if (existing == null)
-            {
-                column.CellStyle.Setters.Add(new Setter(dependencyProperty, brush));
+                column.IsReadOnly = IsReadOnly;
             }
         }
 
@@ -141,36 +41,25 @@ namespace solidware.financials.windows.ui.views.controls
             base.OnItemsSourceChanged(oldValue, newValue);
             if (newValue == null) return;
 
-           var enumerator = newValue.GetEnumerator();
+            var enumerator = newValue.GetEnumerator();
             if (!enumerator.MoveNext()) return;
 
-            var firstRow = enumerator.Current as IDictionary<string, IObservable>;
-
+            var firstRow = enumerator.Current as Row;
             if (firstRow == null) return;
 
-            AutoGenerateColumns = false; 
+            AutoGenerateColumns = false;
             Columns.Clear();
             foreach (var pair in firstRow)
             {
-                Columns.Add(new ExtendedTextColumn {Header = pair.Key, Binding = new Binding("[" + pair.Key + "].Value")});
+                Columns.Add(new ExtendedTextColumn
+                            {
+                                Header = pair.Key,
+                                Binding = new Binding("[" + pair.Key + "].Value")
+                            });
             }
             ConfigureColumns();
         }
 
-        protected override void OnLoadingRow(DataGridRowEventArgs e)
-        {
-            if (ReadOnlyItems != null)
-            {
-                e.Row.IsEnabled = !IsItemReadOnly(e.Row.Item);
-                if (!e.Row.IsEnabled)
-                {
-                    e.Row.Background = HeaderColour;
-                }
-            }
-
-            base.OnLoadingRow(e);
-        }
-
         protected virtual void OnExecutedPaste()
         {
             OnBeginningEdit(new DataGridBeginningEditEventArgs(Columns.First(), new DataGridRow(), new RoutedEventArgs()));
@@ -196,17 +85,11 @@ namespace solidware.financials.windows.ui.views.controls
                 {
                     var column = ColumnFromDisplayIndex(j);
                     if (column.IsReadOnly) continue;
-                    if (IsItemReadOnly(Items[i])) continue;
                     column.OnPastingCellClipboardContent(Items[i], rowData[rowDataIndex][columnDataIndex]);
                 }
             }
         }
 
-        bool IsItemReadOnly(object item)
-        {
-            return ReadOnlyItems.Any(x => ReferenceEquals(x, item));
-        }
-
         protected override void OnKeyUp(KeyEventArgs e)
         {
             switch (e.Key)
product/desktop.ui/views/AddNewIncomeDialog.xaml
@@ -2,15 +2,19 @@
  xmlns:ui="clr-namespace:solidware.financials.windows.ui"              
              x:TypeArguments="presenters:AddNewIncomeViewModel"  
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:presenters="clr-namespace:solidware.financials.windows.ui.presenters" Title="Add Income" Width="400" Height="100"  WindowStartupLocation="CenterOwner">
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:presenters="clr-namespace:solidware.financials.windows.ui.presenters" Title="Add Income" Width="400" Height="115"  WindowStartupLocation="CenterOwner">
     <StackPanel>
         <DockPanel>
-        <Label>Income Amount ($):</Label>
-        <TextBox Text="{Binding Path=amount,  UpdateSourceTrigger=PropertyChanged}"></TextBox>
+            <Label Width="120px">Income Amount ($):</Label>
+            <TextBox Text="{Binding Path=amount, UpdateSourceTrigger=PropertyChanged}"></TextBox>
+        </DockPanel>
+        <DockPanel>
+            <Label Width="120px">Date:</Label>
+            <DatePicker SelectedDate="{Binding Path=date}"></DatePicker>
         </DockPanel>
         <DockPanel LastChildFill="False" HorizontalAlignment="Right">
-        <Button IsDefault="True" Command="{Binding Path=Add}">_Add</Button>
-        <Button IsCancel="True" Command="{Binding Path=Cancel}">_Cancel</Button>
+            <Button IsDefault="True" Command="{Binding Path=Add}">_Add</Button>
+            <Button IsCancel="True" Command="{Binding Path=Cancel}">_Cancel</Button>
         </DockPanel>
     </StackPanel>
 </ui:WPFDialog >
product/desktop.ui/views/TaxSummaryTab.xaml
@@ -9,16 +9,24 @@
             <Label FontWeight="Bold">Income</Label>
             <DockPanel>
                 <Label Width="100">Individual:</Label>
-                <Label Content="{Binding Path=Selected.TotalIncome}" FontWeight="Bold"></Label>
+                <Label Content="{Binding Path=Selected.TotalIncome.Value}" FontWeight="Bold"></Label>
             </DockPanel>
             <DockPanel>
                 <Label Width="100">Family:</Label>
-                <Label Content="{Binding Path=Selected.TotalFamilyIncome}" FontWeight="Bold"></Label>
+                <Label Content="{Binding Path=FamilyIncome.Value}" FontWeight="Bold"></Label>
             </DockPanel>
             </StackPanel>
             <DockPanel LastChildFill="False" HorizontalAlignment="Stretch">
-            <StackPanel Margin="5,5,5,5" Width="500" DataContext="{Binding Path=FederalTaxes}">
-                <Label FontWeight="Bold">Federal Taxes</Label>
+            <GroupBox Header="Federal Taxes" Margin="5,5,5,5" >
+            <StackPanel Width="500">
+                <DockPanel>
+                    <Label Width="100">Individual:</Label>
+                    <Label Content="{Binding Path=Selected.FederalTaxes.Taxes.Value}" ContentStringFormat="{}{0:C}" FontWeight="Bold"/>
+                </DockPanel>
+                <DockPanel>
+                    <Label Width="100">Family:</Label>
+                    <Label Content="{Binding Path=TotalFamilyFederalTaxes}" FontWeight="Bold"/>
+                </DockPanel>
                 <Expander Header="Tax Rates">
                 <StackPanel>
                 <Label FontSize="10" FontWeight="Bold">Federal Tax Rates for 2011</Label>
@@ -30,16 +38,8 @@
                 </ListView>
                 </StackPanel>
                 </Expander>
-                <DockPanel>
-                    <Label Width="100">Individual:</Label>
-                    <Label Content="{Binding Path=FederalTaxes}" FontWeight="Bold"/>
-                </DockPanel>
-                <DockPanel>
-                    <Label Width="100">Family:</Label>
-                    <Label Content="{Binding Path=FederalFamilyTaxes}" FontWeight="Bold"/>
-                </DockPanel>
-                <controls:SmartGrid Margin="5,5,5,5" ItemsSource="{Binding FederalTaxesGrid, Mode=OneWay}" IsReadOnly="True"></controls:SmartGrid>
             </StackPanel>
+            </GroupBox>
             <StackPanel Margin="5,5,5,5" Width="500">
                 <Label FontWeight="Bold">Provincial Taxes</Label>
                 <Expander Header="Provincial Tax Rates">
@@ -54,11 +54,6 @@
                     <Label Width="100">Individual:</Label>
                     <Label Content="{Binding Path=Selected.ProvincialTaxes}" FontWeight="Bold"/>
                 </DockPanel>
-                <DockPanel>
-                    <Label Width="100">Family:</Label>
-                    <Label Content="{Binding Path=Selected.FamilyProvincialTaxes}" FontWeight="Bold"/>
-                </DockPanel>
-                <DataGrid Margin="5,5,5,5" ItemsSource="{Binding Selected.ProvincialTaxesGrid, Mode=OneWay}" IsReadOnly="true"></DataGrid>
             </StackPanel>
             </DockPanel>
         </StackPanel>
product/desktop.ui/solidware.financials.csproj
@@ -135,12 +135,13 @@
     <Compile Include="presenters\DisplayCanadianTaxInformationViewModel.cs" />
     <Compile Include="model\PersonDetails.cs" />
     <Compile Include="presenters\FederalTaxesViewModel.cs" />
+    <Compile Include="presenters\Money.cs" />
     <Compile Include="presenters\specifications\IfFamilyMemberIsSelected.cs" />
     <Compile Include="presenters\ButtonBarPresenter.cs" />
     <Compile Include="presenters\TaxSummaryPresenter.cs" />
     <Compile Include="presenters\StatusBarPresenter.cs" />
     <Compile Include="presenters\ToastViewModel.cs" />
-    <Compile Include="presenters\WpfBindingExtensinos.cs" />
+    <Compile Include="presenters\WpfBindingExtensions.cs" />
     <Compile Include="presenters\WpfCommandBuilder.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="SimpleCommand.cs" />
@@ -160,9 +161,9 @@
     <Compile Include="views\controls\ClipboardHelper.cs" />
     <Compile Include="views\controls\Column.cs" />
     <Compile Include="views\controls\DataGridTable.cs" />
-    <Compile Include="views\controls\IObservable.cs" />
-    <Compile Include="views\controls\ObjectExtensions.cs" />
     <Compile Include="views\controls\Observable.cs" />
+    <Compile Include="views\controls\ObjectExtensions.cs" />
+    <Compile Include="views\controls\ObservableProperty.cs" />
     <Compile Include="views\controls\Row.cs" />
     <Compile Include="views\controls\SmartCollection.cs" />
     <Compile Include="views\DisplayCanadianTaxInformationDialog.xaml.cs">
product/messages/AddIncomeCommandMessage.cs
@@ -8,12 +8,14 @@ namespace solidware.financials.messages
     {
         public Guid PersonId { get; set; }
         public decimal Amount { get; set; }
+        public DateTime Date { get; set; }
     }
 
     public class IncomeMessage : ValueType<IncomeMessage>, Event
     {
         public Guid PersonId { get; set; }
         public decimal Amount { get; set; }
+        public DateTime Date { get; set; }
 
         public override string ToString()
         {
product/service/handlers/AddIncomeCommandMessageHandler.cs
@@ -24,6 +24,7 @@ namespace solidware.financials.service.handlers
             {
                 x.Amount = item.Amount;
                 x.PersonId = item.PersonId;
+                x.Date = item.Date;
             });
         }
     }