def raise_if_not_orderable(self, supplier, customer, quantity, ignore_minimum=False): for message in self.get_orderability_errors( supplier=supplier, quantity=quantity, customer=customer, ignore_minimum=ignore_minimum): raise ProductNotOrderableProblem(message.args[0])
def handle_add( # noqa (C901) request, basket, product_id, quantity=1, unit_type='internal', supplier_id=None, **kwargs): """ Handle adding a product to the basket. :param product_id: product ID to add (or if `child_product_id` is truey, the parent ID). :param quantity: quantity of products to add. :param child_product_id: child product ID to add (if truey). :param supplier_id: The supplier ID for the new line. If None, the first supplier is used. """ product_id = int(product_id) product = get_object_or_404(Product, pk=product_id) if product.mode in (ProductMode.SIMPLE_VARIATION_PARENT, ProductMode.VARIABLE_VARIATION_PARENT): raise ValidationError("Error! Invalid product.", code="invalid_product") try: shop_product = product.get_shop_instance(shop=request.shop) except ShopProduct.DoesNotExist: raise ValidationError("Error! Product is not available in this shop.", code="product_not_available_in_shop") if supplier_id: supplier = shop_product.suppliers.enabled( shop=shop_product.shop).filter(pk=supplier_id).first() else: supplier = shop_product.get_supplier(basket.customer, quantity, basket.shipping_address) if not supplier: raise ValidationError("Error! Invalid supplier.", code="invalid_supplier") try: quantity = parse_decimal_string(quantity) if unit_type == 'display': quantity = shop_product.unit.from_display(quantity) if not product.sales_unit.allow_fractions: if quantity % 1 != 0: msg = _("Error! The quantity `%f` is not allowed. " "Please use an integer value.") % quantity raise ValidationError(msg, code="invalid_quantity") quantity = int(quantity) except (ValueError, decimal.InvalidOperation): raise ValidationError(_(u"Error! The quantity `%s` is not valid.") % quantity, code="invalid_quantity") if quantity <= 0: raise ValidationError(_(u"Error! The quantity `%s` is not valid, " "should be bigger than zero.") % quantity, code="invalid_quantity") product_ids_and_quantities = basket.get_product_ids_and_quantities() already_in_basket_qty = product_ids_and_quantities.get(product.id, 0) shop_product.raise_if_not_orderable(supplier=supplier, quantity=(already_in_basket_qty + quantity), customer=basket.customer) # If the product is a package parent, also check child products if product.is_package_parent(): for child_product, child_quantity in six.iteritems( product.get_package_child_to_quantity_map()): already_in_basket_qty = product_ids_and_quantities.get( child_product.id, 0) total_child_quantity = (quantity * child_quantity) try: sp = child_product.get_shop_instance(shop=request.shop) except ShopProduct.DoesNotExist: raise ProductNotOrderableProblem( "Error! Product %s is not available in shop %s." % (child_product, request.shop)) sp.raise_if_not_orderable(supplier=supplier, quantity=(already_in_basket_qty + total_child_quantity), customer=basket.customer) # TODO: Hook/extension point # if product.form: # return { # "error": u"Form required", # "return": reverse_GET("product-form", kwargs={"pk": product.pk}, GET={"n": quantity}) # } add_product_kwargs = { "product": product, "quantity": quantity, "supplier": supplier, "shop": request.shop, "force_new_line": kwargs.get("force_new_line", False), "extra": kwargs.get("extra"), "parent_line": kwargs.get("parent_line") } line = basket.add_product(**add_product_kwargs) return { 'ok': basket.smart_product_count, 'line_id': line.line_id, 'added': quantity }