예제 #1
0
 def set_metadata(self, x: Directive, lineno: Optional[int] = None):
     meta = dict({}, **(x.meta or {}))
     meta['filename'] = self.filename
     if lineno is None:
         lineno = self.new_lineno + 1
     meta['lineno'] = lineno
     return x._replace(meta=meta)
예제 #2
0
def _partially_book_entry(orig_entry: Directive,
                          booked_entry: Directive) -> Directive:
    """Computes a partially-booked entry.

    Given a pre-booking entry and a post-booking entry, returns a modified copy
    of the pre-booking entry that includes missing units.

    """
    if not isinstance(orig_entry, Transaction): return orig_entry
    assert isinstance(booked_entry, Transaction)
    booked_postings_by_meta = dict()  # type: Dict[int, List[Posting]]
    for posting in booked_entry.postings:
        meta = posting.meta
        if meta is None: continue
        booked_postings_by_meta.setdefault(id(meta), []).append(posting)
    partially_booked_postings = []  # type: List[Posting]
    empty_list = []  # type: List[Posting]
    for posting in orig_entry.postings:
        booked_matches = booked_postings_by_meta.get(
            id(posting.meta), empty_list)
        if len(booked_matches) != 1:
            partially_booked_postings.append(posting)
            continue
        booked_match = booked_matches[0]
        if posting.units is MISSING and booked_match.units is not MISSING:
            posting = posting._replace(units=booked_match.units)
        partially_booked_postings.append(posting)
    return orig_entry._replace(postings=partially_booked_postings)
예제 #3
0
def _format_entry(entry: Directive, currency_column: int) -> str:
    """Wrapper that strips unnecessary whitespace from format_entry."""
    meta = {
        key: entry.meta[key] for key in entry.meta if not key.startswith("_")
    }
    entry = entry._replace(meta=meta)
    string = align(format_entry(entry), currency_column)
    string = string.replace("<class 'beancount.core.number.MISSING'>", "")
    return "\n".join((line.rstrip() for line in string.split("\n")))
예제 #4
0
def categorize_entry(catmap: Dict[Account, Cat],
                     entry: data.Directive) -> Tuple[Cat]:
    """Assigns metadata to each posting."""
    postings = []
    for posting in entry.postings:
        category = catmap[posting.account]
        if category is None:
            category = Cat.OTHER if posting.cost is None else Cat.OTHERASSET
        meta = posting.meta.copy() if posting.meta else {}
        meta["category"] = category
        postings.append(posting._replace(meta=meta))
    return entry._replace(postings=postings)
예제 #5
0
def merge_narration(entry: Directive, comment_narrations: Dict[str, Dict[int, str]]) -> Directive:
    if not isinstance(entry, Transaction):
        return entry
    narrations = []
    for posting in entry.postings:
        if posting.meta:
            narration = posting.meta.get('narration')
            comment_narration = comment_narrations.get(posting.meta.get('filename')).get(posting.meta.get('lineno'))
            if narration is None and comment_narration:
                posting.meta['narration'] = comment_narration
                narration = comment_narration
            if narration:
                narrations.append(narration.strip())
    if entry.narration:
        return entry
    return entry._replace(narration=' | '.join(narrations))
예제 #6
0
def serialise(entry: Directive) -> Any:
    """Serialise an entry."""
    if not entry:
        return None
    ret = entry._asdict()
    ret["type"] = entry.__class__.__name__
    if isinstance(entry, Transaction):
        ret["payee"] = entry.payee or ""
        if entry.tags:
            ret["narration"] += " " + " ".join(["#" + t for t in entry.tags])
        if entry.links:
            ret["narration"] += " " + " ".join(
                ["^" + link for link in entry.links])
        del ret["links"]
        del ret["tags"]
        ret["postings"] = [serialise(pos) for pos in entry.postings]
    elif ret["type"] == "Balance":
        amt = ret["amount"]
        ret["amount"] = {"number": str(amt.number), "currency": amt.currency}
    return ret