Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
    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"])
Ejemplo n.º 3
0
    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()
Ejemplo n.º 4
0
    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"])
Ejemplo n.º 5
0
    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"])
Ejemplo n.º 6
0
    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()
Ejemplo n.º 7
0
    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()
Ejemplo n.º 8
0
    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"
Ejemplo n.º 9
0
    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()
Ejemplo n.º 10
0
    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"])
Ejemplo n.º 11
0
 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)
Ejemplo n.º 12
0
    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"])
Ejemplo n.º 13
0
 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()
Ejemplo n.º 14
0
    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()
Ejemplo n.º 15
0
    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()
Ejemplo n.º 16
0
    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()
Ejemplo n.º 17
0
 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),
                          ])
Ejemplo n.º 18
0
    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()
Ejemplo n.º 19
0
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
Ejemplo n.º 20
0
    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)
Ejemplo n.º 21
0
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()
Ejemplo n.º 22
0
    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()
Ejemplo n.º 23
0
    # 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
Ejemplo n.º 24
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)
Ejemplo n.º 26
0
    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()
Ejemplo n.º 27
0
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)
Ejemplo n.º 28
0
    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)
Ejemplo n.º 29
0
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,
Ejemplo n.º 30
0
            # 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:
Ejemplo n.º 31
0
# 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))
Ejemplo n.º 33
0
                                  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
Ejemplo n.º 34
0



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