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))
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")
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))
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))
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")