def get_orderability_errors( # noqa (C901) self, supplier, quantity, customer, ignore_minimum=False): """ Yield ValidationErrors that would cause this product to not be orderable. :param supplier: Supplier to order this product from. May be None. :type supplier: shoop.core.models.suppliers.Supplier :param quantity: Quantity to order. :type quantity: int|Decimal :param customer: Customer contact. :type customer: shoop.core.models.Contact :param ignore_minimum: Ignore any limitations caused by quantity minimums. :type ignore_minimum: bool :return: Iterable[ValidationError] """ for error in self.get_visibility_errors(customer): yield error if supplier is None and not self.suppliers.exists(): # `ShopProduct` must have at least one `Supplier`. # If supplier is not given and the `ShopProduct` itself # doesn't have suppliers we cannot sell this product. yield ValidationError( _('The product has no supplier.'), code="no_supplier" ) if not ignore_minimum and quantity < self.minimum_purchase_quantity: yield ValidationError( _('The purchase quantity needs to be at least %d for this product.') % self.minimum_purchase_quantity, code="purchase_quantity_not_met" ) if supplier and not self.suppliers.filter(pk=supplier.pk).exists(): yield ValidationError( _('The product is not supplied by %s.') % supplier, code="invalid_supplier" ) if self.product.is_package_parent(): for child_product, child_quantity in six.iteritems(self.product.get_package_child_to_quantity_map()): child_shop_product = child_product.get_shop_instance(shop=self.shop) if not child_shop_product: yield ValidationError("%s: Not available in %s" % (child_product, self.shop), code="invalid_shop") for error in child_shop_product.get_orderability_errors( supplier=supplier, quantity=(quantity * child_quantity), customer=customer, ignore_minimum=ignore_minimum ): code = getattr(error, "code", None) yield ValidationError("%s: %s" % (child_product, error), code=code) if supplier and self.product.stock_behavior == StockBehavior.STOCKED: for error in supplier.get_orderability_errors(self, quantity, customer=customer): yield error purchase_multiple = self.purchase_multiple if quantity > 0 and purchase_multiple > 1 and (quantity % purchase_multiple) != 0: p = (quantity // purchase_multiple) smaller_p = max(purchase_multiple, p * purchase_multiple) larger_p = max(purchase_multiple, (p + 1) * purchase_multiple) if larger_p == smaller_p: message = _('The product can only be ordered in multiples of %(package_size)s, ' 'for example %(smaller_p)s %(unit)s.') % { "package_size": purchase_multiple, "smaller_p": smaller_p, "unit": self.product.sales_unit, } else: message = _('The product can only be ordered in multiples of %(package_size)s, ' 'for example %(smaller_p)s or %(larger_p)s %(unit)s.') % { "package_size": purchase_multiple, "smaller_p": smaller_p, "larger_p": larger_p, "unit": self.product.sales_unit, } yield ValidationError(message, code="invalid_purchase_multiple") for receiver, response in get_orderability_errors.send( ShopProduct, shop_product=self, customer=customer, supplier=supplier, quantity=quantity ): for error in response: yield error
def get_orderability_errors( # noqa (C901) self, supplier, quantity, customer, ignore_minimum=False): """ Yield ValidationErrors that would cause this product to not be orderable. :param supplier: Supplier to order this product from. May be None. :type supplier: shoop.core.models.suppliers.Supplier :param quantity: Quantity to order. :type quantity: int|Decimal :param customer: Customer contact. :type customer: shoop.core.models.Contact :param ignore_minimum: Ignore any limitations caused by quantity minimums. :type ignore_minimum: bool :return: Iterable[ValidationError] """ for error in self.get_visibility_errors(customer): yield error if supplier is None and not self.suppliers.exists(): # `ShopProduct` must have at least one `Supplier`. # If supplier is not given and the `ShopProduct` itself # doesn't have suppliers we cannot sell this product. yield ValidationError(_('The product has no supplier.'), code="no_supplier") if not ignore_minimum and quantity < self.minimum_purchase_quantity: yield ValidationError(_( 'The purchase quantity needs to be at least %d for this product.' ) % self.minimum_purchase_quantity, code="purchase_quantity_not_met") if supplier and not self.suppliers.filter(pk=supplier.pk).exists(): yield ValidationError(_('The product is not supplied by %s.') % supplier, code="invalid_supplier") if self.product.is_package_parent(): for child_product, child_quantity in six.iteritems( self.product.get_package_child_to_quantity_map()): child_shop_product = child_product.get_shop_instance( shop=self.shop) if not child_shop_product: yield ValidationError("%s: Not available in %s" % (child_product, self.shop), code="invalid_shop") for error in child_shop_product.get_orderability_errors( supplier=supplier, quantity=(quantity * child_quantity), customer=customer, ignore_minimum=ignore_minimum): code = getattr(error, "code", None) yield ValidationError("%s: %s" % (child_product, error), code=code) if supplier and self.product.stock_behavior == StockBehavior.STOCKED: for error in supplier.get_orderability_errors(self, quantity, customer=customer): yield error purchase_multiple = self.purchase_multiple if quantity > 0 and purchase_multiple > 1 and (quantity % purchase_multiple) != 0: p = (quantity // purchase_multiple) smaller_p = max(purchase_multiple, p * purchase_multiple) larger_p = max(purchase_multiple, (p + 1) * purchase_multiple) if larger_p == smaller_p: message = _( 'The product can only be ordered in multiples of %(package_size)s, ' 'for example %(smaller_p)s %(unit)s.') % { "package_size": purchase_multiple, "smaller_p": smaller_p, "unit": self.product.sales_unit, } else: message = _( 'The product can only be ordered in multiples of %(package_size)s, ' 'for example %(smaller_p)s or %(larger_p)s %(unit)s.') % { "package_size": purchase_multiple, "smaller_p": smaller_p, "larger_p": larger_p, "unit": self.product.sales_unit, } yield ValidationError(message, code="invalid_purchase_multiple") for receiver, response in get_orderability_errors.send( ShopProduct, shop_product=self, customer=customer, supplier=supplier, quantity=quantity): for error in response: yield error