Source code for shuup.core.basket.update_methods

# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2017, Shoop Commerce Ltd. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import unicode_literals

import six
from django.contrib import messages

from shuup.utils.numbers import parse_decimal_string


[docs]class BasketUpdateMethods(object): def __init__(self, request, basket): """ Initialize. :type request: django.http.HttpRequest :type basket: shuup.front.basket.objects.BaseBasket """ self.request = request self.basket = basket
[docs] def get_prefix_to_method_map(self): """Override this method to link prefixes with their associated methods to call. Format of the dictionary is: { FIELD_NAME_PREFIX: METHOD }. METHOD is a function which accepts the keyword arguments given in `update_basket_contents`. It should perform the necessary changes to the basket_line and then return whether the value had changed or not. (See `update_quantity` or `delete_line` for examples.) """ return { 'q_': self.update_quantity, 'dq_': self.update_display_quantity, 'delete_': self.delete_line, }
[docs] def delete_line(self, line, **kwargs): if line: return self.basket.delete_line(line["line_id"])
def _get_orderability_errors(self, product, supplier, delta): basket_quantities = self.basket.get_product_ids_and_quantities() product_basket_quantity = basket_quantities.get(product.id, 0) total_product_quantity = delta + product_basket_quantity shop_product = product.get_shop_instance(shop=self.request.shop) errors = list(shop_product.get_orderability_errors( supplier=supplier, customer=self.basket.customer, quantity=total_product_quantity )) if product.is_package_parent(): for child_product, child_quantity in six.iteritems(product.get_package_child_to_quantity_map()): child_basket_quantity = basket_quantities.get(child_product.id, 0) total_child_quantity = (delta * child_quantity) + child_basket_quantity shop_product = child_product.get_shop_instance(shop=self.request.shop) child_errors = list(shop_product.get_orderability_errors( supplier=supplier, customer=self.basket.customer, quantity=total_child_quantity )) errors.extend(child_errors) return errors
[docs] def update_display_quantity(self, line, value, **kwargs): if not line: return False new_display_quantity = parse_decimal_string(value) if new_display_quantity is None: return False basket_line = self.basket.get_basket_line(line['line_id']) if basket_line and basket_line.product: unit = basket_line.shop_product.unit new_quantity = unit.from_display(new_display_quantity) else: new_quantity = new_display_quantity return self._update_quantity(line, new_quantity)
[docs] def update_quantity(self, line, value, **kwargs): new_quantity = parse_decimal_string(value) if new_quantity is None: return False return self._update_quantity(line, new_quantity)
def _update_quantity(self, line, new_quantity): if not (line and line["quantity"] != new_quantity): return False changed = False # Ensure sub-lines also get changed accordingly linked_lines = [line] + list(self.basket.find_lines_by_parent_line_id(line["line_id"])) orderable_lines = { basket_line.line_id: basket_line for basket_line in self.basket.get_lines() } for linked_line in linked_lines: orderable_line = orderable_lines.get(linked_line["line_id"]) if not orderable_line: # Customer can change quantity in non-orderable lines regardless linked_line["quantity"] = new_quantity changed = True else: product = orderable_line.product supplier = orderable_line.supplier # Basket quantities already contain current quantities for orderable lines quantity_delta = new_quantity - line["quantity"] errors = self._get_orderability_errors(product, supplier, quantity_delta) if errors: for error in errors: error_texts = ", ".join(six.text_type(sub_error) for sub_error in error) message = u"%s: %s" % (linked_line.get("text") or linked_line.get("name"), error_texts) messages.warning(self.request, message) continue self.basket.update_line(linked_line, quantity=new_quantity) linked_line["quantity"] = new_quantity changed = True return changed