def test_create_simpletlot_initialsplits(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") sp = [] for i, am in enumerate([45, -35, -20]): tr = Transaction(currency=EUR, description="trade stock", notes=u"àçö", post_date=datetime(2014, 1, 1 + i), enter_date=datetime(2014, 1, 1 + i), splits=[ Split(account=a, value=am * 10, memo=u"mémo asset"), Split(account=s, value=-am * 10, quantity=-am, memo=u"mémo brok"), ]) sp.append(tr.splits(account=s)) l = Lot(title=u"test mé", account=s, notes=u"ïlya", splits=sp) book_basic.flush()
def test_create_cdtytransaction(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") tr = Transaction( currency=EUR, description="buy stock", notes="on St-Eugène day", post_date=date(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, memo="mémo asset"), Split(account=s, value=-90, memo="mémo brok"), ], ) # check issue with quantity for broker split not defined with pytest.raises(GncValidationError): book_basic.validate() sb = tr.splits(account=s) sb.quantity = 15 # check issue with quantity not same sign as value with pytest.raises(GncValidationError): book_basic.validate() sb.quantity = -15 # verify imbalance issue with pytest.raises(GncImbalanceError): book_basic.validate() # adjust balance Split(account=a, value=-10, memo="missing asset corr", transaction=tr) book_basic.save() assert str(sb) assert str(sb) # changing currency of an existing transaction is not allowed tr.currency = book_basic.currencies(mnemonic="USD") with pytest.raises(GncValidationError): book_basic.validate() book_basic.cancel() # check sum of quantities are not balanced per commodity but values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v != 0 for k, v in d.items() if k != "cur"])
def test_create_basictransaction_validation_date(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") e = book_basic.accounts(name="exp") splits = [ Split(account=a, value=100, memo="mémo asset"), Split(account=e, value=-10, memo="mémo exp"), ] with pytest.raises(GncValidationError): tr = Transaction( currency=EUR, description="wire from Hélène", notes="on St-Eugène day", post_date=datetime(2014, 1, 1), enter_date=datetime(2014, 1, 1), splits=splits, ) with pytest.raises(GncValidationError): tr = Transaction( currency=EUR, description="wire from Hélène", notes="on St-Eugène day", post_date=datetime(2014, 1, 1), enter_date=time(10, 59, 00), splits=splits, ) with pytest.raises(GncValidationError): tr = Transaction( currency=EUR, description="wire from Hélène", notes="on St-Eugène day", post_date=date(2014, 1, 1), enter_date=date(2014, 1, 1), splits=splits, ) tr = Transaction( currency=EUR, description="wire from Hélène", notes="on St-Eugène day", post_date=None, enter_date=None, splits=splits, ) with pytest.raises(GncImbalanceError): book_basic.flush() book_basic.validate()
def test_create_cdtytransaction_tradingaccount(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") book_basic.use_trading_accounts = True tr = Transaction(currency=EUR, description="buy stock", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=s, value=-100, quantity=-15, memo=u"mémo brok"), ]) book_basic.validate() assert "{}".format( tr) == "Transaction<[EUR] 'buy stock' on 2014-01-02>" assert "{}".format(s) == "Account<asset:broker[ïoà]>" assert "{}".format( tr.splits(account=s) ) == "Split<Account<asset:broker[ïoà]> -100 EUR [-15 ïoà]>" assert "{}".format( tr.splits(account=a)) == "Split<Account<asset[EUR]> 100 EUR>" # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == Decimal(0) for k, v in d.items() if k != "cur"]) # change existing quantity sp = tr.splits(memo=u"mémo brok") sp.quantity += 1 book_basic.validate() # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == Decimal(0) for k, v in d.items() if k != "cur"])
def test_create_cdtytransaction(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") tr = Transaction(currency=EUR, description="buy stock", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=s, value=-90, memo=u"mémo brok"), ]) # check issue with quantity for broker split not defined with pytest.raises(GncValidationError): book_basic.flush() sb = tr.splits(account=s) sb.quantity = 15 # check issue with quantity not same sign as value with pytest.raises(GncValidationError): book_basic.flush() sb.quantity = -15 # verify imbalance issue with pytest.raises(GncImbalanceError): book_basic.flush() # adjust balance Split(account=a, value=-10, memo="missing asset corr", transaction=tr) book_basic.flush() book_basic.save() assert str(sb) assert str(sb) # changing currency of an existing transaction is not allowed tr.currency = book_basic.currencies(mnemonic="USD") with pytest.raises(GncValidationError): book_basic.flush() book_basic.cancel() # check sum of quantities are not balanced per commodity but values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v != 0 for k, v in d.items() if k != "cur"])
def __add_transaction(self, book, date, currency, to_account, transaction): """Adds Transaction to the piecash book. Description and Price Range are provided in transaction argument, whereas Currency is provided directly. from_account indicates the Asset Account, from which the money will be 'taken', whereas to_account indicates the Expense Account, which accumulates the expense. Price is decided on the structure of the Price Range Tuple - if the Tuple has len of 1, the value provided in it is taken directly. Otherwise, random.uniform() is called on the range and the random value from the range is chosen. Chosen Price is also rounded to 2 digits and converted to Decimal to adhere to piecash objects. Function calls book.flush() to save the Transaction, no value is returned. """ description, from_account, price_range = transaction if len(price_range) > 1: value = self.rng.uniform(price_range[0], price_range[1]) else: value = price_range[0] price = Decimal(str(round(value, 2))) tr = Transaction(currency=currency, description=description, post_date=date, splits=[ Split(account=from_account, value=-price), Split(account=to_account, value=price) ]) book.flush()
def __add_shop_transaction(self, book, date, currency, list_of_splits, shop_name): """Adds Split (Shop) Transaction to the book. Instead of adding 1:1 Transaction with to_account and from_account, the function creates the list of 1:1 Splits of to_account and from_account complimenting each other. Then the whole list is provided to the main Transaction. Description of the Transaction is provided in the shop_name argument. Other arguments are described in __add_transaction, please refer to the comments in this function. """ sp_list = [] for split in list_of_splits: to_account = split[0] description, from_account, price_range = split[1] if len(price_range) > 1: value = self.rng.uniform(price_range[0], price_range[1]) else: value = price_range[0] price = Decimal(str(round(value, 2))) sp_list.append(Split(account=to_account, memo=description, value=price)) sp_list.append(Split(account=from_account, value=-price)) tr = Transaction(currency=currency, description=shop_name, post_date=date, splits=sp_list ) book.flush()
def test_create_basictransaction(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") e = book_basic.accounts(name="exp") tr = Transaction(currency=EUR, description=u"wire from Hélène", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 1), enter_date=datetime(2014, 1, 1), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=e, value=-10, memo=u"mémo exp"), ]) # check issue with balance with pytest.raises(GncImbalanceError): book_basic.flush() book_basic.validate() # adjust balance Split(account=e, value=-90, memo="missing exp", transaction=tr) book_basic.flush() # check no issue with str assert str(tr) assert str(tr.splits) assert repr(tr) assert repr(tr.splits) assert tr.notes == u"on St-Eugène day"
def test_create_cdtytransaction_tradingaccount(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") book_basic.use_trading_accounts = True tr = Transaction(currency=EUR, description="buy stock", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=s, value=-100, quantity=-15, memo=u"mémo brok"), ]) book_basic.validate() assert "{}".format(tr) == "Transaction<[EUR] 'buy stock' on 2014-01-02>" assert "{}".format(s) == "Account<asset:broker[ïoà]>" assert "{}".format(tr.splits(account=s)) == "Split<Account<asset:broker[ïoà]> -100 EUR [-15 ïoà]>" assert "{}".format(tr.splits(account=a)) == "Split<Account<asset[EUR]> 100 EUR>" # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == Decimal(0) for k, v in d.items() if k != "cur"]) # change existing quantity sp = tr.splits(memo=u"mémo brok") sp.quantity += 1 book_basic.validate() # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == Decimal(0) for k, v in d.items() if k != "cur"])
def setUp(self): self.date = datetime(2018, 7, 30, 0, 00).date() self.price = 1000 splits = [ Split(account=None, value=self.price, transaction=Transaction(currency=None, post_date=self.date), reconcile_state='n') ] self.reconciler = Reconciler(splits)
def test_create_cdtytransaction_tradingaccount(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") tr = Transaction(currency=EUR, description="buy stock", notes=u"on St-Eugène day", post_date=datetime(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=s, value=-100, quantity=-15, memo=u"mémo brok"), ]) book_basic.book.use_trading_accounts = True book_basic.flush() assert str(tr) assert str(tr.splits) assert repr(tr) assert repr(tr.splits) # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == 0 for k, v in d.items() if k != "cur"]) # change existing quantity sp = tr.splits(memo=u"mémo brok") sp.quantity += 1 book_basic.flush() # check sum of quantities are all balanced per commodity as values are d = defaultdict(lambda: Decimal(0)) for sp in tr.splits: assert sp.quantity == sp.value or sp.account != a d[sp.account.commodity] += sp.quantity d["cur"] += sp.value assert d["cur"] == 0 assert all([v == 0 for k, v in d.items() if k != "cur"])
def make_transaction(self, acc1, acc2, amount, description=None): if not description: description = "" curr = self.book.default_currency splits = [ Split(account=acc1, value=-amount), Split(account=acc2, value=amount) ] tr = Transaction(curr, description=description, splits=splits) # self.book.flush() self.book.save()
def test_tag_split_zero_quantity_with_value(self, book_transactions): broker = book_transactions.accounts(name="broker") inc = book_transactions.accounts.get(name="inc") value = Decimal(250) # Transaction recording capital gains. splits = [ Split(broker, value, quantity=0), Split(inc, -value), ] Transaction(inc.commodity, description="Capital gains", splits=splits) book_transactions.validate() # Transaction recording capital loss. splits = [ Split(broker, -value, quantity=0), Split(inc, value), ] Transaction(inc.commodity, description="Capital loss", splits=splits) book_transactions.validate() # Do the same tests with a -0.0 quantity. This Decimal has is_signed=True. mzero = Decimal("-0.00") # Transaction recording capital gains. splits = [ Split(broker, value, quantity=mzero), Split(inc, -value), ] Transaction(inc.commodity, description="Capital gains", splits=splits) book_transactions.validate() # Transaction recording capital loss. splits = [ Split(broker, -value, quantity=mzero), Split(inc, value), ] Transaction(inc.commodity, description="Capital loss", splits=splits) book_transactions.validate()
def test_tag_split_zero_value(self, book_transactions): broker = book_transactions.accounts(name="broker") asset = book_transactions.accounts.get(name="asset") currency = book_transactions.default_currency # Give away 250 shares for free. quantity = Decimal(-250) splits = [ Split(asset, 0), Split(broker, 0, quantity=quantity), ] Transaction(currency, description="donation", splits=splits) book_transactions.validate()
def test_tag_split_zero_quantity(self, book_transactions): broker = book_transactions.accounts(name="broker") asset = book_transactions.accounts.get(name="asset") inc = book_transactions.accounts.get(name="inc") currency = book_transactions.default_currency value = Decimal(250) splits = [ Split(asset, value), Split(inc, -value), Split(broker, value=0, quantity=0), # tag split for assigning dividend income to stock ] Transaction(currency, description='Dividend income', splits=splits) book_transactions.validate()
def test_create_closedlot_addsplits(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") l = Lot(title=u"test mé", account=s, notes=u"ïlya") l.is_closed = 1 # raise valueerror as lot is closed with pytest.raises(ValueError): tr = Transaction(currency=EUR, description="trade stock", notes=u"àçö", post_date=date(2014, 1, 1), enter_date=datetime(2014, 1, 1), splits=[ Split(account=a, value=10, memo=u"mémo asset"), Split(account=s, value=- 10, quantity=-2, memo=u"mémo brok", lot=l), ])
def test_create_cdtytransaction_cdtycurrency(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") tr = Transaction(currency=s.commodity, description="buy stock", notes=u"on St-Eugène day", post_date=date(2014, 1, 2), enter_date=datetime(2014, 1, 3), splits=[ Split(account=a, value=100, quantity=10, memo=u"mémo asset"), Split(account=s, value=-100, quantity=-10, memo=u"mémo brok"), ]) # raise error as Transaction has a non CURRENCY commodity with pytest.raises(GncValidationError): book_basic.validate()
def add_transaction(book, description, amount, debit_acct, credit_acct, enter_datetime): """Add a transaction to an existing book. `amount` should be a float out to 2 decimal places for the value of the transaction. `debit_acct` and `credit_acct` should be the names of the accounts as given by the .fullname method from a GnuCash Account, e.g. book.accounts.get(fullname="Expenses:Food"). `enter_datetime` should be of type datetime.datetime. """ try: credit = get_account(credit_acct, book) debit = get_account(debit_acct, book) if credit and debit: usd = book.currencies(mnemonic='USD') logger.info('Creating a new transaction in the GnuCash book.') transaction = Transaction(currency=usd, description=description, enter_date=enter_datetime, splits=[ Split(value=amount, account=credit), Split(value=-amount, account=debit) ]) logger.debug('Transaction successfully created.') logger.debug('Attempting to save transaction') book.save() logger.info('Successfully saved transaction') return True elif credit and not debit: logger.error( f'The debit account {debit_acct} was not found. Skipping.') return False elif debit and not credit: logger.error( f'The credit account {credit_acct} was not found. Skipping.') return False except GnucashException as gce: logger.error('Failed to add the transaction') logger.error(gce) return False except ValueError as ve: logger.error('Failed to add the transaction with ValueError:') logger.error(ve) return False
def test_create_basictransaction_neutraltime(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") e = book_basic.accounts(name="exp") tr = Transaction(currency=EUR, description=u"wire from Hélène", notes=u"on St-Eugène day", post_date=date(2014, 1, 1), splits=[ Split(account=a, value=100, memo=u"mémo asset"), Split(account=e, value=-100, memo=u"mémo exp"), ]) assert isinstance(tr.post_date, date) book_basic.flush() book_basic.validate() assert isinstance(tr.post_date, date)
def add_transaction(book, item, currency): logging.info('Adding transaction for account "%s" (%s %s)..', item.account, item.split_amount, currency.mnemonic) root = book.root_account acc = lookup_account(root, item.account) acc2 = lookup_account(root, item.split_category) amount = Decimal(item.split_amount.replace(',', '.')) _ = Transaction( currency=currency, description=item.memo, enter_date=datetime.datetime.now(), post_date=item.date, splits=[ Split(account=acc, value=amount), Split(account=acc2, value=- amount) ] ) book.flush()
def test_create_simplelot_inconsistentaccounts(self, book_basic): EUR = book_basic.commodities(namespace="CURRENCY") racc = book_basic.root_account a = book_basic.accounts(name="asset") s = book_basic.accounts(name="broker") l = Lot(title="test mé", account=a, notes="ïlya") # raise valueerror as split account not the same as lot account tr = Transaction( currency=EUR, description="trade stock", notes="àçö", post_date=date(2014, 1, 1), enter_date=datetime(2014, 1, 1), splits=[ Split(account=a, value=10, memo="mémo asset"), Split(account=s, value=-10, quantity=-2, memo="mémo brok", lot=l), ], ) with pytest.raises(ValueError): book_basic.validate()
# number of accounts N = 5 # number of transactions T = 100 # create accounts accounts = [ Account("account {}".format(i), "ASSET", eur, parent=ra) for i in range(N) ] # create transactions for i, v in enumerate(random.randrange(10) for j in range(T)): tx = Transaction( eur, "transaction {}".format(i), ) Split(accounts[random.randrange(N)], value=v, transaction=tx) Split(accounts[random.randrange(N)], value=-v, transaction=tx) s.save() # select two accounts acc = accounts[0] tacc = accounts[1] # move all splits from account acc to account tacc for spl in list(acc.splits): spl.account = tacc s.save() # check no more splits in account acc assert len(acc.splits) == 0
else: logger.warn("Unmatched loan repayment amount") splits = [ Split(account=tsbAccount, value=amount), Split(account=transferAccount, value=payableAmount), Split(account=intrestAccount, value=intrestAmount) ] else: # just the normal splits splits = [ Split(account=tsbAccount, value=amount), Split(account=transferAccount, value=-1 * amount) ] # now we have the splits we can create the trasnaction Transaction(currency=gbp, enter_date=createdAt, post_date=createdAt.date(), num=hashHex, description=transaction['description'], splits=splits) # save the book if not book.is_saved: book.save() importCount += 1 logger.info("Imported, Total count: {}".format(importCount)) print(json.dumps("Imported, Total count: {}".format(importCount)))
def add_transaction(t): settings_file = os.environ['HOME'] + "/gnucash/settings.yaml" with open(settings_file) as ymlfile: settings = yaml.load(ymlfile) book_path = settings['location'] + settings['gnucash'] log_file = settings['location'] + settings['log'] # check for existance of to_account and from_account book = piecash.open_book(book_path) to_account_found = False from_account_found = False for a in book.accounts: if a.fullname == t.account: from_account_found = True elif a.fullname == t.expense: to_account_found = True success = True expense_account_created = False try: # income - allow for not found accounts to instead go to Imbalance account if t.income: if not to_account_found: t.account = 'Imbalance' if not from_account_found: t.expense = 'Imbalance' # expense - allow creation of expense accounts ONLY # - allow not found "from" accounts to instead go to Imbalance account else: # add missing expense account if not to_account_found: with open_book(book_path, open_if_lock=True, readonly=False) as book: acc = book.root_account for subacc in book.root_account.children: if subacc.name == 'Expenses': acc = subacc break # could change this and loop to support mutli-level expense account creation #t.expense = 'Expense:' + t.expense.split(':')[-1] a = Account( parent=acc, name=t.expense.split(':')[-1], type="EXPENSE", description='Automatically Added from SMS transaction.', commodity=book.commodities.get(mnemonic="USD")) book.save() to_account_found = True expense_account_created = True if not from_account_found: t.account = "Imbalance" # reopen the book and add a transaction # this must be a sqlite3 file with open_book(book_path, open_if_lock=True, readonly=False) as mybook: today = datetime.now() today = today.replace(microsecond=0) # retrieve the currency from the book USD = mybook.currencies(mnemonic='USD') # define the amount as Decimal amount = t.amount # retrieve accounts to_account = mybook.accounts(fullname=t.expense) from_account = mybook.accounts(fullname=t.account) # if income, flip the accounts so 'income' is used instead of 'charge' if t.income: to_account = mybook.accounts(fullname=t.account) from_account = mybook.accounts(fullname=t.expense) # create the transaction with its two splits Transaction(post_date=today, enter_date=today, currency=USD, description=t.description, splits=[ Split(account=to_account, value=amount, memo='Automated from script'), Split(account=from_account, value=-amount, memo='Automated from script'), ]) # save the book mybook.save() except: success = False log(success, t, to_account_found, from_account_found, expense_account_created, log_file)
savings_acct = Account(parent=root_acct, name="Savings", type="BANK", commodity=cad) opening_acct = Account(parent=root_acct, name="Opening Balance", type="EQUITY", commodity=cad) num1 = Decimal("4") num2 = Decimal("100") num3 = Decimal("15") # create transaction with core objects in one step trans1 = Transaction(currency=cad, description="Groceries", splits=[ Split(value=num1, account=expenses_acct), Split(value=-num1, account=savings_acct), ]) # create transaction with core object in multiple steps trans2 = Transaction(currency=cad, description="Opening Savings Balance") split3 = Split(value=num2, account=savings_acct, transaction=trans2) split4 = Split(value=-num2, account=opening_acct, transaction=trans2) # create transaction with factory function trans3 = Transaction.single_transaction(None, None, "Pharmacy", num3, savings_acct, expenses_acct) session.save()
def book_transactions(request): name = request.param if name and database_exists(name): drop_database(name) # create new book with create_book(uri_conn=name, currency="EUR", keep_foreign_keys=False) as b: # create some accounts curr = b.default_currency other_curr = b.currencies(mnemonic="USD") cdty = Commodity(namespace=u"BEL20", mnemonic=u"GnuCash Inc.", fullname=u"GnuCash Inc. stock") asset = Account(name="asset", type="ASSET", commodity=curr, parent=b.root_account) foreign_asset = Account(name="foreign asset", type="ASSET", commodity=other_curr, parent=b.root_account) stock = Account(name="broker", type="STOCK", commodity=cdty, parent=asset) expense = Account(name="exp", type="EXPENSE", commodity=curr, parent=b.root_account) income = Account(name="inc", type="INCOME", commodity=curr, parent=b.root_account) tr1 = Transaction( post_date=date(2015, 10, 21), description="my revenue", currency=curr, splits=[Split(account=asset, value=(1000, 1)), Split(account=income, value=(-1000, 1))], ) tr2 = Transaction( post_date=date(2015, 10, 25), description="my expense", currency=curr, splits=[ Split(account=asset, value=(-100, 1)), Split(account=expense, value=(20, 1), memo="cost of X"), Split(account=expense, value=(80, 1), memo="cost of Y"), ], ) tr_stock = Transaction( post_date=date(2015, 10, 29), description="my purchase of stock", currency=curr, splits=[ Split(account=asset, value=(-200, 1)), Split(account=expense, value=(15, 1), memo="transaction costs"), Split(account=stock, value=(185, 1), quantity=(6, 1), memo="purchase of stock"), ], ) tr_to_foreign = Transaction( post_date=date(2015, 10, 30), description="transfer to foreign asset", currency=curr, splits=[ Split(account=asset, value=(-200, 1)), Split(account=foreign_asset, value=(200, 1), quantity=(135, 1)), ], ) tr_from_foreign = Transaction( post_date=date(2015, 10, 31), description="transfer from foreign asset", currency=other_curr, splits=[ Split(account=asset, value=(135, 1), quantity=(215, 1)), Split(account=foreign_asset, value=(-135, 1)), ], ) Price(commodity=cdty, currency=other_curr, date=date(2015, 11, 1), value=(123, 100)) Price(commodity=cdty, currency=other_curr, date=date(2015, 11, 4), value=(127, 100)) Price(commodity=cdty, currency=curr, date=date(2015, 11, 2), value=(234, 100)) b.save() yield b if name and database_exists(name): drop_database(name)
savings_acct = Account(parent=root_acct, name="Savings", type="BANK", commodity=cad) opening_acct = Account(parent=root_acct, name="Opening Balance", type="EQUITY", commodity=cad) num1 = Decimal("4") num2 = Decimal("100") num3 = Decimal("15") # create transaction with core objects in one step trans1 = Transaction(currency=cad, description="Groceries", splits=[ Split(value=num1, account=expenses_acct), Split(value=-num1, account=savings_acct), ]) # create transaction with core object in multiple steps trans2 = Transaction(currency=cad, description="Opening Savings Balance") split3 = Split(value=num2, account=savings_acct, transaction=trans2) split4 = Split(value=-num2, account=opening_acct, transaction=trans2)
with create_book(bookname, currency="EUR", keep_foreign_keys=False, overwrite=True) as b: # create some accounts curr = b.default_currency other_curr = b.currencies(mnemonic="USD") cdty = Commodity(namespace=u"BEL20", mnemonic=u"GnuCash Inc.", fullname=u"GnuCash Inc. stock") asset = Account(name="asset", type="ASSET", commodity=curr, parent=b.root_account) foreign_asset = Account(name="foreign asset", type="ASSET", commodity=other_curr, parent=b.root_account) stock = Account(name="broker", type="STOCK", commodity=cdty, parent=asset) expense = Account(name="exp", type="EXPENSE", commodity=curr, parent=b.root_account) income = Account(name="inc", type="INCOME", commodity=curr, parent=b.root_account) tr1 = Transaction(post_date=datetime(2015, 10, 21), description="my revenue", currency=curr, splits=[ Split(account=asset, value=(1000, 1)), Split(account=income, value=(-1000, 1)), ] ) tr2 = Transaction(post_date=datetime(2015, 10, 25), description="my expense", currency=curr, splits=[ Split(account=asset, value=(-100, 1)), Split(account=expense, value=(20, 1), memo="cost of X"), Split(account=expense, value=(80, 1), memo="cost of Y"), ] ) tr_stock = Transaction(post_date=datetime(2015, 10, 29), description="my purchase of stock", currency=curr,
# which account are we assigning this to toAccount = donationsIncomeAccount if 'type' in stripeTransaction.source.metadata: if stripeTransaction.source.metadata.type.upper() == 'SNACKSPACE': toAccount = snackspaceIncomeAccount elif stripeTransaction.source.statement_descriptor == 'Snackspace': toAccount = snackspaceIncomeAccount elif stripeTransaction.source.statement_descriptor_suffix == 'Snackspace': toAccount = snackspaceIncomeAccount Transaction(currency=gbp, enter_date=createdAt, post_date=createdAt.date(), num=stripeTransaction.id, description=description, splits=[ Split(account=stripeAccount, value=net), Split(account=toAccount, value=amount), Split(account=feeExpenseAccount, value=fee) ]) logger.info("Saved charge: {}, {}, {}".format(stripeTransaction.id, createdAt.date(), description)) elif stripeTransaction.type == 'adjustment': description = "Stripe: " + stripeTransaction.description if net < 0: toAccount = miscellaneousExpenseAccount else: stripeCharge = stripe.Charge.retrieve(stripeTransaction.source.charge) toAccount = donationsIncomeAccount if 'type' in stripeCharge.metadata:
# create new book with create_book() as book: ra = book.root_account eur = book.default_currency # number of accounts N = 5 # number of transactions T = 100 # create accounts accounts = [Account("account {}".format(i), "ASSET", eur, parent=ra) for i in range(N)] # create transactions for i, v in enumerate(random.randrange(10) for j in range(T)): tx = Transaction(eur, "transaction {}".format(i)) Split(accounts[random.randrange(N)], value=v, transaction=tx) Split(accounts[random.randrange(N)], value=-v, transaction=tx) book.save() # select two accounts acc = accounts[0] tacc = accounts[1] # move all splits from account acc to account tacc for spl in list(acc.splits): spl.account = tacc book.save() # check no more splits in account acc assert len(acc.splits) == 0
today = datetime.now() # retrieve the currency from the book USD = mybook.currencies(mnemonic="USD") # define the amount as Decimal amount = Decimal("25.35") # retrieve accounts to_account = mybook.accounts(fullname="Expenses:Some Expense Account") from_account = mybook.accounts(fullname="Assets:Current Assets:Checking") # create the transaction with its two splits Transaction( post_date=today, enter_date=today, currency=USD, description="Transaction Description!", splits=[ Split(account=to_account, value=amount, memo="Split Memo!"), Split(account=from_account, value=-amount, memo="Other Split Memo!"), ] ) # save the book mybook.save() from piecash import ledger # check the book by exporting to ledger format with open_book("../gnucash_books/simple_book_transaction_creation.gnucash", open_if_lock=True) as mybook: print(ledger(mybook))
pytz.timezone("Europe/London")) if sumUpTransaction['type'] == 'PAYMENT': # build description for gnu cash description = "SumUp: {} ({})".format( sumUpTransaction['transaction_code'], transaction['card']['last_4_digits']) # which account are we assigning this to toAccount = snackspaceIncomeAccount Transaction(currency=gbp, enter_date=createdAt, post_date=createdAt.date(), num=sumUpTransaction['id'], description=description, splits=[ Split(account=sumUpAccount, value=net), Split(account=toAccount, value=amount), Split(account=feeExpenseAccount, value=fee) ]) logger.info("Saved charge: {}, {}, {}".format( sumUpTransaction['id'], createdAt.date(), description)) elif sumUpTransaction['type'] == 'CHARGE_BACK': description = "SumUp: {}".format( sumUpTransaction['transaction_code']) if net < 0: toAccount = miscellaneousExpenseAccount else: toAccount = snackspaceIncomeAccount
# create a book (in memory) s = create_book(currency="EUR") # get the EUR and create the USD currencies c1 = s.book.default_currency c2 = s.book.create_currency_from_ISO("USD") # create two accounts a1 = Account("Acc 1", "ASSET", c1, parent=s.book.root_account) a2 = Account("Acc 2", "ASSET", c2, parent=s.book.root_account) # create a transaction from a1 to a2 tr = Transaction(currency=c1, description="transfer", splits=[ Split(account=a1, value=-100), Split(account=a2, value=100, quantity=30) ]) s.flush() # ledger_str() returns a representation of the transaction in the ledger-cli format tr.ledger_str() # change the book to use the "trading accounts" options s.book.use_trading_accounts = True # add a new transaction identical to the previous tr2 = Transaction(currency=c1, description="transfer 2", splits=[ Split(account=a1, value=-100), Split(account=a2, value=100, quantity=30)