Ejemplo n.º 1
0
    def test_cost_to_str__detail(self):
        cost = position.Cost(D('101.23'), 'USD', datetime.date(2015, 9, 6),
                             "f4412439c31b")
        self.assertEqual('101.23 USD, 2015-09-06, "f4412439c31b"',
                         position.cost_to_str(cost, self.dformat))

        cost = position.Cost(D('101.23'), 'USD', datetime.date(2015, 9, 6),
                             None)
        self.assertEqual('101.23 USD, 2015-09-06',
                         position.cost_to_str(cost, self.dformat))

        cost = position.Cost(D('101.23'), 'USD', None, None)
        self.assertEqual('101.23 USD',
                         position.cost_to_str(cost, self.dformat))

        cost = position.Cost(D('101.23'), 'USD', None, "f4412439c31b")
        self.assertEqual('101.23 USD, "f4412439c31b"',
                         position.cost_to_str(cost, self.dformat))

        cost = position.Cost(None, None, None, "f4412439c31b")
        self.assertEqual('"f4412439c31b"',
                         position.cost_to_str(cost, self.dformat))

        cost = position.Cost(None, 'USD', None, "f4412439c31b")
        self.assertEqual('"f4412439c31b"',
                         position.cost_to_str(cost, self.dformat))
Ejemplo n.º 2
0
    def Posting(self, posting, entry):
        assert posting.account is not None
        flag = f"{ledger_flag(posting.flag)} " if ledger_flag(
            posting.flag) else ""
        flag_posting = f"{flag}{posting.account}"

        pos_str = ""
        # We don't use position.to_string() because that uses the same
        # dformat for amount and cost, but we want dformat from our
        # dcontext to format amounts to the right precision while
        # retaining the full precision for costs.
        if isinstance(posting.units, Amount):
            pos_str = posting.units.to_string(self.dformat)
        # Convert the cost as a price entry, that's what HLedger appears to want.
        if isinstance(posting.cost, position.Cost):
            pos_str += " @ " + position.cost_to_str(
                posting.cost, display_context.DEFAULT_FORMATTER, detail=False)

        price_str = ("@ {}".format(posting.price.to_string())
                     if posting.price is not None and posting.cost is None else
                     "")
        if (posting.meta and "__automatic__" in posting.meta
                and "__residual__" not in posting.meta):
            posting_str = f"{flag_posting}"
        else:
            # Width we have available for the amount: take width of
            # flag_posting add config["indent"] for the indentation
            # of postings and add 2 to separate account from amount
            len_amount = max(0, 76 - (len(flag_posting) + 2 + 2))
            posting_str = (
                f"{flag_posting}  {quote_currency(pos_str):>{len_amount}}"
                f" {quote_currency(price_str)}")
        indent = " " * self.config["indent"]
        self.io.write(indent + posting_str.rstrip())
        self.io.write("\n")

        meta = user_meta(posting.meta or {})
        postdate_key = self.config.get("postdate")
        if postdate_key and isinstance(meta.get(postdate_key), datetime.date):
            postdate = meta[postdate_key]
            del meta[postdate_key]
            meta["date"] = postdate
        auxdate_key = self.config.get("auxdate")
        if auxdate_key and isinstance(meta.get(auxdate_key), datetime.date):
            auxdate = meta[auxdate_key]
            del meta[auxdate_key]
            meta["date2"] = auxdate

        for key, val in meta.items():
            formatted_meta = self.format_meta(key, val)
            if meta:
                self.io.write(2 * indent + f"; {formatted_meta}\n")
Ejemplo n.º 3
0
    def test_cost_to_str__detail(self):
        cost = position.CostSpec(D('101.23'), D('202.46'), 'USD',
                                 datetime.date(2015, 9, 6), "f4412439c31b",
                                 True)
        self.assertEqual('101.23 # 202.46 USD, 2015-09-06, "f4412439c31b", *',
                         position.cost_to_str(cost, self.dformat))

        cost = position.CostSpec(D('101.23'), D('202.46'), 'USD',
                                 datetime.date(2015, 9, 6), "f4412439c31b",
                                 False)
        self.assertEqual('101.23 # 202.46 USD, 2015-09-06, "f4412439c31b"',
                         position.cost_to_str(cost, self.dformat))

        cost = position.CostSpec(D('101.23'), None, 'USD',
                                 datetime.date(2015, 9, 6), None, True)
        self.assertEqual('101.23 USD, 2015-09-06, *',
                         position.cost_to_str(cost, self.dformat))

        cost = position.CostSpec(D('101.23'), D('202.46'), 'USD', None, None,
                                 False)
        self.assertEqual('101.23 # 202.46 USD',
                         position.cost_to_str(cost, self.dformat))

        cost = position.CostSpec(None, D('202.46'), 'USD', None, None, False)
        self.assertEqual('# 202.46 USD',
                         position.cost_to_str(cost, self.dformat))

        cost = position.CostSpec(D('101.23'), None, 'USD', None,
                                 "f4412439c31b", True)
        self.assertEqual('101.23 USD, "f4412439c31b", *',
                         position.cost_to_str(cost, self.dformat))

        cost = position.CostSpec(None, None, None, None, "f4412439c31b", False)
        self.assertEqual('"f4412439c31b"',
                         position.cost_to_str(cost, self.dformat))

        cost = position.CostSpec(None, None, 'USD', None, "f4412439c31b", True)
        self.assertEqual('"f4412439c31b", *',
                         position.cost_to_str(cost, self.dformat))
Ejemplo n.º 4
0
    def test_cost_to_str__simple(self):
        cost = position.Cost(D('101.23'), 'USD', datetime.date(2015, 9, 6),
                             "f4412439c31b")
        self.assertEqual('101.23 USD',
                         position.cost_to_str(cost, self.dformat, False))

        cost = position.Cost(D('101.23'), 'USD', datetime.date(2015, 9, 6),
                             None)
        self.assertEqual('101.23 USD',
                         position.cost_to_str(cost, self.dformat, False))

        cost = position.Cost(D('101.23'), 'USD', None, None)
        self.assertEqual('101.23 USD',
                         position.cost_to_str(cost, self.dformat, False))

        cost = position.Cost(D('101.23'), 'USD', None, "f4412439c31b")
        self.assertEqual('101.23 USD',
                         position.cost_to_str(cost, self.dformat, False))

        cost = position.Cost(None, None, None, "f4412439c31b")
        self.assertEqual('', position.cost_to_str(cost, self.dformat, False))

        cost = position.Cost(None, 'USD', None, "f4412439c31b")
        self.assertEqual('', position.cost_to_str(cost, self.dformat, False))
Ejemplo n.º 5
0
    def Posting(self, posting, entry):
        """Postings"""

        assert posting.account is not None
        flag = f"{ledger_flag(posting.flag)} " if ledger_flag(
            posting.flag) else ""
        flag_posting = f"{flag}{posting.account}"

        pos_str = ""
        # We don't use position.to_string() because that uses the same
        # dformat for amount and cost, but we want dformat from our
        # dcontext to format amounts to the right precision while
        # retaining the full precision for costs.
        if isinstance(posting.units, Amount):
            pos_str = posting.units.to_string(self.dformat)
        # We can't use default=True, even though we're interested in the
        # cost details, but we have to add them ourselves in the format
        # expected by ledger.
        if isinstance(posting.cost, position.Cost):
            pos_str += (" {" + position.cost_to_str(
                posting.cost, display_context.DEFAULT_FORMATTER, detail=False)
                        + "}")
        if posting.cost:
            if posting.cost.date != entry.date:
                pos_str += f" [{posting.cost.date}]"
            if posting.cost.label:
                pos_str += f" ({posting.cost.label})"

        if posting.price is not None:
            price_str = "@ {}".format(posting.price.to_string())
        else:
            # Figure out if we need to insert a price on a posting held at cost.
            # See https://groups.google.com/d/msg/ledger-cli/35hA0Dvhom0/WX8gY_5kHy0J
            # and https://github.com/ledger/ledger/issues/630
            (postings_simple, _, __) = postings_by_type(entry)
            postings_no_amount = [
                posting for posting in postings_simple
                if posting.units is None or is_automatic_posting(posting)
            ]
            cost = posting.cost
            if cost and not postings_no_amount and len(entry.postings) > 2:
                price_str = "@ {}".format(
                    amount.Amount(cost.number, cost.currency).to_string())
            else:
                price_str = ""

        if is_automatic_posting(posting):
            posting_str = f"{flag_posting}"
        else:
            # Width we have available for the amount: take width of
            # flag_posting add config["indent"] for the indentation
            # of postings and add 2 to separate account from amount
            len_amount = max(
                0, 75 - (len(flag_posting) + self.config["indent"] + 2))
            posting_str = (
                f"{flag_posting}  {quote_currency(pos_str):>{len_amount}}"
                f" {quote_currency(price_str)}")
        indent = " " * self.config["indent"]
        self.io.write(indent + posting_str.rstrip())
        meta = user_meta(posting.meta or {})
        dates = []
        postdate_key = self.config.get("postdate")
        if postdate_key and isinstance(meta.get(postdate_key), datetime.date):
            dates.append(str(meta[postdate_key]))
            del meta[postdate_key]
        auxdate_key = self.config.get("auxdate")
        if auxdate_key and isinstance(meta.get(auxdate_key), datetime.date):
            dates.append("=" + str(meta[auxdate_key]))
            del meta[auxdate_key]
        if dates:
            self.io.write("  ; [" + "".join(dates) + "]")
        self.io.write("\n")

        for key, val in meta.items():
            formatted_meta = self.format_meta(key, val)
            if meta:
                self.io.write(2 * indent + f"; {formatted_meta}\n")