public void Generate(IReportWriter writer) { if (doc == null) { return; } var document = view.DocumentViewer.Document; bool found = false; bool first = true; foreach (XElement change in doc.Root.Elements("change")) { string version = (string)change.Attribute("version"); if (string.IsNullOrEmpty(version)) { continue; } bool match = IsSameOrOlder(previousVersion, version); if (!found && match) { writer.WriteHeading("The following changes were already installed"); found = true; } if (first && !found) { writer.WriteHeading("The following changes are now available"); first = false; } string date = (string)change.Attribute("date"); writer.WriteSubHeading(version + " " + date); foreach (string line in change.Value.Split('\r', '\n')) { string trimmed = line.Trim(); if (!string.IsNullOrEmpty(trimmed)) { string brush = found ? "ListItemForegroundBrush" : "ListItemSelectedForegroundBrush"; FlowDocumentReportWriter fwriter = (FlowDocumentReportWriter)writer; Paragraph p = fwriter.WriteParagraph(trimmed, FontStyles.Normal, FontWeights.Normal, AppTheme.Instance.GetThemedBrush(brush), null); p.TextIndent = 20; p.Margin = new Thickness(0); p.Padding = new Thickness(0); } } } if (installButton && !HasLatestVersion()) { document.Blocks.InsertAfter(document.Blocks.FirstBlock, new BlockUIContainer(CreateInstallButton())); } }
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); }
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); })); } }
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); }
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); }
public override void Generate(IReportWriter writer) { this.transactionsByCategory = new Dictionary <Category, List <Transaction> >(); FlowDocumentReportWriter fwriter = (FlowDocumentReportWriter)writer; writer.WriteHeading("Select year for 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; } Paragraph heading = fwriter.CurrentParagraph; ComboBox byYearCombo = new ComboBox(); byYearCombo.Margin = new System.Windows.Thickness(5, 0, 0, 0); int selected = -1; for (int i = startYear; i <= lastYear; i++) { if (i == this.year) { selected = i; } byYearCombo.Items.Add(i); } byYearCombo.SelectedItem = selected != -1 ? selected : lastYear; byYearCombo.SelectionChanged += OnYearChanged; byYearCombo.Margin = new Thickness(10, 0, 0, 0); heading.Inlines.Add(new InlineUIContainer(byYearCombo)); bool empty = true; foreach (TaxForm form in taxCategories.GetForms()) { if (GenerateForm(form, writer, transactions)) { empty = false; } } if (empty) { writer.WriteParagraph("You have not associated any of your categories with Tax Categories. See the Category Properties dialog for more information."); } writer.WriteParagraph("Generated on " + DateTime.Today.ToLongDateString(), System.Windows.FontStyles.Italic, System.Windows.FontWeights.Normal, System.Windows.Media.Brushes.Gray); }
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); }
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); }
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); }
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); }
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); })); } }
public override void Generate(IReportWriter writer) { FlowDocumentReportWriter fwriter = (FlowDocumentReportWriter)writer; writer.WriteHeading("Tax Report For "); int firstYear = DateTime.Now.Year; int lastYear = DateTime.Now.Year; ICollection <Transaction> transactions = this.money.Transactions.GetAllTransactionsByDate(); Transaction first = transactions.FirstOrDefault(); if (first != null) { firstYear = first.Date.Year; } Transaction last = transactions.LastOrDefault(); if (last != null) { lastYear = last.Date.Year; if (this.fiscalYearStart > 0 && last.Date.Month > this.fiscalYearStart + 1) { lastYear++; } // don't show a report containing zero data. Scroll back to the last year // of data and show that. if (this.fiscalYearStart > 0 && lastYear > this.endDate.Year) { SetStartDate(lastYear); } else if (this.fiscalYearStart == 0 && this.startDate.Year > lastYear) { SetStartDate(lastYear); } } Paragraph heading = fwriter.CurrentParagraph; ComboBox byYearCombo = new ComboBox(); byYearCombo.Margin = new System.Windows.Thickness(5, 0, 0, 0); int selected = -1; int index = 0; for (int i = firstYear; i <= lastYear; i++) { if (this.fiscalYearStart > 0 && i == this.endDate.Year) { selected = index; } else if (this.fiscalYearStart == 0 && i == this.startDate.Year) { selected = index; } if (this.fiscalYearStart > 0) { byYearCombo.Items.Add("FY " + i); } else { byYearCombo.Items.Add(i.ToString()); } index++; } if (selected != -1) { byYearCombo.SelectedIndex = selected; } byYearCombo.SelectionChanged += OnYearChanged; byYearCombo.Margin = new Thickness(10, 0, 0, 0); heading.Inlines.Add(new InlineUIContainer(byYearCombo)); /* * <StackPanel Margin="10,5,10,5" Grid.Row="2" Orientation="Horizontal"> * <TextBlock Text="Consolidate securities by: " Background="Transparent"/> * <ComboBox x:Name="ConsolidateSecuritiesCombo" SelectedIndex="0"> * <ComboBoxItem>Date Acquired</ComboBoxItem> * <ComboBoxItem>Date Sold</ComboBoxItem> * </ComboBox> * </StackPanel> * <CheckBox Margin="10,5,10,5" x:Name="CapitalGainsOnlyCheckBox" Grid.Row="3">Capital Gains Only</CheckBox> */ ComboBox consolidateCombo = new ComboBox(); consolidateCombo.Items.Add("Date Acquired"); consolidateCombo.Items.Add("Date Sold"); consolidateCombo.SelectedIndex = this.consolidateOnDateSold ? 1 : 0; consolidateCombo.SelectionChanged += OnConsolidateComboSelectionChanged; writer.WriteParagraph("Consolidate securities by: "); Paragraph prompt = fwriter.CurrentParagraph; prompt.Margin = new Thickness(0, 0, 0, 4); prompt.Inlines.Add(new InlineUIContainer(consolidateCombo)); CheckBox checkBox = new CheckBox(); checkBox.Content = "Capital Gains Only"; checkBox.IsChecked = this.capitalGainsOnly; checkBox.Checked += OnCapitalGainsOnlyChanged; checkBox.Unchecked += OnCapitalGainsOnlyChanged; writer.WriteParagraph(""); Paragraph checkBoxParagraph = fwriter.CurrentParagraph; checkBoxParagraph.Inlines.Add(new InlineUIContainer(checkBox)); if (!capitalGainsOnly) { // find all tax related categories and summarize accordingly. GenerateCategories(writer); } GenerateCapitalGains(writer); FlowDocument document = view.DocumentViewer.Document; document.Blocks.InsertAfter(document.Blocks.FirstBlock, new BlockUIContainer(CreateExportTxfButton())); }
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(); }
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(); }
public void Generate(IReportWriter writer) { if (doc == null) { return; } var document = view.DocumentViewer.Document; bool found = false; bool first = true; var style = new Style(typeof(Paragraph)); style.Setters.Add(new Setter(Paragraph.BackgroundProperty, Brushes.Teal)); style.Setters.Add(new Setter(Paragraph.ForegroundProperty, Brushes.White)); style.Setters.Add(new Setter(Paragraph.FontSizeProperty, 18.0)); document.Resources.Remove("HeadingStyle"); document.Resources.Add("HeadingStyle", style); foreach (XElement change in doc.Root.Elements("change")) { string version = (string)change.Attribute("version"); if (string.IsNullOrEmpty(version)) { continue; } bool match = IsSameOrOlder(previousVersion, version); if (!found && match) { writer.WriteHeading("The following changes were already installed"); found = true; } if (first && !found) { writer.WriteHeading("The following changes are now available"); first = false; } string date = (string)change.Attribute("date"); writer.WriteSubHeading(version + " " + date); foreach (string line in change.Value.Split('\r', '\n')) { string trimmed = line.Trim(); if (!string.IsNullOrEmpty(trimmed)) { FlowDocumentReportWriter fwriter = (FlowDocumentReportWriter)writer; Paragraph p = fwriter.WriteParagraph(trimmed, FontStyles.Normal, FontWeights.Normal, found ? Brushes.Gray : Brushes.Black, 11); p.TextIndent = 20; p.Margin = new Thickness(0); p.Padding = new Thickness(0); } } } if (installButton && !HasLatestVersion()) { document.Blocks.InsertAfter(document.Blocks.FirstBlock, new BlockUIContainer(CreateInstallButton())); } }
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); })); } } }
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); }