示例#1
0
        /// <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);
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Ported from void transfer_details::operator()(post_t& post)
        /// </summary>
        public override void Handle(Post post)
        {
            Xact xact = Temps.CopyXact(post.Xact);

            xact.Date = post.GetDate();

            Post temp = Temps.CopyPost(post, xact);

            temp.State = post.State;

            BindScope boundScope = new BindScope(Scope, temp);
            Value     substitute = Expr.Calc(boundScope);

            if (!Value.IsNullOrEmpty(substitute))
            {
                switch (WhichElement)
                {
                case TransferDetailsElementEnum.SET_DATE:
                    temp.Date = substitute.AsDate;
                    break;

                case TransferDetailsElementEnum.SET_ACCOUNT:
                {
                    string accountName = substitute.AsString;
                    if (!String.IsNullOrEmpty(accountName) && !accountName.EndsWith(":"))
                    {
                        Account prevAccount = temp.Account;
                        temp.Account.RemovePost(temp);

                        accountName += ":" + prevAccount.FullName;

                        string[] accountNames = accountName.Split(':');
                        temp.Account = FiltersCommon.CreateTempAccountFromPath(accountNames, Temps, xact.Journal.Master);
                        temp.Account.AddPost(temp);

                        temp.Account.SetFlags(prevAccount);
                        if (prevAccount.HasXData)
                        {
                            temp.Account.XData.SetFlags(prevAccount.XData);
                        }
                    }
                    break;
                }

                case TransferDetailsElementEnum.SET_PAYEE:
                    xact.Payee = substitute.AsString;
                    break;
                }
            }

            base.Handle(temp);
        }
示例#3
0
        public InjectPosts(PostHandler handler, string tagList, Account master)
            : base(handler)
        {
            TagsList = new List <Tuple <string, Account, ISet <Xact> > >();
            Temps    = new Temporaries();

            foreach (string q in tagList.Split(',').Select(s => s.Trim()))
            {
                string[] accountNames = q.Split(':');
                Account  account      = FiltersCommon.CreateTempAccountFromPath(accountNames, Temps, master);
                account.IsGeneratedAccount = true;

                TagsList.Add(new Tuple <string, Account, ISet <Xact> >(q, account, new HashSet <Xact>()));
            }
        }
示例#4
0
        /// <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;
        }
示例#5
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();
        }
示例#6
0
        /// <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);
                }
            }
        }
示例#7
0
        public override void Handle(Post post)
        {
            bool copyXactDetails = false;

            if (LastXact != post.Xact)
            {
                Temps.CopyXact(post.Xact);
                LastXact        = post.Xact;
                copyXactDetails = true;
            }
            Xact xact = Temps.LastXact;

            xact.Code = null;

            if (copyXactDetails)
            {
                xact.CopyDetails(post.Xact);

                string buf = String.Format("{0}{1}{0}", post.Xact.Payee, IntegerGen.Value());

                xact.Payee = SHA1.GetHash(buf);
                xact.Note  = null;
            }
            else
            {
                xact.Journal = post.Xact.Journal;
            }

            IList <string> accountNames = new List <string>();

            for (Account acct = post.Account; acct != null; acct = acct.Parent)
            {
                string buf = String.Format("{0}{1}{2}", IntegerGen.Value(), acct, acct.FullName);

                accountNames.Add(SHA1.GetHash(buf));
            }

            Account newAccount = FiltersCommon.CreateTempAccountFromPath(accountNames, Temps, xact.Journal.Master);
            Post    temp       = Temps.CopyPost(post, xact, newAccount);

            temp.Note   = null;
            temp.Flags |= SupportsFlagsEnum.POST_ANONYMIZED;

            RenderCommodity(temp.Amount);
            if (temp.Amount.HasAnnotation)
            {
                temp.Amount.Annotation.Tag = null;
                if (temp.Amount.Annotation.Price != null)
                {
                    RenderCommodity(temp.Amount.Annotation.Price);
                }
            }

            if (temp.Cost != null)
            {
                RenderCommodity(temp.Cost);
            }
            if (temp.AssignedAmount != null)
            {
                RenderCommodity(temp.AssignedAmount);
            }

            base.Handle(temp);
        }
示例#8
0
        /// <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);
                    }
                }
            }
        }
示例#9
0
        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);
            }
        }