예제 #1
0
    def test_ReversalAdjustment(self):
        """
        reversing incorrect accounting event
        """
        #setUpLowPay()

        # what initially posted
        usage_event = Usage(Unit.KWH.amount(50), date(1999, 10, 1), self.acm)
        # must read http://martinfowler.com/eaaDev/AgreementDispatcher.html
        event_list = EventList()
        event_list.add(usage_event)
        event_list.process()

        self.assertReallyEqual(Money(500), self.acm.balance_for(ACCOUNT_TYPE.BASE_USAGE))
        self.assertReallyEqual(Money(27.5), self.acm.balance_for(ACCOUNT_TYPE.TAX))

        # adjust
        adjustment1 = Usage(Unit.KWH.amount(70), date(1999, 10, 1),
                            adjusted_event=usage_event)
        #adjustment1 = ReversalAdjustment(usage_event.event_type, date(1999, 11, 1),
        #                                 adjusted_event=usage_event)

        event_list.add(adjustment1)
        event_list.process()

        self.assertReallyEqual(Money(700), self.acm.balance_for(ACCOUNT_TYPE.BASE_USAGE))
        self.assertReallyEqual(Money(38.50), self.acm.balance_for(ACCOUNT_TYPE.TAX))
예제 #2
0
class ShippingRuleFactory(factory.Factory):
    FACTORY_FOR = ShippingRule

    profile = factory.SubFactory(ShippingProfileFactory)
    rule_price = Money(10, money.CURRENCY["GBP"])
    rule_price_extra = Money(20, money.CURRENCY["GBP"])
    despatch_time = 2
    delivery_time = 5
    delivery_time_max = 10
예제 #3
0
 def clean_balance(self):
     value = self.cleaned_data['balance']
     try:
         money_val = Money()
         money_val.from_string(value)
         if money_val.currency.code == 'XXX' and get_def_currency():
             money_val.currency = CURRENCY[get_def_currency()]
     except:
         raise forms.ValidationError("Invalid money value")
     return money_val
예제 #4
0
    def test_balanceUsingTransactions(self):
        """
        page 48
        """
        revenue = self.acm.account_for(ACCOUNT_TYPE.REVENUE)
        deferred = self.acm.account_for(ACCOUNT_TYPE.RECEIVABLES)
        receivables = self.acm.account_for(ACCOUNT_TYPE.DEFERRED)

        revenue.withdraw(Money(500), receivables, date(1999, 1, 4))
        revenue.withdraw(Money(200), deferred, date(1999, 1, 4))

        self.assertReallyEqual(Money(500), receivables.balance())
        self.assertReallyEqual(Money(200), deferred.balance())
        self.assertReallyEqual(Money(-700), revenue.balance())
예제 #5
0
    def testSaveBigAmount(self):
        big_money = Money(2500000, "USD")
        payment = PaymentFactory.build(money=big_money,
                                       money_currency=big_money.currency)
        payment.save()

        self.assertEqual(big_money, Payment.objects.get(pk=payment.pk).money)
    def prepare_data(self,
                     money,
                     return_url,
                     cancel_url,
                     receivers,
                     ipn_url=None,
                     **kwargs):
        """Prepare data for Pay API call"""

        if (not money or not isinstance(money, Money)
                or money <= Money('0.00', money.currency)):
            raise ValueError("amount must be a positive instance of Money")

        if (not isinstance(receivers, ReceiverList) or len(receivers) < 1):
            raise ValueError("receivers must be an instance of ReceiverList")

        data = {
            'actionType': 'PAY',
            'currencyCode': money.currency.code,
            'returnUrl': return_url,
            'cancelUrl': cancel_url
        }

        receiverList = {'receiver': receivers.to_dict()}
        data.update({'receiverList': receiverList})

        if ipn_url:
            data.update({'ipnNotificationUrl': ipn_url})

        if kwargs:
            data.update(**kwargs)

        return data
예제 #7
0
    def testMismatchedAmounts(self):
        """Test mismatching amounts"""

        wrong_amount = str(Money("1337.23", 'SEK'))

        data = {
            'status': 'COMPLETED',
            'transaction_type': 'Adaptive Payment PAY',
            'transaction[0].id': 1,
            'transaction[0].amount': wrong_amount,
            'transaction[0].status': 'COMPLETED',
            'transaction[1].id': 2,
            'transaction[1].amount': wrong_amount,
            'transaction[1].status': 'COMPLETED',
        }

        self.mock_ipn_call(data)

        payment = self.get_payment()

        self.assertEqual(payment.status, 'error')
        self.assertEqual(
            payment.status_detail,
            "IPN amounts didn't match. Payment requested %s. "
            "Payment made %s" % (payment.money, wrong_amount))
예제 #8
0
    def test_usage(self):
        """
        page 37
        """
        usage_evt = Usage(Unit.KWH.amount(50), date(1999, 10, 1), self.acm)
        usage_evt.process()

        # Entry getEntry(Customer, AccountType)
        usage_entry = self.acm.account_for(ACCOUNT_TYPE.BASE_USAGE).entries[0]
        tax_entry = self.acm.account_for(ACCOUNT_TYPE.TAX).entries[0]
        self.assertEqual(Money(500), usage_entry.get_amount())
        self.assertEqual(ACCOUNT_TYPE.BASE_USAGE, usage_entry.get_entry_type())
        self.assertEqual(Money(27.5), tax_entry.get_amount())
        self.assertEqual(ACCOUNT_TYPE.TAX, tax_entry.get_entry_type())

        self.assertIn(usage_entry, usage_evt.resulting_entries)
        self.assertIn(tax_entry, usage_evt.get_all_resulting_entries())
예제 #9
0
파일: account.py 프로젝트: xgenvn/acc
 def balance(self, date=None, period=None):
     if date is None and period is None:
         date = datetime.date.today()
     period = DateRange.upto(date)
     result = Money(0, self.currency)
     for entry in self.entries:
         if period.includes(entry.get_date()):
             result += entry.get_amount()
     return result
예제 #10
0
 def total_gmv(self):
     """Total Gross Merchandise Value of user purchases
     NOTE: This is the customer livetime value!!!
     See also: Stall.total_gmv
     """
     orders = self.user.orders
     paid_orders = orders.filter(Q(is_joomla_order=True) | ~Q(payment=None))
     return Money(0, DEFAULT_CURRENCY) + sum(
         [obj.total() for obj in paid_orders])
예제 #11
0
    def sub_total(self):
        """Returns the total price of all products in the cart for a stall.

        TODO: add delivery.

        """
        amount = Money("0", DEFAULT_CURRENCY)
        for cart_product in self.cart_products.all():
            amount += cart_product.total
        return amount
예제 #12
0
    def setUp(self):

        self.preapproval = Preapproval()
        self.preapproval.money = Money(100, "SEK")
        self.preapproval.save()
        self.preapproval = Preapproval.objects.all()[0]

        self.payment = Payment()
        self.payment.money = Money(100, "USD")
        self.payment.save()
        self.payment = Payment.objects.all()[0]

        george = Receiver(amount=10,
                          email=settings.settings.PAYPAL_EMAIL,
                          primary=False)
        allen = Receiver(amount=90,
                         email="*****@*****.**",
                         primary=True)
        self.recievers = ReceiverList([george, allen])
예제 #13
0
 def setUp(self):
     self.acm = Customer("Acme Coffee Makers")
     standard = ServiceAgreement()
     standard.set_rate(10)
     standard.add_posting_rule(EVENT_TYPE.USAGE,
                               MultiplyByRatePR(ACCOUNT_TYPE.BASE_USAGE),
                               date(1999, 10, 1))
     standard.add_posting_rule(EVENT_TYPE.TAX,
                               AmountFormulaPR(0.055, Money(0),
                                               ACCOUNT_TYPE.TAX),
                               date(1999, 10, 1))
     self.acm.set_service_agreement(standard)
예제 #14
0
 def balance(self):
     if len(self.entries) == 0:
         # XXX: this should be currency neutral 0. or should this class
         # keep Currency?
         return Money(0, 'USD')
     result = None
     for entry in self.entries:
         if result is None:
             result = entry.get_amount()
             continue
         result += entry.get_amount()
     return result
예제 #15
0
    def test_DifferenceAdjustment(self):

        usage1 = Usage(Unit.KWH.amount(20), date(1999, 10, 1), self.acm)
        usage2 = Usage(Unit.KWH.amount(20), date(1999, 10, 2), self.acm)
        usage3 = Usage(Unit.KWH.amount(30), date(1999, 10, 3), self.acm)

        event_list = EventList()
        event_list.add(usage1)
        event_list.add(usage2)
        event_list.add(usage3)
        event_list.process()

        # total 700kw, $700, $38.5 tax

        self.assertReallyEqual(Money(700), self.acm.balance_for(ACCOUNT_TYPE.BASE_USAGE))
        self.assertReallyEqual(Money(38.50), self.acm.balance_for(ACCOUNT_TYPE.TAX))

        # adjustment events

        new1 = Usage(Unit.KWH.amount(10), date(1999, 10, 1), self.acm)
        new2 = Usage(Unit.KWH.amount(10), date(1999, 10, 2), self.acm)
        new3 = Usage(Unit.KWH.amount(15), date(1999, 10, 3), self.acm)

        adj_date = date(2000, 1, 12)
        adj = DifferenceAdjustment(adj_date, self.acm)

        adj.add_old_event(usage1)
        adj.add_old_event(usage2)
        adj.add_old_event(usage3)

        adj.add_new_event(new1)
        adj.add_new_event(new2)
        adj.add_new_event(new3)

        event_list.add(adj)
        event_list.process()

        self.assertReallyEqual(Money(350), self.acm.balance_for(ACCOUNT_TYPE.BASE_USAGE))
        self.assertReallyEqual(Money(19.25), self.acm.balance_for(ACCOUNT_TYPE.TAX))
예제 #16
0
    def process_money(cls, money_str):
        """
        Paypal sends money in the form "XXX 0.00" where XXX is the currency
        code and 0.00 is the amount

        """

        if money_str:
            money_args = str(money_str).split(' ', 1)
            money_args.reverse()
            if money_args and len(money_args) == 2:
                return Money(*money_args)

        return None
예제 #17
0
class OrderFactory(factory.Factory):

    @classmethod
    def _prepare(cls, create, **kwargs):
        if "address" not in kwargs:
            if create:
                address = ShippingAddressFactory(user=kwargs["user"])
            else:
                address = ShippingAddressFactory.build(user=kwargs["user"])
            kwargs["address"] = address
        return super(OrderFactory, cls)._prepare(create, **kwargs)

    user = factory.SubFactory(UserFactory)
    delivery_charge = Money(10, money.CURRENCY["GBP"])
    stall = factory.SubFactory(StallFactory)
예제 #18
0
    def testMismatchedAmounts(self):
        """Test mismatching amounts"""

        wrong_amount = Money("1337.23", 'SEK')
        data = self.get_valid_IPN_call(wrong_amount)

        self.mock_ipn_call(data)

        preapproval = self.get_preapproval()

        self.assertEqual(preapproval.status, 'error')
        self.assertEqual(preapproval.status_detail,
                         ("IPN amounts didn't match. Preapproval "
                          "requested %s. Preapproval made %s" %
                          (preapproval.money, wrong_amount)))
예제 #19
0
    def test_balance_using_multi_legged_transaction(self):
        revenue = self.acm.account_for(ACCOUNT_TYPE.REVENUE)
        deferred = self.acm.account_for(ACCOUNT_TYPE.RECEIVABLES)
        receivables = self.acm.account_for(ACCOUNT_TYPE.DEFERRED)

        multi = Transaction(date(2000, 1, 4))
        multi.add(Money(-700), revenue)
        multi.add(Money(500), receivables)
        multi.add(Money(200), deferred)
        multi.post()

        self.assertReallyEqual(Money(500), receivables.balance())
        self.assertReallyEqual(Money(200), deferred.balance())
        self.assertReallyEqual(Money(-700), revenue.balance())
예제 #20
0
    def discount_amount(self):
        """
        Calculates a discount for a product.

        The two reasons for a discount are:

        - The customer added a coupon code
        - There is free shipping for a product

        @return: Money object representing the discount
        """
        if self.shipping_discount.amount > 0:
            return self.shipping_discount
        elif self.coupon_code:
            try:
                discount = _get_discount(self.cart, self.coupon_code)
            except (Discount.DoesNotExist, CouponAlreadyInCart,
                    CouponAlreadyUsed):
                # Zero discount
                discount = Discount()
        else:
            discount = Discount()
        return Money(discount.calculate(self.pre_discount_total()),
                     DEFAULT_CURRENCY)
예제 #21
0
def get_def_money():
    currency = get_def_currency()
    if currency:
        return Money(0, currency)
    return None
예제 #22
0
파일: account.py 프로젝트: xgenvn/acc
 def withdrawals(self, period):
     result = Money(0, self.currency)
     for entry in self.entries:
         if period.includes(entry.date()) and entry.amount().is_negative():
             result += entry.amount()
     return result
예제 #23
0
파일: account.py 프로젝트: xgenvn/acc
 def deposits(self, period):
     result = Money(0, self.currency)
     for entry in self.entries:
         if period.includes(entry.date()) and entry.amount().is_positive():
             result += entry.amount()
     return result
예제 #24
0
class PaypalAdaptiveFactory(factory.DjangoModelFactory):
    FACTORY_FOR = PaypalAdaptive

    money = Money(1400, 'SEK')
    money_currency = 'SEK'
    created_date = datetime.datetime.now()
예제 #25
0
 def __init__(self, *args, **kwargs):
     self.shipping_discount = Money("0", DEFAULT_CURRENCY)
     super(CartStall, self).__init__(*args, **kwargs)
예제 #26
0
    def delivery_total(self):
        """Returns the delivery charges for this stall, considering all
        products in the cart.
        """
        if self.address:
            country = self.address.country
        else:
            country = self.get_country()

        # This is a little complex so some explanation is in order.
        #
        # We loop through all the products, for each product if there is a
        # rule which matches the selected country we add the price of the
        # _extra_ items to the total. We also keep track of the largest
        # initial price. After we have been through all the products we
        # add the price of the largest initial item and subtract the extra
        # price of the largest initial item rule because otherwise it will
        # be charged twice, once for the initial and once for the already
        # counted extra.

        # This is the rule with the largest initial item price. We need to
        # store it to add to the total later. We also need the extra price
        # because we need to subtract that from the title.
        #
        # Ideally this would be a single variable rule object, unfortunately
        # the shipping rule for the rest of the world is represented as fields
        # on the shipping profile rather than a rule so we need both fields
        # here.
        largest_initial = None
        largest_initial_extra = None
        largest_shipping_discount = None
        largest_shipping_discout_extra = None
        total_shipping_price = money.Money(0, DEFAULT_CURRENCY)
        total_shipping_discount = Money(0, DEFAULT_CURRENCY)

        for cart_product in self.cart_products.all().prefetch_related(
                'product__shipping_profile__shipping_rules__countries'):
            product = cart_product.product

            #Find the a shipping rule for the selected country
            shipping_price, shipping_price_extra = product.get_shipping_prices(
                self.speculative_country)

            shipping_discount, shipping_discout_extra = product.get_shipping_discounts(
                self.speculative_country)

            if largest_initial is None or shipping_price > largest_initial:
                largest_initial = shipping_price
                largest_shipping_discount = shipping_discount
                largest_initial_extra = shipping_price_extra
                largest_shipping_discout_extra = shipping_discout_extra

            total_shipping_price += shipping_price_extra * cart_product.quantity
            total_shipping_discount += shipping_discout_extra * cart_product.quantity

        if largest_initial is not None:
            total_shipping_price += largest_initial

        if largest_initial_extra is not None:
            total_shipping_price -= largest_initial_extra

        if largest_shipping_discount is not None:
            total_shipping_discount += largest_shipping_discount

        if largest_shipping_discout_extra is not None:
            total_shipping_discount -= largest_shipping_discout_extra

        self.shipping_discount = total_shipping_discount

        return total_shipping_price
예제 #27
0
 def delivery(self):
     """
     TODO: Pull from db.
     """
     return Money("0", DEFAULT_CURRENCY)
예제 #28
0
class PaymentFactory(factory.Factory):
    status = Payment.STATUS_CREATED
    amount = Money(10, money.CURRENCY["GBP"])
    pay_key = "some-pay-key"
    purchaser = factory.SubFactory(UserFactory)
예제 #29
0
파일: electricity.py 프로젝트: xgenvn/acc
 def calculate_amount(cls, usage_event):
     return Money(
         usage_event.get_amount().get_amount() * usage_event.get_rate(),
         'USD')
예제 #30
0
    def __init__(self, request):
        # verify that the request is paypal's
        url = '%s?cmd=_notify-validate' % settings.PAYPAL_PAYMENT_HOST
        post_data = {}
        for k, v in request.POST.copy().iteritems():
            post_data[k] = unicode(v).encode('utf-8')
        data = urllib.urlencode(post_data)
        verify_request = UrlRequest().call(url, data=data)

        # check code
        if verify_request.code != 200:
            raise IpnError('PayPal response code was %s' % verify_request.code)

        # check response
        raw_response = verify_request.response
        if raw_response != 'VERIFIED':
            raise IpnError('PayPal response was "%s"' % raw_response)

        # check transaction type
        raw_type = request.POST.get('transaction_type', '')
        allowed_types = [
            IPN_TYPE_PAYMENT, IPN_TYPE_ADJUSTMENT, IPN_TYPE_PREAPPROVAL
        ]

        if raw_type in allowed_types:
            self.type = raw_type
        else:
            raise IpnError('Unknown transaction_type received: %s' % raw_type)

        self.process_transactions(request)

        try:
            # payments and adjustments define these
            self.status = request.POST.get('status', None)
            self.sender_email = request.POST.get('sender_email', None)
            self.action_type = request.POST.get('action_type', None)
            self.payment_request_date = IPN.process_date(
                request.POST.get('payment_request_date', None))
            self.reverse_all_parallel_payments_on_error = request.POST.get(
                'reverse_all_parallel_payments_on_error', 'false') == 'true'
            self.return_url = request.POST.get('return_url', None)
            self.cancel_url = request.POST.get('cancel_url', None)
            self.ipn_notification_url = request.POST.get(
                'ipn_notification_url', None)
            self.pay_key = request.POST.get('pay_key', None)
            self.memo = request.POST.get('memo', None)
            self.fees_payer = request.POST.get('fees_payer', None)
            self.trackingId = request.POST.get('trackingId', None)
            self.preapproval_key = request.POST.get('preapproval_key', None)
            self.reason_code = request.POST.get('reason_code', None)

            # preapprovals define these
            self.approved = request.POST.get('approved', 'false') == 'true'
            self.current_number_of_payments = IPN.process_int(
                request.POST.get('current_number_of_payments', None))
            self.current_total_amount_of_all_payments = IPN.process_money(
                request.POST.get('current_total_amount_of_all_payments', None))
            self.current_period_attempts = IPN.process_int(
                request.POST.get('current_period_attempts', None))
            self.currency_code = Currency(
                request.POST.get('currency_code', None))
            self.date_of_month = IPN.process_int(
                request.POST.get('date_of_month', None))
            self.day_of_week = IPN.process_int(
                request.POST.get('day_of_week', None), None)
            self.starting_date = IPN.process_date(
                request.POST.get('starting_date', None))
            self.ending_date = IPN.process_date(
                request.POST.get('ending_date', None))
            self.max_total_amount_of_all_payments = Money(
                request.POST.get('max_total_amount_of_all_payments', None),
                request.POST.get('currency_code', None))
            self.max_amount_per_payment = IPN.process_money(
                request.POST.get('max_amount_per_payment', None))
            self.max_number_of_payments = IPN.process_int(
                request.POST.get('max_number_of_payments', None))
            self.payment_period = request.POST.get('payment_period', None)
            self.pin_type = request.POST.get('pin_type', None)
        except Exception, e:
            logger.error('Could not parse request')
            raise e