def create_shipment(self, product_quantities, supplier=None, shipment=None): """ Create a shipment for this order from `product_quantities`. `product_quantities` is expected to be a dict mapping Product instances to quantities. Only quantities over 0 are taken into account, and if the mapping is empty or has no quantity value over 0, `NoProductsToShipException` will be raised. :param product_quantities: a dict mapping Product instances to quantities to ship :type product_quantities: dict[shuup.shop.models.Product, decimal.Decimal] :param supplier: Optional Supplier for this product. No validation is made as to whether the given supplier supplies the products. :param shipment: Optional unsaved Shipment for ShipmentProduct's. If not given Shipment is created based on supplier parameter. :raises: NoProductsToShipException :return: Saved, complete Shipment object :rtype: shuup.core.models.Shipment """ if not product_quantities or not any(quantity > 0 for quantity in product_quantities.values()): raise NoProductsToShipException("No products to ship (`quantities` is empty or has no quantity over 0).") assert (supplier or shipment) if shipment: assert shipment.order == self from ._shipments import ShipmentProduct if not shipment: from ._shipments import Shipment shipment = Shipment(order=self, supplier=supplier) shipment.save() for product, quantity in product_quantities.items(): if quantity > 0: sp = ShipmentProduct(shipment=shipment, product=product, quantity=quantity) sp.cache_values() sp.save() shipment.cache_values() shipment.save() self.add_log_entry(_(u"Shipment #%d created.") % shipment.id) self.update_shipping_status() shipment_created.send(sender=type(self), order=self, shipment=shipment) return shipment
def create_shipment(self, product_quantities, supplier=None, shipment=None): """ Create a shipment for this order from `product_quantities`. `product_quantities` is expected to be a dict mapping Product instances to quantities. Only quantities over 0 are taken into account, and if the mapping is empty or has no quantity value over 0, `NoProductsToShipException` will be raised. Orders without a shipping address defined, will raise `NoShippingAddressException`. :param product_quantities: a dict mapping Product instances to quantities to ship :type product_quantities: dict[shuup.shop.models.Product, decimal.Decimal] :param supplier: Optional Supplier for this product. No validation is made :param shipment: Optional unsaved Shipment for ShipmentProduct's. If not given Shipment is created based on supplier parameter. :raises: NoProductsToShipException, NoShippingAddressException :return: Saved, complete Shipment object :rtype: shuup.core.models.Shipment """ if not product_quantities or not any(quantity > 0 for quantity in product_quantities.values()): raise NoProductsToShipException("No products to ship (`quantities` is empty or has no quantity over 0).") if self.shipping_address is None: raise NoShippingAddressException("Shipping address is not set on this order") assert (supplier or shipment) if shipment: assert shipment.order == self else: from ._shipments import Shipment shipment = Shipment(order=self, supplier=supplier) shipment.save() if not supplier: supplier = shipment.supplier supplier.module.ship_products(shipment, product_quantities) self.add_log_entry(_(u"Shipment #%d created.") % shipment.id) self.update_shipping_status() shipment_created.send(sender=type(self), order=self, shipment=shipment) shipment_created_and_processed.send(sender=type(self), order=self, shipment=shipment) return shipment
def create_shipment(self, product_quantities, supplier=None, shipment=None): """ Create a shipment for this order from `product_quantities`. `product_quantities` is expected to be a dict mapping Product instances to quantities. Only quantities over 0 are taken into account, and if the mapping is empty or has no quantity value over 0, `NoProductsToShipException` will be raised. Orders without a shipping address defined, will raise `NoShippingAddressException`. :param product_quantities: a dict mapping Product instances to quantities to ship :type product_quantities: dict[shuup.shop.models.Product, decimal.Decimal] :param supplier: Optional Supplier for this product. No validation is made :param shipment: Optional unsaved Shipment for ShipmentProduct's. If not given Shipment is created based on supplier parameter. :raises: NoProductsToShipException, NoShippingAddressException :return: Saved, complete Shipment object :rtype: shuup.core.models.Shipment """ if not product_quantities or not any(quantity > 0 for quantity in product_quantities.values()): raise NoProductsToShipException("No products to ship (`quantities` is empty or has no quantity over 0).") if self.shipping_address is None: raise NoShippingAddressException("Shipping address is not set on this order") assert (supplier or shipment) if shipment: assert shipment.order == self else: from ._shipments import Shipment shipment = Shipment(order=self, supplier=supplier) shipment.save() if not supplier: supplier = shipment.supplier supplier.module.ship_products(shipment, product_quantities) self.add_log_entry(_(u"Shipment #%d created.") % shipment.id) self.update_shipping_status() shipment_created.send(sender=type(self), order=self, shipment=shipment) shipment_created_and_processed.send(sender=type(self), order=self, shipment=shipment) return shipment
def create_shipment(self, product_quantities, supplier=None, shipment=None): """ Create a shipment for this order from `product_quantities`. `product_quantities` is expected to be a dict mapping Product instances to quantities. Only quantities over 0 are taken into account, and if the mapping is empty or has no quantity value over 0, `NoProductsToShipException` will be raised. Orders without a shipping address defined, will raise `NoShippingAddressException`. :param product_quantities: a dict mapping Product instances to quantities to ship :type product_quantities: dict[shuup.shop.models.Product, decimal.Decimal] :param supplier: Optional Supplier for this product. No validation is made :param shipment: Optional unsaved Shipment for ShipmentProduct's. If not given Shipment is created based on supplier parameter. :raises: NoProductsToShipException, NoShippingAddressException :return: Saved, complete Shipment object :rtype: shuup.core.models.Shipment """ if not product_quantities or not any( quantity > 0 for quantity in product_quantities.values()): raise NoProductsToShipException( "No products to ship (`quantities` is empty or has no quantity over 0)." ) if self.shipping_address is None: raise NoShippingAddressException( "Shipping address is not set on this order") assert (supplier or shipment) from ._shipments import ShipmentProduct if shipment: assert shipment.order == self else: from ._shipments import Shipment shipment = Shipment(order=self, supplier=supplier) shipment.save() if not supplier: supplier = shipment.supplier insufficient_stocks = {} for product, quantity in product_quantities.items(): if quantity > 0: stock_status = supplier.get_stock_status(product.pk) if (product.stock_behavior == StockBehavior.STOCKED) and ( stock_status.physical_count < quantity): insufficient_stocks[product] = stock_status.physical_count sp = ShipmentProduct(shipment=shipment, product=product, quantity=quantity) sp.cache_values() sp.save() if insufficient_stocks: formatted_counts = [ _("%(name)s (physical stock: %(quantity)s)") % { "name": force_text(name), "quantity": force_text(quantity) } for (name, quantity) in insufficient_stocks.items() ] raise Problem( _("Insufficient physical stock count for following products: %(product_counts)s" ) % {"product_counts": ", ".join(formatted_counts)}) shipment.cache_values() shipment.save() self.add_log_entry(_(u"Shipment #%d created.") % shipment.id) self.update_shipping_status() shipment_created.send(sender=type(self), order=self, shipment=shipment) return shipment
def create_shipment(self, product_quantities, supplier=None, shipment=None): """ Create a shipment for this order from `product_quantities`. `product_quantities` is expected to be a dict mapping Product instances to quantities. Only quantities over 0 are taken into account, and if the mapping is empty or has no quantity value over 0, `NoProductsToShipException` will be raised. Orders without a shipping address defined, will raise `NoShippingAddressException`. :param product_quantities: a dict mapping Product instances to quantities to ship :type product_quantities: dict[shuup.shop.models.Product, decimal.Decimal] :param supplier: Optional Supplier for this product. No validation is made :param shipment: Optional unsaved Shipment for ShipmentProduct's. If not given Shipment is created based on supplier parameter. :raises: NoProductsToShipException, NoShippingAddressException :return: Saved, complete Shipment object :rtype: shuup.core.models.Shipment """ if not product_quantities or not any(quantity > 0 for quantity in product_quantities.values()): raise NoProductsToShipException("No products to ship (`quantities` is empty or has no quantity over 0).") if self.shipping_address is None: raise NoShippingAddressException("Shipping address is not set on this order") assert (supplier or shipment) from ._shipments import ShipmentProduct if shipment: assert shipment.order == self else: from ._shipments import Shipment shipment = Shipment(order=self, supplier=supplier) shipment.save() if not supplier: supplier = shipment.supplier insufficient_stocks = {} for product, quantity in product_quantities.items(): if quantity > 0: stock_status = supplier.get_stock_status(product.pk) if (product.stock_behavior == StockBehavior.STOCKED) and (stock_status.physical_count < quantity): insufficient_stocks[product] = stock_status.physical_count sp = ShipmentProduct(shipment=shipment, product=product, quantity=quantity) sp.cache_values() sp.save() if insufficient_stocks: formatted_counts = [_("%(name)s (physical stock: %(quantity)s)") % { "name": force_text(name), "quantity": force_text(quantity) } for (name, quantity) in insufficient_stocks.items()] raise Problem( _("Insufficient physical stock count for following products: %(product_counts)s") % { "product_counts": ", ".join(formatted_counts) }) shipment.cache_values() shipment.save() self.add_log_entry(_(u"Shipment #%d created.") % shipment.id) self.update_shipping_status() shipment_created.send(sender=type(self), order=self, shipment=shipment) return shipment