Exemplo n.º 1
0
    def get_withdraw_limit_data(account, include_pending_requests=True):
        from currencies.money import Money
        withdraw_limit = Decimal(account.balance_money.amount)

        # subtract money which already waiting for output
        if include_pending_requests:
            # TODO: why the f I use last group here? Should we just take all requests?
            group = WithdrawRequestsGroup.objects.filter(
                account=account, is_closed=False).last()
            if group:
                withdraw_requests = group.requests.filter(is_committed=None)
                if withdraw_requests:
                    withdraw_requests_amount = 0
                    for withdraw_request in withdraw_requests:
                        withdraw_requests_amount += Decimal(
                            withdraw_request.amount_money.to(
                                account.currency).amount)
                    withdraw_limit -= Decimal(withdraw_requests_amount)

        # Note: displaying a negative upper bound doesn't make sense,
        # so we round balance to zero in that case.
        withdraw_limit = max(0, withdraw_limit)

        # drop digits beyond needed precision
        withdraw_limit = currencies.round_floor(withdraw_limit)
        return Money(withdraw_limit,
                     account.currency), Money(0, account.currency)
Exemplo n.º 2
0
 def test_get_for_currencies_multiple_currencies(self):
     currencies = [Mock(), Mock()]
     moneys = [Money(10, currencies[0]), Money(-8, currencies[1])]
     balance = Balance(moneys)
     assert balance.get_for_currency(currencies[0]) == Money(
         10, currencies[0])
     assert balance.get_for_currency(currencies[1]) == Money(
         -8, currencies[1])
Exemplo n.º 3
0
 def test_fails_on_unbalanced_movements_and_single_account(self):
     self.data_update(movements_specs=[
         MovementSpec(self.accs[0], Money(100, self.cur)),
         MovementSpec(self.accs[1], Money(-99, self.cur))
     ])
     errmsg = TransactionMovementSpecListValidator\
         .ERR_MSGS['UNBALANCED_SINGLE_CURRENCY']
     self.assertRaisesMessage(ValidationError, errmsg, self.call)
Exemplo n.º 4
0
 def test_should_create_new_instances_on_comparisons(self):
     a, b = Money(100, 'USD'), Money(3, 'USD')
     ab_ids = map(id, [a, b])
     self.assertNotIn(id(a > b), ab_ids)
     self.assertNotIn(id(a < b), ab_ids)
     self.assertNotIn(id(a >= b), ab_ids)
     self.assertNotIn(id(a <= b), ab_ids)
     self.assertNotIn(id(a == b), ab_ids)
     self.assertNotIn(id(a != b), ab_ids)
Exemplo n.º 5
0
 def test_from_data_base(self):
     trans = self.create()
     assert trans.get_description() == self.data['description']
     assert trans.get_date() == self.data['date']
     movements = trans.get_movements_specs()
     assert movements == [
         MovementSpec(self.accs[0], Money(10, self.curs[0])),
         MovementSpec(self.accs[1], Money(-8, self.curs[1])),
     ]
Exemplo n.º 6
0
 def test_fails_if_movements_have_a_single_acc(self):
     self.data_update(movements_specs=[
         MovementSpec(self.accs[0], Money(100, self.cur)),
         MovementSpec(self.accs[0], Money(-100, self.cur))
     ])
     errmsg = TransactionMovementSpecListValidator.ERR_MSGS[
         'SINGLE_ACCOUNT']
     with self.assertRaisesMessage(ValidationError, errmsg):
         self.call()
Exemplo n.º 7
0
 def test_fails_if_duplicated_currency_account_pair(self):
     self.data_update(movements_specs=[
         MovementSpec(self.accs[0], Money(1, self.cur)),
         MovementSpec(self.accs[0], Money(1, self.cur)),
         MovementSpec(self.accs[1], Money(-2, self.cur))
     ])
     errmsg = TransactionMovementSpecListValidator.ERR_MSGS[
         "REPEATED_CURRENCY_ACCOUNT_PAIR"]
     with self.assertRaisesMessage(ValidationError, errmsg):
         self.call()
Exemplo n.º 8
0
 def test_base(self):
     currency = CurrencyTestFactory()
     account = AccountTestFactory()
     other_acc = AccountTestFactory()
     transaction_with = TransactionTestFactory(movements_specs=[
         MovementSpec(account, Money('10', currency)),
         MovementSpec(other_acc, Money('-10', currency)),
     ])
     transaction_without = TransactionTestFactory.create()
     assert list(Transaction.objects.filter_by_account(account)) ==\
         [transaction_with]
Exemplo n.º 9
0
    def test_serializes_as_list_of_moneys(self, m_to_representation):
        currency_one, currency_two = Mock(), Mock()
        balance = Mock()
        balance.get_moneys.return_value = [
            Money('20', currency_one),
            Money('30', currency_two),
        ]
        serializer = BalanceSerializer(balance)

        assert serializer.data == [m_to_representation.return_value] * 2
        assert m_to_representation.call_args_list[0] ==\
            call(Money('20', currency_one))
        assert m_to_representation.call_args_list[1] ==\
            call(Money('30', currency_two))
Exemplo n.º 10
0
    def test_get_balances(self):
        currency_one, currency_two = Mock(), Mock()
        transactions = [
            self.gen_transaction_mock([Money('10', currency_one)]),
            self.gen_transaction_mock([Money('20', currency_two)])
        ]
        initial_balance = Balance([Money('20', currency_two)])

        journal = Journal(Mock(), initial_balance, transactions)

        result = journal.get_balances()
        assert result[0] == initial_balance.add_money(Money(
            '10', currency_one))
        assert result[1] == result[0].add_money(Money('20', currency_two))
Exemplo n.º 11
0
    def test_post_single_transaction(self):
        resp = self.client.post('/transactions/', self.post_data)
        assert resp.status_code == 201, resp.data
        assert resp.json()['date'] == '2018-12-21'
        assert resp.json()['description'] == self.post_data['description']

        obj = Transaction.objects.get(pk=resp.json()['pk'])

        assert obj.get_description() == 'A'
        assert obj.date == date(2018, 12, 21)

        assert obj.get_movements_specs() == [
            MovementSpec(self.accs[0], Money(200, self.cur)),
            MovementSpec(self.accs[1], Money(-200, self.cur))
        ]
Exemplo n.º 12
0
 def test_patch_transaction_with_single_currency_but_unmatched_values_err(self):
     # Same currency, unmatched values!
     trans = TransactionTestFactory()
     moneys = [Money(100, self.cur), Money(-98, self.cur)]
     movements_specs = [MovementSpecTestFactory(money=m) for m in moneys]
     resp = self.client.patch(
         f'/transactions/{trans.pk}/',
         {'movements_specs': [
             MovementSpecSerializer(m).data for m in movements_specs
         ]}
     )
     assert resp.status_code == 400
     assert 'movements_specs' in resp.json()
     err = TransactionMovementSpecListValidator.\
         ERR_MSGS['UNBALANCED_SINGLE_CURRENCY']
     assert err in resp.json()['movements_specs']
Exemplo n.º 13
0
 def get_balance_money(self, with_bonus=False):
     from platforms.cfh.exceptions import CFHError
     from platforms.strategy_store.exceptions import SSError
     # type: (bool) -> Money
     try:
         return Money(*self.get_balance(with_bonus=with_bonus))
     except (CFHError, SSError):
         return NoneMoney()
Exemplo n.º 14
0
 def setUp(self):
     super().setUp()
     self.date_ = date(2017, 12, 24)
     self.accs = [
         AccountFactory()("A", AccTypeEnum.LEAF, get_root_acc()),
         AccountFactory()("B", AccTypeEnum.LEAF, get_root_acc())
     ]
     # Force second money to exactly offset the first.
     self.cur = CurrencyTestFactory()
     self.moneys = [Money(100, self.cur), Money(-100, self.cur)]
     self.data = {
         "description":
         "Hola",
         "date_":
         self.date_,
         "movements_specs":
         [MovementSpec(a, m) for a, m in zip(self.accs, self.moneys)]
     }
Exemplo n.º 15
0
 def requests_sum_total(self):
     if not self.account.currency:
         raise RuntimeError(
             'Cannot display account {0} withdraw requests summ, because account currency is {0}'
             .format(self.account, type(self.account.currency)))
     currency = 'USD' if self.account.currency.is_metal else self.account.currency
     amount = sum([
         wr.amount_money.to(currency).amount for wr in self.alive_requests
     ], 0)
     return Money(amount, currency)
Exemplo n.º 16
0
 def equity_money(self):
     # type: () -> Money
     """
     Return account equity (value of open positions + balance)
     Returns Money object.
     """
     try:
         return Money(self.api.account_equity(self), self.currency)
     except PlatformError as e:
         return NoneMoney()
Exemplo n.º 17
0
 def setUp(self):
     super().setUp()
     self.accs = AccountTestFactory.create_batch(3,
                                                 acc_type=AccTypeEnum.LEAF)
     self.curs = CurrencyTestFactory.create_batch(2)
     self.moneys = [Money(10, self.curs[0]), Money(-8, self.curs[1])]
     self.movements_specs = [
         MovementSpec(self.accs[0], self.moneys[0]),
         MovementSpec(self.accs[1], self.moneys[1])
     ]
     self.data = {
         'description':
         'hola',
         'date':
         date(1993, 11, 23),
         'movements_specs': [
             MovementSpecSerializer(self.movements_specs[0]).data,
             MovementSpecSerializer(self.movements_specs[1]).data
         ]
     }
Exemplo n.º 18
0
 def test_set_movements_base(self):
     cur = CurrencyTestFactory()
     values = ((Decimal(1) / Decimal(3)), (Decimal(2) / Decimal(3)),
               Decimal(-1))
     moneys = [Money(val, cur) for val in values]
     accs = AccountTestFactory.create_batch(3)
     mov_specs = [
         MovementSpec(acc, money) for acc, money in zip(accs, moneys)
     ]
     trans = TransactionTestFactory()
     assert trans.get_movements_specs() != mov_specs
     trans.set_movements(mov_specs)
     assert trans.get_movements_specs() == mov_specs
Exemplo n.º 19
0
 def setUp(self):
     super().setUp()
     # Some default data for the post request
     self.populate_accounts()
     self.accs = AccountTestFactory.create_batch(
         2,
         acc_type=AccTypeEnum.LEAF
     )
     self.cur = CurrencyTestFactory()
     self.moneys = [Money(200, self.cur), Money(-200, self.cur)]
     self.movements_specs = [
         MovementSpec(self.accs[0], self.moneys[0]),
         MovementSpec(self.accs[1], self.moneys[1])
     ]
     self.post_data = {
         'description': 'A',
         'date': date(2018, 12, 21),
         'movements_specs': [
             MovementSpecSerializer(self.movements_specs[0]).data,
             MovementSpecSerializer(self.movements_specs[1]).data
         ]
     }
Exemplo n.º 20
0
 def requests_sum_stats(self):
     if not self.account.currency:
         raise RuntimeError(
             'Cannot display account {0} withdraw requests summ, because account currency is {0}'
             .format(self.account, type(self.account.currency)))
     with Money.convert_cache_key('autonosick_{0}'.format(
             date.today().strftime("%d/%m/%Y"))):
         stats = dict()
         for wr in self.alive_requests:
             m = wr.amount_money
             if wr.payment_system in stats:
                 m = m.to(stats[wr.payment_system].currency)
             if wr.payment_system not in stats:
                 stats[wr.payment_system] = m
             else:
                 stats[wr.payment_system] += m
         return {
             payment_system: {
                 'money': money,
                 'need_check': amount_needs_check(payment_system, money)
             }
             for payment_system, money in stats.items()
         }
Exemplo n.º 21
0
    def test_patch_transaction(self):
        accs = AccountTestFactory.create_batch(
            3,
            acc_type=AccTypeEnum.LEAF
        )
        cur = CurrencyTestFactory()
        trans = TransactionTestFactory()
        new_movements = [MovementSpecSerializer(x).data for x in (
            MovementSpec(accs[0], Money(100, cur)),
            MovementSpec(accs[1], Money(50, cur)),
            MovementSpec(accs[2], Money(-150, cur))
        )]
        resp = self.client.patch(
            f'/transactions/{trans.pk}/',
            {'movements_specs': new_movements}
        )
        assert resp.status_code == 200, resp.data
        trans.refresh_from_db()

        movements = trans.get_movements_specs()
        assert len(movements) == 3
        assert [x.money for x in movements] == \
            [Money(100, cur), Money(50, cur), Money(-150, cur)]
Exemplo n.º 22
0
    def test_check_balance_and_add_transaction(self):
        # The user has two accounts he uses, with two transactions between them
        cur = CurrencyTestFactory()
        accs = AccountTestFactory.create_batch(2, acc_type=AccTypeEnum.LEAF)
        transactions = [
            TransactionTestFactory(date_=date(2018, 1, 2),
                                   movements_specs=[
                                       MovementSpec(accs[0], Money(100, cur)),
                                       MovementSpec(accs[1], Money(-100, cur))
                                   ]),
            TransactionTestFactory(date_=date(2018, 1, 1),
                                   movements_specs=[
                                       MovementSpec(accs[0], Money(22, cur)),
                                       MovementSpec(accs[1], Money(-22, cur))
                                   ])
        ]
        transactions.sort(key=lambda x: x.get_date(), reverse=True)
        serialized_transactions = \
            TransactionSerializer(transactions, many=True).data

        # He also has another two accounts with an unrelated transaction
        other_accs = AccountTestFactory.create_batch(2,
                                                     acc_type=AccTypeEnum.LEAF)
        TransactionTestFactory(date_=date(2017, 1, 2),
                               movements_specs=[
                                   MovementSpec(other_accs[0], Money(100,
                                                                     cur)),
                                   MovementSpec(other_accs[1],
                                                Money(-100, cur))
                               ])

        # He queries ony for transactions involving acc1, and see the
        # same ones listed, in chronological order
        assert self.get_json(f"{URLS.transaction}?account_id={accs[0].pk}") == \
            serialized_transactions

        # He adds a new transaction of 10 cur to acc2
        new_transaction = self.post_json(
            URLS.transaction, {
                "description":
                "New Transaction",
                "date":
                "2018-01-03",
                "movements_specs": [{
                    "account": accs[0].pk,
                    "money": {
                        "quantity": 10,
                        "currency": cur.pk
                    }
                }, {
                    "account": accs[1].pk,
                    "money": {
                        "quantity": -10,
                        "currency": cur.pk
                    }
                }]
            })
        serialized_transactions.insert(0, new_transaction)

        # He queries again for transactions involving acc1, and see all
        # of them listed
        assert self.get_json(f"{URLS.transaction}?account_id={accs[0].pk}") == \
            serialized_transactions
Exemplo n.º 23
0
 def get_referral_money(self):
     return Money(sum(map(lambda r: float(r.api.account_balance(r) or 0), self.agent_accounts.non_demo_active())) \
         if self.is_ib else 0, USD)
Exemplo n.º 24
0
 def test_base(self):
     currency = Mock()
     money = Money('10.24', currency)
     assert money.quantity == Decimal('10.24')
     assert money.currency == currency
Exemplo n.º 25
0
 def test_equal_false_diff_quantities(self):
     currency = Mock()
     one = Balance([Money('10', currency)])
     two = Balance([Money('9', currency)])
     assert one != two
Exemplo n.º 26
0
 def test_equal_false_diff_currencies(self):
     currencies = [Mock(), Mock()]
     one = Balance([Money('10', currencies[0])])
     two = Balance([Money('10', currencies[1])])
     assert one != two
Exemplo n.º 27
0
 def test_equal_true(self):
     currency = Mock()
     one = Balance([Money('10', currency)])
     two = Balance([Money('7', currency), Money('3', currency)])
     assert one == two
Exemplo n.º 28
0
 def test_get_currencies_base(self):
     currencies = [Mock(), Mock()]
     balance = Balance(
         [Money('11', currencies[0]),
          Money('7', currencies[1])])
     assert balance.get_currencies() == set(currencies)
Exemplo n.º 29
0
 def test_get_for_currency_present_two_movements(self):
     currency = Mock()
     moneys = [Money(10, currency), Money(20, currency)]
     balance = Balance(moneys)
     assert balance.get_for_currency(currency) == Money(30, currency)
Exemplo n.º 30
0
 def test_get_for_currency_not_present_return_zero(self):
     currencies = [Mock(), Mock()]
     money = Money(10, currencies[0])
     balance = Balance([money])
     assert balance.get_for_currency(currencies[1]) == Money(
         0, currencies[1])