Example #1
0
def get_price(request, product_slug):
    """Get base price for a product, returning the answer encoded as JSON."""
    quantity = Decimal('1')

    try:
        product = Product.objects.get_by_site(active=True, slug=product_slug)
    except Product.DoesNotExist:
        return http.HttpResponseNotFound(json_encode(('', _("not available"))), mimetype="text/javascript")

    prod_slug = product.slug

    if request.method == "POST" and request.POST.has_key('quantity'):
        try:
            quantity = round_decimal(request.POST['quantity'], places=2, roundfactor=.25)
        except RoundedDecimalError:
            quantity = Decimal('1.0')
            log.warn("Could not parse a decimal from '%s', returning '1.0'", request.POST['quantity'])

    if 'ConfigurableProduct' in product.get_subtypes():
        cp = product.configurableproduct
        chosen_options = optionids_from_post(cp, request.POST)
        pvp = cp.get_product_from_options(chosen_options)

        if not pvp:
            return http.HttpResponse(json_encode(('', _("not available"))), mimetype="text/javascript")
        prod_slug = pvp.slug
        price = moneyfmt(pvp.get_qty_price(quantity))
    else:
        price = moneyfmt(product.get_qty_price(quantity))

    if not price:
        return http.HttpResponse(json_encode(('', _("not available"))), mimetype="text/javascript")

    return http.HttpResponse(json_encode((prod_slug, price)), mimetype="text/javascript")
Example #2
0
    def __unicode__(self):
        if self.discount_type == DISCOUNT_AMOUNT:
            discount = moneyfmt(self.discount)
        else:
            discount = u'%s%%' % floatformat(self.discount)

        return u'%s off %s or more' % (discount, moneyfmt(self.cart_minimum))
Example #3
0
File: tests.py Project: 34/T
    def testUSD(self):
        l10n_settings.set_l10n_setting('default_currency', 'USD')
        
        val = Decimal('10.00')
        self.assertEqual(moneyfmt(val), '$10.00')

        self.assertEqual(moneyfmt(val, currency_code='USD'), '$10.00')
Example #4
0
def set_quantity(request):
    """Set the quantity for a cart item.

    Intended to be called via the cart itself, returning to the cart after done.
    """
    cart_url = urlresolvers.reverse('satchmo_cart')

    if not request.POST:
        return HttpResponseRedirect(cart_url)

    success, cart, cartitem, errors = _set_quantity(request)

    if request.is_ajax():
        if errors:
            return _json_response({'errors': errors, 'results': _("Error")}, True)
        else:
            return _json_response({
                'item_id': cartitem.id,
                'item_qty': str(cartitem.quantity) or "0",
                'item_price': unicode(moneyfmt(cartitem.line_total)) or "0.00",
                'cart_total': unicode(moneyfmt(cart.total)) or "0.00",
                'cart_count': str(cart.numItems) or '0',
            })

    else:
        if success:
            return HttpResponseRedirect(cart_url)
        else:
            return display(request, cart = cart, error_message = errors)
Example #5
0
    def test_checkout(self):
        """
        Run through a full checkout process
        """
        cache_delete()
        tax = config_get('TAX','MODULE')
        tax.update('tax.modules.percent')
        pcnt = config_get('TAX', 'PERCENT')
        pcnt.update('10')
        shp = config_get('TAX', 'TAX_SHIPPING')
        shp.update(False)

        self.test_cart_adding()
        response = self.client.post(url('satchmo_checkout-step1'), get_step1_post_data(self.US))
        self.assertRedirects(response, url('DUMMY_satchmo_checkout-step2'),
            status_code=302, target_status_code=200)
        data = {
            'credit_type': 'Visa',
            'credit_number': '4485079141095836',
            'month_expires': '1',
            'year_expires': '2014',
            'ccv': '552',
            'shipping': 'FlatRate'}
        response = self.client.post(url('DUMMY_satchmo_checkout-step2'), data)
        self.assertRedirects(response, url('DUMMY_satchmo_checkout-step3'),
            status_code=302, target_status_code=200)
        response = self.client.get(url('DUMMY_satchmo_checkout-step3'))
        amount = smart_str('Shipping + ' + moneyfmt(Decimal('4.00')))
        self.assertContains(response, amount, count=1, status_code=200)

        amount = smart_str('Tax + ' + moneyfmt(Decimal('4.60')))
        self.assertContains(response, amount, count=1, status_code=200)

        amount = smart_str('Total = ' + moneyfmt(Decimal('54.60')))
        self.assertContains(response, amount, count=1, status_code=200)

        response = self.client.post(url('DUMMY_satchmo_checkout-step3'), {'process' : 'True'})
        self.assertRedirects(response, url('DUMMY_satchmo_checkout-success'),
            status_code=302, target_status_code=200)
        self.assertEqual(len(mail.outbox), 1)

        # Log in as a superuser
        user = User.objects.create_user('fredsu', '*****@*****.**', 'passwd')
        user.is_staff = True
        user.is_superuser = True
        user.save()
        self.client.login(username='******', password='******')

        # Test pdf generation
        order_id = Order.objects.all()[0].id
        response = self.client.get('/admin/print/invoice/%d/' % order_id)
        self.assertContains(response, 'reportlab', status_code=200)
        response = self.client.get('/admin/print/packingslip/%d/' % order_id)
        self.assertContains(response, 'reportlab', status_code=200)
        response = self.client.get('/admin/print/shippinglabel/%d/' % order_id)
        self.assertContains(response, 'reportlab', status_code=200)
Example #6
0
File: tests.py Project: 34/T
    def testFake(self):
        currencies = l10n_settings.get_l10n_setting('currency_formats')
        currencies['FAKE'] = {'symbol': '^ ', 'positive' : "%(val)0.2f ^", 'negative': "(%(val)0.2f) ^", 'decimal' : ','}
        
        l10n_settings.set_l10n_setting('currency_formats', currencies)
        
        val = Decimal('10.00')
        self.assertEqual(moneyfmt(val, currency_code='FAKE'), '10,00 ^')

        val = Decimal('-50.00')
        self.assertEqual(moneyfmt(val, currency_code='FAKE'), '(50,00) ^')
Example #7
0
    def test_checkout(self):
        """
        Run through a full checkout process
        """
        cache_delete()
        tax = config_get("TAX", "MODULE")
        tax.update("tax.modules.percent")
        pcnt = config_get("TAX", "PERCENT")
        pcnt.update("10")
        shp = config_get("TAX", "TAX_SHIPPING")
        shp.update(False)

        self.test_cart_adding()
        response = self.client.post(url("satchmo_checkout-step1"), get_step1_post_data(self.US))
        self.assertRedirects(response, url("DUMMY_satchmo_checkout-step2"), status_code=302, target_status_code=200)
        data = {
            "credit_type": "Visa",
            "credit_number": "4485079141095836",
            "month_expires": "1",
            "year_expires": "2014",
            "ccv": "552",
            "shipping": "FlatRate",
        }
        response = self.client.post(url("DUMMY_satchmo_checkout-step2"), data)
        self.assertRedirects(response, url("DUMMY_satchmo_checkout-step3"), status_code=302, target_status_code=200)
        response = self.client.get(url("DUMMY_satchmo_checkout-step3"))
        amount = smart_str("Shipping + " + moneyfmt(Decimal("4.00")))
        self.assertContains(response, amount, count=1, status_code=200)

        amount = smart_str("Tax + " + moneyfmt(Decimal("4.60")))
        self.assertContains(response, amount, count=1, status_code=200)

        amount = smart_str("Total = " + moneyfmt(Decimal("54.60")))
        self.assertContains(response, amount, count=1, status_code=200)

        response = self.client.post(url("DUMMY_satchmo_checkout-step3"), {"process": "True"})
        self.assertRedirects(response, url("DUMMY_satchmo_checkout-success"), status_code=302, target_status_code=200)
        self.assertEqual(len(mail.outbox), 1)

        # Log in as a superuser
        user = User.objects.create_user("fredsu", "*****@*****.**", "passwd")
        user.is_staff = True
        user.is_superuser = True
        user.save()
        self.client.login(username="******", password="******")

        # Test pdf generation
        order_id = Order.objects.all()[0].id
        response = self.client.get("/admin/print/invoice/%d/" % order_id)
        self.assertContains(response, "reportlab", status_code=200)
        response = self.client.get("/admin/print/packingslip/%d/" % order_id)
        self.assertContains(response, "reportlab", status_code=200)
        response = self.client.get("/admin/print/shippinglabel/%d/" % order_id)
        self.assertContains(response, "reportlab", status_code=200)
Example #8
0
    def test_custom_product(self):
        """
        Verify that the custom product is working as expected.
        """
        response = self.client.get(prefix+"/")
        self.assertContains(response, "Computer", count=1)
        response = self.client.get(prefix+"/product/satchmo-computer/")
        self.assertContains(response, "Memory", count=1)
        self.assertContains(response, "Case", count=1)
        self.assertContains(response, "Monogram", count=1)
        response = self.client.post(prefix+'/cart/add/', { "productname" : "satchmo-computer",
                                                      "5" : "1.5gb",
                                                      "6" : "mid",
                                                      "custom_monogram": "CBM",
                                                      "quantity" : '1'})
        self.assertRedirects(response, prefix + '/cart/',
            status_code=302, target_status_code=200)
        response = self.client.get(prefix+'/cart/')
        self.assertContains(response, '/satchmo-computer/">satchmo computer', count=1, status_code=200)
        amount = smart_str(moneyfmt(Decimal('168.00')))
        self.assertContains(response, amount, count=4)

        amount = smart_str('Monogram: CBM  ' + moneyfmt(Decimal('10.00')))
        self.assertContains(response, amount, count=1)

        amount = smart_str('Case - External Case: Mid  ' + moneyfmt(Decimal('10.00')))
        self.assertContains(response, amount, count=1)

        amount = smart_str('Memory - Internal RAM: 1.5 GB  ' + moneyfmt(Decimal('25.00')))
        self.assertContains(response, amount, count=1)

        response = self.client.post(url('satchmo_checkout-step1'), get_step1_post_data(self.US))
        self.assertRedirects(response, url('DUMMY_satchmo_checkout-step2'),
            status_code=302, target_status_code=200)
        data = {
            'credit_type': 'Visa',
            'credit_number': '4485079141095836',
            'month_expires': '1',
            'year_expires': '2012',
            'ccv': '552',
            'shipping': 'FlatRate'}
        response = self.client.post(url('DUMMY_satchmo_checkout-step2'), data)
        self.assertRedirects(response, url('DUMMY_satchmo_checkout-step3'),
            status_code=302, target_status_code=200)
        response = self.client.get(url('DUMMY_satchmo_checkout-step3'))

        amount = smart_str('satchmo computer - ' + moneyfmt(Decimal('168.00')))
        self.assertContains(response, amount, count=1, status_code=200)
        response = self.client.post(url('DUMMY_satchmo_checkout-step3'), {'process' : 'True'})
        self.assertRedirects(response, url('DUMMY_satchmo_checkout-success'),
            status_code=302, target_status_code=200)
        self.assertEqual(len(mail.outbox), 1)
Example #9
0
def apply_discount(sender, instance, **kwargs):
    """Modifies the specified order's total discount based on the order's total value"""

    discount = TieredDiscount.objects.valid(instance.sub_total)
    if discount is not None:
        log.debug('Found a valid automatic discount: %s' % discount)
        log.debug('Order discount BEFORE processing: %s' % moneyfmt(instance.discount))

        amount = discount.amount(instance.sub_total)
        instance.discount += amount
        instance.total -= amount
        log.debug('Order discount AFTER processing: %s' % moneyfmt(instance.discount))
    else:
        log.debug('No valid automatic discounts found for this order')
Example #10
0
def currency(value, args=""):
    """Convert a value to a money formatted string.

    places:  required number of places after the decimal point
    curr:    optional currency symbol before the sign (may be blank)
    wrapcents:tag to wrap the part after the decimal point

    Usage:
        val|currency
        val|currency:'places=2'
        val|currency:'places=2:wrapcents=sup'
    """
    
    if value == '' or value is None:
        return value

    args, kwargs = get_filter_args(args, 
        keywords=('places','curr', 'wrapcents'),
        intargs=('places',), stripquotes=True)

    try:
        value = Decimal(str(value))
    except InvalidOperation:
        log.error("Could not convert value '%s' to decimal", value)
        raise
        
    if not 'places' in kwargs:
        kwargs['places'] = 2
        
    return mark_safe(moneyfmt(value, **kwargs))
Example #11
0
    def render(self, context):

        try:
            show_tax = self.show_tax.resolve(context)
        except template.VariableDoesNotExist:
            show_tax = self.raw_tax

        if show_tax:
            tag = CartitemLineTaxedTotalNode(self.raw_cartitem, self.raw_currency)
            return tag.render(context)

        try:
            cartitem = self.cartitem.resolve(context)
        except template.VariableDoesNotExist:
            log.warn('Could not resolve template variable: %s', self.cartitem)
            return ''

        try:
            show_currency = self.show_currency.resolve(context)
        except template.VariableDoesNotExist:
            show_currency = self.raw_currency

        if show_currency:
            return moneyfmt(cartitem.line_total)
        else:
            return cartitem.line_total
Example #12
0
 def balance_due(self):
     if self.balance:
         b = self.balance
     else:
         b = Decimal('0.00')
         
     return moneyfmt(b)
Example #13
0
    def apply_to_order(self, order):
        """Apply up to the full amount of the balance of this cert to the order.

        Returns new balance.
        """
        amount = min(order.balance, self.balance)
        log.info('applying %s from giftcert #%i [%s] to order #%i [%s]',
            moneyfmt(amount),
            self.id,
            moneyfmt(self.balance),
            order.id,
            moneyfmt(order.balance))

        processor = get_processor_by_key('PAYMENT_GIFTCERTIFICATE')
        orderpayment = processor.record_payment(order=order, amount=amount)
        self.orderpayment = orderpayment
        return self.use(amount, orderpayment=orderpayment)
Example #14
0
 def test_product(self):
     # Test for an easily missed reversion. When you lookup a productvariation product then
     # you should get the page of the parent configurableproduct, but with the options for
     # that variation already selected
     response = self.client.get(prefix+'/product/neat-book-soft/')
     self.assertContains(response, 'option value="soft" selected="selected"')
     amount = moneyfmt(Decimal('5.00'))
     self.assertContains(response, smart_str(amount))
Example #15
0
    def discount_str(self, instance):
        """Returns a string representing the discount based on its type"""

        if instance.discount_type == DISCOUNT_AMOUNT:
            return moneyfmt(instance.discount)
        elif instance.discount_type == DISCOUNT_PERCENT:
            return u'%s%%' % instance.discount
        else:
            return instance.discount
Example #16
0
def option_total_price(product, option_item):
    """
    Returns the total price as $10.00
    The currency symbol is set in the settings.py file
    """
    if option_item.price_change:
        val = product.unit_price + option_item.price_change
    else:
        val = product.unit_price
    return moneyfmt(val)
Example #17
0
def product_shipping(product, args=''):
    if not args:
        raise template.TemplateSyntaxError('product_shipping needs the name of the carrier, as product|productshipping:"carrier"')
    
    try:
        c = Carrier.objects.get(key=args)
    except Carrier.DoesNotExist:
        raise template.TemplateSyntaxError('product_shipping needs the name of a valid carrier, could not find carrier "%s"' % args)
    shipping = c.price(product)
    
    return mark_safe(moneyfmt(shipping))
Example #18
0
def tiered_shipping(price, args=''):
    if not args:
        raise template.TemplateSyntaxError('tiered_shipping needs the name of the carrier, as value|tiered_shipping:"carrier"')

    try:
        c = Carrier.objects.get(key=args)
    except Carrier.DoesNotExist:
        raise template.TemplateSyntaxError('tiered_shipping needs the name of a valid carrier, could not find carrier "%s"' % args)
    shipping = c.price(Decimal(price))

    return mark_safe(moneyfmt(shipping))
Example #19
0
def option_total_price(product, option_item):
    """
    Returns the price as (+$1.00)
    or (-$1.00) depending on the sign of the price change
    The currency symbol is set in the settings.py file
    """
    if option_item.price_change:
        val = product.unit_price + option_item.price_change
    else:
        val = product.unit_price
    return moneyfmt(val)
Example #20
0
def get_price(request, product_slug):
    """Get base price for a product, returning the answer encoded as JSON."""
    quantity = Decimal('1')

    try:
        product = Product.objects.get_by_site(active=True, slug=product_slug)
    except Product.DoesNotExist:
        return http.HttpResponseNotFound(json_encode(('', _("not available"))),
                                         mimetype="text/javascript")

    prod_slug = product.slug

    if request.method == "POST" and request.POST.has_key('quantity'):
        try:
            quantity = round_decimal(request.POST['quantity'],
                                     places=2,
                                     roundfactor=.25)
        except RoundedDecimalError:
            quantity = Decimal('1.0')
            log.warn("Could not parse a decimal from '%s', returning '1.0'",
                     request.POST['quantity'])

    if 'ConfigurableProduct' in product.get_subtypes():
        cp = product.configurableproduct
        chosen_options = optionids_from_post(cp, request.POST)
        pvp = cp.get_product_from_options(chosen_options)

        if not pvp:
            return http.HttpResponse(json_encode(('', _("not available"))),
                                     mimetype="text/javascript")
        prod_slug = pvp.slug
        price = moneyfmt(pvp.get_qty_price(quantity))
    else:
        price = moneyfmt(product.get_qty_price(quantity))

    if not price:
        return http.HttpResponse(json_encode(('', _("not available"))),
                                 mimetype="text/javascript")

    return http.HttpResponse(json_encode((prod_slug, price)),
                             mimetype="text/javascript")
Example #21
0
 def render(self, context):
     taxer = _get_taxprocessor(context['request'])
     try:
         item = template.resolve_variable(self.cartitem, context)
     except template.VariableDoesNotExist:
         raise template.TemplateSyntaxError("No such variable: %s", self.cartitem)
     
     total = item.line_total + taxer.by_price(item.product.taxClass, item.line_total)
     
     if self.currency:
         return moneyfmt(total)
     return total
Example #22
0
    def amount(self, total):
        """Returns the discount amount"""

        amount = Decimal('0.0')
        if self.discount_type == DISCOUNT_AMOUNT:
            log.debug('Discounting a fixed amount: %s' % moneyfmt(self.discount))
            amount = self.discount
        elif self.discount_type == DISCOUNT_PERCENT:
            log.debug('Discounting by a percent of order total: %s' % self.discount)
            amount = total * self.discount / Decimal('100.0')

        return amount
Example #23
0
    def render(self, context):
        taxer = _get_taxprocessor(context['request'])
        try:
            price = template.resolve_variable(self.price, context)
        except template.VariableDoesNotExist:
            raise template.TemplateSyntaxError("No such variable: %s", self.price)

        total = price + taxer.by_price(self.taxclass, price)
        
        if self.currency:
            return moneyfmt(total)
                        
        return total
Example #24
0
def tiered_price_table(carrier):
    """Creates a table with all shipping tiers"""

    try:
        c = Carrier.objects.get(key=carrier)
    except Carrier.DoesNotExist:
        raise template.TemplateSyntaxError('tiered_price_table needs the name of a valid carrier, could not find carrier "%s"' % carrier)

    rows = ['<table class="tiered_price tiered_price_carrier_%s">' % carrier]
    rows.append('<tr><th>Order Total</th><th>Shipping price</th></tr>')
    ranges = []

    last = None
    for tier in c.tiers.all().order_by('-price'):
        t = {}
        t['price'] = moneyfmt(tier.price)
        t['from'] = moneyfmt(tier.min_total)
        if last:
            t['to'] = moneyfmt(last.min_total)
        else:
            t['to'] = None

        ranges.append(t)
        last = tier

    ranges.reverse()

    for tier in ranges:
        price = {}
        price['price'] = tier['price']
        if tier['to']:
            price['range'] = "%s-%s" % (tier['from'], tier['to'])
        else:
            price['range'] = "%s+" % (tier['from'])

        rows.append('<tr><td>%(range)s</td><td>%(price)s</td></tr>' % price)

    rows.append('</table>')
    return mark_safe('\n'.join(rows))
Example #25
0
    def render(self, context):
        taxer = _get_taxprocessor(context['request'])
        try:
            price = template.resolve_variable(self.price, context)
        except template.VariableDoesNotExist:
            raise template.TemplateSyntaxError("No such variable: %s",
                                               self.price)

        total = price + taxer.by_price(self.taxclass, price)

        if self.currency:
            return moneyfmt(total)

        return total
Example #26
0
    def render(self, context):
        taxer = _get_taxprocessor(context["request"])
        try:
            cart = template.resolve_variable(self.cart, context)
        except template.VariableDoesNotExist:
            raise template.TemplateSyntaxError("No such variable: %s", self.cart)

        total = Decimal("0.00")
        for item in cart:
            total += item.line_total + taxer.by_price(item.product.taxClass, item.line_total)
        if self.currency:
            return moneyfmt(total)

        return total
Example #27
0
    def render(self, context):
        taxer = _get_taxprocessor(context['request'])
        try:
            item = template.resolve_variable(self.cartitem, context)
        except template.VariableDoesNotExist:
            raise template.TemplateSyntaxError("No such variable: %s",
                                               self.cartitem)

        total = item.line_total + taxer.by_price(item.product.taxClass,
                                                 item.line_total)

        if self.currency:
            return moneyfmt(total)
        return total
Example #28
0
    def _activate(self, user):
        today = datetime.utcnow().date()
        code = "%x%x%x%x%x" % uuid1().fields[0:5]
        discount = Discount(
            site=self.site,
            description=_(u"Invite discount "
                u"for %(last_name)s %(first_name)s") % {
                    'last_name': user.last_name,
                    'first_name': user.first_name},
            code=code,
            active=True,
            amount=self.amount,
            percentage=self.percentage,
            automatic=False,
            allowedUses=1,
            minOrder=self.minOrder,
            startDate=today,
            endDate=today + timedelta(days=self.daysValid),
            shipping=self.shipping,
            allValid=self.allValid)
        discount.save()
        for product in self.valid_products.all():
            discount.valid_products.add(product)
        for category in self.valid_categories.all():
            discount.valid_categories.add(category)
        discount.save()
        discount_amount = None
        if self.amount is not None:
            discount_amount = moneyfmt(self.amount)
        else:
            discount_amount = "%s%%" % self.percentage
        send_store_mail(
            subject=_(u"A discount coupon for you"),
            context={
                'first_name': user.first_name,
                'invites_number': self.invites_target,
                'discount_amount': discount_amount,
                'coupon_code': discount.code,
                'end_date': discount.endDate},
            template='invites/mail/discount.txt',
            recipients_list=[user.email],
            template_html='invites/mail/discount.html')

        # create new InviterDiscount
        inviter_discount = InviterDiscount(
            user=user,
            coupon=discount,
            template=self)
        inviter_discount.save()
        return True
Example #29
0
    def amount(self, total):
        """Returns the discount amount"""

        amount = Decimal('0.0')
        if self.discount_type == DISCOUNT_AMOUNT:
            log.debug('Discounting a fixed amount: %s' %
                      moneyfmt(self.discount))
            amount = self.discount
        elif self.discount_type == DISCOUNT_PERCENT:
            log.debug('Discounting by a percent of order total: %s' %
                      self.discount)
            amount = total * self.discount / Decimal('100.0')

        return amount
Example #30
0
    def capture_payment(self, testing=False, order=None, amount=NOTSET):
        """
        Process the transaction and return a ProcessorResponse
        """
        if not order:
            order = self.order

        if amount == NOTSET:
            amount = order.balance

        payment = None

        valid_gc = False
        if self.order.paid_in_full:
            success = True
            reason_code = "0"
            response_text = _("No balance to pay")
            self.record_payment()

        else:
            try:
                gc = GiftCertificate.objects.from_order(self.order)
                valid_gc = gc.valid

            except GiftCertificate.DoesNotExist:
                success = False
                reason_code = "1"
                response_text = _("No such Gift Certificate")

            if not valid_gc:
                success = False
                reason_code = "2"
                response_text = _("Bad Gift Certificate")

            else:
                gc.apply_to_order(self.order)
                payment = gc.payment
                reason_code = "0"
                response_text = _("Success")
                success = True

                if not self.order.paid_in_full:
                    response_text = _(
                        "%s balance remains after gift certificate was applied"
                    ) % moneyfmt(self.order.balance)

        return ProcessorResult(self.key,
                               success,
                               response_text,
                               payment=payment)
Example #31
0
def option_price(option_item):
    """
    Returns the price as (+$1.00)
    or (-$1.00) depending on the sign of the price change
    The currency symbol is set in the settings.py file
    """
    output = ""
    if option_item.price_change != 0:
        amount = moneyfmt(abs(option_item.price_change))
    if option_item.price_change < 0:
        output = "(- %s)" % amount
    if option_item.price_change > 0:
        output = "(+ %s)" % amount
    return output
Example #32
0
    def _activate(self, user):
        today = datetime.utcnow().date()
        code = "%x%x%x%x%x" % uuid1().fields[0:5]
        discount = Discount(
            site=self.site,
            description=_(u"Invite discount "
                          u"for %(last_name)s %(first_name)s") % {
                              'last_name': user.last_name,
                              'first_name': user.first_name
                          },
            code=code,
            active=True,
            amount=self.amount,
            percentage=self.percentage,
            automatic=False,
            allowedUses=1,
            minOrder=self.minOrder,
            startDate=today,
            endDate=today + timedelta(days=self.daysValid),
            shipping=self.shipping,
            allValid=self.allValid)
        discount.save()
        for product in self.valid_products.all():
            discount.valid_products.add(product)
        for category in self.valid_categories.all():
            discount.valid_categories.add(category)
        discount.save()
        discount_amount = None
        if self.amount is not None:
            discount_amount = moneyfmt(self.amount)
        else:
            discount_amount = "%s%%" % self.percentage
        send_store_mail(subject=_(u"A discount coupon for you"),
                        context={
                            'first_name': user.first_name,
                            'invites_number': self.invites_target,
                            'discount_amount': discount_amount,
                            'coupon_code': discount.code,
                            'end_date': discount.endDate
                        },
                        template='invites/mail/discount.txt',
                        recipients_list=[user.email],
                        template_html='invites/mail/discount.html')

        # create new InviterDiscount
        inviter_discount = InviterDiscount(user=user,
                                           coupon=discount,
                                           template=self)
        inviter_discount.save()
        return True
Example #33
0
def option_price(option_item):
    """
    Returns the price as (+$1.00)
    or (-$1.00) depending on the sign of the price change
    The currency symbol is set in the settings.py file
    """
    output = ""
    if option_item.price_change != 0:
        amount = moneyfmt(abs(option_item.price_change))
    if option_item.price_change < 0:
        output = "(- %s)" % amount
    if option_item.price_change > 0:
        output = "(+ %s)" % amount
    return output
Example #34
0
def set_quantity(request):
    """Set the quantity for a cart item.

    Intended to be called via the cart itself, returning to the cart after done.
    """
    cart_url = urlresolvers.reverse('satchmo_cart')

    if not request.POST:
        return HttpResponseRedirect(cart_url)

    success, cart, cartitem, errors = _set_quantity(request)

    if request.is_ajax():
        if errors:
            return _json_response({
                'errors': errors,
                'results': _("Error")
            }, True)
        else:
            return _json_response({
                'item_id':
                cartitem.id,
                'item_qty':
                str(cartitem.quantity) or "0",
                'item_price':
                unicode(moneyfmt(cartitem.line_total)) or "0.00",
                'cart_total':
                unicode(moneyfmt(cart.total)) or "0.00",
                'cart_count':
                str(cart.numItems) or '0',
            })

    else:
        if success:
            return HttpResponseRedirect(cart_url)
        else:
            return display(request, cart=cart, error_message=errors)
Example #35
0
def product_shipping(product, args=''):
    if not args:
        raise template.TemplateSyntaxError(
            'product_shipping needs the name of the carrier, as product|productshipping:"carrier"'
        )

    try:
        c = Carrier.objects.get(key=args)
    except Carrier.DoesNotExist:
        raise template.TemplateSyntaxError(
            'product_shipping needs the name of a valid carrier, could not find carrier "%s"'
            % args)
    shipping = c.price(product)

    return mark_safe(moneyfmt(shipping))
Example #36
0
def tiered_shipping(price, args=''):
    if not args:
        raise template.TemplateSyntaxError(
            'tiered_shipping needs the name of the carrier, as value|tiered_shipping:"carrier"'
        )

    try:
        c = Carrier.objects.get(key=args)
    except Carrier.DoesNotExist:
        raise template.TemplateSyntaxError(
            'tiered_shipping needs the name of a valid carrier, could not find carrier "%s"'
            % args)
    shipping = c.price(Decimal(price))

    return mark_safe(moneyfmt(shipping))
Example #37
0
    def render(self, context):
        taxer = _get_taxprocessor(context['request'])
        try:
            cart = template.resolve_variable(self.cart, context)
        except template.VariableDoesNotExist:
            raise template.TemplateSyntaxError("No such variable: %s",
                                               self.cart)

        total = Decimal('0.00')
        for item in cart:
            total += item.line_total + taxer.by_product_and_price(
                item.product.taxClass, item.line_total, product=item.product)
        if self.currency:
            return moneyfmt(total)

        return total
Example #38
0
def _get_shipping_choices(request, paymentmodule, cart, contact, default_view_tax=False):
    """Iterate through legal shipping modules, building the list for display to the user.
    
    Returns the shipping choices list, along with a dictionary of shipping choices, useful
    for building javascript that operates on shipping choices.
    """
    shipping_options = []
    shipping_dict = {}
    
    if not cart.is_shippable:
        methods = [shipping_method_by_key('NoShipping'),]
    else:
        methods = shipping_methods()
    
    for method in methods:
        method.calculate(cart, contact)
        if method.valid():
            template = lookup_template(paymentmodule, 'shipping/options.html')
            t = loader.get_template(template)
            shipcost = method.cost()
            shipping_tax = None
            taxed_shipping_price = None
            if config_value_safe('TAX','TAX_SHIPPING', False):
                shipping_tax = TaxClass.objects.get(title=config_value('TAX', 'TAX_CLASS'))
                taxer = _get_taxprocessor(request)
                total = shipcost + taxer.by_price(shipping_tax, shipcost)
                taxed_shipping_price = moneyfmt(total)
            c = RequestContext(request, {
                'amount': shipcost,
                'description' : method.description(),
                'method' : method.method(),
                'expected_delivery' : method.expectedDelivery(),
                'default_view_tax' : default_view_tax,
                'shipping_tax': shipping_tax,
                'taxed_shipping_price': taxed_shipping_price})
            shipping_options.append((method.id, t.render(c)))
            shipping_dict[method.id] = shipcost
    
    return shipping_options, shipping_dict
Example #39
0
    def do(self):
        """
        Send out daily authorize.net payments to John
        """
        start_of_day_time = datetime.time(0, 0)
        start_of_today = datetime.datetime.combine(datetime.date.today(), start_of_day_time)
        today_cutoff_time = start_of_today + datetime.timedelta(hours=15, minutes=45)
        yesterday_cutoff_time = today_cutoff_time - datetime.timedelta(hours=23, minutes=59, seconds=59)
        payments = OrderPayment.objects.filter(time_stamp__gte=yesterday_cutoff_time, time_stamp__lt=today_cutoff_time)
        checkins = OrderCheckin.objects.filter(timestamp__gte=yesterday_cutoff_time, timestamp__lt=today_cutoff_time)
        todays_total_payments = 0
        for payment in payments:
            todays_total_payments += payment.amount
        for checkin in checkins:
            todays_total_payments += checkin.gross_amount()

        if todays_total_payments > 0:
            todays_total_payments = moneyfmt(todays_total_payments)
            send_mail('Sales total for today: %s' % todays_total_payments,
                'http://%s%s' % (django_settings.SITE_DOMAIN, reverse('checkin_reports')),
                django_settings.DEFAULT_FROM_EMAIL, ['*****@*****.**', ] if django_settings.IS_PROD else ['*****@*****.**'],
                connection=django.core.mail.get_connection(backend='django.core.mail.backends.smtp.EmailBackend')
            )
Example #40
0
def remove(request):
    """Remove an item from the cart."""
    if not request.POST:
        # Should be a POST request
        return bad_or_missing(request, "Please use a POST request")

    success, cart, cartitem, errors = _set_quantity(request, force_delete=True)

    if request.is_ajax():
        if errors:
            return _json_response({'errors': errors, 'results': _("Error")}, True)
        else:
            return _json_response({
                'cart_total': unicode(moneyfmt(cart.total)),
                'cart_count': str(cart.numItems),
                'item_id': cartitem.id,
                'results': success, # Legacy
            })
    else:
        if errors:
            return display(request, cart=cart, error_message=errors)
        else:
            url = urlresolvers.reverse('satchmo_cart')
            return HttpResponseRedirect(url)
Example #41
0
def remove(request):
    """Remove an item from the cart."""
    if not request.POST:
        # Should be a POST request
        return bad_or_missing(request, "Please use a POST request")

    success, cart, cartitem, errors = _set_quantity(request, force_delete=True)

    if request.is_ajax():
        if errors:
            return _json_response({'errors': errors, 'results': _("Error")}, True)
        else:
            return _json_response({
                'cart_total': six.text_type(moneyfmt(cart.total)),
                'cart_count': str(cart.numItems),
                'item_id': cartitem.id,
                'results': success, # Legacy
            })
    else:
        if errors:
            return display(request, cart=cart, error_message=errors)
        else:
            url = reverse('satchmo_cart')
            return HttpResponseRedirect(url)
Example #42
0
    def render(self, context):

        try:
            show_tax = self.show_tax.resolve(context)
        except template.VariableDoesNotExist:
            show_tax = self.raw_tax

        if show_tax:
            tag = CartTaxedTotalNode(self.raw_cart, self.raw_currency)
            return tag.render(context)

        try:
            cart = self.cart.resolve(context)
        except template.VariableDoesNotExist:
            log.warn('Could not resolve template variable: %s', self.cart)
            return ''

        try:
            show_currency = self.show_currency.resolve(context)
        except template.VariableDoesNotExist:
            show_currency = self.raw_currency

        try:
            show_discount = self.show_discount.resolve(context)
        except template.VariableDoesNotExist:
            show_discount = self.raw_show_discount

        if show_discount:
            total = cart.total_undiscounted
        else:
            total = cart.total

        if show_currency:
            return moneyfmt(cart.total)
        else:
            return cart.total
Example #43
0
    def render(self, context):

        try:
            show_tax = self.show_tax.resolve(context)
        except template.VariableDoesNotExist:
            show_tax = self.raw_tax

        if show_tax:
            tag = CartTaxedTotalNode(self.raw_cart, self.raw_currency)
            return tag.render(context)

        try:
            cart = self.cart.resolve(context)
        except template.VariableDoesNotExist:
            log.warn('Could not resolve template variable: %s', self.cart)
            return ''

        try:
            show_currency = self.show_currency.resolve(context)
        except template.VariableDoesNotExist:
            show_currency = self.raw_currency

        try:
            show_discount = self.show_discount.resolve(context)
        except template.VariableDoesNotExist:
            show_discount = self.raw_show_discount

        if show_discount:
            total = cart.total_undiscounted
        else:
            total = cart.total

        if show_currency:
            return moneyfmt(cart.total)
        else:
            return cart.total
Example #44
0
def add(request, id=0, redirect_to='satchmo_cart'):
    """Add an item to the cart."""
    log.debug('FORM: %s', request.POST)
    formdata = request.POST.copy()
    productslug = None

    cartplaces = config_value('SHOP', 'CART_PRECISION')
    roundfactor = config_value('SHOP', 'CART_ROUNDING')

    if 'productname' in formdata:
        productslug = formdata['productname']
    try:
        product, details = product_from_post(productslug, formdata)

        if not (product and product.active):
            log.debug("product %s is not active" % productslug)
            return bad_or_missing(request, _("That product is not available at the moment."))
        else:
            log.debug("product %s is active" % productslug)

    except (Product.DoesNotExist, MultiValueDictKeyError):
        log.debug("Could not find product: %s", productslug)
        return bad_or_missing(request, _('The product you have requested does not exist.'))

    # First we validate that the number isn't too big.
    if decimal_too_big(formdata['quantity']):
        return _product_error(request, product, _("Please enter a smaller number."))

    # Then we validate that we can round it appropriately.
    try:
        quantity = round_decimal(formdata['quantity'], places=cartplaces, roundfactor=roundfactor)
    except RoundedDecimalError:
        return _product_error(request, product,
            _("Invalid quantity."))

    if quantity <= Decimal('0'):
        return _product_error(request, product,
            _("Please enter a positive number."))

    cart = Cart.objects.from_request(request, create=True)
    # send a signal so that listeners can update product details before we add it to the cart.
    satchmo_cart_details_query.send(
            cart,
            product=product,
            quantity=quantity,
            details=details,
            request=request,
            form=formdata
            )
    try:
        added_item = cart.add_item(product, number_added=quantity, details=details)

    except CartAddProhibited as cap:
        return _product_error(request, product, cap.message)

    # got to here with no error, now send a signal so that listeners can also operate on this form.
    satchmo_cart_add_complete.send(cart, cart=cart, cartitem=added_item, product=product, request=request, form=formdata)
    satchmo_cart_changed.send(cart, cart=cart, request=request)

    if request.is_ajax():
        data = {
            'id': product.id,
            'name': product.translated_name(),
            'item_id': added_item.id,
            'item_qty': str(round_decimal(quantity, 2)),
            'item_price': six.text_type(moneyfmt(added_item.line_total)) or "0.00",
            'cart_count': str(round_decimal(cart.numItems, 2)),
            'cart_total': six.text_type(moneyfmt(cart.total)),
            # Legacy result, for now
            'results': _("Success"),
        }
        log.debug('CART AJAX: %s', data)

        return _json_response(data)
    else:
        url = reverse(redirect_to)
        return HttpResponseRedirect(url)
Example #45
0
def productvariation_details(product, include_tax, user, create=False):
    """Build the product variation details, for conversion to javascript.

    Returns variation detail dictionary built like so:
    details = {
        "OPTION_KEY" : {
            "SLUG": "Variation Slug",
            "PRICE" : {"qty" : "$price", [...]},
            "SALE" : {"qty" : "$price", [...]},
            "TAXED" : "$taxed price",   # omitted if no taxed price requested
            "QTY" : 1
        },
        [...]
    }
    """

    ignore_stock = config_value('PRODUCT', 'NO_STOCK_CHECKOUT')
    discount = find_best_auto_discount(product)
    use_discount = discount and discount.percentage > 0

    if include_tax:
        from tax.utils import get_tax_processor
        taxer = get_tax_processor(user=user)
        tax_class = product.taxClass

    details = {'SALE': use_discount}

    variations = ProductPriceLookup.objects.filter(
        parentid=product.id).order_by("-price")
    if variations.count() == 0:
        if create:
            log.debug('Creating price lookup for %s', product)
            ProductPriceLookup.objects.smart_create_for_product(product)
            variations = ProductPriceLookup.objects.filter(
                parentid=product.id).order_by("-price")
        else:
            log.warning(
                'You must run satchmo_rebuild_pricing and add it to a cron-job to run every day, or else the product details will not work for product detail pages.'
            )
    for detl in variations:
        key = detl.key
        if details.has_key(key):
            detail = details[key]
            qty = detl.quantity
        else:
            detail = {}
            detail['SLUG'] = detl.productslug

            if not detl.active:
                qty = round_decimal('-1.0')
            elif ignore_stock:
                qty = round_decimal('10000.0')
            else:
                qty = round_decimal(detl.items_in_stock)

            detail['QTY'] = round_decimal(qty)

            detail['PRICE'] = {}

            if use_discount:
                detail['SALE'] = {}

            if include_tax:
                detail['TAXED'] = {}
                if use_discount:
                    detail['TAXED_SALE'] = {}

            if detl.productimage_set:
                detail['ADDITIONAL_IMAGES'] = [
                    u"%s" % prodimg.picture
                    for prodimg in detl.productimage_set.all()
                ]

            details[key] = detail

        qtykey = "%d" % detl.quantity

        price = detl.dynamic_price

        detail['PRICE'][qtykey] = moneyfmt(price)
        if use_discount:
            detail['SALE'][qtykey] = moneyfmt(
                calc_discounted_by_percentage(price, discount.percentage))

        if include_tax:
            tax_price = taxer.by_price(tax_class, price) + price
            detail['TAXED'][qtykey] = moneyfmt(tax_price)
            if use_discount:
                detail['TAXED_SALE'][qtykey] = moneyfmt(
                    calc_discounted_by_percentage(tax_price,
                                                  discount.percentage))

    return details
Example #46
0
 def __str__(self):
     return "%s: %s=%s" % (_('Price Adjustment'), self.label,
                           moneyfmt(self.amount))
Example #47
0
    def test_custom_product(self):
        """
        Verify that the custom product is working as expected.
        """
        response = self.client.get(prefix + "/")
        self.assertContains(response, "Computer", count=1)
        response = self.client.get(prefix + "/product/satchmo-computer/")
        self.assertContains(response, "Memory", count=1)
        self.assertContains(response, "Case", count=1)
        self.assertContains(response, "Monogram", count=1)
        response = self.client.post(
            prefix + '/cart/add/', {
                "productname": "satchmo-computer",
                "5": "1.5gb",
                "6": "mid",
                "custom_monogram": "CBM",
                "quantity": '1'
            })
        self.assertRedirects(response,
                             prefix + '/cart/',
                             status_code=302,
                             target_status_code=200)
        response = self.client.get(prefix + '/cart/')
        self.assertContains(response,
                            '/satchmo-computer/">satchmo computer',
                            count=1,
                            status_code=200)
        amount = smart_str(moneyfmt(Decimal('168.00')))
        self.assertContains(response, amount, count=4)

        amount = smart_str('Monogram: CBM  ' + moneyfmt(Decimal('10.00')))
        self.assertContains(response, amount, count=1)

        amount = smart_str('Case - External Case: Mid  ' +
                           moneyfmt(Decimal('10.00')))
        self.assertContains(response, amount, count=1)

        amount = smart_str('Memory - Internal RAM: 1.5 GB  ' +
                           moneyfmt(Decimal('25.00')))
        self.assertContains(response, amount, count=1)

        response = self.client.post(reverse('satchmo_checkout-step1'),
                                    get_step1_post_data(self.US))
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-step2'),
                             status_code=302,
                             target_status_code=200)
        data = {
            'credit_type': 'Visa',
            'credit_number': '4485079141095836',
            'month_expires': '1',
            'year_expires': '2020',
            'ccv': '552',
            'shipping': 'FlatRate'
        }
        response = self.client.post(reverse('DUMMY_satchmo_checkout-step2'),
                                    data)
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-step3'),
                             status_code=302,
                             target_status_code=200)
        response = self.client.get(reverse('DUMMY_satchmo_checkout-step3'))

        amount = smart_str('satchmo computer - ' + moneyfmt(Decimal('168.00')))
        self.assertContains(response, amount, count=1, status_code=200)
        response = self.client.post(reverse('DUMMY_satchmo_checkout-step3'),
                                    {'process': 'True'})
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-success'),
                             status_code=302,
                             target_status_code=200)
        self.assertEqual(len(mail.outbox), 1)
Example #48
0
def _get_shipping_choices(request,
                          paymentmodule,
                          cart,
                          contact,
                          default_view_tax=False,
                          order=None):
    """Iterate through legal shipping modules, building the list for display to the user.

    Returns the shipping choices list, along with a dictionary of shipping choices, useful
    for building javascript that operates on shipping choices.
    """
    shipping_options = []
    shipping_dict = {}
    rendered = {}
    if not order:
        try:
            order = Order.objects.from_request(request)
        except Order.DoesNotExist:
            pass

    discount = None
    if order:
        try:
            discount = Discount.objects.by_code(order.discount_code)
        except Discount.DoesNotExist:
            pass

    if not cart.is_shippable:
        methods = [
            shipping_method_by_key('NoShipping'),
        ]
    else:
        methods = shipping_methods()

    tax_shipping = config_value_safe('TAX', 'TAX_SHIPPING', False)
    shipping_tax = None

    if tax_shipping:
        taxer = _get_taxprocessor(request)
        shipping_tax = TaxClass.objects.get(
            title=config_value('TAX', 'TAX_CLASS'))

    for method in methods:
        method.calculate(cart, contact)
        if method.valid(order=order):
            template = lookup_template(paymentmodule, 'shipping/options.html')
            t = loader.get_template(template)
            shipcost = finalcost = method.cost()

            if discount and order:
                order.shipping_cost = shipcost
                discount.calc(order)
                shipdiscount = discount.item_discounts.get('Shipping', 0)
            else:
                shipdiscount = 0

            # set up query to determine shipping price to show
            shipprice = Price()
            shipprice.price = shipcost
            shipadjust = PriceAdjustmentCalc(shipprice)
            if shipdiscount:
                shipadjust += PriceAdjustment('discount', _('Discount'),
                                              shipdiscount)

            satchmo_shipping_price_query.send(cart, adjustment=shipadjust)
            shipdiscount = shipadjust.total_adjustment()

            if shipdiscount:
                finalcost -= shipdiscount

            shipping_dict[method.id] = {
                'cost': shipcost,
                'discount': shipdiscount,
                'final': finalcost
            }

            taxed_shipping_price = None
            if tax_shipping:
                taxcost = taxer.by_price(shipping_tax, finalcost)
                total = finalcost + taxcost
                taxed_shipping_price = moneyfmt(total)
                shipping_dict[method.id]['taxedcost'] = total
                shipping_dict[method.id]['tax'] = taxcost

            c = RequestContext(
                request, {
                    'amount': finalcost,
                    'description': method.description(),
                    'method': method.method(),
                    'expected_delivery': method.expectedDelivery(),
                    'default_view_tax': default_view_tax,
                    'shipping_tax': shipping_tax,
                    'taxed_shipping_price': taxed_shipping_price
                })
            rendered[method.id] = t.render(c)

    #now sort by price, low to high
    sortme = [(value['cost'], key) for key, value in shipping_dict.items()]
    sortme.sort()

    shipping_options = [(key, rendered[key]) for cost, key in sortme]

    shipping_choices_query.send(sender=cart,
                                cart=cart,
                                paymentmodule=paymentmodule,
                                contact=contact,
                                default_view_tax=default_view_tax,
                                order=order,
                                shipping_options=shipping_options,
                                shipping_dict=shipping_dict)
    return shipping_options, shipping_dict
Example #49
0
 def formatted_price(self, obj):
     """Format the price in the list_display so that the currency symbol shows
     """
     return moneyfmt(obj.unit_price)
Example #50
0
 def __unicode__(self):
     sb = moneyfmt(self.start_balance)
     b = moneyfmt(self.balance)
     return u"Gift Cert: %s/%s" % (sb, b)
Example #51
0
 def __str__(self):
     sb = moneyfmt(self.start_balance)
     b = moneyfmt(self.balance)
     return "Gift Cert: %s/%s" % (sb, b)
Example #52
0
 def cart_min_currency(self, instance):
     return moneyfmt(instance.cart_minimum)
Example #53
0
        added_item = cart.add_item(product, number_added=quantity, details=details)

    except CartAddProhibited, cap:
        return _product_error(request, product, cap.message)

    # got to here with no error, now send a signal so that listeners can also operate on this form.
    satchmo_cart_add_complete.send(cart, cart=cart, cartitem=added_item, product=product, request=request, form=formdata)
    satchmo_cart_changed.send(cart, cart=cart, request=request)

    if request.is_ajax():
        data = {
            'id': product.id,
            'name': product.translated_name(),
            'item_id': added_item.id,
            'item_qty': str(round_decimal(quantity, 2)),
            'item_price': unicode(moneyfmt(added_item.line_total)) or "0.00",
            'cart_count': str(round_decimal(cart.numItems, 2)),
            'cart_total': unicode(moneyfmt(cart.total)),
            # Legacy result, for now
            'results': _("Success"),
        }
        log.debug('CART AJAX: %s', data)

        return _json_response(data)
    else:
        url = urlresolvers.reverse(redirect_to)
        return HttpResponseRedirect(url)

def add_ajax(request, id=0, **kwargs):
    # Allow for legacy apps to still use this url
    if not request.META.has_key('HTTP_X_REQUESTED_WITH'):
Example #54
0
    def test_checkout(self):
        """
        Run through a full checkout process
        """
        cache_delete()
        tax = config_get('TAX', 'MODULE')
        tax.update('tax.modules.percent')
        pcnt = config_get('TAX', 'PERCENT')
        pcnt.update('10')
        shp = config_get('TAX', 'TAX_SHIPPING_PERCENT')
        shp.update(False)

        self.test_cart_adding()
        response = self.client.post(reverse('satchmo_checkout-step1'),
                                    get_step1_post_data(self.US))
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-step2'),
                             status_code=302,
                             target_status_code=200)
        data = {
            'credit_type': 'Visa',
            'credit_number': '4485079141095836',
            'month_expires': '1',
            'year_expires': '2020',
            'ccv': '552',
            'shipping': 'FlatRate'
        }
        response = self.client.post(reverse('DUMMY_satchmo_checkout-step2'),
                                    data)
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-step3'),
                             status_code=302,
                             target_status_code=200)
        response = self.client.get(reverse('DUMMY_satchmo_checkout-step3'))
        amount = smart_str('Shipping + ' + moneyfmt(Decimal('4.00')))
        self.assertContains(response, amount, count=1, status_code=200)

        amount = smart_str('Tax + ' + moneyfmt(Decimal('4.60')))
        self.assertContains(response, amount, count=1, status_code=200)

        amount = smart_str('Total = ' + moneyfmt(Decimal('54.60')))
        self.assertContains(response, amount, count=1, status_code=200)

        response = self.client.post(reverse('DUMMY_satchmo_checkout-step3'),
                                    {'process': 'True'})
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-success'),
                             status_code=302,
                             target_status_code=200)
        self.assertEqual(len(mail.outbox), 1)

        # Log in as a superuser
        user = User.objects.create_user('fredsu', '*****@*****.**', 'passwd')
        user.is_staff = True
        user.is_superuser = True
        user.save()
        self.client.login(username='******', password='******')

        # Test invoice, packing slip and shipping label generation
        order_id = Order.objects.all()[0].id
        response = self.client.get('/admin/print/invoice/%d/' % order_id)
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/admin/print/packingslip/%d/' % order_id)
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/admin/print/shippinglabel/%d/' % order_id)
        self.assertEqual(response.status_code, 200)
Example #55
0
    def capture_payment(self, request, testing=False, order=None, amount=None):
        """
        Process the transaction and return a ProcessorResponse
        """

        if not order:
            order = self.order

        if amount is None:
            amount = order.balance

        payment = None

        points = int(request.POST.get('points', None))

        if self.order.paid_in_full:
            success = True
            reason_code = "0"
            response_text = _("No balance to pay")
            self.record_payment()

        else:
            #contact = Contact.objects.from_request(request)
            if points:
                reward, created = Reward.objects.get_or_create(
                    contact=order.contact)

                if points > reward.points:
                    success = False
                    reason_code = "0"
                    response_text = _(
                        "You Do not have that many reward points.")
                    return ProcessorResult(self.key,
                                           success,
                                           response_text,
                                           payment=payment)

                point_modifier = config_value('PAYMENT_REWARD', 'POINTS_VALUE')
                point_value = point_modifier * points

                if point_value > order.balance:
                    success = False
                    reason_code = "0"
                    response_text = _(
                        "You are trying to use too many points for this order."
                    )
                    return ProcessorResult(self.key,
                                           success,
                                           response_text,
                                           payment=payment)
                else:
                    points_used = points
                    point_value_used = point_value

                    orderpayment = self.record_payment(order=order,
                                                       amount=point_value_used)
                    reward_item = RewardItem.objects.add_order_payment(
                        reward, order, orderpayment, points_used,
                        point_value_used)

                    reason_code = "0"
                    response_text = _("Success")
                    success = True

                if not self.order.paid_in_full:
                    url = reverse('satchmo_balance_remaining')
                    response_text = _("%s balance remains after using points"
                                      ) % moneyfmt(self.order.balance)
            else:
                success = False
                reason_code = "0"
                response_text = _(
                    "Please enter the amount of reward points you want to redeem"
                )

        return ProcessorResult(self.key,
                               success,
                               response_text,
                               payment=payment)
Example #56
0
    def test_two_checkouts_dont_duplicate_contact(self):
        """
        Two checkouts with the same email address do not duplicate contacts
        Ticket #1264 [Invalid]
        """

        tax = config_get('TAX', 'MODULE')
        tax.update('tax.modules.percent')
        pcnt = config_get('TAX', 'PERCENT')
        pcnt.update('10')
        shp = config_get('TAX', 'TAX_SHIPPING_PERCENT')
        shp.update(False)

        # First checkout
        self.test_cart_adding()
        response = self.client.post(reverse('satchmo_checkout-step1'),
                                    get_step1_post_data(self.US))
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-step2'),
                             status_code=302,
                             target_status_code=200)
        data = {
            'credit_type': 'Visa',
            'credit_number': '4485079141095836',
            'month_expires': '1',
            'year_expires': '2020',
            'ccv': '552',
            'shipping': 'FlatRate'
        }
        response = self.client.post(reverse('DUMMY_satchmo_checkout-step2'),
                                    data)
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-step3'),
                             status_code=302,
                             target_status_code=200)
        response = self.client.get(reverse('DUMMY_satchmo_checkout-step3'))
        amount = smart_str('Shipping + ' + moneyfmt(Decimal('4.00')))
        self.assertContains(response, amount, count=1, status_code=200)

        amount = smart_str('Tax + ' + moneyfmt(Decimal('4.60')))
        self.assertContains(response, amount, count=1, status_code=200)

        amount = smart_str('Total = ' + moneyfmt(Decimal('54.60')))
        self.assertContains(response, amount, count=1, status_code=200)

        response = self.client.post(reverse('DUMMY_satchmo_checkout-step3'),
                                    {'process': 'True'})
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-success'),
                             status_code=302,
                             target_status_code=200)

        # Second checkout
        self.test_cart_adding()
        response = self.client.post(reverse('satchmo_checkout-step1'),
                                    get_step1_post_data(self.US))
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-step2'),
                             status_code=302,
                             target_status_code=200)
        data = {
            'credit_type': 'Visa',
            'credit_number': '4485079141095836',
            'month_expires': '1',
            'year_expires': '2020',
            'ccv': '552',
            'shipping': 'FlatRate'
        }
        response = self.client.post(reverse('DUMMY_satchmo_checkout-step2'),
                                    data)
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-step3'),
                             status_code=302,
                             target_status_code=200)
        response = self.client.get(reverse('DUMMY_satchmo_checkout-step3'))
        amount = smart_str('Shipping + ' + moneyfmt(Decimal('4.00')))
        self.assertContains(response, amount, count=1, status_code=200)

        amount = smart_str('Tax + ' + moneyfmt(Decimal('4.60')))
        self.assertContains(response, amount, count=1, status_code=200)

        amount = smart_str('Total = ' + moneyfmt(Decimal('54.60')))
        self.assertContains(response, amount, count=1, status_code=200)

        response = self.client.post(reverse('DUMMY_satchmo_checkout-step3'),
                                    {'process': 'True'})
        self.assertRedirects(response,
                             reverse('DUMMY_satchmo_checkout-success'),
                             status_code=302,
                             target_status_code=200)

        self.assertEqual(len(mail.outbox), 2)

        qs = Contact.objects.filter(email="*****@*****.**")
        # We expects that the contact do not duplicate
        self.assertEqual(len(qs), 1)
Example #57
0
 def __unicode__(self):
     return u"%s: %s=%s" % (_('Price Adjustment'), self.label,
                            moneyfmt(self.amount))
Example #58
0
 def order_link(self):
     return mark_safe(u'<a href="/admin/shop/order/%i/">%s #%i (%s)</a>' %
                      (self.order.id, ugettext('Order'), self.order.id,
                       moneyfmt(self.order.total)))