def create_shipment_of_all_products(self, supplier=None): """ Create a shipment of all the products in this Order, no matter whether or not any have been previously marked as shipped or not. See the documentation for `create_shipment`. :param supplier: The Supplier to use. If `None`, the first supplier in the order is used. (If several are in the order, this fails.) :return: Saved, complete Shipment object :rtype: shoop.shop.models.Shipment """ suppliers_to_product_quantities = defaultdict(lambda: defaultdict(lambda: 0)) lines = ( self.lines .filter(type=OrderLineType.PRODUCT) .values_list("supplier_id", "product_id", "quantity")) for supplier_id, product_id, quantity in lines: if product_id: suppliers_to_product_quantities[supplier_id][product_id] += quantity if not suppliers_to_product_quantities: raise NoProductsToShipException("Could not find any products to ship.") if supplier is None: if len(suppliers_to_product_quantities) > 1: # pragma: no cover raise ValueError("Can only use create_shipment_of_all_products when there is only one supplier") supplier_id, quantities = suppliers_to_product_quantities.popitem() supplier = Supplier.objects.get(pk=supplier_id) else: quantities = suppliers_to_product_quantities[supplier.id] products = dict((product.pk, product) for product in Product.objects.filter(pk__in=quantities.keys())) quantities = dict((products[product_id], quantity) for (product_id, quantity) in quantities.items()) return self.create_shipment(supplier, quantities)
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[shoop.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: shoop.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, supplier, product_quantities): """ 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 supplier: The Supplier for this product. No validation is made as to whether the given supplier supplies the products. :param product_quantities: a dict mapping Product instances to quantities to ship :type product_quantities: dict[shoop.shop.models.products.Product, decimal.Decimal] :raises: NoProductsToShipException :return: Saved, complete Shipment object :rtype: shoop.core.models.shipments.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)." ) from .shipments import Shipment, ShipmentProduct 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.check_and_set_fully_shipped() return shipment