Example #1
0
def test_admin_catalog_discount_contact_group_filter(rf, admin_user):
    shop, supplier, contact, group, category = _init_test()
    default_price = Decimal("15.0")
    discounted_price_value = Decimal("12")
    product = factories.create_product("p1", shop=shop, supplier=supplier, default_price=default_price)
    product.get_shop_instance(shop).categories.add(category)

    ProductCatalog.index_product(product)
    view = DiscountEditView.as_view()

    # create a discounted price for the contact group
    payload = _get_default_discount_data(
        {"contact_group": group.pk, "discounted_price_value": str(discounted_price_value)}
    )
    request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user)
    with patch("django.db.transaction.on_commit", new=atomic_commit_mock):
        response = view(request, pk=None)
    assert response.status_code == 302

    anon_catalog = ProductCatalog(context=ProductCatalogContext(purchasable_only=False))
    customer_catalog = ProductCatalog(context=ProductCatalogContext(purchasable_only=False, contact=contact))

    _assert_products_queryset(anon_catalog, [(product.pk, default_price, None)])
    _assert_products_queryset(customer_catalog, [(product.pk, default_price, discounted_price_value)])

    # remove the group from the discount
    discount = Discount.objects.last()
    payload = _get_default_discount_data({"discounted_price_value": str(discounted_price_value)})
    request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user)
    with patch("django.db.transaction.on_commit", new=atomic_commit_mock):
        response = view(request, pk=discount.pk)
    assert response.status_code == 302

    _assert_products_queryset(anon_catalog, [(product.pk, default_price, discounted_price_value)])
    _assert_products_queryset(customer_catalog, [(product.pk, default_price, discounted_price_value)])
Example #2
0
def test_admin_catalog_discount_product_filter(rf, admin_user):
    shop, supplier, contact, group, category = _init_test()
    default_price = Decimal("15.0")
    discount_percentage = Decimal("10")
    product = factories.create_product("p1", shop=shop, supplier=supplier, default_price=default_price)
    product2 = factories.create_product("p2", shop=shop, supplier=supplier, default_price=default_price)

    ProductCatalog.index_product(product)
    ProductCatalog.index_product(product2)
    view = DiscountEditView.as_view()

    # create a 10% discount for the product
    payload = _get_default_discount_data({"product": product.pk, "discount_percentage": str(discount_percentage)})
    request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user)
    with patch("django.db.transaction.on_commit", new=atomic_commit_mock):
        response = view(request, pk=None)
    assert response.status_code == 302

    anon_catalog = ProductCatalog(context=ProductCatalogContext(purchasable_only=False))
    customer_catalog = ProductCatalog(context=ProductCatalogContext(purchasable_only=False, contact=contact))

    # discount is indexed
    discounted_price = (default_price - (default_price * discount_percentage * Decimal(0.01))).quantize(Decimal("0.01"))
    _assert_products_queryset(
        anon_catalog,
        [
            (product.pk, default_price, discounted_price),
            (product2.pk, default_price, None),
        ],
    )
    _assert_products_queryset(
        customer_catalog,
        [
            (product.pk, default_price, discounted_price),
            (product2.pk, default_price, None),
        ],
    )

    # changed the discount product
    discount = Discount.objects.last()
    payload = _get_default_discount_data({"product": product2.pk, "discount_percentage": str(discount_percentage)})
    request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user)
    with patch("django.db.transaction.on_commit", new=atomic_commit_mock):
        response = view(request, pk=discount.pk)
    assert response.status_code == 302

    _assert_products_queryset(
        anon_catalog,
        [
            (product.pk, default_price, None),
            (product2.pk, default_price, discounted_price),
        ],
    )
    _assert_products_queryset(
        customer_catalog,
        [
            (product.pk, default_price, None),
            (product2.pk, default_price, discounted_price),
        ],
    )
Example #3
0
def test_product_catalog_indexing(rf, admin_user, settings):
    shop = get_default_shop()
    supplier = get_simple_supplier(shop=shop)
    supplier.stock_managed = True
    supplier.save()
    product = create_product("simple-test-product", shop, supplier)

    ProductCatalog.index_product(product)

    # no purchasable products
    catalog = ProductCatalog(
        ProductCatalogContext(shop=shop, purchasable_only=True))
    assert catalog.get_products_queryset().count() == 0

    # add 10 items to the stock
    stock_qty = 10
    request = apply_request_middleware(rf.post("/",
                                               data={
                                                   "purchase_price":
                                                   decimal.Decimal(32.00),
                                                   "delta":
                                                   stock_qty
                                               }),
                                       user=admin_user)
    response = process_stock_adjustment(request, supplier.id, product.id)
    assert response.status_code == 200
    pss = supplier.get_stock_status(product.pk)
    assert pss.logical_count == stock_qty

    # now there are purchasable products
    assert catalog.get_products_queryset().count() == 1
    assert product in catalog.get_products_queryset()

    # create a random order with 10 units of the product
    source = OrderSource(shop)
    source.status = get_initial_order_status()
    source.add_line(
        type=OrderLineType.PRODUCT,
        supplier=supplier,
        product=product,
        base_unit_price=source.create_price(1),
        quantity=10,
    )
    OrderCreator().create_order(source)

    pss = supplier.get_stock_status(product.pk)
    assert pss.logical_count == 0

    # stocks are gone
    assert catalog.get_products_queryset().count() == 0
Example #4
0
def test_product_catalog_availability():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    product1 = factories.create_product("p1", shop=shop, supplier=supplier, default_price=Decimal("30"))
    product2 = factories.create_product("p2", shop=shop, supplier=supplier, default_price=Decimal("10"))

    supplier.stock_managed = True
    supplier.save()

    # add 10 products to product1 stock
    supplier.adjust_stock(product1.pk, delta=10)

    catalog_available_only = ProductCatalog(context=ProductCatalogContext(purchasable_only=True))
    catalog_visible_only = ProductCatalog(context=ProductCatalogContext(purchasable_only=False))
    catalog_all = ProductCatalog(context=ProductCatalogContext(purchasable_only=False, visible_only=False))
    ProductCatalog.index_product(product1)
    ProductCatalog.index_product(product2)

    assert catalog_available_only.get_products_queryset().count() == 1
    assert catalog_visible_only.get_products_queryset().count() == 2
    assert catalog_all.get_products_queryset().count() == 2

    # change the product1 visibility
    ShopProduct.objects.all().update(visibility=ShopProductVisibility.NOT_VISIBLE)
    ProductCatalog.index_product(product1)
    ProductCatalog.index_product(product2)

    assert catalog_available_only.get_products_queryset().count() == 0
    assert catalog_visible_only.get_products_queryset().count() == 0
    assert catalog_all.get_products_queryset().count() == 2
Example #5
0
def test_supplier_changed_reindex_catalog(rf, admin_user):
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier(shop)
    supplier.stock_managed = True
    supplier.save()
    product = factories.create_product("p1",
                                       shop,
                                       supplier,
                                       default_price=Decimal("10"))
    supplier.adjust_stock(product.pk, 40)  # add 40 to the stock
    ProductCatalog.index_product(product)

    catalog = ProductCatalog(ProductCatalogContext(purchasable_only=True))
    assert product in catalog.get_products_queryset()

    # disable the supplier
    edit_view = SupplierEditView.as_view()
    payload = {
        "base-name": supplier.name,
        "base-description__en": "",
        "base-type": SupplierType.INTERNAL.value,
        "base-stock_managed": True,
        "base-supplier_modules": [supplier.supplier_modules.first().pk],
        "base-shops": shop.pk,
        "base-enabled": "",
        "base-logo": "",
        "address-name": "Address Name",
        "address-email": "*****@*****.**",
        "address-phone": "23742578329",
        "address-tax_number": "ABC123",
        "address-street": "Streetz",
        "address-postal_code": "90014",
        "address-city": "Los Angeles",
        "address-region_code": "CA",
        "address-country": "US",
    }
    request = apply_request_middleware(rf.post("/", payload), user=admin_user)
    response = edit_view(request, pk=supplier.pk)
    assert response.status_code == 302

    supplier.refresh_from_db()
    assert not supplier.enabled

    # product is not available anymore
    assert product not in catalog.get_products_queryset()
Example #6
0
def test_product_catalog_purchasable():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    product1 = factories.create_product("p1", shop=shop, supplier=supplier, default_price=Decimal("30"))
    product2 = factories.create_product("p2", shop=shop, supplier=supplier, default_price=Decimal("10"))

    supplier.stock_managed = True
    supplier.save()

    # add 10 products to product1 stock
    supplier.adjust_stock(product1.pk, delta=10)

    catalog = ProductCatalog(context=ProductCatalogContext(purchasable_only=True))
    ProductCatalog.index_product(product1)
    ProductCatalog.index_product(product2)

    _assert_products_queryset(catalog, [(product1.pk, Decimal("30"), None)])
    _assert_shop_products_queryset(catalog, [(product1.get_shop_instance(shop).pk, Decimal("30"), None)])
Example #7
0
def test_product_catalog_product_discount():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    product1 = factories.create_product("p1",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=Decimal("10"))
    product2 = factories.create_product("p2",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=Decimal("20"))

    # create a $5 discount for the product
    Discount.objects.create(
        shop=shop,
        product=product1,
        discount_amount_value=Decimal(5),
        start_datetime=timezone.now(),
        end_datetime=timezone.now() + timedelta(days=1),
    )

    catalog = ProductCatalog(context=ProductCatalogContext(
        purchasable_only=False))
    ProductCatalog.index_product(product1)
    ProductCatalog.index_product(product2)

    _assert_products_queryset(
        catalog,
        [
            (product1.pk, Decimal("10"), Decimal("5")),
            (product2.pk, Decimal("20"), None),
        ],
    )
    _assert_shop_products_queryset(
        catalog,
        [
            (product1.get_shop_instance(shop).pk, Decimal("10"), Decimal("5")),
            (product2.get_shop_instance(shop).pk, Decimal("20"), None),
        ],
    )
    _assert_price(product1, shop, Decimal("5"), Decimal("10"))
    _assert_price(product2, shop, Decimal("20"), Decimal("20"))
Example #8
0
def test_admin_catalog_discount_category_filter(rf, admin_user):
    shop, supplier, contact, group, category = _init_test()
    default_price = Decimal("15.0")
    discount_amount = Decimal("5")
    product = factories.create_product("p1", shop=shop, supplier=supplier, default_price=default_price)
    product.get_shop_instance(shop).categories.add(category)

    ProductCatalog.index_product(product)
    view = DiscountEditView.as_view()

    # create a $5 discount for the category
    payload = _get_default_discount_data({"category": category.pk, "discount_amount_value": str(discount_amount)})
    request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user)
    with patch("django.db.transaction.on_commit", new=atomic_commit_mock):
        response = view(request, pk=None)
    assert response.status_code == 302

    anon_catalog = ProductCatalog(context=ProductCatalogContext(purchasable_only=False))
    customer_catalog = ProductCatalog(context=ProductCatalogContext(purchasable_only=False, contact=contact))

    # discount is indexed
    discounted_price = (default_price - discount_amount).quantize(Decimal("0.01"))
    _assert_products_queryset(anon_catalog, [(product.pk, default_price, discounted_price)])
    _assert_products_queryset(customer_catalog, [(product.pk, default_price, discounted_price)])

    # make the exclude_selected_category flag be True
    discount = Discount.objects.last()
    payload = _get_default_discount_data(
        {
            "category": category.pk,
            "exclude_selected_category": "on",
            "discount_amount_value": str(discount_amount),
        }
    )
    request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user)
    with patch("django.db.transaction.on_commit", new=atomic_commit_mock):
        response = view(request, pk=discount.pk)
    assert response.status_code == 302

    # discounts removed from the product
    _assert_products_queryset(anon_catalog, [(product.pk, default_price, None)])
    _assert_products_queryset(customer_catalog, [(product.pk, default_price, None)])
Example #9
0
def test_product_catalog_simple_list():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    product1 = factories.create_product("p1", shop=shop, supplier=supplier, default_price=Decimal("30"))
    product2 = factories.create_product("p2", shop=shop, supplier=supplier, default_price=Decimal("10"))
    product3 = factories.create_product("p3", shop=shop, supplier=supplier, default_price=Decimal("20"))

    catalog = ProductCatalog(context=ProductCatalogContext(purchasable_only=False))
    ProductCatalog.index_product(product1)
    ProductCatalog.index_product(product2)
    ProductCatalog.index_product(product3)

    _assert_products_queryset(
        catalog,
        [
            (product2.pk, Decimal("10"), None),
            (product3.pk, Decimal("20"), None),
            (product1.pk, Decimal("30"), None),
        ],
    )
    _assert_shop_products_queryset(
        catalog,
        [
            (product2.get_shop_instance(shop).pk, Decimal("10"), None),
            (product3.get_shop_instance(shop).pk, Decimal("20"), None),
            (product1.get_shop_instance(shop).pk, Decimal("30"), None),
        ],
    )
    _assert_price(product1, shop, Decimal("30"), Decimal("30"))
    _assert_price(product2, shop, Decimal("10"), Decimal("10"))
    _assert_price(product3, shop, Decimal("20"), Decimal("20"))
Example #10
0
def test_product_catalog_variations():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    parent = factories.create_product("p1", shop=shop, supplier=supplier, default_price=Decimal("10"))
    child1 = factories.create_product("p2", shop=shop, supplier=supplier, default_price=Decimal("20"))
    child2 = factories.create_product("p3", shop=shop, supplier=supplier, default_price=Decimal("40"))
    child3 = factories.create_product("p4", shop=shop, supplier=supplier, default_price=Decimal("50"))

    child1.link_to_parent(parent)
    child2.link_to_parent(parent)
    child3.link_to_parent(parent)

    catalog = ProductCatalog(context=ProductCatalogContext(purchasable_only=False))
    ProductCatalog.index_product(parent)

    _assert_products_queryset(
        catalog,
        [
            (parent.pk, Decimal("10"), None),
            (child1.pk, Decimal("20"), None),
            (child2.pk, Decimal("40"), None),
            (child3.pk, Decimal("50"), None),
        ],
    )
    _assert_shop_products_queryset(
        catalog,
        [
            (parent.get_shop_instance(shop).pk, Decimal("10"), None),
            (child1.get_shop_instance(shop).pk, Decimal("20"), None),
            (child2.get_shop_instance(shop).pk, Decimal("40"), None),
            (child3.get_shop_instance(shop).pk, Decimal("50"), None),
        ],
    )
    _assert_price(parent, shop, Decimal("10"), Decimal("10"))
    _assert_price(child1, shop, Decimal("20"), Decimal("20"))
    _assert_price(child2, shop, Decimal("40"), Decimal("40"))
    _assert_price(child3, shop, Decimal("50"), Decimal("50"))
Example #11
0
def test_product_catalog_category_discount():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    contact = factories.create_random_person()
    group = PersonContact.get_default_group()
    category = factories.get_default_category()
    contact.groups.add(group)
    product1 = factories.create_product("p1",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=Decimal("10"))
    product2 = factories.create_product("p2",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=Decimal("20"))
    product3 = factories.create_product("p3",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=Decimal("30"))
    product1.get_shop_instance(shop).categories.add(category)
    product3.get_shop_instance(shop).categories.add(category)

    # create a 10% discount for the category
    Discount.objects.create(
        shop=shop,
        category=category,
        discount_percentage=Decimal(0.1),
        start_datetime=timezone.now(),
        end_datetime=timezone.now() + timedelta(days=1),
    )

    catalog = ProductCatalog(context=ProductCatalogContext(
        purchasable_only=False))
    ProductCatalog.index_product(product1)
    ProductCatalog.index_product(product2)
    ProductCatalog.index_product(product3)

    _assert_products_queryset(
        catalog,
        [
            (product1.pk, Decimal("10"), Decimal("9")),
            (product2.pk, Decimal("20"), None),
            (product3.pk, Decimal("30"), Decimal("27")),
        ],
    )
    _assert_shop_products_queryset(
        catalog,
        [
            (product1.get_shop_instance(shop).pk, Decimal("10"), Decimal("9")),
            (product2.get_shop_instance(shop).pk, Decimal("20"), None),
            (product3.get_shop_instance(shop).pk, Decimal("30"),
             Decimal("27")),
        ],
    )
    _assert_price(product1, shop, Decimal("9"), Decimal("10"))
    _assert_price(product2, shop, Decimal("20"), Decimal("20"))
    _assert_price(product3, shop, Decimal("27"), Decimal("30"))
Example #12
0
def test_product_catalog_visibilities():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    contact = factories.create_random_person()
    group = factories.create_random_contact_group(shop)
    contact.groups.add(group)
    product = factories.create_product("p", shop=shop, supplier=supplier, default_price=Decimal("10"))

    catalog_visible_only = ProductCatalog(context=ProductCatalogContext(purchasable_only=False))
    catalog_visible_contact = ProductCatalog(context=ProductCatalogContext(purchasable_only=False, contact=contact))
    catalog_all = ProductCatalog(context=ProductCatalogContext(purchasable_only=False, visible_only=False))
    ProductCatalog.index_product(product)

    assert catalog_visible_only.get_products_queryset().count() == 1
    assert catalog_visible_contact.get_products_queryset().count() == 1
    assert catalog_all.get_products_queryset().count() == 1

    # change the visibility to groups
    shop_product = product.get_shop_instance(shop)
    shop_product.visibility_limit = ProductVisibility.VISIBLE_TO_GROUPS
    shop_product.save()
    shop_product.visibility_groups.add(group)
    ProductCatalog.index_product(product)

    assert catalog_visible_only.get_products_queryset().count() == 0
    assert catalog_visible_contact.get_products_queryset().count() == 1
    assert catalog_all.get_products_queryset().count() == 1

    # change the visibility to logged in
    shop_product.visibility_limit = ProductVisibility.VISIBLE_TO_LOGGED_IN
    shop_product.save()
    ProductCatalog.index_product(product)

    assert catalog_visible_only.get_products_queryset().count() == 0
    assert catalog_visible_contact.get_products_queryset().count() == 1
    assert catalog_all.get_products_queryset().count() == 1
Example #13
0
def test_product_catalog_cgp_with_variations():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    contact = factories.create_random_person()
    group = PersonContact.get_default_group()
    contact.groups.add(group)
    parent = factories.create_product("p1",
                                      shop=shop,
                                      supplier=supplier,
                                      default_price=Decimal("10"))
    child1 = factories.create_product("p2",
                                      shop=shop,
                                      supplier=supplier,
                                      default_price=Decimal("20"))
    child2 = factories.create_product("p3",
                                      shop=shop,
                                      supplier=supplier,
                                      default_price=Decimal("40"))
    child3 = factories.create_product("p4",
                                      shop=shop,
                                      supplier=supplier,
                                      default_price=Decimal("50"))

    child1.link_to_parent(parent)
    child2.link_to_parent(parent)
    child3.link_to_parent(parent)

    # set a price for child2
    CgpPrice.objects.create(shop=shop,
                            product=child2,
                            group=group,
                            price_value=Decimal("5"))
    # create a discount for child3
    CgpDiscount.objects.create(shop=shop,
                               product=child3,
                               group=group,
                               discount_amount_value=Decimal("35"))

    catalog = ProductCatalog(
        context=ProductCatalogContext(purchasable_only=False, contact=contact))
    ProductCatalog.index_product(parent)

    _assert_products_queryset(
        catalog,
        [
            (child2.pk, Decimal("5"), None),
            (parent.pk, Decimal("10"), None),
            (child1.pk, Decimal("20"), None),
            (child3.pk, Decimal("50"), Decimal("15")),
        ],
    )
    _assert_shop_products_queryset(
        catalog,
        [
            (child2.get_shop_instance(shop).pk, Decimal("5"), None),
            (parent.get_shop_instance(shop).pk, Decimal("10"), None),
            (child1.get_shop_instance(shop).pk, Decimal("20"), None),
            (child3.get_shop_instance(shop).pk, Decimal("50"), Decimal("15")),
        ],
    )
    # no customer
    _assert_price(parent, shop, Decimal("10"), Decimal("10"))
    _assert_price(child1, shop, Decimal("20"), Decimal("20"))
    _assert_price(child2, shop, Decimal("40"), Decimal("40"))
    _assert_price(child3, shop, Decimal("50"), Decimal("50"))
    # with the customer in the group
    _assert_price(parent, shop, Decimal("10"), Decimal("10"), customer=contact)
    _assert_price(child1, shop, Decimal("20"), Decimal("20"), customer=contact)
    _assert_price(child2, shop, Decimal("5"), Decimal("40"), customer=contact)
    _assert_price(child3, shop, Decimal("15"), Decimal("50"), customer=contact)
Example #14
0
def test_product_catalog_discounted_price():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    contact = factories.create_random_person()
    group = PersonContact.get_default_group()
    contact.groups.add(group)
    product1 = factories.create_product("p1",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=Decimal("50"))
    product2 = factories.create_product("p2",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=Decimal("30"))

    # set price for product2
    CgpPrice.objects.create(shop=shop,
                            product=product2,
                            group=group,
                            price_value=Decimal(25))
    # create a discount for product2
    CgpDiscount.objects.create(shop=shop,
                               product=product2,
                               group=group,
                               discount_amount_value=Decimal(7))

    anon_catalog = ProductCatalog(context=ProductCatalogContext(
        purchasable_only=False))
    customer_catalog = ProductCatalog(
        context=ProductCatalogContext(purchasable_only=False, contact=contact))
    ProductCatalog.index_product(product1)
    ProductCatalog.index_product(product2)

    _assert_products_queryset(
        anon_catalog,
        [
            (product2.pk, Decimal("30"), None),
            (product1.pk, Decimal("50"), None),
        ],
    )
    _assert_products_queryset(
        customer_catalog,
        [
            (product2.pk, Decimal("25"), Decimal("23")),
            (product1.pk, Decimal("50"), None),
        ],
    )
    _assert_shop_products_queryset(
        anon_catalog,
        [
            (product2.get_shop_instance(shop).pk, Decimal("30"), None),
            (product1.get_shop_instance(shop).pk, Decimal("50"), None),
        ],
    )
    _assert_shop_products_queryset(
        customer_catalog,
        [
            (product2.get_shop_instance(shop).pk, Decimal("25"),
             Decimal("23")),
            (product1.get_shop_instance(shop).pk, Decimal("50"), None),
        ],
    )
    # no customer
    _assert_price(product1, shop, Decimal("50"), Decimal("50"))
    _assert_price(product2, shop, Decimal("30"), Decimal("30"))
    # with the customer in the group
    _assert_price(product1,
                  shop,
                  Decimal("50"),
                  Decimal("50"),
                  customer=contact)
    _assert_price(product2,
                  shop,
                  Decimal("18"),
                  Decimal("30"),
                  customer=contact)
Example #15
0
def index_product(product_id: int):
    """
    Task to call the ProductCatalog to index the product.
    This util function can be used by a task runner to index this asynchronously.
    """
    ProductCatalog.index_product(product_id)
Example #16
0
def test_admin_catalog_discount_happy_hour_filter(rf, admin_user):
    shop, supplier, contact, group, category = _init_test()
    default_price = Decimal("15.0")
    discounted_price_value = Decimal("12")
    product = factories.create_product("p1", shop=shop, supplier=supplier, default_price=default_price)
    product.get_shop_instance(shop).categories.add(category)

    ProductCatalog.index_product(product)
    discount_view = DiscountEditView.as_view()
    happy_hour_view = HappyHourEditView.as_view()

    # create a happy hour, from 9am to 11am
    payload = {"name": "Mondays", "from_hour": "09:00", "to_hour": "11:00", "weekdays": "0"}
    request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user)
    with patch("django.db.transaction.on_commit", new=atomic_commit_mock):
        response = happy_hour_view(request, pk=None)
    assert response.status_code == 302

    happy_hour = HappyHour.objects.last()

    # create a discounted price using the happy hour
    payload = _get_default_discount_data(
        {
            "start_datetime": datetime(2021, 1, 1).strftime("%Y-%m-%d %H:%M"),
            "end_datetime": datetime(2022, 1, 1).strftime("%Y-%m-%d %H:%M"),
            "happy_hours": happy_hour.pk,
            "discounted_price_value": str(discounted_price_value),
        }
    )
    request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user)
    with patch("django.db.transaction.on_commit", new=atomic_commit_mock):
        response = discount_view(request, pk=None)
    assert response.status_code == 302

    catalog = ProductCatalog(context=ProductCatalogContext(purchasable_only=False))

    # # Monday, 6am
    # with patch.object(timezone, "now", return_value=datetime(2021, 1, 4, 6, 0, tzinfo=pytz.utc)):
    #     _assert_products_queryset(catalog, [(product.pk, default_price, None)])
    # # Monday, 10am
    # with patch.object(timezone, "now", return_value=datetime(2021, 1, 4, 10, 0, tzinfo=pytz.utc)):
    #     _assert_products_queryset(catalog, [(product.pk, default_price, discounted_price_value)])

    # change the happy hour time to Tuesdays, from 3pm to 6pm
    discount = happy_hour.discounts.last()
    assert discount
    payload = {"name": "Tuesdays", "from_hour": "15:00", "to_hour": "18:00", "weekdays": "1", "discounts": discount.pk}
    request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user)
    with patch("django.db.transaction.on_commit", new=atomic_commit_mock):
        response = happy_hour_view(request, pk=happy_hour.pk)
    assert response.status_code == 302

    # Monday, 10am
    with patch.object(timezone, "now", return_value=datetime(2021, 1, 4, 10, 0, tzinfo=pytz.utc)):
        _assert_products_queryset(catalog, [(product.pk, default_price, None)])
    # Monday, 5pm
    with patch.object(timezone, "now", return_value=datetime(2021, 1, 4, 17, 0, tzinfo=pytz.utc)):
        _assert_products_queryset(catalog, [(product.pk, default_price, None)])
    # Tuesday, 5pm
    with patch.object(timezone, "now", return_value=datetime(2021, 1, 5, 17, 0, tzinfo=pytz.utc)):
        _assert_products_queryset(catalog, [(product.pk, default_price, discounted_price_value)])
Example #17
0
def test_product_catalog_happy_hour_discount():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    product1 = factories.create_product("p1",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=Decimal("10"))
    product2 = factories.create_product("p2",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=Decimal("20"))

    # create a 20% discount for a happy hour (should be in range of 8pm-9pm)
    discount = Discount.objects.create(
        shop=shop,
        discount_percentage=Decimal(0.2),
        start_datetime=datetime(2021, 1, 1, tzinfo=pytz.utc),
        end_datetime=datetime(2021, 1, 30, tzinfo=pytz.utc),
    )
    happy_hour = HappyHour.objects.create(name="Super Happy", shop=shop)
    # the happy hour is on Mondays from 8-9pm
    TimeRange.objects.create(from_hour=time(20, 0),
                             to_hour=time(21, 0),
                             weekday=0,
                             happy_hour=happy_hour)
    discount.happy_hours.add(happy_hour)

    catalog = ProductCatalog(context=ProductCatalogContext(
        purchasable_only=False))
    ProductCatalog.index_product(product1)
    ProductCatalog.index_product(product2)

    # Monday, 12pm
    with patch.object(timezone,
                      "now",
                      return_value=datetime(2021, 1, 4, 12, 0,
                                            tzinfo=pytz.utc)):
        _assert_products_queryset(
            catalog,
            [
                (product1.pk, Decimal("10"), None),
                (product2.pk, Decimal("20"), None),
            ],
        )
        _assert_shop_products_queryset(
            catalog,
            [
                (product1.get_shop_instance(shop).pk, Decimal("10"), None),
                (product2.get_shop_instance(shop).pk, Decimal("20"), None),
            ],
        )
        _assert_price(product1, shop, Decimal("10"), Decimal("10"))
        _assert_price(product2, shop, Decimal("20"), Decimal("20"))

    # Monday, 8:30pm
    with patch.object(timezone,
                      "now",
                      return_value=datetime(2021,
                                            1,
                                            4,
                                            20,
                                            30,
                                            tzinfo=pytz.utc)):
        _assert_products_queryset(
            catalog,
            [
                (product1.pk, Decimal("10"), Decimal("8")),
                (product2.pk, Decimal("20"), Decimal("16")),
            ],
        )
        _assert_shop_products_queryset(
            catalog,
            [
                (product1.get_shop_instance(shop).pk, Decimal("10"),
                 Decimal("8")),
                (product2.get_shop_instance(shop).pk, Decimal("20"),
                 Decimal("16")),
            ],
        )
        _assert_price(product1, shop, Decimal("8"), Decimal("10"))
        _assert_price(product2, shop, Decimal("16"), Decimal("20"))
Example #18
0
def test_product_catalog_happy_hour_timezone_discount():
    """
    Make sure a discount is valid for different timezones
    """
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    product1 = factories.create_product("p1",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=Decimal("10"))

    discount = Discount.objects.create(
        shop=shop,
        discount_percentage=Decimal(0.1),
        start_datetime=datetime(2021, 1, 1, tzinfo=pytz.utc),
        end_datetime=datetime(2021, 1, 30, tzinfo=pytz.utc),
    )
    happy_hour = HappyHour.objects.create(name="Super Happy", shop=shop)
    # the happy hour is available on Mondays, from 2am-4am (UTC)
    TimeRange.objects.create(from_hour=time(2, 0),
                             to_hour=time(4, 0),
                             weekday=0,
                             happy_hour=happy_hour)
    discount.happy_hours.add(happy_hour)

    catalog = ProductCatalog(context=ProductCatalogContext(
        purchasable_only=False))
    ProductCatalog.index_product(product1)

    # Monday, 2am UTC - valid discounts
    with patch.object(timezone,
                      "now",
                      return_value=datetime(2021, 1, 4, 2, 0,
                                            tzinfo=pytz.utc)):
        _assert_price(product1, shop, Decimal("9"), Decimal("10"))
        _assert_products_queryset(catalog,
                                  [(product1.pk, Decimal("10"), Decimal("9"))])

    # it's Monday, 11:58pm in Brazil, the discount shouldn't be valid
    sao_paulo_tz = pytz.timezone("America/Sao_Paulo")
    with patch.object(timezone,
                      "now",
                      return_value=sao_paulo_tz.localize(
                          datetime(2021, 1, 4, 23, 58))):
        _assert_price(product1, shop, Decimal("10"), Decimal("10"))
        _assert_products_queryset(catalog,
                                  [(product1.pk, Decimal("10"), None)])

    # it's Monday, 2:58am in Brazil on Monday, the discount shouldn't be valid
    with patch.object(timezone,
                      "now",
                      return_value=sao_paulo_tz.localize(
                          datetime(2021, 1, 4, 2, 58))):
        _assert_price(product1, shop, Decimal("10"), Decimal("10"))
        _assert_products_queryset(catalog,
                                  [(product1.pk, Decimal("10"), None)])

    # it's Sunday, 11:58pm in Brazil, the discount should be available as it is Monday 2:58am in UTC
    with patch.object(timezone,
                      "now",
                      return_value=sao_paulo_tz.localize(
                          datetime(2021, 1, 3, 23, 58))):
        _assert_price(product1, shop, Decimal("9"), Decimal("10"))
        _assert_products_queryset(catalog,
                                  [(product1.pk, Decimal("10"), Decimal("9"))])