Exemplo n.º 1
0
def add_variant_to_delivery_group(group,
                                  variant,
                                  total_quantity,
                                  discounts=None,
                                  add_to_existing=True):
    """Adds total_quantity of variant to group.
    Raises InsufficientStock exception if quantity could not be fulfilled.

    By default, first adds variant  to existing lines with same variant.
    It can be disabled with setting add_to_existing to False.

    Order lines are created by increasing quantity of lines,
    as long as total_quantity of variant will be added.
    """
    quantity_left = (add_variant_to_existing_lines(
        group, variant, total_quantity) if add_to_existing else total_quantity)

    price = variant.get_price_per_item(discounts)
    while quantity_left > 0:
        stock = variant.select_stockrecord()
        if not stock:
            raise InsufficientStock(variant)  #satchless
        quantity = (stock.quantity_available
                    if quantity_left > stock.quantity_available else
                    quantity_left)
        group.lines.create(product=variant.product,
                           product_name=variant.display_product(),
                           product_sku=variant.sku,
                           quantity=quantity,
                           unit_price_net=price,
                           stock=stock)
        allocate_stock(stock, quantity)
        # refresh stock for accessing quantity_allocated
        stock.refresh_from_db()
        quantity_left -= quantity
Exemplo n.º 2
0
def add_items_to_delivery_group(delivery_group, partition, discounts=None):
    for item_line in partition:
        product_variant = item_line.variant
        price = item_line.get_price_per_item(discounts)
        total_quantity = item_line.get_quantity()

        while total_quantity > 0:
            stock = product_variant.select_stockrecord()
            if not stock:
                raise InsufficientStock(product_variant)
            quantity = (stock.quantity_available
                        if total_quantity > stock.quantity_available else
                        total_quantity)
            delivery_group.items.create(
                product=product_variant.product,
                quantity=quantity,
                unit_price_net=price.net,
                product_name=product_variant.display_product(),
                product_sku=product_variant.sku,
                unit_price_gross=price.gross,
                stock=stock,
                stock_location=stock.location.name)
            total_quantity -= quantity
            # allocate quantity to avoid overselling
            Stock.objects.allocate_stock(stock, quantity)
            # refresh for reading quantity_available in next select_stockrecord
            stock.refresh_from_db()
Exemplo n.º 3
0
def test_contains_unavailable_variants():
    missing_variant = Mock(check_quantity=Mock(
        side_effect=InsufficientStock('')))
    cart = MagicMock()
    cart.lines.all.return_value = [Mock(variant=missing_variant)]
    assert utils.contains_unavailable_variants(cart)

    variant = Mock(check_quantity=Mock())
    cart.lines.all.return_value = [Mock(variant=variant)]
    assert not utils.contains_unavailable_variants(cart)
Exemplo n.º 4
0
def test_contains_unavailable_products():
    missing_product = Mock(check_quantity=Mock(
        side_effect=InsufficientStock('')))
    cart = MagicMock()
    cart.__iter__.return_value = [Mock(product=missing_product)]
    assert utils.contains_unavailable_products(cart)

    product = Mock(check_quantity=Mock())
    cart.__iter__.return_value = [Mock(product=product)]
    assert not utils.contains_unavailable_products(cart)
Exemplo n.º 5
0
def test_add_to_cart_form_when_insufficient_stock():
    cart_lines = []
    cart = Mock(add=lambda variant, quantity: cart_lines.append(variant),
                get_line=Mock(return_value=Mock(quantity=1)))

    form = forms.AddToCartForm(data={'quantity': 1}, cart=cart, product=Mock())
    exception_mock = InsufficientStock(
        Mock(get_stock_quantity=Mock(return_value=4)))
    product_variant = Mock(check_quantity=Mock(side_effect=exception_mock))
    form.get_variant = Mock(return_value=product_variant)
    assert not form.is_valid()
Exemplo n.º 6
0
def add_variant_to_delivery_group(group,
                                  variant,
                                  total_quantity,
                                  discounts=None,
                                  add_to_existing=True,
                                  package_offer=False):
    """Adds total_quantity of variant to group.
    Raises InsufficientStock exception if quantity could not be fulfilled.

    By default, first adds variant to existing lines with same variant.
    It can be disabled with setting add_to_existing to False.

    Order lines are created by increasing quantity of lines,
    as long as total_quantity of variant will be added.
    """
    quantity_left = (add_variant_to_existing_lines(
        group, variant, total_quantity) if add_to_existing else total_quantity)
    # if package_offer:
    price = variant.get_price_per_item(discounts)
    while quantity_left > 0:
        stock = variant.select_stockrecord()
        if not stock:
            raise InsufficientStock(variant)
        quantity = (stock.quantity_available
                    if quantity_left > stock.quantity_available else
                    quantity_left)

        if package_offer:
            unit_price_net = 0.00
            unit_price_gross = 0.00
        else:
            unit_price_net = price.net
            unit_price_gross = price.gross

        group.lines.create(
            product=variant.product,
            product_name=variant.display_product()
            [0:128],  # TODO: do something about it
            product_sku=variant.sku,
            quantity=quantity,
            unit_price_net=unit_price_net,
            unit_price_gross=unit_price_gross,
            stock=stock,
            stock_location=stock.location.name)
        Stock.objects.allocate_stock(stock, quantity)
        # refresh stock for accessing quantity_allocated
        stock.refresh_from_db()
        quantity_left -= quantity
Exemplo n.º 7
0
def test_replace_cartline_form_when_insufficient_stock(monkeypatch, cart,
                                                       variant):
    initial_quantity = 1
    replaced_quantity = 4

    cart.add(variant, initial_quantity)
    exception_mock = InsufficientStock(
        Mock(get_stock_quantity=Mock(return_value=2)))
    monkeypatch.setattr('saleor.product.models.ProductVariant.check_quantity',
                        Mock(side_effect=exception_mock))
    data = {'quantity': replaced_quantity}
    form = forms.ReplaceCartLineForm(data=data, cart=cart, product=variant)
    assert not form.is_valid()
    with pytest.raises(KeyError):
        form.save()
    assert cart.quantity == initial_quantity
Exemplo n.º 8
0
    def fix_lines_quantities(self):
        for group in self.groups.all():
            for item in group.lines.all():
                try:
                    if not item.quantity:
                        raise InsufficientStock(item.variant)
                    item.variant.check_quantity(item.quantity)
                except InsufficientStock:
                    if item.quantity:
                        item.quantity = item.variant.get_stock()
                    if item.quantity:
                        item.save()
                    else:
                        item.delete()

            if not group.lines.exists():
                group.delete()
Exemplo n.º 9
0
 def check_quantity(self, quantity):
     available_quantity = self.get_stock_quantity()
     if quantity > available_quantity:
         raise InsufficientStock(self)