def get_price(request, product_slug): """Get base price for a product, returning the answer encoded as JSON.""" quantity = 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 'quantity' in request.POST: quantity = int(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 = money_format(pvp.get_qty_price(quantity)) else: price = money_format(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")
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]', money_format(amount), self.id, money_format(self.balance), order.id, money_format(order.balance)) config = config_get_group('PAYMENT_GIFTCERTIFICATE') orderpayment = record_payment(order, config, amount) return self.use(amount, orderpayment=orderpayment)
def get_price_detail(request, product_slug): """Get all price details for a product, returning the response encoded as JSON.""" results = { "success": False, "message": _("not available") } price = None if request.method == "POST": reqdata = request.POST else: reqdata = request.GET try: product = Product.objects.get_by_site(active=True, slug=product_slug) found = True if 'quantity' in reqdata: quantity = int(reqdata['quantity']) else: quantity = 1 if 'ConfigurableProduct' in product.get_subtypes(): cp = product.configurableproduct chosen_options = optionids_from_post(cp, reqdata) product = cp.get_product_from_options(chosen_options) if product: price = product.get_qty_price(quantity) base_tax = get_tax(request.user, product, quantity) price_with_tax = price + base_tax results['slug'] = product.slug results['currency_price'] = money_format(price) results['price'] = float(price) results['tax'] = float(base_tax) results['currency_tax'] = money_format(base_tax) results['currency_price_with_tax'] = money_format(price_with_tax) results['price_with_tax'] = float(price_with_tax) results['success'] = True results['message'] = "" except Product.DoesNotExist: found = False data = json_encode(results) if found: return http.HttpResponse(data, mimetype="text/javascript") else: return http.HttpResponseNotFound(data, mimetype="text/javascript")
def balance_due(self): if self.balance: b = self.balance else: b = Decimal('0.00') return money_format(b)
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 money_format(cartitem.line_total) else: return cartitem.line_total
def get_price_detail(request, product_slug): """Get all price details for a product, returning the response encoded as JSON.""" results = {"success": False, "message": _("not available")} price = None if request.method == "POST": reqdata = request.POST else: reqdata = request.GET try: product = Product.objects.get_by_site(active=True, slug=product_slug) found = True if 'quantity' in reqdata: quantity = int(reqdata['quantity']) else: quantity = 1 if 'ConfigurableProduct' in product.get_subtypes(): cp = product.configurableproduct chosen_options = optionids_from_post(cp, reqdata) product = cp.get_product_from_options(chosen_options) if product: price = product.get_qty_price(quantity) base_tax = get_tax(request.user, product, quantity) price_with_tax = price + base_tax results['slug'] = product.slug results['currency_price'] = money_format(price) results['price'] = float(price) results['tax'] = float(base_tax) results['currency_tax'] = money_format(base_tax) results['currency_price_with_tax'] = money_format(price_with_tax) results['price_with_tax'] = float(price_with_tax) results['success'] = True results['message'] = "" except Product.DoesNotExist: found = False data = json_encode(results) if found: return http.HttpResponse(data, mimetype="text/javascript") else: return http.HttpResponseNotFound(data, mimetype="text/javascript")
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() valid_methods = [] for method in methods: method.calculate(cart, contact) if method.valid(): valid_methods.append((method, method.cost())) # sort methods by cost valid_methods.sort(key=lambda method_cost: int(method_cost[1])) for method, shipcost in valid_methods: template = lookup_template(paymentmodule, 'shipping_options.html') t = loader.get_template(template) shipping_tax = None taxed_shipping_price = None if config_value('TAX', 'TAX_SHIPPING'): shipping_tax = config_value('TAX', 'TAX_CLASS') taxer = _get_taxprocessor(request) total = shipcost + taxer.by_price(shipping_tax, shipcost) taxed_shipping_price = money_format(total) data = { '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 } if hasattr(method, 'shipping_discount'): data['discount'] = method.shipping_discount() c = RequestContext(request, data) shipping_options.append((method.id, t.render(c))) shipping_dict[method.id] = shipcost return shipping_options, shipping_dict
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(money_format(shipping))
def currency(value): """Convert a value to a money formatted string. Usage: val|currency """ if value == '' or value is None: return value return mark_safe(money_format(value))
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 format is base upon locale """ if option_item.price_change: val = product.unit_price + option_item.price_change else: val = product.unit_price return money_format(val)
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 money_format(total) return total
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() valid_methods = [] for method in methods: method.calculate(cart, contact) if method.valid(): valid_methods.append((method, method.cost())) # sort methods by cost valid_methods.sort(key=lambda method_cost: int(method_cost[1])) for method, shipcost in valid_methods: template = lookup_template(paymentmodule, 'shipping_options.html') t = loader.get_template(template) shipping_tax = None taxed_shipping_price = None if config_value('TAX', 'TAX_SHIPPING'): shipping_tax = config_value('TAX', 'TAX_CLASS') taxer = _get_taxprocessor(request) total = shipcost + taxer.by_price(shipping_tax, shipcost) taxed_shipping_price = money_format(total) data = { '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 } if hasattr(method, 'shipping_discount'): data['discount'] = method.shipping_discount() c = RequestContext(request, data) shipping_options.append((method.id, t.render(c))) shipping_dict[method.id] = shipcost return shipping_options, shipping_dict
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 money_format(total) return total
def option_price(option_item): """ Returns the price as (+$1.00) or (-$1.00) depending on the sign of the price change The currency format is base upon locale """ output = "" if option_item.price_change != 0: amount = money_format(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
def _order_total(self): #Needed for the admin list display return money_format(self.total)
def force_recalculate_total(self, save=True): """Calculates sub_total, taxes and total.""" zero = Decimal("0.0000000000") # Find the discount code and calculate it discount = find_discount_for_code(self.discount_code) discount.calc(self) # Save the total discount in this Order's discount attribute self.discount = discount.total itemprices = [] fullprices = [] # Apply discounts to line item for lineitem in self.orderitem_set.all(): lid = lineitem.id if lid in discount.item_discounts: lineitem.discount = discount.item_discounts[lid] else: lineitem.discount = zero if save: lineitem.save() itemprices.append(lineitem.sub_total) fullprices.append(lineitem.line_item_price) if 'Shipping' in discount.item_discounts: self.shipping_discount = discount.item_discounts['Shipping'] else: self.shipping_discount = zero 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, money_format(item_sub_total), money_format(self.shipping_sub_total), money_format(self.discount), money_format(self.tax) ) self.total = Decimal(item_sub_total + self.shipping_sub_total + self.tax) if save: self.save()
def balance_forward(self): return money_format(self.balance)
def _amount_total(self): return money_format(self.amount)
def __unicode__(self): sb = money_format(self.start_balance) b = money_format(self.balance) return u"Gift Cert: %s/%s" % (sb, b)
def isValid(self, cart=None): """ Make sure this discount still has available uses and is in the current date range. If a cart has been populated, validate that it does apply to the products we have selected. """ if not self.active: return (False, ugettext('This coupon is disabled.')) if self.startDate > datetime.date.today(): return (False, ugettext('This coupon is not active yet.')) if self.endDate < datetime.date.today(): return (False, ugettext('This coupon has expired.')) if self.numUses > self.allowedUses: return (False, ugettext('This discount has exceeded the number of allowed uses.')) if not cart: return (True, ugettext('Valid.')) minOrder = self.minOrder or 0 if cart.total < minOrder: return (False, ugettext('This discount only applies to orders of at least %s.' % money_format(minOrder))) validItems = False validproducts = self._get_valid_product_dict() if validproducts: for cart_item in cart.cartitem_set.all(): if cart_item.product.id in validproducts: validItems = True break # Once we have 1 valid item, we exit else: validItems = True if validItems: return (True, ugettext('Valid.')) else: return (False, ugettext('This discount cannot be applied to the products in your cart.'))
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", [...]}, "TAXED" : "$taxed price", # omitted if no taxed price requested "QTY" : 1 }, [...] } """ config = Config.objects.get_current() ignore_stock = config.no_stock_checkout if include_tax: taxer = get_taxprocessor(user) tax_class = product.taxClass details = {} variations = ProductPriceLookup.objects.filter(parentid=product.id) 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) 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] else: detail = {} detail['SLUG'] = detl.productslug if not detl.active: qty = -1 elif ignore_stock: qty = 10000 else: qty = detl.items_in_stock detail['QTY'] = qty detail['PRICE'] = {} if include_tax: detail['TAXED'] = {} details[key] = detail price = detl.dynamic_price detail['PRICE'][detl.quantity] = money_format(price) if include_tax: tax_price = taxer.by_price(tax_class, price) + price detail['TAXED'][detl.quantity] = money_format(tax_price) return details
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, money_format(self.order.total)))
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, money_format(self.order.total)))
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", [...]}, "TAXED" : "$taxed price", # omitted if no taxed price requested "QTY" : 1 }, [...] } """ config = Config.objects.get_current() ignore_stock = config.no_stock_checkout if include_tax: taxer = get_taxprocessor(user) tax_class = product.taxClass details = {} variations = ProductPriceLookup.objects.filter(parentid=product.id) 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) 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] else: detail = {} detail['SLUG'] = detl.productslug if not detl.active: qty = -1 elif ignore_stock: qty = 10000 else: qty = detl.items_in_stock detail['QTY'] = qty detail['PRICE'] = {} if include_tax: detail['TAXED'] = {} details[key] = detail price = detl.dynamic_price detail['PRICE'][detl.quantity] = money_format(price) if include_tax: tax_price = taxer.by_price(tax_class, price) + price detail['TAXED'][detl.quantity] = money_format(tax_price) return details