def _add_posting(self, transaction): split = transaction.narration.split(';') if len(split) >= 2: transaction_type = split[1].strip() create_simple_posting(transaction, self._mapping[transaction_type], None, self.currency) return transaction
def gen_transaction(self, row): trade_type = row['交易类型'] trade_amount = row['金额(元)'].replace('¥', '') trade_status = row['当前状态'] trade_time = dateparser.parse(row['交易时间']) trade_account = row['支付方式'] trade_partner = row['交易对方'] trade_description = row['商品'] trade_comment = row['备注'] meta = {} meta['trade_time'] = row['交易时间'] if trade_comment != '/': meta['comment'] = trade_comment entry = Transaction(meta, trade_time.strftime('%Y-%m-%d'), '*', trade_partner, trade_description, data.EMPTY_SET, data.EMPTY_SET, []) amount1 = trade_amount if row['收/支'] == '支出': amount1 = '-' + trade_amount data.create_simple_posting(entry, accounts.get_reality_account(row, 'wechat', trade_account), amount1, 'CNY') if trade_type == '商户消费' or trade_type == '扫二维码付款': data.create_simple_posting(entry, accounts.get_account(trade_partner, trade_description, trade_time, trade_comment), trade_amount, 'CNY') return entry
def test_json_to_entry(): valid_accounts = ['Assets:US:ETrade:Cash', 'Assets:US:ETrade:GLD'] json_txn = { 'type': 'transaction', 'date': '2017-12-12', 'flag': '*', 'payee': 'Test3', 'narration': '', 'metadata': {}, 'postings': [ { 'account': 'Assets:US:ETrade:Cash', 'number': '100', 'currency': 'USD', }, { 'account': 'Assets:US:ETrade:GLD', }, ], } txn = Transaction({}, datetime.date(2017, 12, 12), '*', 'Test3', '', frozenset(), frozenset(), []) create_simple_posting(txn, 'Assets:US:ETrade:Cash', '100', 'USD') create_simple_posting(txn, 'Assets:US:ETrade:GLD', None, None) assert json_to_entry(json_txn, valid_accounts) == txn
def test_deserialise(): postings = [ { 'account': 'Assets:ETrade:Cash', 'number': '100', 'currency': 'USD', }, { 'account': 'Assets:ETrade:GLD', }, ] json_txn = { 'type': 'Transaction', 'date': '2017-12-12', 'flag': '*', 'payee': 'Test3', 'narration': 'asdfasd #tag ^link', 'meta': {}, 'postings': postings, } txn = Transaction({}, datetime.date(2017, 12, 12), '*', 'Test3', 'asdfasd', frozenset(['tag']), frozenset(['link']), []) create_simple_posting(txn, 'Assets:ETrade:Cash', '100', 'USD') create_simple_posting(txn, 'Assets:ETrade:GLD', None, None) assert deserialise(json_txn) == txn with pytest.raises(KeyError): deserialise({}) with pytest.raises(FavaAPIException): deserialise({'type': 'NoEntry'})
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']) 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 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 create_sort_data(self): account = 'Assets:Bank:Checking' date1 = date(2014, 1, 15) date2 = date(2014, 1, 18) date3 = date(2014, 1, 20) entries = [ data.Transaction(data.new_metadata(".", 1100), date3, FLAG, None, "Next day", None, None, []), data.Close(data.new_metadata(".", 1000), date2, account), data.Balance(data.new_metadata(".", 1001), date2, account, A('200.00 USD"'), None, None), data.Open(data.new_metadata(".", 1002), date2, account, 'USD', None), data.Transaction(data.new_metadata(".", 1009), date2, FLAG, None, "Transaction 2", None, None, []), data.Transaction(data.new_metadata(".", 1008), date2, FLAG, None, "Transaction 1", None, None, []), data.Transaction(data.new_metadata(".", 900), date1, FLAG, None, "Previous day", None, None, []), ] for entry in entries: if isinstance(entry, data.Transaction): data.create_simple_posting(entry, 'Assets:Bank:Checking', '123.45', 'USD') return entries
def extract(self, file, existing_entries=None): self.initialize(file) counter = itertools.count() new_entries = [] config = self.config self.read_file(file) for ot in self.get_transactions(): metadata = data.new_metadata(file.name, next(counter)) # metadata['file_account'] = self.file_account(None) # metadata['type'] = ot.type # Optional metadata, useful for debugging #TODO # description fields: # - beancount: (payee, narration): # payee is optional, narration is mandatory # - OFX: ot.payee tends to be the "main" description field, while ot.memo is optional # Build transaction entry entry = data.Transaction(metadata, ot.date.date(), self.FLAG, self.get_transaction_type_desc(ot), ot.payee, data.EMPTY_SET, data.EMPTY_SET, []) data.create_simple_posting(entry, config['main_account'], ot.amount, self.currency) # TODO: Commented out so smart_importer can fill this in # target_acct = self.get_target_acct(ot) # data.create_simple_posting(entry, target_acct, None, None) new_entries.append(entry) if self.includes_balances: new_entries += self.extract_balance(file, counter) return(new_entries)
def add_splitdata(handler, transaction, taccount, tvalue, tcurrency, account=None, value=-0.5): saccount = _get_valid_account_list_or_string( handler, account, msg=f"Choose split account for {taccount}") echo_info_params("Split account will be {}", [saccount]) fraction = get_valid_fraction(None, msg="Choose split fraction", default=value) svalue = tvalue * fraction trvalue = f"{round(tvalue, 2):.2f}" srvalue = f"{round(svalue, 2):.2f}" if svalue != 0: echo_info_params( f"{trvalue} {tcurrency} will be split into {saccount} with value " f"{srvalue} {tcurrency}") # Add line. create_simple_posting(transaction, account=saccount, number=svalue, currency=tcurrency) else: echo_info("Zero value split ignored")
def test_deserialise(): postings = [ {"account": "Assets:ETrade:Cash", "amount": "100 USD"}, {"account": "Assets:ETrade:GLD"}, ] json_txn = { "type": "Transaction", "date": "2017-12-12", "flag": "*", "payee": "Test3", "narration": "asdfasd #tag ^link", "meta": {}, "postings": postings, } txn = Transaction( {}, datetime.date(2017, 12, 12), "*", "Test3", "asdfasd", frozenset(["tag"]), frozenset(["link"]), [], ) create_simple_posting(txn, "Assets:ETrade:Cash", "100", "USD") create_simple_posting(txn, "Assets:ETrade:GLD", None, None) assert deserialise(json_txn) == txn with pytest.raises(KeyError): deserialise({}) with pytest.raises(FavaAPIException): deserialise({"type": "NoEntry"})
def test_serialise(app): assert serialise(None) is None txn = Transaction({}, datetime.date(2017, 12, 12), '*', 'Test3', 'asdfasd', frozenset(['tag']), frozenset(['link']), []) create_simple_posting(txn, 'Assets:ETrade:Cash', '100', 'USD') create_simple_posting(txn, 'Assets:ETrade:GLD', None, None) json_txn = { 'date': '2017-12-12', 'flag': '*', 'meta': {}, 'narration': 'asdfasd #tag ^link', 'payee': 'Test3', 'type': 'Transaction', 'postings': [ { 'account': 'Assets:ETrade:Cash', 'amount': '100 USD', }, { 'account': 'Assets:ETrade:GLD', 'amount': '', }, ], } with app.test_request_context(): serialised = loads(dumps(serialise(txn))) assert serialised == json_txn
def test_deserialise(): postings = [ { 'account': 'Assets:ETrade:Cash', 'amount': '100 USD', }, { 'account': 'Assets:ETrade:GLD', }, ] json_txn = { 'type': 'Transaction', 'date': '2017-12-12', 'flag': '*', 'payee': 'Test3', 'narration': 'asdfasd #tag ^link', 'meta': {}, 'postings': postings, } txn = Transaction({}, datetime.date(2017, 12, 12), '*', 'Test3', 'asdfasd', frozenset(['tag']), frozenset(['link']), []) create_simple_posting(txn, 'Assets:ETrade:Cash', '100', 'USD') create_simple_posting(txn, 'Assets:ETrade:GLD', None, None) assert deserialise(json_txn) == txn with pytest.raises(KeyError): deserialise({}) with pytest.raises(FavaAPIException): deserialise({'type': 'NoEntry'})
def test_serialise(app): assert serialise(None) is None txn = Transaction({}, datetime.date(2017, 12, 12), '*', 'Test3', 'asdfasd', frozenset(['tag']), frozenset(['link']), []) create_simple_posting(txn, 'Assets:ETrade:Cash', '100', 'USD') create_simple_posting(txn, 'Assets:ETrade:GLD', None, None) json_txn = { 'type': 'Transaction', 'date': '2017-12-12', 'flag': '*', 'payee': 'Test3', 'narration': 'asdfasd #tag ^link', 'meta': {}, } with app.test_request_context(): serialised = loads(dumps(serialise(txn))) for key, value in json_txn.items(): assert serialised[key] == value or str(serialised[key]) == value assert serialised['postings'][0]['account'] == 'Assets:ETrade:Cash' assert serialised['postings'][0]['units'] == { 'currency': 'USD', 'number': 100, }
def add_fee_postings(self, entry, ot): config = self.config if hasattr(ot, 'fees') or hasattr(ot, 'commission'): if getattr(ot, 'fees', 0) != 0: data.create_simple_posting(entry, config['fees'], ot.fees, self.currency) if getattr(ot, 'commission', 0) != 0: data.create_simple_posting(entry, config['fees'], ot.commission, self.currency)
def add_linedata( handler, transaction, account=None, value=None, no_value=False, splits=None, do_split=False, ): """Validate/prompt user for linedata.""" taccount = _get_valid_account_list_or_string(handler, account, allow_other=True, msg="Choose account") echo_info_params("Account will be {}", [taccount]) # Get posting value. if not no_value: # Use value defined in template if present. tvalue, tcurrency = get_valid_payment(value, msg="Enter value", force_once=True, allow_empty=True) else: # Valueless line. tvalue = None tcurrency = None if tvalue is not None: echo_info_params("Value will be {} {}", [f"{tvalue:.2f}", tcurrency]) else: echo_info("Value will be empty") # Add line. create_simple_posting(transaction, account=taccount, number=tvalue, currency=tcurrency) # Get splits. if not no_value and tvalue is not None and do_split: if splits is not None: # Splits defined by template. for _, split in enumerate(splits, start=1): add_splitdata(handler, transaction, taccount, tvalue, tcurrency, **split) else: splitno = 1 splitting = click.confirm("Add split?", default=False) while splitting: echo_info_params("Adding split {}...", [splitno]) add_splitdata(handler, transaction, taccount, tvalue, tcurrency) splitting = click.confirm("Add another split?", default=False) splitno += 1
def process_deposit(self, entry): txn = new_txn(entry) assert len( entry["giveto"]) == 1, "More than one giveto action in an entry" giveto = entry["giveto"][0] amount = to_decimal(giveto["give"]) initial_balance = to_decimal(giveto['account_money']) account = self.get_member(giveto["account_id"], giveto["account_name"], txn.date, initial_balance) bcdata.create_simple_posting(txn, account, -amount, "EUR") bcdata.create_simple_posting(txn, "Assets:Cash:Bar", amount, "EUR") self.entries.append(txn)
def test_serialise(app): assert serialise(None) is None txn = Transaction( {}, datetime.date(2017, 12, 12), "*", "Test3", "asdfasd", frozenset(["tag"]), frozenset(["link"]), [], ) create_simple_posting(txn, "Assets:ETrade:Cash", "100", "USD") create_simple_posting(txn, "Assets:ETrade:GLD", None, None) json_txn = { "date": "2017-12-12", "flag": "*", "meta": {}, "narration": "asdfasd #tag ^link", "payee": "Test3", "type": "Transaction", "postings": [ { "account": "Assets:ETrade:Cash", "amount": "100 USD" }, { "account": "Assets:ETrade:GLD", "amount": "" }, ], } with app.test_request_context(): serialised = loads(dumps(serialise(txn))) assert serialised == json_txn txn = txn._replace(payee="") json_txn["payee"] = "" serialised = loads(dumps(serialise(txn))) assert serialised == json_txn txn = txn._replace(payee=None) serialised = loads(dumps(serialise(txn))) assert serialised == json_txn
def __init__(self, member: Member, amount: decimal.Decimal, date: typing.Optional[datetime.datetime] = None): super(DepositTxn, self).__init__(title="%s deposited €%s" % (member.display_name, amount), date=date, meta={ "type": "deposit", }) self.primary_account = member bcdata.create_simple_posting(self.txn, member.account, -amount, "EUR") bcdata.create_simple_posting(self.txn, CASH_ACCT, amount, "EUR")
def parse(self): transactions = [] d = self.soup table = d.find(lambda a:a.name == "table" and "商户名称" in a.text and a.find('table') == None) trs = table.select('tr') for x in range(2, len(trs)): tds = trs[x].select('td') time = datetime.strptime(tds[1].text.strip(), '%Y-%m-%d') description = tds[4].text.strip() price_array = tds[5].text.strip().split('/') price = price_array[0] currency = self.get_currency(price_array[1]) print("Importing {} at {}".format(description, time)) account = get_account_by_guess(description, '', time) flag = "*" amount = float(price.replace(',', '')) if not '支出' in tds[6].text: amount = -amount if account == "Expenses:Unknown": flag = "!" meta = {} meta = data.new_metadata( 'beancount/core/testing.beancount', 12345, meta ) counterparty = description if '-' in description: counterparty = description.split('-')[0] description = '-'.join(description.split('-')[1:]) else: description = '' entry = Transaction( meta, date(time.year, time.month, time.day), flag, counterparty, description, data.EMPTY_SET, data.EMPTY_SET, [] ) data.create_simple_posting(entry, account, price, currency) data.create_simple_posting(entry, Account工商, None, None) if not self.deduplicate.find_duplicate(entry, -amount, None, Account工商): transactions.append(entry) self.deduplicate.apply_beans() transactions.reverse() return transactions
def __init__(self, payer: Member, payee: Member, amount: decimal.Decimal, date: typing.Optional[datetime.datetime] = None): super(TransferTxn, self).__init__(title="%s gave %s a gift of €%s" % (payer.display_name, payee.display_name, amount), date=date, meta={ "type": "transfer", }) self.primary_account = payer bcdata.create_simple_posting(self.txn, payer.account, amount, "EUR") bcdata.create_simple_posting(self.txn, payee.account, -amount, "EUR")
def test_transaction_has_conversion(self): entry = self.create_empty_transaction() posting = data.create_simple_posting(entry, 'Assets:Bank:Checking', '123.45', 'USD') posting = posting._replace(price=A('153.02 CAD')) entry.postings[0] = posting self.assertTrue(data.transaction_has_conversion(entry))
def test_create_simple_posting(self): entry = self.create_empty_transaction() posting = data.create_simple_posting(entry, 'Assets:Bank:Checking', '123.45', 'USD') self.assertTrue(isinstance(posting, data.Posting)) self.assertTrue(entry.postings) self.assertEqual(entry.postings[0], posting)
def test_get_entry(self): entry = self.create_empty_transaction() posting = data.create_simple_posting(entry, 'Assets:Bank:Checking', '123.45', 'USD') self.assertEqual(entry, data.get_entry(entry)) self.assertEqual(entry, data.get_entry(data.TxnPosting(entry, posting)))
def test_null_meta_posting(): FILTER.set('any(some_meta:"1")') txn = Transaction( {}, datetime.date(2017, 12, 12), "*", "", "", None, None, [], ) # This will create a posting with meta set to `None`. create_simple_posting(txn, "Assets:ETrade:Cash", "100", "USD") assert txn.postings[0].meta is None assert len(FILTER.apply([txn])) == 0
def __init__(self, buyer: Member, products: typing.List[typing.Tuple[Product, int]], date: typing.Optional[datetime.datetime]=None): total_cost = decimal.Decimal("0.00") total_count = 0 for product, count in products: total_count += count total_cost += count * product.price super(BuyTxn, self).__init__( title="%s bought %d items for €%s" % (buyer.display_name, total_count, total_cost), date=date, meta={ "type": "purchase", }) self.buyer = buyer charge = decimal.Decimal("0.00") paybacks = collections.defaultdict(lambda: decimal.Decimal("0.00")) for product, qty in products: charge += product.price * qty if product.payback is not None: paybacks[product.payback.account] += \ product.payback.amount * qty bcdata.create_simple_posting( self.txn, "Assets:Inventory:Bar", -qty, product.currency) bcdata.create_simple_posting( self.txn, buyer.account, qty, product.currency ) bcdata.create_simple_posting( self.txn, buyer.account, charge, "EUR" ) for payee, amt in paybacks.items(): bcdata.create_simple_posting( self.txn, payee, -amt, "EUR" ) charge -= amt bcdata.create_simple_posting( self.txn, "Income:Bar", -charge, "EUR", )
def parse(self): d = self.soup tables = d.select('#loopBand2>table>tr') currencies_count = int(len(tables) / 4) transactions = [] for x in range(0, currencies_count): title = tables[x * 4] contents = tables[x * 4 + 3] currency = title.select('#fixBand29 td>table td')[1].text.strip() currency = self.get_currency(currency) bands = contents.select('#loopBand3>table>tr') for band in bands: tds = band.select( 'td>table>tr>td #fixBand9>table>tr>td>table>tr>td') time = self.get_date(tds[1].text.strip()) description = tds[3].text.strip() price = tds[4].text.strip() print("Importing {} at {}".format(description, time)) account = get_account_by_guess(description, '', time) flag = "*" amount = float(price.replace(',', '')) if account == "Unknown": flag = "!" meta = {} meta = data.new_metadata( 'beancount/core/testing.beancount', 12345, meta ) entry = Transaction( meta, time, flag, description, None, data.EMPTY_SET, data.EMPTY_SET, [] ) data.create_simple_posting(entry, account, price, currency) data.create_simple_posting(entry, Account民生, None, None) if not self.deduplicate.find_duplicate(entry, -amount, None, Account民生): transactions.append(entry) self.deduplicate.apply_beans() return transactions
def generate_transfer_entry(self, ot, file, counter): """ Cash or in-kind transfers. One of: [credit, debit, dep, transfer, income, dividends, capgains_lt, capgains_st, other]""" config = self.config metadata = data.new_metadata(file.name, next(counter)) target_acct = self.get_target_acct(ot) date = getattr(ot, 'tradeDate', None) if not date: date = ot.date date = date.date() try: if ot.type in ['transfer']: units = ot.units elif ot.type in ['other', 'credit', 'debit', 'dep', 'cash']: units = ot.amount else: units = ot.total except AttributeError: print("Could not determine field for transaction amount") # import pdb; pdb.set_trace() if ot.type in [ 'income', 'dividends', 'capgains_lt', 'capgains_st', 'transfer' ] and (hasattr(ot, 'security') and ot.security): ticker, ticker_long_name = self.get_ticker_info(ot.security) description = f'[{ticker}] {ticker_long_name}' if ot.type in [ 'income', 'dividends', 'capgains_st', 'capgains_lt' ]: # no need to do this for transfers target_acct = self.commodity_leaf( target_acct, ticker) # book to Income:Dividends:HOOLI else: # cash transfer description = ot.type ticker = self.currency # Build transaction entry entry = data.Transaction(metadata, date, self.FLAG, ot.memo, description, data.EMPTY_SET, data.EMPTY_SET, []) # Build postings if ot.type in ['income', 'dividends', 'capgains_st', 'capgains_lt']: # cash data.create_simple_posting(entry, self.cash_account, ot.total, self.currency) data.create_simple_posting(entry, target_acct, -1 * ot.total, self.currency) else: main_acct = self.commodity_leaf(config['main_account'], ticker) data.create_simple_posting(entry, main_acct, units, ticker) data.create_simple_posting(entry, target_acct, -1 * units, ticker) return entry
def process_buy(self, entry): txn = new_txn(entry) amount = to_decimal(entry["products_totalprice"]) if amount < 0: amount = -amount assert len(entry["takefrom"]) == 1, "More than one account in takefrom" takefrom = entry["takefrom"][0] initial_balance = to_decimal(takefrom["account_money"]) account_name = self.get_member(takefrom["account_id"], takefrom["account_name"], txn.date, initial_balance) total_giveto_amount = to_decimal(0) if "giveto" in entry: for giveto in entry["giveto"]: giveto_account = self.get_member( giveto["account_id"], giveto["account_name"], txn.date, to_decimal(giveto["account_money"])) giveto_amount = to_decimal(giveto["account_money_give"]) total_giveto_amount += giveto_amount bcdata.create_simple_posting(txn, giveto_account, -giveto_amount, "EUR") bcdata.create_simple_posting(txn, account_name, amount, "EUR") bcdata.create_simple_posting(txn, "Income:Bar", total_giveto_amount - amount, "EUR") products = {} for product in entry["products"]: product_currency = product_types_inverse[product["product_name"]] products[product_currency] = products.get(product_currency, 0) + 1 assert sum(products.values()) == entry["products_amount"] for product_currency, qty in products.items(): bcdata.create_simple_posting(txn, "Assets:Inventory:Bar", -qty, product_currency) bcdata.create_simple_posting(txn, account_name, qty, product_currency) # TODO: Report products purchased self.entries.append(txn)
def transfer_opening_balances(self): for account, balance in self.initial_balances.items(): if balance is None: continue if balance == 0: continue txn = bcdata.Transaction( meta={}, date=datetime.date(1970, 1, 1), flag="txn", payee="", narration="Initial balance transfer for " + account, tags=set(), links=set(), postings=[]) bcdata.create_simple_posting(txn, account, -balance, "EUR") bcdata.create_simple_posting(txn, "Assets:InitialBalances", balance, "EUR") yield txn
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 get_member(self, id, name, date, balance): #name = member_account(name) name = self.accounts_by_id[id] if id in self.accounts_by_id and self.accounts_by_id[id] != name: # Generate rename txn = bcdata.Transaction(meta={}, date=date, flag="txn", payee="", narration="Rename %(from)s to %(to)s" % { "from": self.accounts_by_id[id], "to": name, }, tags=set("rename"), links=set(), postings=[]) bcdata.create_simple_posting(txn, self.accounts_by_id[id], balance, "EUR") bcdata.create_simple_posting(txn, name, -balance, "EUR") self.entries.append(txn) if self.accounts_by_id[id] not in DONT_CLOSE: self.entries.append( bcdata.Close( meta={}, date=date + datetime.timedelta(days=1), account=self.accounts_by_id[id], )) # Disable the balance assertion for the next day self.last_assertion[name] = date self.initial_balances[name] = None self.accounts_by_id[id] = name elif name not in self.initial_balances: self.initial_balances[name] = balance self.last_assertion[name] = date self.accounts_by_id[id] = name elif self.last_assertion.get( name, None) != date and name != "Assets:Cash:Bar": self.entries.append( bcdata.Balance({"iline": str(self.line)}, date, name, bcdata.Amount(-balance, "EUR"), None, None)) self.last_assertion[name] = date return name
def test_has_entry_account_component(self): entry = data.Transaction(data.new_metadata(".", 0), datetime.date.today(), FLAG, None, "Something", None, None, []) data.create_simple_posting(entry, 'Liabilities:US:CreditCard', '-50', 'USD') data.create_simple_posting(entry, 'Expenses:Food:Restaurant', '50', 'USD') has_component = data.has_entry_account_component self.assertTrue(has_component(entry, 'US')) self.assertFalse(has_component(entry, 'CA')) self.assertTrue(has_component(entry, 'CreditCard')) self.assertTrue(has_component(entry, 'Liabilities')) self.assertFalse(has_component(entry, 'Assets')) self.assertTrue(has_component(entry, 'Restaurant')) self.assertTrue(has_component(entry, 'Food')) self.assertTrue(has_component(entry, 'Expenses')) self.assertFalse(has_component(entry, 'Equity'))