Example #1
0
def test_discount_for_logged_in_contacts(rf):
    default_price = 10
    request, product = _init_test_for_product(rf, default_price)
    assert request.customer == AnonymousContact()

    product_discount_amount = 2
    Discount.objects.create(
        shop=request.shop,
        active=True,
        contact_group=PersonContact.get_default_group(),
        discount_amount_value=product_discount_amount,
    )
    Discount.objects.create(
        shop=request.shop,
        active=True,
        contact_group=CompanyContact.get_default_group(),
        discount_amount_value=product_discount_amount,
    )
    assert product.get_price_info(request).price == request.shop.create_price(
        default_price)

    # setting customer to request should apply the discount
    request.customer = factories.create_random_person()
    assert product.get_price_info(request).price == request.shop.create_price(
        default_price - product_discount_amount)

    # Company as customer should work too
    request.customer = factories.create_random_company()
    assert product.get_price_info(request).price == request.shop.create_price(
        default_price - product_discount_amount)
def test_unsaved_contact(admin_user):
    payment_method = get_default_payment_method()
    _assign_component_for_service(payment_method, [PersonContact.get_default_group()])
    person = PersonContact(name="Kalle")
    source = _get_source_for_contact(admin_user, payment_method)
    source.customer = person
    assert not person.pk and not source.customer.pk
    _test_service_availability(source, payment_method, False)
def test_unsaved_contact(admin_user):
    payment_method = get_default_payment_method()
    _assign_component_for_service(payment_method, [PersonContact.get_default_group()])
    person = PersonContact(name="Kalle")
    source = _get_source_for_contact(admin_user, payment_method)
    source.customer = person
    assert not person.pk and not source.customer.pk
    _test_service_availability(source, payment_method, False)
Example #4
0
def _init_test():
    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)
    return shop, supplier, contact, group, category
Example #5
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 #6
0
def create_sample_product(name, description, business_segment, image_file,
                          shop):
    product = Product.objects.create(
        name=name,
        description=description,
        type=get_default_product_type(),
        tax_class=get_default_tax_class(),
        sales_unit=SalesUnit.objects.first(),
        sku=fuzzy.FuzzyText(length=10).fuzz(),
    )

    image_file_path = os.path.join(SAMPLE_IMAGES_BASE_DIR, image_file)
    path = "ProductImages/Samples/%s" % business_segment.capitalize()
    filer_image = _filer_image_from_file_path(image_file_path, path)

    media_file = MediaFile.objects.create(file=filer_image)
    media_file.shops.add(shop)

    media = ProductMedia.objects.create(product=product,
                                        kind=ProductMediaKind.IMAGE,
                                        file=filer_image)
    media.save()
    media.shops.add(shop)
    product.primary_image = media
    product.save()

    # create the price and round it to the number of decimals of the currency
    price = shop.create_price(
        decimal.Decimal(random.random() *
                        random.randrange(0, 500))).as_rounded()

    sp = ShopProduct.objects.create(
        product=product,
        purchasable=True,
        visibility=ShopProductVisibility.ALWAYS_VISIBLE,
        default_price_value=price,
        shop=shop,
        shop_primary_image=media,
    )
    supplier = get_default_supplier(shop)
    supplier.stock_managed = False
    supplier.save()
    sp.categories.set(shop.categories.all())
    sp.suppliers.add(supplier)

    # configure prices
    if "shuup.customer_group_pricing" in settings.INSTALLED_APPS:
        from shuup.customer_group_pricing.models import CgpPrice

        CgpPrice.objects.create(product=product,
                                price_value=random.randint(15, 340),
                                shop=shop,
                                group=PersonContact.get_default_group())

    return product
Example #7
0
def create_sample_product(name, description, business_segment, image_file, shop):
    product = Product.objects.create(
        name=name,
        description=description,
        type=get_default_product_type(),
        tax_class=get_default_tax_class(),
        sales_unit=SalesUnit.objects.first(),
        sku=fuzzy.FuzzyText(length=10).fuzz()
    )

    image_file_path = os.path.join(SAMPLE_IMAGES_BASE_DIR, image_file)
    path = "ProductImages/Samples/%s" % business_segment.capitalize()
    filer_image = _filer_image_from_file_path(image_file_path, path)

    media_file = MediaFile.objects.create(file=filer_image)
    media_file.shops.add(shop)

    media = ProductMedia.objects.create(
        product=product,
        kind=ProductMediaKind.IMAGE,
        file=filer_image
    )
    media.save()
    media.shops.add(shop)
    product.primary_image = media
    product.save()

    # create the price and round it to the number of decimals of the currency
    price = shop.create_price(decimal.Decimal(random.random() * random.randrange(0, 500))).as_rounded()

    sp = ShopProduct.objects.create(
        product=product,
        purchasable=True,
        visibility=ShopProductVisibility.ALWAYS_VISIBLE,
        default_price_value=price,
        shop=shop,
        shop_primary_image=media
    )
    sp.categories = shop.categories.all()
    sp.suppliers.add(get_default_supplier())

    # configure prices
    if "shuup.customer_group_pricing" in settings.INSTALLED_APPS:
        from shuup.customer_group_pricing.models import CgpPrice
        CgpPrice.objects.create(
            product=product,
            price_value=random.randint(15, 340),
            shop=shop,
            group=PersonContact.get_default_group()
        )

    return product
Example #8
0
def test_discount_for_person_contacts(rf):
    default_price = 10
    request, product = _init_test_for_product(rf, default_price)
    assert request.customer == AnonymousContact()

    product_discount_amount = 2
    Discount.objects.create(
        shop=request.shop,
        active=True,
        contact_group=PersonContact.get_default_group(),
        discount_amount_value=product_discount_amount,
    )
    assert product.get_price_info(request).price == request.shop.create_price(
        default_price)

    # Setting customer to request activates the discount
    request.customer = factories.create_random_person()
    assert product.get_price_info(request).price == request.shop.create_price(
        default_price - product_discount_amount)

    # Using company contact as customer means no discount
    request.customer = factories.create_random_company()
    assert product.get_price_info(request).price == request.shop.create_price(
        default_price)
Example #9
0
def test_default_person_contact_group_repr_and_str():
    pdg = PersonContact.get_default_group()
    assert repr(pdg) == '<ContactGroup:%d-default_person_group>' % pdg.pk
    assert str(pdg) == 'Person Contacts'
def test_admin_custom_customer_price_updates(rf, admin_user):
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    contact = factories.create_random_person()
    group = PersonContact.get_default_group()
    contact.groups.add(group)
    product_type = factories.get_default_product_type()
    tax_class = factories.get_default_tax_class()
    sales_unit = factories.get_default_sales_unit()

    view = ProductEditView.as_view()
    group_price = "10.0"
    default_price = "15.0"

    payload = {
        "base-name__en": "My Product",
        "base-type": product_type.pk,
        "base-sku": "p1",
        "base-shipping_mode": ShippingMode.NOT_SHIPPED.value,
        "base-tax_class": tax_class.pk,
        "base-sales_unit": sales_unit.pk,
        "base-width": "0",
        "base-height": "0",
        "base-depth": "0",
        "base-net_weight": "0",
        "base-gross_weight": "0",
        f"shop{shop.pk}-default_price_value": default_price,
        f"shop{shop.pk}-visibility":
        ShopProductVisibility.ALWAYS_VISIBLE.value,
        f"shop{shop.pk}-visibility_limit":
        ProductVisibility.VISIBLE_TO_ALL.value,
        f"shop{shop.pk}-minimum_purchase_quantity": "1",
        f"shop{shop.pk}-purchase_multiple": "1",
        f"shop{shop.pk}-suppliers": [supplier.pk],
        f"customer_group_pricing-s_{shop.pk}_g_{group.pk}":
        group_price,  # set price for the group
    }

    # create a new product
    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))

    product = Product.objects.first()
    _assert_products_queryset(anon_catalog,
                              [(product.pk, Decimal(default_price), None)])
    _assert_products_queryset(customer_catalog,
                              [(product.pk, Decimal(group_price), None)])

    payload.update({
        # remove the customer group price
        f"customer_group_pricing-s_{shop.pk}_g_{group.pk}": "",
        "media-TOTAL_FORMS": 0,
        "media-INITIAL_FORMS": 0,
        "media-MIN_NUM_FORMS": 0,
        "media-MAX_NUM_FORMS": 1000,
        "images-TOTAL_FORMS": 0,
        "images-INITIAL_FORMS": 0,
        "images-MIN_NUM_FORMS": 0,
        "images-MAX_NUM_FORMS": 1000,
    })

    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=product.get_shop_instance(shop).pk)
    assert response.status_code == 302

    # default price for both
    _assert_products_queryset(anon_catalog,
                              [(product.pk, Decimal(default_price), None)])
    _assert_products_queryset(customer_catalog,
                              [(product.pk, Decimal(default_price), None)])
Example #11
0
 def filter(self):
     return json.dumps({"groups": [PersonContact.get_default_group().pk]})
Example #12
0
 def filter(self):
     return json.dumps({"groups": [PersonContact.get_default_group().pk]})
Example #13
0
def test_default_person_contact_group_repr_and_str():
    pdg = PersonContact.get_default_group()
    assert repr(pdg) == '<ContactGroup:%d-default_person_group>' % pdg.pk
    assert str(pdg) == 'Person Contacts'
Example #14
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 #15
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)