Exemple #1
0
 def test_basic(self):
     pcalc = PriceAdjustmentCalc(self.price)
     p = PriceAdjustment('test', amount=Decimal(1))
     pcalc += p
     pcalc += p
     p = PriceAdjustment('test2', amount=Decimal(10))
     pcalc += p
     self.assertEqual(pcalc.total_adjustment(), Decimal(12))
Exemple #2
0
 def test_basic(self):
     pcalc = PriceAdjustmentCalc(self.price)
     p = PriceAdjustment('test', amount=Decimal(1))
     pcalc += p
     pcalc += p
     p = PriceAdjustment('test2', amount=Decimal(10))
     pcalc += p
     self.assertEqual(pcalc.total_adjustment(), Decimal(12))
Exemple #3
0
 def _dynamic_price(self):
     """Get the current price as modified by all listeners."""
     adjust = PriceAdjustmentCalc(self)
     signals.satchmo_price_query.send(
         self,
         adjustment=adjust,
         slug=self.product.slug,
         discountable=self.product.is_discountable)
     return adjust.final_price()
Exemple #4
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():
            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
Exemple #5
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
Exemple #6
0
    def force_recalculate_total(self, save=True):
        """Calculates sub_total, taxes and total."""
        zero = Decimal("0.0000000000")
        total_discount = Decimal("0.0000000000")

        discount = Discount.objects.by_code(self.discount_code)
        discount.calc(self)

        discounts = discount.item_discounts
        itemprices = []
        fullprices = []

        qty_override = config_value('SHOP','CART_QTY')
        if qty_override:
            itemct = self.numItems

        for lineitem in self.orderitem_set.all():
            lid = lineitem.id
            if lid in discounts:
                lineitem.discount = discounts[lid]
                total_discount += lineitem.discount
                #log.debug('total_discount (calc): %s', total_discount)
            else:
                lineitem.discount = zero
            # now double check against other discounts, such as tiered discounts
            if qty_override:
                qty = itemct
            else:
                qty = lineitem.quantity

            adjustment = get_product_quantity_adjustments(lineitem.product, qty=qty)

            if adjustment and adjustment.price:
                baseprice = adjustment.price.price
                finalprice = adjustment.final_price()
                #We need to add in any OrderItemDetail price adjustments before we do anything else
                baseprice += lineitem.get_detail_price()
                finalprice += lineitem.get_detail_price()
                if baseprice > finalprice or baseprice != lineitem.unit_price:
                    unitdiscount = (lineitem.discount/lineitem.quantity) + baseprice-finalprice
                    unitdiscount = trunc_decimal(unitdiscount, 2)
                    linediscount = unitdiscount * lineitem.quantity
                    total_discount += linediscount
                    #log.debug('total_discount (line): %s', total_discount)
                    fullydiscounted = (baseprice - unitdiscount) * lineitem.quantity
                    lineitem.unit_price = baseprice
                    lineitem.discount = linediscount
                    lineitem.line_item_price = baseprice * lineitem.quantity
                    log.debug('Adjusting lineitem unit price for %s. Full price=%s, discount=%s.  Final price for qty %d is %s',
                        lineitem.product.slug, baseprice, unitdiscount, lineitem.quantity, fullydiscounted)
            if save:
                lineitem.save()

            itemprices.append(lineitem.sub_total)
            fullprices.append(lineitem.line_item_price)

        shipprice = Price()
        shipprice.price = self.shipping_cost
        shipadjust = PriceAdjustmentCalc(shipprice)
        if 'Shipping' in discounts:
            shipadjust += PriceAdjustment('discount', _('Discount'), discounts['Shipping'])

        signals.satchmo_shipping_price_query.send(self, adjustment=shipadjust)
        shipdiscount = shipadjust.total_adjustment()
        self.shipping_discount = shipdiscount
        total_discount += shipdiscount
        #log.debug('total_discount (+ship): %s', total_discount)

        self.discount = total_discount

        if itemprices:
            item_sub_total = reduce(operator.add, itemprices)
        else:
            item_sub_total = zero

        if fullprices:
            full_sub_total = reduce(operator.add, fullprices)
        else:
            full_sub_total = zero

        self.sub_total = full_sub_total

        taxProcessor = get_tax_processor(self)
        totaltax, taxrates = taxProcessor.process()
        self.tax = totaltax

        # clear old taxes
        for taxdetl in self.taxes.all():
            taxdetl.delete()

        for taxdesc, taxamt in taxrates.items():
            taxdetl = OrderTaxDetail(order=self, tax=taxamt, description=taxdesc, method=taxProcessor.method)
            taxdetl.save()

        log.debug("Order #%i, recalc: sub_total=%s, shipping=%s, discount=%s, tax=%s",
            self.id,
            moneyfmt(item_sub_total),
            moneyfmt(self.shipping_sub_total),
            moneyfmt(self.discount),
            moneyfmt(self.tax))

        self.total = Decimal(item_sub_total + self.shipping_sub_total + self.tax)

        if save:
            self.save()
Exemple #7
0
 def _dynamic_price(self):
     """Get the current price as modified by all listeners."""
     adjust = PriceAdjustmentCalc(self)
     signals.satchmo_price_query.send(self, adjustment=adjust,
         slug=self.product.slug, discountable=self.product.is_discountable)
     return adjust.final_price()