示例#1
0
        private void WriteDetails(IReportWriter writer, string prefix, SecurityGroup securityTypeGroup)
        {
            decimal      marketValue            = 0;
            decimal      costBasis              = 0;
            decimal      gainLoss               = 0;
            bool         foundSecuritiesInGroup = false;
            SecurityType st = securityTypeGroup.Type;

            string caption = prefix + Security.GetSecurityTypeCaption(st);

            IList <SecurityGroup> groups = calc.RegroupBySecurity(securityTypeGroup);

            foreach (SecurityGroup g in groups)
            {
                foreach (var i in g.Purchases)
                {
                    // only report the security group header if it has some units left in it.
                    if (i.UnitsRemaining > 0)
                    {
                        if (!foundSecuritiesInGroup)
                        {
                            foundSecuritiesInGroup = true;

                            // create the security type group and subtable for these securities.
                            writer.WriteSubHeading(caption);
                            writer.StartTable();
                            writer.StartColumnDefinitions();

                            foreach (var minwidth in new double[] { 20,  //Expander
                                                                    80,  // Date Acquired
                                                                    300, // Description
                                                                    100, // Quantity
                                                                    100, // Price
                                                                    100, // Market Value
                                                                    100, // Unit Cost
                                                                    100, // Cost Basis
                                                                    100, // Gain/Loss
                                                                    50,  // %
                                     })
                            {
                                writer.WriteColumnDefinition("Auto", minwidth, double.MaxValue);
                            }
                            writer.EndColumnDefinitions();
                            WriteRowHeaders(writer);
                            break;
                        }
                    }
                }
                if (foundSecuritiesInGroup)
                {
                    WriteSecurities(writer, g.Purchases, ref marketValue, ref costBasis, ref gainLoss);
                }
            }

            writer.StartFooterRow();
            WriteRow(writer, true, true, FontWeights.Bold, null, "Total", null, null, null, marketValue, null, costBasis, gainLoss);
            // only close the table
            writer.EndTable();
        }
示例#2
0
        public void Generate(IReportWriter writer)
        {
            writer.WriteHeading("Unaccepted Transactions");

            Transactions transactions = myMoney.Transactions;

            foreach (Account a in this.myMoney.Accounts.GetAccounts(true))
            {
                if (a.IsClosed)
                {
                    continue;
                }

                bool first = true;

                foreach (Transaction t in this.myMoney.Transactions.GetTransactionsFrom(a))
                {
                    if (t.Unaccepted)
                    {
                        if (first)
                        {
                            writer.EndTable();
                            writer.WriteHeading(a.Name);
                            writer.StartTable();

                            writer.StartColumnDefinitions();
                            foreach (double minWidth in new double[] { 100, 300, 120 })
                            {
                                writer.WriteColumnDefinition(minWidth.ToString(), minWidth, double.MaxValue);
                            }
                            writer.EndColumnDefinitions();

                            writer.StartHeaderRow();
                            foreach (string header in new string[] { "Date", "Payee/Category/Memo", "Amount", })
                            {
                                writer.StartCell();
                                writer.WriteParagraph(header);
                                writer.EndCell();
                            }
                            writer.EndRow();

                            first = false;
                        }
                        WriteRow(writer, t.Date.ToShortDateString(), t.PayeeName ?? string.Empty, t.Amount.ToString("C"));
                        WriteRow(writer, string.Empty, t.CategoryName ?? string.Empty, string.Empty);
                        WriteRow(writer, string.Empty, t.Memo ?? string.Empty, string.Empty);
                    }
                }
            }

            writer.EndTable();

            writer.WriteParagraph("Generated on " + DateTime.Today.ToLongDateString(), System.Windows.FontStyles.Italic, System.Windows.FontWeights.Normal, System.Windows.Media.Brushes.Gray);
        }
示例#3
0
        void WriteHeaders(IReportWriter writer)
        {
            writer.StartTable();
            writer.StartColumnDefinitions();
            for (int i = 0; i < 9; i++)
            {
                writer.WriteColumnDefinition("Auto", 100, double.MaxValue);
            }
            writer.EndColumnDefinitions();

            writer.StartHeaderRow();
            writer.StartCell();
            writer.WriteParagraph("Security");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Quantity");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Date Acquired");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Acquisition Price");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Cost Basis");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Date Sold");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Sale Price");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Proceeds");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Gain or Loss");
            writer.EndCell();
            writer.EndRow();
        }
示例#4
0
        public void Generate(IReportWriter writer)
        {
            flowwriter = writer as FlowDocumentReportWriter;

            calc = new CostBasisCalculator(this.myMoney, this.reportDate);

            string heading = "Investment Portfolio Summary";

            if (this.account != null)
            {
                heading += " for " + account.Name + " (" + account.AccountId + ")";
            }

            writer.WriteHeading(heading);

            if (reportDate.Date != DateTime.Today)
            {
                writer.WriteSubHeading("As of " + reportDate.Date.AddDays(-1).ToLongDateString());
            }

            totalMarketValue = 0;
            totalGainLoss    = 0;

            // outer table contains 2 columns, left is the summary table, right is the pie chart.
            writer.StartTable();
            writer.StartColumnDefinitions();
            writer.WriteColumnDefinition("Auto", 100, double.MaxValue);
            writer.WriteColumnDefinition("Auto", 100, double.MaxValue);
            writer.EndColumnDefinitions();
            writer.StartRow();
            writer.StartCell();

            writer.StartTable();
            writer.StartColumnDefinitions();

            foreach (double minWidth in new double[] { 300, 100, 100 })
            {
                writer.WriteColumnDefinition("Auto", minWidth, double.MaxValue);
            }
            writer.EndColumnDefinitions();
            writer.StartHeaderRow();
            writer.StartCell();
            writer.WriteParagraph("Security Type");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Market Value");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Gain/Loss");
            writer.EndCell();
            writer.EndRow();

            List <SecurityPieData> data = new List <SecurityPieData>();

            decimal cash = this.myMoney.GetInvestmentCashBalance(account);

            if (cash > 0)
            {
                writer.StartRow();
                writer.StartCell();
                writer.WriteParagraph("Cash");
                writer.EndCell();
                writer.StartCell();
                writer.WriteNumber(cash.ToString("C"));
                writer.EndCell();
                writer.EndRow();

                data.Add(new SecurityPieData()
                {
                    Total = RoundToNearestCent(cash),
                    Name  = "Cash"
                });
            }

            totalMarketValue += cash;

            if (account == null)
            {
                WriteSummary(writer, data, "Tax Deferred ", new Predicate <Account>((a) => { return(a.IsTaxDeferred); }));
                WriteSummary(writer, data, "", new Predicate <Account>((a) => { return(!a.IsTaxDeferred); }));
            }
            else
            {
                WriteSummary(writer, data, "", new Predicate <Account>((a) => { return(a == account); }));
            }

            writer.StartHeaderRow();
            writer.StartCell();
            writer.WriteParagraph("Total");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber(totalMarketValue.ToString("C"));
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber(totalGainLoss.ToString("C"));
            writer.EndCell();
            writer.EndRow();
            writer.EndTable();

            writer.EndCell();
            // pie chart
            Chart chart = new Chart();

            chart.MinWidth            = 400;
            chart.MinHeight           = 300;
            chart.BorderThickness     = new Thickness(0);
            chart.Padding             = new Thickness(0);
            chart.Margin              = new Thickness(0, 00, 0, 0);
            chart.VerticalAlignment   = VerticalAlignment.Top;
            chart.HorizontalAlignment = HorizontalAlignment.Left;

            PieSeries series = new PieSeries();

            series.IndependentValueBinding = new Binding("Name");
            series.DependentValueBinding   = new Binding("Total");
            chart.Series.Add(series);
            series.ItemsSource = data;

            writer.StartCell();
            writer.WriteElement(chart);
            writer.EndCell();

            // end the outer table.
            writer.EndTable();

            totalMarketValue = 0;
            totalGainLoss    = 0;

            List <SecuritySale> errors = new List <SecuritySale>(calc.GetPendingSales(new Predicate <Account>((a) => { return(a == account); })));

            if (errors.Count > 0)
            {
                writer.WriteSubHeading("Pending Sales");

                foreach (var sp in errors)
                {
                    writer.WriteParagraph(string.Format("Pending sale of {1} units of '{2}' from account '{0}' recorded on {3}", sp.Account.Name, sp.UnitsSold, sp.Security.Name, sp.DateSold.ToShortDateString()));
                }
            }


            if (account == null)
            {
                WriteDetails(writer, "Tax Deferred ", new Predicate <Account>((a) => { return(a.IsTaxDeferred); }));
                WriteDetails(writer, "", new Predicate <Account>((a) => { return(!a.IsTaxDeferred); }));
            }
            else
            {
                WriteDetails(writer, "", new Predicate <Account>((a) => { return(a == account); }));
            }
        }
示例#5
0
        private void WriteDetails(IReportWriter writer, string prefix, Predicate <Account> filter)
        {
            // compute summary
            foreach (var securityTypeGroup in calc.GetHoldingsBySecurityType(filter))
            {
                decimal marketValue = 0;
                decimal costBasis   = 0;
                decimal gainLoss    = 0;

                SecurityType st = securityTypeGroup.Key;

                string caption = prefix + Security.GetSecurityTypeCaption(st);

                bool     foundSecuritiesInGroup = false;
                Security current = null;
                List <SecurityPurchase> bySecurity = new List <SecurityPurchase>();

                foreach (SecurityPurchase i in securityTypeGroup.Value)
                {
                    if (current != null && current != i.Security)
                    {
                        WriteSecurities(writer, bySecurity, ref marketValue, ref costBasis, ref gainLoss);
                        bySecurity.Clear();
                    }
                    current = i.Security;

                    // only report the security group header if it has some units left in it.
                    if (i.UnitsRemaining > 0)
                    {
                        if (!foundSecuritiesInGroup)
                        {
                            foundSecuritiesInGroup = true;

                            // create the security type group and subtable for these securities.
                            writer.WriteSubHeading(caption);
                            writer.StartTable();
                            writer.StartColumnDefinitions();

                            foreach (var minwidth in new double[] { 20,  //Expander
                                                                    80,  // Date Acquired
                                                                    300, // Description
                                                                    100, // Quantity
                                                                    100, // Price
                                                                    100, // Market Value
                                                                    100, // Unit Cost
                                                                    100, // Cost Basis
                                                                    100, // Gain/Loss
                                                                    50,  // %
                                     })
                            {
                                writer.WriteColumnDefinition("Auto", minwidth, double.MaxValue);
                            }
                            writer.EndColumnDefinitions();
                            WriteRowHeaders(writer);
                        }
                        bySecurity.Add(i);
                    }
                }

                if (foundSecuritiesInGroup)
                {
                    // write the final group of securities.
                    WriteSecurities(writer, bySecurity, ref marketValue, ref costBasis, ref gainLoss);

                    writer.StartFooterRow();

                    WriteRow(writer, true, true, FontWeights.Bold, null, "Total", null, null, null, marketValue, null, costBasis, gainLoss);

                    // only close the table
                    writer.EndTable();
                }
            }
        }
示例#6
0
        public void Generate(IReportWriter writer)
        {
            writer.WriteHeading("Net Worth Statement");

            List <PieData> data = new List <PieData>();

            // outer table contains 2 columns, left is the summary table, right is the pie chart.
            writer.StartTable();
            writer.StartColumnDefinitions();
            writer.WriteColumnDefinition("420", 420, 420);
            writer.WriteColumnDefinition("620", 620, 620);
            writer.EndColumnDefinitions();
            writer.StartRow();
            writer.StartCell();

            // inner table contains the "data"
            writer.StartTable();
            writer.StartColumnDefinitions();
            foreach (double width in new double[] { 300, 100 })
            {
                writer.WriteColumnDefinition(width.ToString(), width, width);
            }
            writer.EndColumnDefinitions();

            WriteHeader(writer, "Liquid Assets");

            decimal totalBalance   = 0;
            decimal balance        = 0;
            bool    hasTaxDeferred = false;
            bool    hasRetirement  = false;

            Transactions transactions = myMoney.Transactions;

            foreach (Account a in this.myMoney.Accounts.GetAccounts(true))
            {
                if (a.Type == AccountType.Retirement)
                {
                    hasRetirement = true;
                    continue;
                }
                if (a.IsTaxDeferred)
                {
                    hasTaxDeferred = true;
                }
                if (a.Type == AccountType.Credit ||
                    a.Type == AccountType.Asset ||
                    a.Type == AccountType.Brokerage ||
                    a.Type == AccountType.CategoryFund ||
                    a.Type == AccountType.Loan)
                {
                    continue;
                }

                balance += a.BalanceNormalized;
            }

            if (balance > 0)
            {
                data.Add(new PieData()
                {
                    Name = "Cash", Total = balance
                });
            }
            WriteRow(writer, "Cash", balance);

            totalBalance += balance;
            balance       = this.myMoney.GetInvestmentCashBalance(new Predicate <Account>((a) => { return(!a.IsClosed && (a.Type == AccountType.Brokerage)); }));

            if (balance > 0)
            {
                data.Add(new PieData()
                {
                    Name = "Investment Cash", Total = balance
                });
            }
            WriteRow(writer, "Investment Cash", balance);
            totalBalance += balance;

            bool hasNoneRetirement = false;

            if (hasRetirement)
            {
                WriteHeader(writer, "Retirement Assets");
                balance = this.myMoney.GetInvestmentCashBalance(new Predicate <Account>((a) => { return(!a.IsClosed && a.Type == AccountType.Retirement); }));

                if (balance > 0)
                {
                    data.Add(new PieData()
                    {
                        Name = "Retirement Cash", Total = balance
                    });
                }
                WriteRow(writer, "Retirement Cash", balance);
                totalBalance += balance;

                totalBalance += WriteSecurities(writer, data, "Retirement ", new Predicate <Account>((a) => { return(a.Type == AccountType.Retirement); }), out hasNoneRetirement);
            }

            bool hasNoneTypeTaxDeferred = false;

            if (hasTaxDeferred)
            {
                WriteHeader(writer, "Tax Deferred Assets");
                totalBalance += WriteSecurities(writer, data, "Tax Deferred ", new Predicate <Account>((a) => { return(a.Type == AccountType.Brokerage && a.IsTaxDeferred); }), out hasNoneTypeTaxDeferred);
            }

            balance = 0;

            WriteHeader(writer, "Long Term Assets");

            foreach (Account a in this.myMoney.Accounts.GetAccounts(true))
            {
                if ((a.Type == AccountType.Loan || a.Type == AccountType.Asset) && a.Balance > 0) // then this is a loan out to someone else...
                {
                    if (a.BalanceNormalized > 0)
                    {
                        data.Add(new PieData()
                        {
                            Name = a.Name, Total = a.BalanceNormalized
                        });
                    }
                    WriteRow(writer, a.Name, a.BalanceNormalized);
                    totalBalance += a.BalanceNormalized;
                }
            }

            bool hasNoneType = false;

            totalBalance += WriteSecurities(writer, data, "", new Predicate <Account>((a) => { return(a.Type == AccountType.Brokerage && !a.IsTaxDeferred); }), out hasNoneType);

            balance = 0;
            WriteHeader(writer, "Liabilities");

            foreach (Account a in this.myMoney.Accounts.GetAccounts(true))
            {
                if (a.Type != AccountType.Credit)
                {
                    continue;
                }
                balance += a.BalanceNormalized;
            }
            totalBalance += balance;

            if (balance > 0)
            {
                data.Add(new PieData()
                {
                    Name = "Credit", Total = balance
                });
            }
            WriteRow(writer, "Credit", balance);
            balance = 0;
            foreach (Account a in this.myMoney.Accounts.GetAccounts(true))
            {
                if (a.Type == AccountType.Loan && a.BalanceNormalized < 0)
                {
                    balance += a.BalanceNormalized;
                    if (a.BalanceNormalized > 0)
                    {
                        data.Add(new PieData()
                        {
                            Name = a.Name, Total = a.BalanceNormalized
                        });
                    }
                    WriteRow(writer, a.Name, a.BalanceNormalized);
                }
            }
            totalBalance += balance;

            writer.StartFooterRow();

            writer.StartCell();
            writer.WriteParagraph("Total");
            writer.EndCell();

            writer.StartCell();
            writer.WriteNumber(totalBalance.ToString("C"));
            writer.EndCell();

            writer.EndRow();
            writer.EndTable();

            writer.EndCell();
            writer.StartCell();


            // pie chart
            Chart chart = new Chart();

            chart.MinWidth          = 600;
            chart.MinHeight         = 400;
            chart.BorderThickness   = new Thickness(0);
            chart.VerticalAlignment = VerticalAlignment.Top;

            PieSeries series = new PieSeries();

            series.IndependentValueBinding = new Binding("Name");
            series.DependentValueBinding   = new Binding("Total");
            chart.Series.Add(series);
            series.ItemsSource = data;

            writer.WriteElement(chart);

            writer.EndCell();
            writer.EndRow();
            writer.EndTable();

            if (hasNoneRetirement || hasNoneTypeTaxDeferred || hasNoneType)
            {
                writer.WriteParagraph("(*) One ore more of your securities has no SecurityType, you can fix this using View/Securities",
                                      System.Windows.FontStyles.Italic, System.Windows.FontWeights.Normal, System.Windows.Media.Brushes.Maroon);
            }

            writer.WriteParagraph("Generated on " + DateTime.Today.ToLongDateString(), System.Windows.FontStyles.Italic, System.Windows.FontWeights.Normal, System.Windows.Media.Brushes.Gray);
        }
示例#7
0
        bool GenerateForm(TaxForm form, IReportWriter writer, ICollection <Transaction> transactions)
        {
            var byCategory = new Dictionary <Category, decimal>();

            // could be one to many mapping.
            Dictionary <TaxCategory, List <Category> > map = new Dictionary <TaxCategory, List <Category> >();

            // find our matching category
            foreach (TaxCategory tc in form.Categories)
            {
                foreach (Category c in this.myMoney.Categories.GetCategories())
                {
                    if (c.TaxRefNum == tc.RefNum)
                    {
                        byCategory[c] = 0M;

                        List <Category> list = null;
                        if (!map.TryGetValue(tc, out list))
                        {
                            list    = new List <Category>();
                            map[tc] = list;
                        }
                        list.Add(c);
                    }
                }
            }

            bool found = false;

            // summarize the year.
            foreach (Transaction t in transactions)
            {
                if (t.Date.Year == this.year)
                {
                    found |= Summarize(byCategory, t);
                }
            }

            if (!found)
            {
                return(false);
            }

            writer.WriteHeading("Form " + form.Name);


            writer.StartTable();
            writer.StartColumnDefinitions();
            writer.WriteColumnDefinition("20", 20, 20);    // expander column
            writer.WriteColumnDefinition("300", 300, 300); // row category name
            writer.WriteColumnDefinition("100", 100, 00);  // row value
            writer.EndColumnDefinitions();

            foreach (TaxCategory tc in form.Categories)
            {
                List <Category> list = null;
                if (map.TryGetValue(tc, out list))
                {
                    if (list.Count > 1)
                    {
                        decimal total = 0;
                        foreach (Category c in list)
                        {
                            total += byCategory[c];
                        }
                        if (total != 0)
                        {
                            writer.StartExpandableRowGroup();

                            // header row for the total.
                            writer.StartRow();
                            writer.StartCell();
                            writer.WriteParagraph(tc.Name);
                            writer.EndCell();
                            writer.StartCell();
                            writer.WriteNumber(total.ToString("N0"));
                            writer.EndCell();
                            writer.EndRow();

                            foreach (Category c in list)
                            {
                                decimal v = byCategory[c];
                                if (v != 0)
                                {
                                    writer.StartRow();
                                    writer.StartCell();
                                    writer.WriteParagraph("    " + c.GetFullName());
                                    writer.EndCell();
                                    writer.StartCell();
                                    writer.WriteNumber(v.ToString("N0"));
                                    AddHyperlink(c, writer);
                                    writer.EndCell();
                                    writer.EndRow();
                                }
                            }

                            writer.EndExpandableRowGroup();
                        }
                    }
                    else if (list.Count == 1)
                    {
                        Category c = list[0];
                        decimal  v = byCategory[c];
                        if (v != 0)
                        {
                            writer.StartRow();
                            writer.StartCell(); // null expander
                            writer.EndCell();
                            writer.StartCell();
                            writer.WriteParagraph(tc.Name);
                            writer.EndCell();
                            writer.StartCell();
                            writer.WriteNumber(v.ToString("N0"));
                            AddHyperlink(c, writer);
                            writer.EndCell();
                            writer.EndRow();
                        }
                    }
                }
            }
            writer.EndTable();

            return(true);
        }
示例#8
0
        public override void Generate(IReportWriter writer)
        {
            byCategory = new Dictionary <Category, CashFlowColumns>();

            FlowDocumentReportWriter fwriter = (FlowDocumentReportWriter)writer;

            writer.WriteHeading("Cash Flow Report ");

            ICollection <Transaction> transactions = this.myMoney.Transactions.GetAllTransactionsByDate();

            int startYear = year;
            int lastYear  = year;

            Transaction first = transactions.FirstOrDefault();

            if (first != null)
            {
                startYear = first.Date.Year;
            }
            Transaction last = transactions.LastOrDefault();

            if (last != null)
            {
                lastYear = last.Date.Year;
            }

            columns = new List <string>();

            DateTime date = new DateTime(year, month, 1);

            for (int i = columnCount - 1; i >= 0; i--)
            {
                if (byYear)
                {
                    int    y          = year - i;
                    string columnName = y.ToString();
                    columns.Add(columnName);
                    GenerateColumn(writer, columnName, transactions, 0, y);
                }
                else
                {
                    int      m          = month - i;
                    DateTime md         = date.AddMonths(-i);
                    string   columnName = md.ToString("MM/yyyy");
                    columns.Add(columnName);
                    GenerateColumn(writer, columnName, transactions, md.Month, md.Year);
                }
            }


            Paragraph heading = fwriter.CurrentParagraph;

            monthMap = new Dictionary <string, int>();

            heading.Inlines.Add(" including ");

            ComboBox countCombo = new ComboBox();

            countCombo.Margin = new System.Windows.Thickness(5, 0, 0, 0);
            for (int i = 1; i <= 12; i++)
            {
                countCombo.Items.Add(i.ToString());
            }
            countCombo.SelectedIndex     = this.columnCount - 1;
            countCombo.SelectionChanged += OnColumnCountChanged;
            heading.Inlines.Add(new InlineUIContainer(countCombo));

            ComboBox byYearMonthCombo = new ComboBox();

            byYearMonthCombo.Margin = new System.Windows.Thickness(5, 0, 0, 0);
            byYearMonthCombo.Items.Add("Years");
            byYearMonthCombo.Items.Add("Months");

            byYearMonthCombo.SelectedIndex     = (byYear ? 0 : 1);
            byYearMonthCombo.SelectionChanged += OnByYearMonthChanged;

            heading.Inlines.Add(new InlineUIContainer(byYearMonthCombo));

            heading.Inlines.Add(new InlineUIContainer(CreateExportReportButton()));

            writer.StartTable();
            writer.StartColumnDefinitions();

            writer.WriteColumnDefinition("20", 20, 20); // expander column
            writer.WriteColumnDefinition("300", 300, 300);

            for (int i = 0; i < columns.Count; i++)
            {
                writer.WriteColumnDefinition("Auto", 100, double.MaxValue);
            }
            writer.EndColumnDefinitions();


            WriteRow(writer, true, true, "", this.columns.ToArray());

            CashFlowColumns columnTotals = new CashFlowColumns();

            GenerateGroup(writer, byCategory, columnTotals, "Income", (c) => { return(IsIncome(c)); });

            GenerateGroup(writer, byCategory, columnTotals, "Expenses", (c) => { return(IsExpense(c)); });

            GenerateGroup(writer, byCategory, columnTotals, "Investments", (c) => { return(IsInvestment(c)); });

            List <decimal> totals  = columnTotals.GetOrderedValues(this.columns);
            decimal        balance = (from d in totals select d).Sum();

            WriteRow(writer, true, true, "Total", FormatValues(totals).ToArray());

            writer.EndTable();

            writer.WriteParagraph("Net cash flow for this period is " + balance.ToString("C0"));

            writer.WriteParagraph("Generated on " + DateTime.Today.ToLongDateString(), System.Windows.FontStyles.Italic, System.Windows.FontWeights.Normal, System.Windows.Media.Brushes.Gray);
        }
示例#9
0
        bool GenerateForm(TaxForm form, IReportWriter writer, ICollection <Transaction> transactions)
        {
            var byCategory = new Dictionary <Category, decimal>();

            // could be one to many mapping.
            Dictionary <TaxCategory, List <Category> > map = new Dictionary <TaxCategory, List <Category> >();

            // find our matching category
            foreach (TaxCategory tc in form.Categories)
            {
                foreach (Category c in this.myMoney.Categories.GetCategories())
                {
                    if (c.TaxRefNum == tc.RefNum)
                    {
                        byCategory[c] = 0M;

                        List <Category> list = null;
                        if (!map.TryGetValue(tc, out list))
                        {
                            list    = new List <Category>();
                            map[tc] = list;
                        }
                        list.Add(c);
                    }
                }
            }

            bool found = false;

            // summarize the year.
            foreach (Transaction t in transactions)
            {
                if (t.Transfer != null || t.IsDeleted || t.Status == TransactionStatus.Void)
                {
                    continue;
                }
                bool include = t.Date >= this.startDate && t.Date < this.endDate;
                var  extra   = myMoney.TransactionExtras.FindByTransaction(t.Id);
                if (extra != null && extra.TaxYear != -1)
                {
                    var taxYearStartDate = new DateTime(extra.TaxYear, fiscalYearStart + 1, 1);
                    if (fiscalYearStart > 0)
                    {
                        // Note: "FY2020" means July 2019 to July 2020, in other words
                        // it is the end date that represents the year.
                        taxYearStartDate = taxYearStartDate.AddYears(-1);
                    }
                    var taxYearEndDate = taxYearStartDate.AddYears(1);
                    include = taxYearStartDate >= this.startDate && taxYearEndDate <= this.endDate;
                }
                if (include)
                {
                    found |= Summarize(byCategory, t);
                }
            }

            if (!found)
            {
                return(false);
            }

            writer.WriteHeading("Form " + form.Name);


            writer.StartTable();
            writer.StartColumnDefinitions();
            writer.WriteColumnDefinition("20", 20, 20);    // expander column
            writer.WriteColumnDefinition("300", 300, 300); // row category name
            writer.WriteColumnDefinition("100", 100, 00);  // row value
            writer.EndColumnDefinitions();

            foreach (TaxCategory tc in form.Categories)
            {
                List <Category> list = null;
                if (map.TryGetValue(tc, out list))
                {
                    if (list.Count > 1)
                    {
                        decimal total = 0;
                        foreach (Category c in list)
                        {
                            total += byCategory[c];
                        }
                        if (total != 0)
                        {
                            writer.StartExpandableRowGroup();

                            // header row for the total.
                            writer.StartRow();
                            writer.StartCell();
                            writer.WriteParagraph(tc.Name);
                            writer.EndCell();
                            writer.StartCell();
                            writer.WriteNumber(total.ToString("N0"));
                            writer.EndCell();
                            writer.EndRow();

                            foreach (Category c in list)
                            {
                                decimal v = byCategory[c];
                                if (v != 0)
                                {
                                    writer.StartRow();
                                    writer.StartCell();
                                    writer.WriteParagraph("    " + c.GetFullName());
                                    writer.EndCell();
                                    writer.StartCell();
                                    writer.WriteNumber(v.ToString("N0"));
                                    AddHyperlink(c, writer);
                                    writer.EndCell();
                                    writer.EndRow();
                                }
                            }

                            writer.EndExpandableRowGroup();
                        }
                    }
                    else if (list.Count == 1)
                    {
                        Category c = list[0];
                        decimal  v = byCategory[c];
                        if (v != 0)
                        {
                            writer.StartRow();
                            writer.StartCell(); // null expander
                            writer.EndCell();
                            writer.StartCell();
                            writer.WriteParagraph(tc.Name);
                            writer.EndCell();
                            writer.StartCell();
                            writer.WriteNumber(v.ToString("N0"));
                            AddHyperlink(c, writer);
                            writer.EndCell();
                            writer.EndRow();
                        }
                    }
                }
            }
            writer.EndTable();

            return(true);
        }
示例#10
0
        public void Generate(IReportWriter writer)
        {
            flowwriter = writer as FlowDocumentReportWriter;

            calc = new CostBasisCalculator(this.myMoney, this.reportDate);

            string heading = "Investment Portfolio Summary";

            if (this.selectedGroup != null)
            {
                heading = "Investment Portfolio - " + this.selectedGroup.Type;
            }
            if (this.account != null)
            {
                heading += " for " + account.Name + " (" + account.AccountId + ")";
            }

            writer.WriteHeading(heading);

            if (reportDate.Date != DateTime.Today)
            {
                writer.WriteSubHeading("As of " + reportDate.Date.AddDays(-1).ToLongDateString());
            }

            totalMarketValue = 0;
            totalGainLoss    = 0;

            // outer table contains 2 columns, left is the summary table, right is the pie chart.
            writer.StartTable();
            writer.StartColumnDefinitions();
            writer.WriteColumnDefinition("Auto", 100, double.MaxValue);
            writer.WriteColumnDefinition("Auto", 100, double.MaxValue);
            writer.EndColumnDefinitions();
            writer.StartRow();
            writer.StartCell();

            writer.StartTable();
            writer.StartColumnDefinitions();

            writer.WriteColumnDefinition("30", 30, 30);
            foreach (double minWidth in new double[] { 300, 100, 100 })
            {
                writer.WriteColumnDefinition("Auto", minWidth, double.MaxValue);
            }
            writer.EndColumnDefinitions();

            var series = new ChartDataSeries()
            {
                Name = "Portfolio"
            };
            IList <ChartDataValue> data = series.Values;

            if (account == null)
            {
                if (this.selectedGroup != null)
                {
                    WriteSummary(writer, data, TaxStatus.Taxable, null, null, false);
                }
                else
                {
                    WriteSummary(writer, data, TaxStatus.TaxFree, "Tax Free ", new Predicate <Account>((a) => { return(!a.IsClosed && a.IsTaxFree && IsInvestmentAccount(a)); }), true);
                    WriteSummary(writer, data, TaxStatus.TaxDeferred, "Tax Deferred ", new Predicate <Account>((a) => { return(!a.IsClosed && a.IsTaxDeferred && IsInvestmentAccount(a)); }), true);
                    WriteSummary(writer, data, TaxStatus.Taxable, "Taxable ", new Predicate <Account>((a) => { return(!a.IsClosed && !a.IsTaxDeferred && !a.IsTaxFree && IsInvestmentAccount(a)); }), true);
                }
            }
            else
            {
                WriteSummary(writer, data, account.TaxStatus, "", new Predicate <Account>((a) => { return(a == account); }), false);
            }

            WriteHeaderRow(writer, "Total", totalMarketValue.ToString("C"), totalGainLoss.ToString("C"));
            writer.EndTable();

            writer.EndCell();
            // pie chart
            AnimatingPieChart chart = new AnimatingPieChart();

            chart.Width               = 400;
            chart.Height              = 300;
            chart.BorderThickness     = new Thickness(0);
            chart.Padding             = new Thickness(0);
            chart.Margin              = new Thickness(0, 00, 0, 0);
            chart.VerticalAlignment   = VerticalAlignment.Top;
            chart.HorizontalAlignment = HorizontalAlignment.Left;
            chart.Series              = series;
            chart.ToolTipGenerator    = OnGenerateToolTip;
            chart.PieSliceClicked    += OnPieSliceClicked;

            writer.StartCell();
            writer.WriteElement(chart);
            writer.EndCell();

            // end the outer table.
            writer.EndTable();

            totalMarketValue = 0;
            totalGainLoss    = 0;

            if (this.selectedGroup != null)
            {
                WriteDetails(writer, "", this.selectedGroup);
            }
            else
            {
                List <SecuritySale> errors = new List <SecuritySale>(calc.GetPendingSales(new Predicate <Account>((a) => { return(a == account); })));
                if (errors.Count > 0)
                {
                    writer.WriteSubHeading("Pending Sales");

                    foreach (var sp in errors)
                    {
                        writer.WriteParagraph(string.Format("Pending sale of {1} units of '{2}' from account '{0}' recorded on {3}", sp.Account.Name, sp.UnitsSold, sp.Security.Name, sp.DateSold.ToShortDateString()));
                    }
                }

                if (account == null)
                {
                    WriteDetails(writer, "Tax Free ", new Predicate <Account>((a) => { return(!a.IsClosed && a.IsTaxFree && IsInvestmentAccount(a)); }));
                    WriteDetails(writer, "Tax Deferred ", new Predicate <Account>((a) => { return(!a.IsClosed && a.IsTaxDeferred && IsInvestmentAccount(a)); }));
                    WriteDetails(writer, "Taxable ", new Predicate <Account>((a) => { return(!a.IsClosed && !a.IsTaxFree && !a.IsTaxDeferred && IsInvestmentAccount(a)); }));
                }
                else
                {
                    WriteDetails(writer, "", new Predicate <Account>((a) => { return(a == account); }));
                }
            }
        }
示例#11
0
        public override void Generate(IReportWriter writer)
        {
            byCategory = new Dictionary <Category, CashFlowColumns>();

            FlowDocumentReportWriter fwriter = (FlowDocumentReportWriter)writer;

            writer.WriteHeading("Cash Flow Report ");

            ICollection <Transaction> transactions = this.myMoney.Transactions.GetAllTransactionsByDate();

            DateTime    firstTransactionDate = DateTime.Now;
            Transaction first = transactions.FirstOrDefault();

            if (first != null)
            {
                firstTransactionDate = first.Date;
            }

            columns = new List <string>();

            DateTime start = this.startDate;

            while (start < this.endDate)
            {
                DateTime end        = (byYear) ? start.AddYears(1) : start.AddMonths(1);
                string   columnName = start.ToString("MM/yyyy");
                if (byYear)
                {
                    columnName = (this.fiscalYearStart == 0) ? start.Year.ToString() : "FY" + end.Year.ToString();
                }
                columns.Add(columnName);
                GenerateColumn(writer, columnName, transactions, start, end);
                start = end;
            }

            Paragraph heading = fwriter.CurrentParagraph;

            monthMap = new Dictionary <string, int>();
            heading.Inlines.Add(" - from ");

            var previousButton = new Button();

            previousButton.Content    = "\uE100";
            previousButton.ToolTip    = "Previous year";
            previousButton.FontFamily = new FontFamily("Segoe UI Symbol");
            previousButton.Click     += OnPreviousClick;
            previousButton.Margin     = new System.Windows.Thickness(5, 0, 0, 0);
            heading.Inlines.Add(new InlineUIContainer(previousButton));

            DatePicker fromPicker = new DatePicker();

            fromPicker.DisplayDateStart     = firstTransactionDate;
            fromPicker.SelectedDate         = this.startDate;
            fromPicker.Margin               = new System.Windows.Thickness(5, 0, 0, 0);
            fromPicker.SelectedDateChanged += OnSelectedFromDateChanged;
            heading.Inlines.Add(new InlineUIContainer(fromPicker));

            heading.Inlines.Add(" to ");

            DatePicker toPicker = new DatePicker();

            toPicker.DisplayDateStart     = firstTransactionDate;
            toPicker.SelectedDate         = this.endDate;
            toPicker.Margin               = new System.Windows.Thickness(5, 0, 0, 0);
            toPicker.SelectedDateChanged += OnSelectedToDateChanged;;
            heading.Inlines.Add(new InlineUIContainer(toPicker));

            var nextButton = new Button();

            nextButton.Content    = "\uE101";
            nextButton.ToolTip    = "Next year";
            nextButton.FontFamily = new FontFamily("Segoe UI Symbol");
            nextButton.Margin     = new System.Windows.Thickness(5, 0, 0, 0);
            nextButton.Click     += OnNextClick;
            heading.Inlines.Add(new InlineUIContainer(nextButton));


            ComboBox byYearMonthCombo = new ComboBox();

            byYearMonthCombo.Margin = new System.Windows.Thickness(5, 0, 0, 0);
            byYearMonthCombo.Items.Add("by years");
            byYearMonthCombo.Items.Add("by month");
            byYearMonthCombo.SelectedIndex     = (byYear ? 0 : 1);
            byYearMonthCombo.SelectionChanged += OnByYearMonthChanged;

            heading.Inlines.Add(new InlineUIContainer(byYearMonthCombo));

            heading.Inlines.Add(new InlineUIContainer(CreateExportReportButton()));

            writer.StartTable();
            writer.StartColumnDefinitions();

            writer.WriteColumnDefinition("20", 20, 20); // expander column
            writer.WriteColumnDefinition("300", 300, 300);

            for (int i = 0; i < columns.Count; i++)
            {
                writer.WriteColumnDefinition("Auto", 100, double.MaxValue);
            }
            writer.EndColumnDefinitions();


            WriteRow(writer, true, true, "", this.columns.ToArray());

            CashFlowColumns columnTotals = new CashFlowColumns();

            GenerateGroup(writer, byCategory, columnTotals, "Income", (c) => { return(IsIncome(c)); });

            GenerateGroup(writer, byCategory, columnTotals, "Expenses", (c) => { return(IsExpense(c)); });

            GenerateGroup(writer, byCategory, columnTotals, "Investments", (c) => { return(IsInvestment(c)); });

            GenerateGroup(writer, byCategory, columnTotals, "Unknown", (c) => { return(IsUnknown(c)); });


            List <decimal> totals  = columnTotals.GetOrderedValues(this.columns);
            decimal        balance = (from d in totals select d).Sum();

            WriteRow(writer, true, true, "Total", FormatValues(totals).ToArray());

            writer.EndTable();

            writer.WriteParagraph("Net cash flow for this period is " + balance.ToString("C0"));

            writer.WriteParagraph("Generated on " + DateTime.Today.ToLongDateString(), System.Windows.FontStyles.Italic, System.Windows.FontWeights.Normal, System.Windows.Media.Brushes.Gray);
        }
示例#12
0
        public void Generate(IReportWriter writer)
        {
            flowwriter = writer as FlowDocumentReportWriter;

            calc = new CostBasisCalculator(this.myMoney, this.reportDate);

            string heading = "Investment Portfolio Summary";

            if (this.account != null)
            {
                heading += " for " + account.Name + " (" + account.AccountId + ")";
            }

            writer.WriteHeading(heading);

            if (reportDate.Date != DateTime.Today)
            {
                writer.WriteSubHeading("As of " + reportDate.Date.AddDays(-1).ToLongDateString());
            }

            totalMarketValue = 0;
            totalGainLoss    = 0;

            // outer table contains 2 columns, left is the summary table, right is the pie chart.
            writer.StartTable();
            writer.StartColumnDefinitions();
            writer.WriteColumnDefinition("Auto", 100, double.MaxValue);
            writer.WriteColumnDefinition("Auto", 100, double.MaxValue);
            writer.EndColumnDefinitions();
            writer.StartRow();
            writer.StartCell();

            writer.StartTable();
            writer.StartColumnDefinitions();

            foreach (double minWidth in new double[] { 300, 100, 100 })
            {
                writer.WriteColumnDefinition("Auto", minWidth, double.MaxValue);
            }
            writer.EndColumnDefinitions();



            List <SecurityPieData> data = new List <SecurityPieData>();

            if (account == null)
            {
                WriteSummary(writer, data, TaxableIncomeType.None, "Retirement Tax Free ", new Predicate <Account>((a) => { return(!a.IsClosed && !a.IsTaxDeferred && a.Type == AccountType.Retirement); }), true);
                WriteSummary(writer, data, TaxableIncomeType.All, "Retirement ", new Predicate <Account>((a) => { return(!a.IsClosed && a.IsTaxDeferred && a.Type == AccountType.Retirement); }), true);
                WriteSummary(writer, data, TaxableIncomeType.All, "Tax Deferred ", new Predicate <Account>((a) => { return(!a.IsClosed && a.IsTaxDeferred && a.Type == AccountType.Brokerage); }), true);
                WriteSummary(writer, data, TaxableIncomeType.Gains, "", new Predicate <Account>((a) => { return(!a.IsClosed && !a.IsTaxDeferred && a.Type == AccountType.Brokerage); }), true);
            }
            else
            {
                TaxableIncomeType taxableIncomeType;

                if (account.IsTaxDeferred)
                {
                    taxableIncomeType = TaxableIncomeType.All;
                }
                else
                {
                    if (account.Type == AccountType.Retirement)
                    {
                        // Currently treating this combination as tax free
                        taxableIncomeType = TaxableIncomeType.None;
                    }
                    else
                    {
                        taxableIncomeType = TaxableIncomeType.Gains;
                    }
                }

                WriteSummary(writer, data, taxableIncomeType, "", new Predicate <Account>((a) => { return(a == account); }), false);
            }

            WriteheaderRow(writer, "Total", totalMarketValue.ToString("C"), totalGainLoss.ToString("C"));
            writer.EndTable();

            writer.EndCell();
            // pie chart
            Chart chart = new Chart();

            chart.MinWidth            = 400;
            chart.MinHeight           = 300;
            chart.BorderThickness     = new Thickness(0);
            chart.Padding             = new Thickness(0);
            chart.Margin              = new Thickness(0, 00, 0, 0);
            chart.VerticalAlignment   = VerticalAlignment.Top;
            chart.HorizontalAlignment = HorizontalAlignment.Left;

            PieSeries series = new PieSeries();

            series.IndependentValueBinding = new Binding("Name");
            series.DependentValueBinding   = new Binding("Total");
            chart.Series.Add(series);
            series.ItemsSource = data;

            writer.StartCell();
            writer.WriteElement(chart);
            writer.EndCell();

            // end the outer table.
            writer.EndTable();

            totalMarketValue = 0;
            totalGainLoss    = 0;

            List <SecuritySale> errors = new List <SecuritySale>(calc.GetPendingSales(new Predicate <Account>((a) => { return(a == account); })));

            if (errors.Count > 0)
            {
                writer.WriteSubHeading("Pending Sales");

                foreach (var sp in errors)
                {
                    writer.WriteParagraph(string.Format("Pending sale of {1} units of '{2}' from account '{0}' recorded on {3}", sp.Account.Name, sp.UnitsSold, sp.Security.Name, sp.DateSold.ToShortDateString()));
                }
            }

            if (account == null)
            {
                WriteDetails(writer, "Retirement Tax Free ", new Predicate <Account>((a) => { return(!a.IsClosed && !a.IsTaxDeferred && a.Type == AccountType.Retirement); }));
                WriteDetails(writer, "Retirement ", new Predicate <Account>((a) => { return(!a.IsClosed && a.IsTaxDeferred && a.Type == AccountType.Retirement); }));
                WriteDetails(writer, "Tax Deferred ", new Predicate <Account>((a) => { return(!a.IsClosed && a.IsTaxDeferred && a.Type == AccountType.Brokerage); }));
                WriteDetails(writer, "", new Predicate <Account>((a) => { return(!a.IsClosed && !a.IsTaxDeferred && a.Type == AccountType.Brokerage); }));
            }
            else
            {
                WriteDetails(writer, "", new Predicate <Account>((a) => { return(a == account); }));
            }
        }
示例#13
0
        private void GenerateCategories(IReportWriter writer)
        {
            TaxCategoryCollection taxCategories = new TaxCategoryCollection();
            List <TaxCategory>    list          = taxCategories.GenerateGroups(money, this.startDate, this.endDate);

            if (list == null)
            {
                writer.WriteParagraph("You have not associated any categories with tax categories.");
                writer.WriteParagraph("Please use the Category Properties dialog to associate tax categories then try again.");
                return;
            }

            writer.WriteHeading("Tax Categories");
            writer.StartTable();

            writer.StartColumnDefinitions();
            writer.WriteColumnDefinition("auto", 100, double.MaxValue);
            writer.WriteColumnDefinition("auto", 100, double.MaxValue);
            writer.WriteColumnDefinition("auto", 100, double.MaxValue);
            writer.EndColumnDefinitions();
            writer.StartHeaderRow();
            writer.StartCell();
            writer.WriteParagraph("Category");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Amount");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber("Tax Excempt");
            writer.EndCell();
            writer.EndRow();

            decimal tax = GetSalesTax();

            writer.StartRow();
            writer.StartCell();
            writer.WriteParagraph("Sales Tax");
            writer.EndCell();
            writer.StartCell();
            writer.WriteNumber(tax.ToString("C"), FontStyles.Normal, FontWeights.Bold, null);
            writer.EndCell();
            writer.EndRow();

            foreach (TaxCategory tc in list)
            {
                writer.StartHeaderRow();
                writer.StartCell();
                writer.WriteParagraph(tc.Name);
                writer.EndCell();
                writer.StartCell();
                writer.EndCell();
                writer.EndRow();

                decimal sum = 0;
                IDictionary <string, List <Transaction> > groups = tc.Groups;
                foreach (KeyValuePair <string, List <Transaction> > subtotal in groups)
                {
                    writer.StartRow();
                    writer.StartCell();
                    writer.WriteParagraph(subtotal.Key);
                    writer.EndCell();

                    decimal value     = 0;
                    decimal taxExempt = 0;
                    foreach (Transaction t in subtotal.Value)
                    {
                        var amount = t.Amount;
                        if (t.Investment != null && t.Investment.Security != null && t.Investment.Security.Taxable == YesNo.No)
                        {
                            taxExempt += amount;
                        }
                        else
                        {
                            value += amount;
                        }
                    }

                    if (tc.DefaultSign < 0)
                    {
                        value = value * -1;
                    }

                    writer.StartCell();
                    writer.WriteNumber(value.ToString("C"));
                    writer.EndCell();

                    writer.StartCell();
                    if (taxExempt > 0)
                    {
                        writer.WriteNumber(taxExempt.ToString("C"));
                    }
                    writer.EndCell();
                    writer.EndRow();
                    sum += value;
                }

                writer.StartRow();
                writer.StartCell();
                writer.EndCell();
                writer.StartCell();
                writer.WriteNumber(sum.ToString("C"), FontStyles.Normal, FontWeights.Bold, null);
                writer.EndCell();
                writer.EndRow();
            }

            writer.EndTable();
        }
示例#14
0
        private void GenerateCapitalGains(IReportWriter writer)
        {
            var calculator = new CapitalGainsTaxCalculator(this.money, this.endDate, this.consolidateOnDateSold, true);

            List <SecuritySale> errors = new List <SecuritySale>(from s in calculator.GetSales() where s.Error != null select s);

            if (errors.Count > 0)
            {
                writer.WriteHeading("Errors Found");
                foreach (SecuritySale error in errors)
                {
                    writer.WriteParagraph(error.Error.Message);
                }
            }

            if ((from u in calculator.Unknown where InRange(u.DateSold) select u).Any())
            {
                writer.WriteHeading("Capital Gains with Unknown Cost Basis");

                writer.StartTable();
                writer.StartColumnDefinitions();
                for (int i = 0; i < 4; i++)
                {
                    writer.WriteColumnDefinition("Auto", 100, double.MaxValue);
                }
                writer.EndColumnDefinitions();

                writer.StartHeaderRow();
                writer.StartCell();
                writer.WriteParagraph("Security");
                writer.EndCell();
                writer.StartCell();
                writer.WriteNumber("Quantity");
                writer.EndCell();
                writer.StartCell();
                writer.WriteNumber("Date Sold");
                writer.EndCell();
                writer.StartCell();
                writer.WriteNumber("Sale Price");
                writer.EndCell();
                writer.StartCell();
                writer.WriteNumber("Proceeds");
                writer.EndCell();
                writer.EndRow();

                foreach (var data in calculator.Unknown)
                {
                    if (!InRange(data.DateSold))
                    {
                        continue;
                    }
                    writer.StartRow();
                    writer.StartCell();
                    writer.WriteParagraph(data.Security.Name);
                    writer.EndCell();

                    writer.StartCell();
                    writer.WriteNumber(Rounded(data.UnitsSold, 3));
                    writer.EndCell();

                    writer.StartCell();
                    writer.WriteNumber(data.DateSold.ToShortDateString());
                    writer.EndCell();

                    writer.StartCell();
                    writer.WriteNumber(data.SalePricePerUnit.ToString("C"));
                    writer.EndCell();

                    writer.StartCell();
                    writer.WriteNumber(data.SaleProceeds.ToString("C"));
                    writer.EndCell();
                }

                writer.EndTable();
            }

            if (calculator.ShortTerm.Count > 0)
            {
                decimal total = 0;
                writer.WriteHeading("Short Term Capital Gains and Losses");
                WriteHeaders(writer);
                foreach (var data in calculator.ShortTerm)
                {
                    if (!InRange(data.DateSold))
                    {
                        continue;
                    }
                    WriteCapitalGains(writer, data);
                    total += data.TotalGain;
                }
                WriteCapitalGainsTotal(writer, total);
                writer.EndTable();
            }

            if (calculator.LongTerm.Count > 0)
            {
                decimal total = 0;
                writer.WriteHeading("Long Term Capital Gains and Losses");
                WriteHeaders(writer);
                foreach (var data in calculator.LongTerm)
                {
                    if (!InRange(data.DateSold))
                    {
                        continue;
                    }
                    WriteCapitalGains(writer, data);
                    total += data.TotalGain;
                }
                WriteCapitalGainsTotal(writer, total);
            }
            writer.EndTable();
        }
示例#15
0
        public override void Generate(IReportWriter writer)
        {
            writer.WriteHeading("Budget Report");

            this.rows = new Dictionary <string, BudgetRow>();

            this.columns = new Dictionary <DateTime, BudgetColumn>();

            foreach (Category rc in money.Categories.GetRootCategories())
            {
                if (rc.Type != CategoryType.Expense)
                {
                    continue;
                }
                string rowHeader = rc.Name;
                this.CategoryFilter = rc;


                // Add column for the budget itself.
                BudgetColumn budgetColumn;
                if (!columns.TryGetValue(DateTime.MinValue, out budgetColumn))
                {
                    budgetColumn = new BudgetColumn()
                    {
                        Name = BudgetColumnHeader,
                    };
                    columns[DateTime.MinValue] = budgetColumn;
                }
                budgetColumn.Total += rc.Budget;

                foreach (BudgetData b in this.Compute())
                {
                    BudgetRow row = null;
                    if (!rows.TryGetValue(rowHeader, out row))
                    {
                        row = new BudgetRow()
                        {
                            Name   = rowHeader,
                            Budget = rc.Budget
                        };
                        rows[rowHeader] = row;
                    }

                    DateTime budgetDate = new DateTime(b.BudgetDate.Year, b.BudgetDate.Month, 1);
                    row.Actuals.Add((decimal)b.Actual);
                    row.Headers.Add(b.Name);

                    // Add column for this BudgetData
                    BudgetColumn col;
                    if (!columns.TryGetValue(budgetDate, out col))
                    {
                        col = new BudgetColumn()
                        {
                            Date = budgetDate,
                            Name = b.Name
                        };
                        columns[budgetDate] = col;
                    }
                    col.Total += (decimal)b.Actual;
                }
            }

            writer.StartTable();

            writer.StartColumnDefinitions();
            writer.WriteColumnDefinition("300", 300, 300); // category names
            foreach (var pair in from p in columns orderby p.Key select p)
            {
                writer.WriteColumnDefinition("Auto", 100, double.MaxValue); // decimal values.
            }
            writer.WriteColumnDefinition("Auto", 100, double.MaxValue);     // total.
            writer.EndColumnDefinitions();

            // write table headers
            List <string> master = new List <string>();

            writer.StartHeaderRow();
            writer.StartCell();
            writer.EndCell();
            foreach (var pair in from p in columns orderby p.Key select p)
            {
                BudgetColumn c    = pair.Value;
                string       name = c.Name;
                if (name != BudgetColumnHeader)
                {
                    master.Add(name); // list of all columns we have found (not including "Budget" column)
                }
                writer.StartCell();
                writer.WriteNumber(name);
                writer.EndCell();
            }
            writer.StartCell();
            writer.WriteNumber("Balance");
            writer.EndCell();
            writer.EndRow();

            Brush   overBudgetBrush = Brushes.Red;
            decimal totalBalance    = 0;

            // Now write out the rows.
            foreach (BudgetRow row in from r in rows.Values orderby r.Name select r)
            {
                writer.StartRow();
                writer.StartCell();
                writer.WriteParagraph(row.Name);
                writer.EndCell();

                writer.StartCell();
                decimal budget = row.Budget;
                writer.WriteNumber(budget.ToString("C"));
                writer.EndCell();

                decimal balance = 0;

                foreach (string col in master)
                {
                    writer.StartCell();
                    int i = row.Headers.IndexOf(col);
                    if (i >= 0)
                    {
                        decimal actual = row.Actuals[i];
                        writer.WriteNumber(actual.ToString("C"), FontStyles.Normal, FontWeights.Normal,
                                           actual > budget ? overBudgetBrush : null);

                        balance += (row.Budget - actual);
                    }
                    writer.EndCell();
                }

                totalBalance += balance;

                writer.StartCell();
                writer.WriteNumber(balance.ToString("C"));
                writer.EndCell();

                writer.EndRow();
            }

            // Now write out the totals.
            writer.StartHeaderRow();
            writer.StartCell();
            writer.EndCell();
            foreach (var pair in from p in columns orderby p.Key select p)
            {
                BudgetColumn c = pair.Value;
                writer.StartCell();
                writer.WriteNumber(c.Total.ToString("C"));
                writer.EndCell();
            }
            writer.StartCell();
            writer.WriteNumber(totalBalance.ToString("C"));
            writer.EndCell();

            writer.EndRow();

            writer.EndTable();

            writer.WriteParagraph("Generated on " + DateTime.Today.ToLongDateString(), System.Windows.FontStyles.Italic, System.Windows.FontWeights.Normal, System.Windows.Media.Brushes.Gray);
        }
示例#16
0
        public void Generate(IReportWriter writer)
        {
            writer.WriteHeading("Net Worth Statement");

            var series = new ChartDataSeries()
            {
                Name = "Net Worth"
            };
            IList <ChartDataValue> data = series.Values;

            // outer table contains 2 columns, left is the summary table, right is the pie chart.
            writer.StartTable();
            writer.StartColumnDefinitions();
            writer.WriteColumnDefinition("450", 450, 450);
            writer.WriteColumnDefinition("620", 620, 620);
            writer.EndColumnDefinitions();
            writer.StartRow();
            writer.StartCell();

            // inner table contains the "data"
            writer.StartTable();
            writer.StartColumnDefinitions();
            writer.WriteColumnDefinition("30", 30, 30);
            writer.WriteColumnDefinition("300", 300, 300);
            writer.WriteColumnDefinition("Auto", 100, double.MaxValue);

            writer.EndColumnDefinitions();

            WriteHeader(writer, "Cash");

            decimal totalBalance   = 0;
            decimal balance        = 0;
            bool    hasTaxDeferred = false;
            bool    hasTaxFree     = false;

            Transactions transactions = myMoney.Transactions;

            foreach (Account a in this.myMoney.Accounts.GetAccounts(true))
            {
                if (a.IsTaxDeferred)
                {
                    hasTaxDeferred = true;
                }
                if (a.IsTaxFree)
                {
                    hasTaxFree = true;
                }
                if (a.Type == AccountType.Credit ||
                    a.Type == AccountType.Asset ||
                    a.Type == AccountType.Brokerage ||
                    a.Type == AccountType.Retirement ||
                    a.Type == AccountType.CategoryFund ||
                    a.Type == AccountType.Loan)
                {
                    continue;
                }

                balance += a.BalanceNormalized;
            }

            // Non-investment Cash
            var color = GetRandomColor();

            if (balance > 0)
            {
                data.Add(new ChartDataValue()
                {
                    Label = "Cash", Value = (double)balance, Color = color
                });
            }
            WriteRow(writer, color, "Cash", balance);
            totalBalance += balance;

            // Investment Cash
            balance = this.myMoney.GetInvestmentCashBalanceNormalized(new Predicate <Account>((a) => { return(!a.IsClosed && IsInvestmentAccount(a)); }));
            color   = GetRandomColor();
            data.Add(new ChartDataValue()
            {
                Label = "Investment Cash", Value = (double)balance, Color = color
            });
            WriteRow(writer, color, "Investment Cash", balance);
            totalBalance += balance;

            bool hasNoneTypeTaxDeferred = false;

            if (hasTaxDeferred)
            {
                WriteHeader(writer, "Tax Deferred Assets");
                totalBalance += WriteSecurities(writer, data, "Tax Deferred ", new Predicate <Account>((a) => { return(a.IsTaxDeferred); }), out hasNoneTypeTaxDeferred);
            }

            bool hasNoneTypeTaxFree = false;

            if (hasTaxFree)
            {
                WriteHeader(writer, "Tax Free Assets");
                totalBalance += WriteSecurities(writer, data, "Tax Free ", new Predicate <Account>((a) => { return(a.IsTaxFree); }), out hasNoneTypeTaxFree);
            }

            balance = 0;

            WriteHeader(writer, "Other Assets");

            foreach (Account a in this.myMoney.Accounts.GetAccounts(true))
            {
                if ((a.Type == AccountType.Loan || a.Type == AccountType.Asset) && a.Balance > 0) // then this is a loan out to someone else...
                {
                    color = GetRandomColor();
                    if (a.BalanceNormalized > 0)
                    {
                        data.Add(new ChartDataValue()
                        {
                            Label = a.Name, Value = (double)a.BalanceNormalized, Color = color
                        });
                    }
                    WriteRow(writer, color, a.Name, a.BalanceNormalized);
                    totalBalance += a.BalanceNormalized;
                }
            }

            bool hasNoneType = false;

            totalBalance += WriteSecurities(writer, data, "", new Predicate <Account>((a) => { return(IsInvestmentAccount(a) && !a.IsTaxDeferred && !a.IsTaxFree); }), out hasNoneType);

            balance = 0;
            WriteHeader(writer, "Liabilities");

            foreach (Account a in this.myMoney.Accounts.GetAccounts(true))
            {
                if (a.Type != AccountType.Credit)
                {
                    continue;
                }
                balance += a.BalanceNormalized;
            }
            totalBalance += balance;

            color = GetRandomColor();
            if (balance > 0)
            {
                data.Add(new ChartDataValue()
                {
                    Label = "Credit", Value = (double)balance, Color = color
                });
            }
            WriteRow(writer, color, "Credit", balance);
            balance = 0;
            foreach (Account a in this.myMoney.Accounts.GetAccounts(true))
            {
                if (a.Type == AccountType.Loan && a.BalanceNormalized < 0)
                {
                    balance += a.BalanceNormalized;
                    color    = GetRandomColor();
                    if (a.BalanceNormalized > 0)
                    {
                        data.Add(new ChartDataValue()
                        {
                            Label = a.Name, Value = (double)a.BalanceNormalized, Color = color
                        });
                    }
                    WriteRow(writer, color, a.Name, a.BalanceNormalized);
                }
            }
            totalBalance += balance;

            writer.StartFooterRow();

            writer.StartCell(1, 2);
            writer.WriteParagraph("Total");
            writer.EndCell();

            writer.StartCell();
            writer.WriteNumber(totalBalance.ToString("C"));
            writer.EndCell();

            writer.EndRow();
            writer.EndTable();

            writer.EndCell();
            writer.StartCell();


            // pie chart
            AnimatingPieChart chart = new AnimatingPieChart();

            chart.Width             = 600;
            chart.Height            = 400;
            chart.BorderThickness   = new Thickness(0);
            chart.VerticalAlignment = VerticalAlignment.Top;
            chart.Series            = series;
            chart.ToolTipGenerator  = OnGenerateToolTip;
            chart.PieSliceClicked  += OnPieSliceClicked;

            writer.WriteElement(chart);

            writer.EndCell();
            writer.EndRow();
            writer.EndTable();

            if (hasNoneTypeTaxDeferred || hasNoneTypeTaxFree || hasNoneType)
            {
                writer.WriteParagraph("(*) One ore more of your securities has no SecurityType, you can fix this using View/Securities",
                                      System.Windows.FontStyles.Italic, System.Windows.FontWeights.Normal, System.Windows.Media.Brushes.Maroon);
            }

            writer.WriteParagraph("Generated on " + DateTime.Today.ToLongDateString(), System.Windows.FontStyles.Italic, System.Windows.FontWeights.Normal, System.Windows.Media.Brushes.Gray);
        }