Beispiel #1
0
 def __set__(self, obj, value):
     if isinstance(value, tuple):
         value = Money(amount=value[0], currency=value[1])
     if isinstance(value, Money):
         obj.__dict__[self.field.name] = value.amount
         setattr(obj, self.currency_field_name,
                 smart_unicode(value.currency))
     elif isinstance(value, ExpressionNode):
         if isinstance(value.children[1], Money):
             value.children[1] = value.children[1].amount
         obj.__dict__[self.field.name] = value
     else:
         if value:
             value = str(value)
         obj.__dict__[self.field.name] = self.field.to_python(value)
Beispiel #2
0
    def test_balance_simple(self):
        account1 = self.account()
        account2 = self.account()

        with db_transaction.atomic():
            transaction = Transaction.objects.create()
            Leg.objects.create(transaction=transaction,
                               account=account1,
                               amount=Money(100, "EUR"))
            Leg.objects.create(transaction=transaction,
                               account=account2,
                               amount=Money(-100, "EUR"))

        self.assertEqual(account1.simple_balance(), Balance(100, "EUR"))
        self.assertEqual(account2.simple_balance(), Balance(-100, "EUR"))
    def test_mul_float_warning(self):
        # This should be changed to TypeError exception after deprecation period is over.
        with warnings.catch_warnings(record=True) as warning_list:
            warnings.simplefilter("always")
            Money(amount="10") * 1.2
            assert "Multiplying Money instances with floats is deprecated" in [
                w.message.args[0] for w in warning_list
            ]

        with warnings.catch_warnings(record=True) as warning_list:
            warnings.simplefilter("always")
            1.2 * Money(amount="10")
            assert "Multiplying Money instances with floats is deprecated" in [
                w.message.args[0] for w in warning_list
            ]
Beispiel #4
0
 def test_init_omit_currency(self):
     with pytest.raises(
             TypeError,
             match=
             r"__init__\(\) missing 1 required positional argument: 'currency'",
     ):
         Money(amount=self.one_million_decimal)
    def to_python(self, value):

        if value is None:
            return None
        if isinstance(value, Money):
            return value

        if not isinstance(value, tuple) or len(value) != 2:
            raise Exception(
                "Invalid money input, expected amount and currency, got: %s." %
                value)

        amount, currency = value
        if not currency:
            raise forms.ValidationError(_('Currency is missing'))

        if not isinstance(currency, basestring):
            raise forms.ValidationError(
                _("Unrecognized currency type '%s'." % currency))

        currency = currency.upper()
        if currency not in CURRENCIES or currency == DEFAULT_CURRENCY_CODE:
            raise forms.ValidationError(
                _("Unrecognized currency type '%s'." % currency))

        amount = super(MoneyField, self).to_python(amount)
        return Money(amount=amount, currency=currency)
Beispiel #6
0
    def setUp(self):
        super(VitepayUpdateApiTest, self).setUp()

        order_payment = VitepayOrderPaymentFactory.create(
            amount=Money(2000, XOF))
        self.payment = VitepayPaymentFactory.create(
            order_id='opc-1', order_payment=order_payment)
Beispiel #7
0
    def test_authorization_action(self, mock_post, create_hash, get_current_host):
        """
        Play some posts that Vitepay might fire at us.
        """
        self.init_projects()
        order = OrderFactory.create()
        DonationFactory.create(amount=Money(2000, XOF), order=order)
        order_payment = OrderPaymentFactory.create(payment_method='vitepayOrangemoney', order=order)
        adapter = VitepayPaymentAdapter(order_payment)
        authorization_action = adapter.get_authorization_action()
        data = {
            u"api_key": u"123",
            u"hash": u"123123",
            u"redirect": 0,
            u"payment": {
                u"description": u"Thanks for your donation!",
                u"order_id": u"opc-{}".format(order_payment.id),
                u"decline_url": u"https://onepercentclub.com/orders/{}/failed".format(order_payment.order.id),
                u"p_type": u"orange_money",
                u"country_code": u"ML",
                u"language_code": u"fr",
                u"amount_100": 200000,
                u"cancel_url": u"https://onepercentclub.com/orders/{}/failed".format(order_payment.order.id),
                u"currency_code": u"XOF",
                u"callback_url": u"https://onepercentclub.com/payments_vitepay/status_update/",
                u"return_url": u"https://onepercentclub.com/orders/{}/success".format(order_payment.order.id)
            }
        }

        self.assertEqual(mock_post.call_args[0][0], 'https://api.vitepay.com/v1/prod/payments')
        self.assertEqual(json.loads(mock_post.call_args[1]['data']), data)
        self.assertEqual(mock_post.call_args[1]['headers'], {'Content-Type': 'application/json'})

        self.assertEqual(authorization_action['url'], 'https://vitepay.com/some-path-to-pay')
Beispiel #8
0
def Deserializer(stream_or_string, **options):
    """
    Deserialize a stream or string of JSON data.
    """
    if not isinstance(stream_or_string, (bytes, six.string_types)):
        stream_or_string = stream_or_string.read()
    if isinstance(stream_or_string, bytes):
        stream_or_string = stream_or_string.decode('utf-8')
    try:
        for obj in json.loads(stream_or_string):
            money_fields = {}
            fields = {}
            Model = _get_model(obj["model"])
            for (field_name, field_value) in six.iteritems(obj['fields']):
                field = Model._meta.get_field(field_name)
                if isinstance(field, MoneyField) and field_value is not None:
                    money_fields[field_name] = Money(
                        field_value,
                        obj['fields'][get_currency_field_name(field_name)])
                else:
                    fields[field_name] = field_value
            obj['fields'] = fields

            for obj in PythonDeserializer([obj], **options):
                for field, value in money_fields.items():
                    setattr(obj.object, field, value)
                yield obj
    except GeneratorExit:
        raise
 def test_rmod_float_warning(self):
     # This should be changed to TypeError exception after deprecation period is over.
     with warnings.catch_warnings(record=True) as warning_list:
         warnings.simplefilter("always")
         2.0 % Money(amount="10")
         assert ("Calculating percentages of Money instances using floats is deprecated"
                 in [w.message.args[0] for w in warning_list])
Beispiel #10
0
    def test_create_payment_redirect(self, charge, get_current_host):
        """
        Test Flutterwave payment that turns to success without otp (one time pin)
        """
        self.init_projects()
        order = OrderFactory.create()
        DonationFactory.create(amount=Money(150000, NGN), order=order)
        order_payment = OrderPaymentFactory.create(
            payment_method='flutterwaveCreditcard',
            order=order,
            integration_data=integration_data)
        adapter = FlutterwaveCreditcardPaymentAdapter(order_payment)
        authorization_action = adapter.get_authorization_action()

        self.assertEqual(adapter.payment.amount, '150000.00')
        self.assertEqual(adapter.payment.status, 'started')
        self.assertEqual(adapter.payment.transaction_reference, 'FLW005')
        self.assertEqual(
            authorization_action, {
                'method': 'get',
                'payload': {
                    'method': 'flutterwave-otp',
                    'text': redirect_response['data']['responsemessage']
                },
                'type': 'redirect',
                'url': redirect_response['data']['authurl']
            })
Beispiel #11
0
 def compress(self, data_list):
     try:
         if data_list[0] is None:
             return None
     except IndexError:
         return None
     return Money(*data_list[:2])
Beispiel #12
0
 def get_open_orders(self, symbol='btc_usd'):
     params = {'order_id': -1, 'symbol': symbol}
     resp = self.okcoin_request('order_info.do', params)
     if resp and 'result' in resp and resp['result']:
         rawos = resp['orders']
     else:
         raise ExchangeError(
             'okcoin', 'unable to get open orders. response was %r' % resp)
     orders = []
     for o in rawos:
         side = 'ask' if o['type'] == 'sell' else 'bid'
         orders.append(
             MyOrder(Money(o['price'],
                           self.fiatcurrency), Money(o['amount']), side,
                     self.name, str(o['order_id'])))
     return orders
Beispiel #13
0
    def test_account_balance_after_out_of_order_ids(self):
        src = self.account()
        dst = self.account()
        # Take test_account_balance_after() as a reference test,
        # here we reverse the order of creation (to make the IDs go
        # backwards), and set the dates to force the order we want
        dst.transfer_to(src, Money(70, "EUR"), date="2000-01-15")
        src.transfer_to(dst, Money(50, "EUR"), date="2000-01-10")
        src.transfer_to(dst, Money(100, "EUR"), date="2000-01-05")
        src.transfer_to(dst, Money(100, "EUR"), date="2000-01-01")

        legs = Leg.objects.filter(account=dst).order_by("transaction__date").all()
        self.assertEqual(legs[0].account_balance_after(), Balance("100", "EUR"))
        self.assertEqual(legs[1].account_balance_after(), Balance("200", "EUR"))
        self.assertEqual(legs[2].account_balance_after(), Balance("250", "EUR"))
        self.assertEqual(legs[3].account_balance_after(), Balance("180", "EUR"))
Beispiel #14
0
 def test_transfer_pos_to_pos(self):
     src = self.account(type=Account.TYPES.income)
     dst = self.account(type=Account.TYPES.income)
     src.transfer_to(dst, Money(100, 'EUR'))
     self.assertEqual(src.balance(), Balance(-100, 'EUR'))
     self.assertEqual(dst.balance(), Balance(100, 'EUR'))
     Account.validate_accounting_equation()
Beispiel #15
0
    def test_arithmetic_operations_return_real_subclass_instance(self):
        """
        Arithmetic operations on a subclass instance should return instances in the same subclass
        type.
        """

        extended_money = ExtendedMoney(amount=2, currency=self.USD)

        operated_money = +extended_money
        assert type(extended_money) == type(operated_money)
        operated_money = -extended_money
        assert type(extended_money) == type(operated_money)
        operated_money = ExtendedMoney(
            amount=1, currency=self.USD) + ExtendedMoney(amount=1,
                                                         currency=self.USD)
        assert type(extended_money) == type(operated_money)
        operated_money = ExtendedMoney(amount=3, currency=self.USD) - Money(
            amount=1, currency=self.USD)
        assert type(extended_money) == type(operated_money)
        operated_money = (1 * extended_money)
        assert type(extended_money) == type(operated_money)
        operated_money = (extended_money / 1)
        assert type(extended_money) == type(operated_money)
        operated_money = abs(ExtendedMoney(amount=-2, currency=self.USD))
        assert type(extended_money) == type(operated_money)
        operated_money = (50 % ExtendedMoney(amount=4, currency=self.USD))
        assert type(extended_money) == type(operated_money)
Beispiel #16
0
    def setUp(self):
        super(InterswitchUpdateApiTest, self).setUp()

        self.order_payment = InterswitchOrderPaymentFactory.create(
            amount=Money(2000, XOF))
        self.payment = InterswitchPaymentFactory.create(
            order_payment=self.order_payment)
Beispiel #17
0
 def test_authorization_action(self, get_current_host, create_hash):
     """
     Play some posts that Vitepay might fire at us.
     """
     self.init_projects()
     order = OrderFactory.create()
     DonationFactory.create(amount=Money(2000, NGN), order=order)
     order_payment = OrderPaymentFactory.create(payment_method='interswitchWebpay', order=order)
     adapter = InterswitchPaymentAdapter(order_payment)
     authorization_action = adapter.get_authorization_action()
     redirect_url = 'https://onepercentclub.com/payments_interswitch/payment_response/{0}'.format(order_payment.id)
     data = {
         'hash': '123123',
         'product_id': '1234',
         'site_redirect_url': redirect_url,
         'local_date_time': None,
         'txn_ref': '-{0}'.format(order_payment.id),
         'cust_name': None,
         'currency': '566',
         'amount': 200000,
         'pay_item_name': None,
         'cust_id': None,
         'pay_item_id': '123',
         'site_name': 'testserver',
         'cust_id_desc': None,
         'cust_name_desc': None
     }
     self.assertEqual(authorization_action['url'], 'https://stageserv.interswitchng.com/test_paydirect/pay')
     self.assertEqual(authorization_action['payload'], data)
Beispiel #18
0
    def test_create_success_payment(self, mock_client):
        """
        Test Lipisha M-PESA payment that turns to success.
        """

        authorization_action = self.adapter.get_authorization_action()

        self.assertEqual(int(self.adapter.payment.reference), self.order_payment.id)

        self.assertEqual(authorization_action, {
            'payload': {
                'account_number': '353535#{}'.format(self.order_payment.id),
                'amount': 1500,
                'business_number': '1234'
            },
            'type': 'process'
        })

        # Now confirm the payment by user and have Lipisha send a success
        instance = mock_client.return_value
        instance.get_transactions.return_value = lipisha_success_response

        self.order_payment.integration_data = {}
        adapter = LipishaPaymentAdapter(self.order_payment)
        adapter.check_payment_status()
        authorization_action = adapter.get_authorization_action()
        self.assertEqual(adapter.payment.transaction_amount, '2500.0000')
        self.assertEqual(adapter.payment.status, 'settled')
        self.assertEqual(authorization_action, {
            "type": "success"
        })
        # Donation amount should have been updated
        self.donation.refresh_from_db()
        self.assertEqual(self.donation.amount, Money(2500.00, 'KES'))
Beispiel #19
0
    def test_multiple_donations(self):
        DonationFactory.create(
            order=OrderFactory.create(status=StatusDefinition.SUCCESS),
            fundraiser=self.fundraiser,
            amount=Money(100, 'USD')
        )
        DonationFactory.create(
            order=OrderFactory.create(status=StatusDefinition.SUCCESS),
            fundraiser=self.fundraiser,
            amount=Money(100, 'EUR')
        )

        self.assertEqual(
            self.fundraiser.amount_donated,
            Money(250, 'EUR')
        )
Beispiel #20
0
 def test_transfer_to(self):
     account1 = self.account(type=Account.TYPES.income)
     account2 = self.account(type=Account.TYPES.income)
     transaction = account1.transfer_to(account2, Money(500, "EUR"))
     self.assertEqual(transaction.legs.count(), 2)
     self.assertEqual(account1.balance(), Balance(-500, "EUR"))
     self.assertEqual(account2.balance(), Balance(500, "EUR"))
Beispiel #21
0
 def test_transfer_neg_to_neg(self):
     src = self.account(type=Account.TYPES.asset)
     dst = self.account(type=Account.TYPES.asset)
     src.transfer_to(dst, Money(100, "EUR"))
     self.assertEqual(src.balance(), Balance(-100, "EUR"))
     self.assertEqual(dst.balance(), Balance(100, "EUR"))
     Account.validate_accounting_equation()
Beispiel #22
0
 def compress(self, data_list):
     if data_list:
         if not self.required and data_list[0] in self.empty_values:
             return None
         else:
             return Money(*data_list[:2])
     return None
Beispiel #23
0
 def __mul__(self, other):
     if isinstance(other, Money):
         raise TypeError('Cannot multiply two Money instances.')
     else:
         return Money(
             amount=(self.amount * Decimal(str(other))),
             currency=self.currency)
Beispiel #24
0
    def _handle_orders(self, data):
        """Expected fields for Order import:
        completed   (string<date>)
        user        (string<email>)
        total       (string)
        donations   (array)
            project     (string<title>)
            amount      (float)
            reward      (string<title>)
            name        (string)
        """
        try:
            user = Member.objects.get(email=data['user'])
        except (TypeError, Member.DoesNotExist):
            user = None
        completed = data['completed']
        created = data['created']
        total = data['total']
        order, new = Order.objects.get_or_create(user=user,
                                                 created=created,
                                                 total=total,
                                                 completed=completed)
        if new:
            if data['donations']:
                for don in data['donations']:
                    try:
                        project = Project.objects.get(slug=don['project'])
                    except Project.DoesNotExist:
                        print "Could not find project {0}".format(
                            don['project'])
                        continue
                    try:
                        reward = project.reward_set.get(title=don['reward'])
                    except Reward.MultipleObjectsReturned:
                        reward = project.reward_set.filter(
                            title=don['reward']).all()[0]
                    except (Reward.DoesNotExist, KeyError):
                        reward = None
                    donation = Donation.objects.create(
                        project=project,
                        reward=reward,
                        name=don.get('name', '')[:199],
                        order=order,
                        amount=Money(don['amount'], 'EUR'))
                    Donation.objects.filter(pk=donation.pk).update(
                        created=created, updated=completed or created)

            order_payment = OrderPayment.objects.create(order=order)
            order_payment.payment_method = 'externalLegacy'

            OrderPayment.objects.filter(pk=order_payment.pk).update(
                created=created, status='settled', closed=completed)

            Order.objects.filter(pk=order.pk).update(created=created,
                                                     status='success',
                                                     updated=completed
                                                     or created,
                                                     confirmed=completed,
                                                     completed=completed)
Beispiel #25
0
 def totals_donated(self):
     confirmed = [StatusDefinition.PENDING, StatusDefinition.SUCCESS]
     donations = self.donation_set.filter(order__status__in=confirmed)
     totals = [
         Money(data['amount__sum'], data['amount_currency']) for data in
         donations.values('amount_currency').annotate(Sum('amount')).order_by()
     ]
     return totals
Beispiel #26
0
    def test_account_balance_after(self):
        src = self.account()
        dst = self.account()
        src.transfer_to(dst, Money(100, "EUR"))
        src.transfer_to(dst, Money(100, "EUR"))
        src.transfer_to(dst, Money(50, "EUR"))
        dst.transfer_to(src, Money(70, "EUR"))

        legs = Leg.objects.filter(account=dst).order_by("pk").all()
        self.assertEqual(legs[0].account_balance_after(),
                         Balance("100", "EUR"))
        self.assertEqual(legs[1].account_balance_after(),
                         Balance("200", "EUR"))
        self.assertEqual(legs[2].account_balance_after(),
                         Balance("250", "EUR"))
        self.assertEqual(legs[3].account_balance_after(),
                         Balance("180", "EUR"))
 def test_str(self):
     one_million_pln = Money('1000000', 'PLN')
     if PYTHON2:
         assert str(one_million_pln) == 'PLN1,000,000.00'
         assert str(self.one_million_bucks) == 'USD1,000,000.00'
     else:
         assert str(one_million_pln) == '1,000,000.00 zł'
         assert str(self.one_million_bucks) == 'US$1,000,000.00'
Beispiel #28
0
    def setUp(self):
        super(TestFundraiserAmountDonated, self).setUp()

        self.init_projects()

        campaign = ProjectPhase.objects.get(slug="campaign")
        project = ProjectFactory.create(status=campaign)
        self.fundraiser = FundraiserFactory(project=project, amount=Money(1000, 'EUR'))
Beispiel #29
0
 def test_transfer_expense_to_liability(self):
     # This should perform the reverse action to that in the above test_transfer_liability_to_expense()
     src = self.account(type=Account.TYPES.expense)
     dst = self.account(type=Account.TYPES.liability)
     src.transfer_to(dst, Money(100, "EUR"))
     self.assertEqual(src.balance(), Balance(100, "EUR"))
     self.assertEqual(dst.balance(), Balance(100, "EUR"))
     Account.validate_accounting_equation()
Beispiel #30
0
 def setUp(self):
     self.order = OrderFactory.create()
     self.donation = DonationFactory.create(amount=Money(1500, KES), order=self.order)
     self.order_payment = OrderPaymentFactory.create(
         payment_method='lipishaMpesa',
         order=self.order
     )
     self.adapter = LipishaPaymentAdapter(self.order_payment)
Beispiel #31
0
    def test_account_balance_after(self):
        src = self.account()
        dst = self.account()
        src.transfer_to(dst, Money(100, 'EUR'))
        src.transfer_to(dst, Money(100, 'EUR'))
        src.transfer_to(dst, Money(50, 'EUR'))
        dst.transfer_to(src, Money(70, 'EUR'))

        legs = Leg.objects.filter(account=dst).order_by('pk').all()
        self.assertEqual(legs[0].account_balance_after(),
                         Balance('100', 'EUR'))
        self.assertEqual(legs[1].account_balance_after(),
                         Balance('200', 'EUR'))
        self.assertEqual(legs[2].account_balance_after(),
                         Balance('250', 'EUR'))
        self.assertEqual(legs[3].account_balance_after(),
                         Balance('180', 'EUR'))
    def test_round_context_override(self):
        import decimal

        x = Money(amount='2.5', currency=self.USD)
        assert x.round(0) == Money(amount=2, currency=self.USD)
        x = Money(amount='3.5', currency=self.USD)
        assert x.round(0) == Money(amount=4, currency=self.USD)

        with decimal.localcontext() as ctx:
            ctx.rounding = decimal.ROUND_HALF_UP
            x = Money(amount='2.5', currency=self.USD)
            assert x.round(0) == Money(amount=3, currency=self.USD)
            x = Money(amount='3.5', currency=self.USD)
            assert x.round(0) == Money(amount=4, currency=self.USD)
 def test_round(self):
     x = Money(amount='1234.33569', currency=self.USD)
     assert x.round(-4) == Money(amount='0', currency=self.USD)
     assert x.round(-3) == Money(amount='1000', currency=self.USD)
     assert x.round(-2) == Money(amount='1200', currency=self.USD)
     assert x.round(-1) == Money(amount='1230', currency=self.USD)
     assert x.round(0) == Money(amount='1234', currency=self.USD)
     assert x.round(None) == Money(amount='1234', currency=self.USD)
     assert x.round(1) == Money(amount='1234.3', currency=self.USD)
     assert x.round(2) == Money(amount='1234.34', currency=self.USD)
     assert x.round(3) == Money(amount='1234.336', currency=self.USD)
     assert x.round(4) == Money(amount='1234.3357', currency=self.USD)
 def test_get_sub_unit(self):
     m = Money(amount=123, currency=self.USD)
     assert m.get_amount_in_sub_unit() == 12300