/// <summary> /// Ported from changed_value_posts::output_revaluation /// </summary> public void OutputRevaluation(Post post, Date date) { if (date.IsValid()) { post.XData.Date = date; } try { BindScope boundScope = new BindScope(Report, post); RepricedTotal = TotalExpr.Calc(boundScope); } finally { post.XData.Date = default(Date); } if (!Value.IsNullOrEmpty(LastTotal)) { Value diff = RepricedTotal - LastTotal; if (!Value.IsNullOrEmptyOrFalse(diff)) { Xact xact = Temps.CreateXact(); xact.Payee = "Commodities revalued"; xact.Date = date.IsValid() ? date : post.ValueDate; if (!ForAccountsReports) { FiltersCommon.HandleValue( /* value= */ diff, /* account= */ RevaluedAccount, /* xact= */ xact, /* temps= */ Temps, /* handler= */ (PostHandler)Handler, /* date= */ xact.Date.Value, /* act_date_p= */ true, /* total= */ RepricedTotal); } else if (ShowUnrealized) { FiltersCommon.HandleValue( /* value= */ diff.Negated(), /* account= */ (diff.IsLessThan(Value.Zero) ? LossesEquityAccount : GainsEquityAccount), /* xact= */ xact, /* temps= */ Temps, /* handler= */ (PostHandler)Handler, /* date= */ xact.Date.Value, /* act_date_p= */ true, /* total= */ new Value(), /* direct_amount= */ false, /* mark_visited= */ true); } } } }
/// <summary> /// Ported from collapse_posts::report_subtotal /// </summary> public void ReportSubtotal() { if (Count == 0) { return; } int displayedCount = 0; foreach (Post post in ComponentPosts) { BindScope boundScope = new BindScope(Report, post); if (OnlyPredicate.Calc(boundScope).Bool&& DisplayPredicate.Calc(boundScope).Bool) { displayedCount++; } } if (displayedCount == 1) { base.Handle(LastPost); } else if (OnlyCollapseIfZero && !Subtotal.IsZero) { foreach (Post post in ComponentPosts) { base.Handle(post); } } else { Date earliestDate = default(Date); Date latestDate = default(Date); foreach (Post post in ComponentPosts) { Date date = post.GetDate(); Date valueDate = post.ValueDate; if (!earliestDate.IsValid() || date < earliestDate) { earliestDate = date; } if (!latestDate.IsValid() || valueDate > latestDate) { latestDate = valueDate; } } Xact xact = Temps.CreateXact(); xact.Payee = LastXact.Payee; xact.Date = earliestDate.IsValid() ? earliestDate : LastXact.Date; Logger.Debug("filters.collapse", () => String.Format("Pseudo-xact date = {0}", xact.Date)); Logger.Debug("filters.collapse", () => String.Format("earliest date = {0}", earliestDate)); Logger.Debug("filters.collapse", () => String.Format("latest date = {0}", latestDate)); FiltersCommon.HandleValue( /* value= */ Subtotal, /* account= */ TotalsAccount, /* xact= */ xact, /* temps= */ Temps, /* handler= */ (PostHandler)Handler, /* date= */ latestDate, /* act_date_p= */ false); } ComponentPosts.Clear(); LastXact = null; LastPost = null; Subtotal = Value.Get(0); Count = 0; }
/// <summary> /// Ported from subtotal_posts::report_subtotal /// </summary> public void ReportSubtotal(string specFmt = null, DateInterval interval = null) { if (!ComponentPosts.Any()) { return; } Date?rangeStart = interval != null ? interval.Start : null; Date?rangeFinish = interval != null ? interval.InclusiveEnd : null; if (!rangeStart.HasValue || !rangeFinish.HasValue) { foreach (Post post in ComponentPosts) { Date date = post.GetDate(); Date valueDate = post.ValueDate; if (!rangeStart.HasValue || date < rangeStart) { rangeStart = date; } if (!rangeFinish.HasValue || valueDate > rangeFinish) { rangeFinish = valueDate; } } } ComponentPosts.Clear(); string outDate; if (!String.IsNullOrEmpty(specFmt)) { outDate = TimesCommon.Current.FormatDate(rangeFinish.Value, FormatTypeEnum.FMT_CUSTOM, specFmt); } else if (!String.IsNullOrEmpty(DateFormat)) { outDate = "- " + TimesCommon.Current.FormatDate(rangeFinish.Value, FormatTypeEnum.FMT_CUSTOM, DateFormat); } else { outDate = "- " + TimesCommon.Current.FormatDate(rangeFinish.Value); } Xact xact = Temps.CreateXact(); xact.Payee = outDate; xact.Date = rangeStart.Value; foreach (KeyValuePair <string, AcctValue> pair in Values) { FiltersCommon.HandleValue( /* value= */ pair.Value.Value, /* account= */ pair.Value.Account, /* xact= */ xact, /* temps= */ Temps, /* handler= */ (PostHandler)Handler, /* date= */ rangeFinish.Value, /* act_date_p= */ false); } Values.Clear(); }
/// <summary> /// Ported from posts_as_equity::report_subtotal /// </summary> public void ReportSubtotal() { Date finish = default(Date); foreach (Post post in ComponentPosts) { Date date = post.GetDate(); if (!finish.IsValid() || date > finish) { finish = date; } } Xact xact = Temps.CreateXact(); xact.Payee = "Opening Balances"; xact.Date = finish; Value total = Value.Get(0); foreach (KeyValuePair <string, AcctValue> pair in Values) { Value value = pair.Value.Value.StripAnnotations(Report.WhatToKeep()); if (!Value.IsNullOrEmpty(value)) { if (value.Type == ValueTypeEnum.Balance) { foreach (KeyValuePair <Commodity, Amount> amountPair in value.AsBalance.Amounts) { if (!amountPair.Value.IsZero) { FiltersCommon.HandleValue( /* value= */ Value.Get(amountPair.Value), /* account= */ pair.Value.Account, /* xact= */ xact, /* temps= */ Temps, /* handler= */ (PostHandler)Handler, /* date= */ finish, /* act_date_p= */ false); } } } else { FiltersCommon.HandleValue( /* value= */ Value.Get(value.AsAmount), /* account= */ pair.Value.Account, /* xact= */ xact, /* temps= */ Temps, /* handler= */ (PostHandler)Handler, /* date= */ finish, /* act_date_p= */ false); } } if (!pair.Value.IsVirtual || pair.Value.MustBalance) { total.InPlaceAdd(value); } } Values.Clear(); // This last part isn't really needed, since an Equity:Opening // Balances posting with a null amount will automatically balance with // all the other postings generated. But it does make the full // balancing amount clearer to the user. if (!total.IsZero) { Action <Amount> postCreator = amt => { Post balancePost = Temps.CreatePost(xact, BalanceAccount); balancePost.Amount = amt.Negated(); Handler.Handle(balancePost); }; if (total.Type == ValueTypeEnum.Balance) { total.AsBalance.MapSortedAmounts(postCreator); } else { postCreator(total.AsAmount); } } }
/// <summary> /// Ported from changed_value_posts::output_revaluation /// </summary> public void OutputRevaluation(Post post, Date date) { if (date.IsValid()) { post.XData.Date = date; } try { BindScope boundScope = new BindScope(Report, post); RepricedTotal = TotalExpr.Calc(boundScope); } finally { post.XData.Date = default(Date); } Logger.Current.Debug("filters.changed_value", () => String.Format("output_revaluation(last_total) = {0}", LastTotal)); Logger.Current.Debug("filters.changed_value", () => String.Format("output_revaluation(repriced_total) = {0}", RepricedTotal)); if (!Value.IsNullOrEmpty(LastTotal)) { Value diff = RepricedTotal - LastTotal; if (!Value.IsNullOrEmptyOrFalse(diff)) { Logger.Current.Debug("filters.changed_value", () => String.Format("output_revaluation(strip(diff)) = {0}", diff.StripAnnotations(Report.WhatToKeep()))); Xact xact = Temps.CreateXact(); xact.Payee = "Commodities revalued"; xact.Date = date.IsValid() ? date : post.ValueDate; if (!ForAccountsReports) { FiltersCommon.HandleValue( /* value= */ diff, /* account= */ RevaluedAccount, /* xact= */ xact, /* temps= */ Temps, /* handler= */ (PostHandler)Handler, /* date= */ xact.Date.Value, /* act_date_p= */ true, /* total= */ RepricedTotal); } else if (ShowUnrealized) { FiltersCommon.HandleValue( /* value= */ diff.Negated(), /* account= */ (diff.IsLessThan(Value.Zero) ? LossesEquityAccount : GainsEquityAccount), /* xact= */ xact, /* temps= */ Temps, /* handler= */ (PostHandler)Handler, /* date= */ xact.Date.Value, /* act_date_p= */ true, /* total= */ new Value(), /* direct_amount= */ false, /* mark_visited= */ true); } } } }
public bool OutputRounding(Post post) { BindScope boundScope = new BindScope(Report, post); Value newDisplayTotal = new Value(); if (ShowRounding) { newDisplayTotal = DisplayTotalExpr.Calc(boundScope).StripAnnotations(Report.WhatToKeep()); Logger.Current.Debug("filters.changed_value.rounding", () => String.Format("rounding.new_display_total = {0}", newDisplayTotal)); } // Allow the posting to be displayed if: // 1. Its display_amount would display as non-zero, or // 2. The --empty option was specified, or // 3. a) The account of the posting is <Revalued>, and // b) the revalued option is specified, and // c) the --no-rounding option is not specified. if (post.Account == RevaluedAccount) { if (ShowRounding) { LastDisplayTotal = newDisplayTotal; } return(true); } Value repricedAmount = DisplayAmountExpr.Calc(boundScope).StripAnnotations(Report.WhatToKeep()); if (!Value.IsNullOrEmptyOrFalse(repricedAmount)) { if (!Value.IsNullOrEmpty(LastDisplayTotal)) { Logger.Current.Debug("filters.changed_value.rounding", () => String.Format("rounding.repriced_amount = {0}", repricedAmount)); Value preciseDisplayTotal = newDisplayTotal.Truncated() - repricedAmount.Truncated(); Logger.Current.Debug("filters.changed_value.rounding", () => String.Format("rounding.precise_display_total = {0}", preciseDisplayTotal)); Logger.Current.Debug("filters.changed_value.rounding", () => String.Format("rounding.last_display_total = {0}", LastDisplayTotal)); Value diff = preciseDisplayTotal - LastDisplayTotal; if (!Value.IsNullOrEmptyOrFalse(diff)) { Logger.Current.Debug("filters.changed_value.rounding", () => String.Format("rounding.diff = {0}", diff)); FiltersCommon.HandleValue( /* value= */ diff, /* account= */ RoundingAccount, /* xact= */ post.Xact, /* temps= */ Temps, /* handler= */ (PostHandler)Handler, /* date= */ default(Date), /* act_date_p= */ true, /* total= */ preciseDisplayTotal, /* direct_amount= */ true, /* mark_visited= */ false, /* bidir_link= */ false); } } if (ShowRounding) { LastDisplayTotal = newDisplayTotal; } return(true); } else { return(Report.EmptyHandler.Handled); } }