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))
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()
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
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
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()
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()