def deserialise(json_entry): """Parse JSON to a Beancount entry. Args: json_entry: The entry. Raises: KeyError: if one of the required entry fields is missing. FavaAPIException: if the type of the given entry is not supported. """ if json_entry['type'] == 'Transaction': date = util.date.parse_date(json_entry['date'])[0] narration, tags, links = extract_tags_links(json_entry['narration']) postings = [deserialise_posting(pos) for pos in json_entry['postings']] return data.Transaction(json_entry['meta'], date, json_entry['flag'], json_entry['payee'], narration, tags, links, postings) if json_entry['type'] == 'Balance': date = util.date.parse_date(json_entry['date'])[0] number = parse_number(json_entry['number']) amount = Amount(number, json_entry['currency']) return data.Balance(json_entry['meta'], date, json_entry['account'], amount, None, None) if json_entry['type'] == 'Note': date = util.date.parse_date(json_entry['date'])[0] comment = json_entry['comment'].replace('"', '') return data.Note(json_entry['meta'], date, json_entry['account'], comment) raise FavaAPIException('Unsupported entry type.')
def extract_balance(self, statement:CCSTMTRS, existing_entries=None): amount = statement.balance.balamt # Seems Chase doesn't provide a proper date for this: if statement.transactions: last_tx = statement.transactions[-1] bal_datetime = last_tx.dtposted else: return [] currency = statement.curdef bal_date = datetime.date( bal_datetime.year, bal_datetime.month, bal_datetime.day ) unique_key = str(bal_date) match_key = 'source-report-date' existing_by_id = self.find_existing(existing_entries, match_key, _type=data.Balance) if unique_key in existing_by_id: # We don't do duplicate balance assertions return [] return [data.Note( account=self.accounts['root'], # amount=data.Amount(amount, currency), comment=f"balance {amount} {currency}", date=bal_date, meta={'lineno': 0, 'filename': '', match_key: unique_key}, # tolerance=0.5, # Need to verify these # diff_amount=None, # Set by system )]
def json_to_entry(json_entry, valid_accounts): """Parse JSON to a Beancount entry.""" # pylint: disable=not-callable date = util.date.parse_date(json_entry['date'])[0] if json_entry['type'] == 'transaction': narration, tags, links = extract_tags_links(json_entry['narration']) txn = data.Transaction(json_entry['metadata'], date, json_entry['flag'], json_entry['payee'], narration, tags, links, []) if not json_entry.get('postings'): raise FavaAPIException('Transaction contains no postings.') for posting in json_entry['postings']: if posting['account'] not in valid_accounts: raise FavaAPIException('Unknown account: {}.'.format( posting['account'])) data.create_simple_posting(txn, posting['account'], posting.get('number') or None, posting.get('currency')) return txn elif json_entry['type'] == 'balance': if json_entry['account'] not in valid_accounts: raise FavaAPIException('Unknown account: {}.'.format( json_entry['account'])) number = D(json_entry['number']) amount = Amount(number, json_entry.get('currency')) return data.Balance(json_entry['metadata'], date, json_entry['account'], amount, None, None) elif json_entry['type'] == 'note': if json_entry['account'] not in valid_accounts: raise FavaAPIException('Unknown account: {}.'.format( json_entry['account'])) if '"' in json_entry['comment']: raise FavaAPIException('Note contains double-quotes (")') return data.Note(json_entry['metadata'], date, json_entry['account'], json_entry['comment']) else: raise FavaAPIException('Unsupported entry type.')
def deserialise(json_entry): """Parse JSON to a Beancount entry. Args: json_entry: The entry. Raises: KeyError: if one of the required entry fields is missing. FavaAPIException: if the type of the given entry is not supported. """ if json_entry["type"] == "Transaction": date = util.date.parse_date(json_entry["date"])[0] narration, tags, links = extract_tags_links(json_entry["narration"]) postings = [deserialise_posting(pos) for pos in json_entry["postings"]] return data.Transaction( json_entry["meta"], date, json_entry.get("flag", ""), json_entry.get("payee", ""), narration, tags, links, postings, ) if json_entry["type"] == "Balance": date = util.date.parse_date(json_entry["date"])[0] raw_amount = json_entry["amount"] amount = Amount(D(str(raw_amount["number"])), raw_amount["currency"]) return data.Balance( json_entry["meta"], date, json_entry["account"], amount, None, None ) if json_entry["type"] == "Note": date = util.date.parse_date(json_entry["date"])[0] comment = json_entry["comment"].replace('"', "") return data.Note( json_entry["meta"], date, json_entry["account"], comment ) raise FavaAPIException("Unsupported entry type.")
def deserialise(json_entry): """Parse JSON to a Beancount entry. Args: json_entry: The entry. Raises: KeyError: if one of the required entry fields is missing. FavaAPIException: if the type of the given entry is not supported. """ # pylint: disable=not-callable if json_entry['type'] == 'Transaction': date = util.date.parse_date(json_entry['date'])[0] narration, tags, links = extract_tags_links(json_entry['narration']) txn = data.Transaction(json_entry['meta'], date, json_entry['flag'], json_entry['payee'], narration, tags, links, []) for posting in json_entry['postings']: data.create_simple_posting(txn, posting['account'], parse_number(posting.get('number')), posting.get('currency')) return txn elif json_entry['type'] == 'Balance': date = util.date.parse_date(json_entry['date'])[0] number = parse_number(json_entry['number']) amount = Amount(number, json_entry['currency']) return data.Balance(json_entry['meta'], date, json_entry['account'], amount, None, None) elif json_entry['type'] == 'Note': date = util.date.parse_date(json_entry['date'])[0] comment = json_entry['comment'].replace('"', '') return data.Note(json_entry['meta'], date, json_entry['account'], comment) else: raise FavaAPIException('Unsupported entry type.')
def unwrap_entry(data: dict) -> bean.Directive: type, e = itemgetter("type", "entry")(data) meta = e.get("meta") date = parse_date(e["date"]) if type == "Open": return bean.Open( meta, date, account=e["account"], currencies=e.get("currencies", []), booking=e.get("booking"), ) if type == "Close": return bean.Close(meta, date, account=e["account"]) if type == "Commodity": return bean.Commodity(meta, date, currency=e["currency"]) if type == "Pad": return bean.Pad(meta, date, account=e["account"], source_account=e["source_account"]) if type == "Balance": return bean.Balance( meta, date, account=e["account"], amount=parse_amount(e["amount"]), tolerance=e.get("tolerance"), diff_amount=e.get("diff_amount"), ) if type == "Transaction": return bean.Transaction( meta, date, flag=e["flag"], payee=e.get("payee"), narration=e["narration"], tags=set(e["tags"] if "tags" in e else []), links=set(e["links"] if "links" in e else []), postings=[parse_posting(p) for p in e.get("postings", [])], ) if type == "Note": return bean.Note(meta, date, account=e["account"], comment=e.get("comment", "")) if type == "Event": return bean.Event(meta, date, type=e["type"], description=e["description"]) if type == "Query": return bean.Query(meta, date, name=e["name"], query_string=e["query_string"]) if type == "Price": return bean.Price(meta, date, currency=e["currency"], amount=parse_amount(e["amount"])) if type == "Document": return bean.Document( meta, date, account=e["account"], filename=e["filename"], tags=set(e["tags"] if "tags" in e else []), links=set(e["links"] if "links" in e else []), ) if type == "Custom": return bean.Custom(meta, date, type=e["type"], values=e["values"])
def CreateNote(txn, account, comment) -> data.Note: """Create a Note directive.""" fileloc = data.new_metadata('<ameritrade>', 0) date = Date(txn) return data.Note(fileloc, date, account, comment)