예제 #1
0
def test_admin_edit(rf, admin_user):
    shop = get_default_shop()

    group = get_default_customer_group(shop)
    cgpd = ContactGroupPriceDisplay.objects.for_group_and_shop(group, shop)
    view = ContactGroupPriceDisplayEditView.as_view()


    options = get_price_display_options_for_group_and_shop(group, shop)
    assert options.show_prices

    request = apply_request_middleware(rf.get("/"), user=admin_user)
    response = view(request, pk=cgpd.pk)
    response.render()
    content = force_text(response.content)

    data = extract_form_fields(BeautifulSoup(content))

    data.update({
        "price_display_mode": [PriceDisplayChoices.HIDE.value],
        "group": group.id,
    })

    request = apply_request_middleware(rf.post("/", data), user=admin_user, shop=shop)
    response = view(request, pk=cgpd.pk)
    assert response.status_code == 302  # save successful

    group = get_default_customer_group(shop)

    options = get_price_display_options_for_group_and_shop(group, shop)
    assert options.show_prices is False
    assert options.include_taxes is None

    # none, with_taxes, without_taxes, hide
    k = "price_display_mode"
    data.update({k: [PriceDisplayChoices.NONE.value]})
    request = apply_request_middleware(rf.post("/", data), user=admin_user, shop=shop)
    response = view(request, pk=cgpd.pk)
    assert response.status_code == 302  # save successful

    options = get_price_display_options_for_group_and_shop(group, shop)
    assert options.show_prices is True  # default
    assert options.include_taxes is None

    data.update({k: [PriceDisplayChoices.WITH_TAXES.value]})
    request = apply_request_middleware(rf.post("/", data), user=admin_user, shop=shop)
    response = view(request, pk=cgpd.pk)
    assert response.status_code == 302  # save successful
    options = get_price_display_options_for_group_and_shop(group, shop)
    assert options.show_prices is True  # default
    assert options.include_taxes is True

    data.update({k: [PriceDisplayChoices.WITHOUT_TAXES.value]})
    request = apply_request_middleware(rf.post("/", data), user=admin_user, shop=shop)
    response = view(request, pk=cgpd.pk)
    assert response.status_code == 302  # save successful

    options = get_price_display_options_for_group_and_shop(group, shop)
    assert options.show_prices is True
    assert options.include_taxes is False
예제 #2
0
파일: test_form.py 프로젝트: ruqaiya/shuup
def _get_test_product():
    shop = get_default_shop()
    product = create_product("Just-A-Pricing-Product", shop, default_price=200)
    CgpPrice.objects.create(
        product=product, shop=shop, group=get_default_customer_group(),
        price_value=250)
    CgpDiscount.objects.create(
        product=product, shop=shop, group=get_default_customer_group(),
        discount_amount_value=100)
    return product
예제 #3
0
파일: test_form.py 프로젝트: ruqaiya/shuup
def test_change_shop_price(form):
    product = _get_test_product()
    shop = get_default_shop()
    group = get_default_customer_group()
    price = shop.create_price

    form_field = "s_%d_g_%d" % (shop.id, group.id)
    frm = form(product=product, shop=shop, empty_permitted=True)
    form_data = get_form_data(frm, prepared=True)

    if form == CustomerGroupPricingForm:
        form_data[form_field] = "4000"
    else:
        form_data[form_field] = "50"

    frm = form(product=product, shop=shop, data=form_data, empty_permitted=True)
    frm.full_clean()
    frm.save()

    if form == CustomerGroupPricingForm:
        assert CgpPrice.objects.get(product=product, shop=shop, group=group).price == price(4000)
    else:
        assert CgpDiscount.objects.get(product=product, shop=shop, group=group).discount_amount == price(50)

    # Never mind actually, same price for all shops
    form_data[form_field] = ""

    frm = form(product=product, shop=shop, data=form_data, empty_permitted=True)
    frm.full_clean()
    frm.save()

    if form == CustomerGroupPricingForm:
        assert not CgpPrice.objects.filter(product=product, shop=shop, group=group).exists()
    else:
        assert not CgpDiscount.objects.filter(product=product, shop=shop, group=group).exists()
예제 #4
0
def test_editing_sales_ranges_multi_shop(rf, admin_user):
    get_default_shop()
    another_shop = get_shop(prices_include_tax=True)
    another_shop.status = ShopStatus.ENABLED
    another_shop.save()
    group = get_default_customer_group()
    data = {}
    for shop in Shop.objects.all():
        data.update(get_edit_view_data(shop, group, 0, 50))

    assert ContactGroupSalesRange.objects.count() == 0
    # To make this test work we need to mock members form_part since the extra
    # forms does not render correctly
    with patch.object(ContactGroupEditView, "base_form_part_classes", [ContactGroupBaseFormPart]):
        request = apply_request_middleware(rf.post("/", data=data), user=admin_user)
        view = ContactGroupEditView.as_view()
        response = view(request=request, pk=group.pk)
        if hasattr(response, "render"):
            response.render()
        assert response.status_code in [200, 302]

    assert ContactGroupSalesRange.objects.count() == 2
    for shop in Shop.objects.all():
        sales_range = ContactGroupSalesRange.objects.filter(group=group, shop=shop).first()
        assert sales_range.min_value == 0
        assert sales_range.max_value == 50
예제 #5
0
def test_order_creator_customer_details(rf, admin_user):
    shop = get_default_shop()
    contact = create_random_person(locale="en_US", minimum_name_comp_len=5)
    company = create_random_company()
    group = get_default_customer_group()
    contact.groups.add(group)
    contact.company_memberships.add(company)
    contact.save()
    product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop)
    order = create_random_order(contact, products=[product])
    request = apply_request_middleware(rf.get("/", {"command": "customer_details", "id": contact.id}), user=admin_user)
    response = OrderEditView.as_view()(request)
    data = json.loads(response.content.decode("utf8"))

    assert "customer_info" in data
    assert "order_summary" in data
    assert "recent_orders" in data
    assert data["customer_info"]["name"] == contact.full_name
    assert data["customer_info"]["phone_no"] == contact.phone
    assert data["customer_info"]["email"] == contact.email
    assert company.full_name in data["customer_info"]["companies"]
    assert group.name in data["customer_info"]["groups"]
    assert data["customer_info"]["merchant_notes"] == contact.merchant_notes
    assert len(data["order_summary"]) == 1
    assert data["order_summary"][0]["year"] == order.order_date.year
    assert data["order_summary"][0]["total"] == format_money(order.taxful_total_price)
    assert len(data["recent_orders"]) == 1
    assert data["recent_orders"][0]["status"] == order.get_status_display()
    assert data["recent_orders"][0]["total"] == format_money(order.taxful_total_price)
    assert data["recent_orders"][0]["payment_status"] == force_text(order.payment_status.label)
    assert data["recent_orders"][0]["shipment_status"] == force_text(order.shipping_status.label)
def test_product_visibility(rf, admin_user, regular_user):
    anon_contact = get_person_contact(AnonymousUser())
    shop_product = get_default_shop_product()
    admin_contact = get_person_contact(admin_user)
    regular_contact = get_person_contact(regular_user)


    with modify(shop_product.product, deleted=True):  # NB: assigning to `product` here works because `get_shop_instance` populates `_product_cache`
        assert error_exists(shop_product.get_visibility_errors(customer=anon_contact), "product_deleted")
        assert error_exists(shop_product.get_visibility_errors(customer=admin_contact), "product_deleted")
        with pytest.raises(ProductNotVisibleProblem):
            shop_product.raise_if_not_visible(anon_contact)
        assert not shop_product.is_list_visible()

    with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_ALL, visibility=ShopProductVisibility.NOT_VISIBLE):
        assert error_exists(shop_product.get_visibility_errors(customer=anon_contact), "product_not_visible")
        assert error_does_not_exist(shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible")
        assert not shop_product.is_list_visible()

    with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_LOGGED_IN, visibility=ShopProductVisibility.ALWAYS_VISIBLE):
        assert error_exists(shop_product.get_visibility_errors(customer=anon_contact), "product_not_visible_to_anonymous")
        assert error_does_not_exist(shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible_to_anonymous")

    customer_group = get_default_customer_group()
    grouped_user = get_user_model().objects.create_user(username=printable_gibberish(20))
    grouped_contact = get_person_contact(grouped_user)
    with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_GROUPS, visibility=ShopProductVisibility.ALWAYS_VISIBLE):
        shop_product.visibility_groups.add(customer_group)
        customer_group.members.add(grouped_contact)
        customer_group.members.remove(get_person_contact(regular_user))
        assert error_does_not_exist(shop_product.get_visibility_errors(customer=grouped_contact), "product_not_visible_to_group")
        assert error_does_not_exist(shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible_to_group")
        assert error_exists(shop_product.get_visibility_errors(customer=regular_contact), "product_not_visible_to_group")
예제 #7
0
def test_category_links_plugin_with_customer(rf, show_all_categories):
    """
    Test plugin for categories that is visible for certain group
    """
    shop = get_default_shop()
    group = get_default_customer_group()
    customer = create_random_person()
    customer.groups.add(group)
    customer.save()

    request = rf.get("/")
    request.shop = get_default_shop()
    apply_request_middleware(request)
    request.customer = customer

    category = get_default_category()
    category.status = CategoryStatus.VISIBLE
    category.visibility = CategoryVisibility.VISIBLE_TO_GROUPS
    category.visibility_groups.add(group)
    category.shops.add(shop)
    category.save()

    vars = {"request": request}
    context = get_jinja_context(**vars)
    plugin = CategoryLinksPlugin({"categories": [category.pk], "show_all_categories": show_all_categories})
    assert category.is_visible(customer)
    assert category in plugin.get_context_data(context)["categories"]

    customer_without_groups = create_random_person()
    customer_without_groups.groups.clear()

    assert not category.is_visible(customer_without_groups)
    request.customer = customer_without_groups
    context = get_jinja_context(**vars)
    assert category not in plugin.get_context_data(context)["categories"]
def get_default_behavior_settings():
    return {
        FixedCostBehaviorComponent.__name__.lower(): {
            "description__en": "Fixed cost test",
            "price_value": 1,
            "id": "",
        },
        WaivingCostBehaviorComponent.__name__.lower(): {
            "description__en": "Waiving cost test",
            "price_value": 1,
            "waive_limit_value": 1,
            "id": "",
        },
        "weight_based_price_ranges": {
            "description__en": "Weight based pricing test",
            "price_value": 1,
            "min_value": 1,
            "max_value": 2,
            "id": "",
        },
        WeightLimitsBehaviorComponent.__name__.lower(): {
            "min_weight": 0,
            "max_weight": 1,
            "id": "",
        },
        GroupAvailabilityBehaviorComponent.__name__.lower(): {
            "groups": [get_default_customer_group().pk]
        },
        RoundingBehaviorComponent.__name__.lower(): {
            "mode": RoundingMode.ROUND_UP.value,
            "quant": decimal.Decimal('0.05')
        },
        StaffOnlyBehaviorComponent.__name__.lower(): {}
    }
예제 #9
0
def test_basic_form_sanity(form):
    shop = get_default_shop()
    group = get_default_customer_group()
    product = _get_test_product()
    frm = form(product=product, empty_permitted=True)
    assert len(frm.groups) == ContactGroup.objects.count()
    assert len(frm.shops) == Shop.objects.count()

    assert "s_%d_g_%d" % (shop.id, group.id) in frm.fields
예제 #10
0
def test_form_part_for_random_group(rf, admin_user):
    get_default_shop()
    group = get_default_customer_group()
    request = apply_request_middleware(rf.get("/"), user=admin_user)
    initialized_view = ContactGroupEditView(request=request, kwargs={"pk": group.pk})
    initialized_view.object = initialized_view.get_object() # Just for test
    form_def_values = initialized_view.get_form().form_defs.values()
    assert [form_def for form_def in form_def_values if form_def.name == "base"]
    # contact_group_sales_ranges should be in form defs
    assert [form_def for form_def in form_def_values if "contact_group_sales_ranges" in form_def.name]
예제 #11
0
def test_condition_doesnt_match(rf):
    activate("en")
    request, shop, group = initialize_test(rf, False)
    condition = ContactGroupCondition.objects.create()
    condition.contact_groups = [get_default_customer_group()]
    condition.save()

    request.customer = None

    assert not condition.matches(request)
예제 #12
0
def test_customers(django_user_model):
    users = [django_user_model.objects.create_user('Joe-%d' % x, '*****@*****.**' % x, 'password') for x in range(10)]
    group = get_default_customer_group()
    assert str(group) == DEFAULT_NAME
    for user in users:
        contact = get_person_contact(user)
        group.members.add(contact)

    for user in users:
        assert PersonContact.objects.get(user=user).user_id == user.pk, "Customer profile found"
        assert DEFAULT_IDENTIFIER in user.contact.groups.values_list("identifier", flat=True), "Joe is now in the group"
def initialize_test(rf, include_tax=False):
    shop = get_shop(prices_include_tax=include_tax)

    group = get_default_customer_group()
    customer = create_random_person()
    customer.groups.add(group)
    customer.save()

    request = apply_request_middleware(rf.get("/"))
    request.shop = shop
    request.customer = customer
    return request, shop, group
예제 #14
0
def test_with_multiple_groups(admin_user):
    payment_method = get_default_payment_method()
    group = get_default_customer_group()
    person = create_random_person()
    groups = [group, person.get_default_group()]
    _assign_component_for_service(payment_method, groups)

    person.user = admin_user
    person.save()
    source = _get_source_for_contact(admin_user, payment_method)
    assert source.customer == person
    assert len([group for group in person.groups.all() if group in groups]) == 1
    _test_service_availability(source, payment_method, True)
예제 #15
0
파일: test_form.py 프로젝트: ruqaiya/shuup
def test_basic_form_sanity(form):
    shop = get_default_shop()
    group = get_default_customer_group()
    product = _get_test_product()

    kwargs = dict(product=product, shop=shop)
    if form == CustomerGroupPricingForm:
        kwargs.update(dict(empty_permitted=True))

    frm = form(**kwargs)

    assert len(frm.groups) == ContactGroup.objects.count()

    assert "s_%d_g_%d" % (shop.id, group.id) in frm.fields
예제 #16
0
def test_contact_group_members_formset(rf):
    FormSet = formset_factory(ContactGroupMembersForm, ContactGroupMembersFormSet, extra=1, can_delete=True)
    contact_group = get_default_customer_group()
    person = create_random_person()

    # No members
    formset = FormSet(contact_group=contact_group)
    assert formset.initial_form_count() == 0

    # Add a member
    data = dict(get_form_data(formset, True), **{"form-0-member": person.pk})
    formset = FormSet(contact_group=contact_group, data=data)
    formset.save()
    assert contact_group.members.filter(pk=person.pk).exists()
예제 #17
0
def test_contact_group_behavior(admin_user):
    payment_method = get_default_payment_method()
    group = get_default_customer_group()
    _assign_component_for_service(payment_method, [group])

    person = create_random_person()
    person.user = admin_user
    person.save()
    source = _get_source_for_contact(admin_user, payment_method)
    assert source.customer == person
    assert group not in person.groups.all()
    _test_service_availability(source, payment_method, False)

    person.groups.add(group)
    assert group in person.groups.all()
    _test_service_availability(source, payment_method, True)
예제 #18
0
def test_context_contact_group_condition(rf):
    original_price_value, discount_value = 123, 15
    request = get_request_for_contact_tests(rf)
    customer = create_random_person()
    default_group = get_default_customer_group()
    customer.groups.add(default_group)
    request.customer = customer

    condition = ContactGroupCondition.objects.create()
    condition.contact_groups.add(default_group)
    product = create_random_product_and_campaign(request.shop, [condition], original_price_value, discount_value)

    discounted_value = original_price_value - discount_value
    assert_product_price_value_with_customer(request, customer, product, discounted_value)

    request.customer.groups.clear()
    assert_product_price_value_with_customer(request, customer, product, original_price_value)
예제 #19
0
def test_product_query_with_group_visibility(regular_user):
    default_group = get_default_customer_group()
    shop_product = get_default_shop_product()
    shop_product.visibility_limit = 3
    shop_product.save()
    shop = shop_product.shop
    product = shop_product.product
    shop_product.visibility_groups.add(default_group)
    regular_contact = get_person_contact(regular_user)

    assert not Product.objects.listed(shop=shop, customer=regular_contact).filter(pk=product.pk).exists()
    regular_contact.groups.add(default_group)
    assert Product.objects.listed(shop=shop, customer=regular_contact).filter(pk=product.pk).count() == 1

    shop_product.visibility_groups.add(regular_contact.get_default_group())
    # Multiple visibility groups for shop product shouldn't cause duplicate matches
    assert Product.objects.listed(shop=shop, customer=regular_contact).filter(pk=product.pk).count() == 1
def test_basket_contact_group_condition(rf):
    product_price_value, campaign_discount_value = 123, 15
    request = get_request_for_contact_tests(rf)
    customer = create_random_person()
    default_group = get_default_customer_group()
    customer.groups.add(default_group)
    request.customer = customer

    condition = ContactGroupBasketCondition.objects.create()
    condition.contact_groups.add(default_group)
    basket, original_line_count, original_price = create_basket_and_campaign(
        request, [condition], product_price_value, campaign_discount_value)

    assert basket.customer == customer
    assert_discounted_basket(basket, original_line_count, original_price, campaign_discount_value)

    customer.groups.remove(default_group)
    assert_non_discounted_basket(basket, original_line_count, original_price)
예제 #21
0
def test_editing_sales_ranges(rf, admin_user):
    shop = get_default_shop()
    group = get_default_customer_group()
    data = get_edit_view_data(shop, group, 1, 100)
    assert ContactGroupSalesRange.objects.count() == 0
    # To make this test work we need to mock members form_part since the
    # extra forms does not render correctly
    with patch.object(ContactGroupEditView, "base_form_part_classes", [ContactGroupBaseFormPart]):
        request = apply_request_middleware(rf.post("/", data=data), user=admin_user)
        view = ContactGroupEditView.as_view()
        response = view(request=request, pk=group.pk)
        if hasattr(response, "render"):
            response.render()
        assert response.status_code in [200, 302]

    sales_range = ContactGroupSalesRange.objects.filter(group=group, shop=shop).first()
    assert sales_range.min_value == 1
    assert sales_range.max_value == 100
예제 #22
0
def test_clear_prices(form):
    product = _get_test_product()
    # We can clear the prices out, can't we?
    form_data = {}

    if form == CustomerGroupDiscountForm:
        group = get_default_customer_group()
        shop = get_default_shop()
        CgpDiscount.objects.create(product=product, shop=shop, group=group, discount_amount_value=10)

    frm = form(product=product, data=form_data, empty_permitted=True)
    frm.full_clean()
    frm.save()

    if form == CustomerGroupPricingForm:
        assert not CgpPrice.objects.filter(product=product).exists()
    else:
        assert not CgpDiscount.objects.filter(product=product, shop=shop).exists()
예제 #23
0
def test_order_customer_groups(rf, admin_user):
    customer = create_random_person()
    default_group = get_default_customer_group()
    default_group.members.add(customer)
    source = seed_source(admin_user)
    source.customer=customer

    source.add_line(
        type=OrderLineType.PRODUCT,
        product=get_default_product(),
        supplier=get_default_supplier(),
        quantity=1,
        base_unit_price=source.create_price(10),
    )
    source.add_line(
        type=OrderLineType.OTHER,
        quantity=1,
        base_unit_price=source.create_price(10),
        require_verification=True,
    )

    creator = OrderCreator()
    order = creator.create_order(source)
    assert get_data_dict(source.billing_address) == get_data_dict(order.billing_address)
    assert get_data_dict(source.shipping_address) == get_data_dict(order.shipping_address)
    customer = source.customer
    assert customer == order.customer
    assert customer.groups.count() == 2
    assert order.customer_groups.filter(id=default_group.id).exists()
    with pytest.raises(ProtectedError):
        default_group.delete()

    assert customer.tax_group is not None
    assert customer.tax_group == order.tax_group
    with pytest.raises(ProtectedError):
        customer.tax_group.delete()

    new_group = create_random_contact_group()
    new_group.members.add(customer)

    order.phone = "911"
    order.save()
    assert order.customer_groups.filter(id=default_group.id).exists()
    assert not order.customer_groups.filter(id=new_group.id).exists()
예제 #24
0
def test_get_by_contact_group(admin_user):
    get_default_shop()
    for i in range(0, 10):
        create_random_person()

    contact = create_random_person()
    group = get_default_customer_group()
    group.members.add(contact)

    client = _get_client(admin_user)

    response = client.get("/api/shuup/contact/", data={"groups": group.id})
    assert response.status_code == status.HTTP_200_OK
    contact_data = json.loads(response.content.decode("utf-8"))

    assert group.members.count() == len(contact_data)
    assert contact_data[0].get("id") == contact.id
    assert contact_data[0].get("email") == contact.email
    assert contact_data[0].get("name") == contact.name
예제 #25
0
파일: __init__.py 프로젝트: gurch101/shuup
def initialize_test(rf, include_tax=False):
    activate("en")
    shop = get_shop(prices_include_tax=include_tax)

    # Valid baskets needs some payment methods to be available
    get_payment_method(shop)
    # Since some of the baskets are created for the default shop:
    get_payment_method(None)

    group = get_default_customer_group()
    customer = create_random_person()
    customer.groups.add(group)
    customer.save()

    request = rf.get("/")
    request.shop = shop
    apply_request_middleware(request)
    request.customer = customer
    return request, shop, group
예제 #26
0
def test_sales_ranges_basic():
    shop = get_default_shop()
    supplier = get_default_supplier()
    default_group = get_default_customer_group()
    # Create non active range for default group
    ContactGroupSalesRange.objects.create(group=default_group, shop=shop, min_value=0, max_value=0)
    person = create_random_person()
    default_group.members.add(person)
    initial_group_count = person.groups.count()
    sales_ranges = [
        ("silver", 0, 50),
        ("gold", 50, 100),
        ("diamond", 100, 1000)
    ]
    for identifier, min, max in sales_ranges:
        create_sales_range(identifier, shop, min, max)

    payment = create_fully_paid_order(shop, person, supplier, "sku1", 10)
    assert get_total_sales(shop, person) == 10
    update_customers_groups(Payment, payment)
    assert person.groups.count() == (initial_group_count + 1)
    assert bool([group for group in person.groups.all() if group.identifier == "silver"])
    # Since group has inactive range person shouldn't be removed from it
    assert bool([group for group in person.groups.all() if group == default_group])

    payment = create_fully_paid_order(shop, person, supplier, "sku2", 50)
    assert get_total_sales(shop, person) == 60
    update_customers_groups(Payment, payment)
    assert person.groups.count() == (initial_group_count + 1)
    assert bool([group for group in person.groups.all() if group.identifier == "gold"])
    # Since group has inactive range person shouldn't be removed from it
    assert bool([group for group in person.groups.all() if group == default_group])

    payment = create_fully_paid_order(shop, person, supplier, "sku3", 200)
    assert get_total_sales(shop, person) == 260
    update_customers_groups(Payment, payment)
    assert person.groups.count() == (initial_group_count + 1)
    assert bool([group for group in person.groups.all() if group.identifier == "diamond"])
    # Since group has inactive range person shouldn't be removed from it
    assert bool([group for group in person.groups.all() if group == default_group])
예제 #27
0
def test_category_copy_visibility(rf, admin_user):
    shop = get_default_shop()
    group = get_default_customer_group()
    category = get_default_category()
    category.status = CategoryStatus.INVISIBLE
    category.visibility = CategoryVisibility.VISIBLE_TO_GROUPS
    category.shops.add(shop)
    category.visibility_groups.add(group)
    category.save()
    product = create_product("test_product", shop=shop)
    shop_product = product.get_shop_instance(shop)
    shop_product.primary_category = category
    shop_product.save()
    view = CategoryCopyVisibilityView.as_view()
    request = apply_request_middleware(rf.post("/"), user=admin_user)
    response = view(request, pk=category.pk)
    shop_product.refresh_from_db()
    assert response.status_code == 200
    assert shop_product.visibility == ShopProductVisibility.NOT_VISIBLE
    assert shop_product.visibility_limit.value == category.visibility.value
    assert shop_product.visibility_groups.count() == category.visibility_groups.count()
    assert set(shop_product.visibility_groups.all()) == set(category.visibility_groups.all())
예제 #28
0
def test_category_links_plugin_with_customer(rf, show_all_categories):
    """
    Test plugin for categories that is visible for certain group
    """
    shop = get_default_shop()
    group = get_default_customer_group()
    customer = create_random_person()
    customer.groups.add(group)
    customer.save()

    request = rf.get("/")
    request.shop = get_default_shop()
    apply_request_middleware(request)
    request.customer = customer

    category = get_default_category()
    category.status = CategoryStatus.VISIBLE
    category.visibility = CategoryVisibility.VISIBLE_TO_GROUPS
    category.visibility_groups.add(group)
    category.shops.add(shop)
    category.save()

    vars = {"request": request}
    context = get_jinja_context(**vars)
    plugin = CategoryLinksPlugin({
        "categories": [category.pk],
        "show_all_categories": show_all_categories
    })
    assert category.is_visible(customer)
    assert category in plugin.get_context_data(context)["categories"]

    customer_without_groups = create_random_person()
    customer_without_groups.groups.clear()

    assert not category.is_visible(customer_without_groups)
    request.customer = customer_without_groups
    context = get_jinja_context(**vars)
    assert category not in plugin.get_context_data(context)["categories"]
예제 #29
0
def test_order_creator_customer_details(rf, admin_user):
    shop = get_default_shop()
    contact = create_random_person(locale="en_US", minimum_name_comp_len=5)
    company = create_random_company()
    group = get_default_customer_group()
    contact.groups.add(group)
    contact.company_memberships.add(company)
    contact.save()
    product = create_product(
        sku=printable_gibberish(),
        supplier=get_default_supplier(),
        shop=shop
    )
    order = create_random_order(contact, products=[product])
    request = apply_request_middleware(rf.get("/", {
        "command": "customer_details",
        "id": contact.id
    }), user=admin_user)
    response =OrderEditView.as_view()(request)
    data = json.loads(response.content.decode("utf8"))

    assert "customer_info" in data
    assert "order_summary" in data
    assert "recent_orders" in data
    assert data["customer_info"]["name"] == contact.full_name
    assert data["customer_info"]["phone_no"] == contact.phone
    assert data["customer_info"]["email"] == contact.email
    assert company.full_name in data["customer_info"]["companies"]
    assert group.name in data["customer_info"]["groups"]
    assert data["customer_info"]["merchant_notes"] == contact.merchant_notes
    assert len(data["order_summary"]) == 1
    assert data["order_summary"][0]["year"] == order.order_date.year
    assert data["order_summary"][0]["total"] == format_money(order.taxful_total_price)
    assert len(data["recent_orders"]) == 1
    assert data["recent_orders"][0]["status"] == order.get_status_display()
    assert data["recent_orders"][0]["total"] == format_money(order.taxful_total_price)
    assert data["recent_orders"][0]["payment_status"] == force_text(order.payment_status.label)
    assert data["recent_orders"][0]["shipment_status"] == force_text(order.shipping_status.label)
def get_default_behavior_settings():
    return {
        FixedCostBehaviorComponent.__name__.lower(): {
            "description__en": "Fixed cost test",
            "price_value": 1,
            "id": "",
        },
        WaivingCostBehaviorComponent.__name__.lower(): {
            "description__en": "Waiving cost test",
            "price_value": 1,
            "waive_limit_value": 1,
            "id": "",
        },
        "weight_based_price_ranges": {
            "description__en": "Weight based pricing test",
            "price_value": 1,
            "min_value": 1,
            "max_value": 2,
            "id": "",
        },
        WeightLimitsBehaviorComponent.__name__.lower(): {
            "min_weight": 0,
            "max_weight": 1,
            "id": "",
        },
        GroupAvailabilityBehaviorComponent.__name__.lower(): {
            "groups": [get_default_customer_group().pk]
        },
        StaffOnlyBehaviorComponent.__name__.lower(): {},
        OrderTotalLimitBehaviorComponent.__name__.lower(): {
            "min_price_value": 0,
            "max_price_value": 21
        },
        CountryLimitBehaviorComponent.__name__.lower(): {
            "available_in_countries": ["FI",]
        }
    }
def get_default_behavior_settings():
    return {
        FixedCostBehaviorComponent.__name__.lower(): {
            "description__en": "Fixed cost test",
            "price_value": 1,
            "id": "",
        },
        WaivingCostBehaviorComponent.__name__.lower(): {
            "description__en": "Waiving cost test",
            "price_value": 1,
            "waive_limit_value": 1,
            "id": "",
        },
        "weight_based_price_ranges": {
            "description__en": "Weight based pricing test",
            "price_value": 1,
            "min_value": 1,
            "max_value": 2,
            "id": "",
        },
        WeightLimitsBehaviorComponent.__name__.lower(): {
            "min_weight": 0,
            "max_weight": 1,
            "id": "",
        },
        GroupAvailabilityBehaviorComponent.__name__.lower(): {
            "groups": [get_default_customer_group().pk]
        },
        StaffOnlyBehaviorComponent.__name__.lower(): {},
        OrderTotalLimitBehaviorComponent.__name__.lower(): {
            "min_price_value": 0,
            "max_price_value": 21
        },
        CountryLimitBehaviorComponent.__name__.lower(): {
            "available_in_countries": ["FI",]
        }
    }
예제 #32
0
def test_sales_ranges_basic():
    shop = get_default_shop()
    supplier = get_default_supplier()
    default_group = get_default_customer_group()
    # Create non active range for default group
    ContactGroupSalesRange.objects.create(group=default_group, shop=shop, min_value=0, max_value=0)
    person = create_random_person()
    default_group.members.add(person)
    initial_group_count = person.groups.count()
    sales_ranges = [("silver", 0, 50), ("gold", 50, 100), ("diamond", 100, 1000)]
    for identifier, min, max in sales_ranges:
        create_sales_range(identifier, shop, min, max)

    payment = create_fully_paid_order(shop, person, supplier, "sku1", 10)
    assert get_total_sales(shop, person) == 10
    update_customers_groups(Payment, payment)
    assert person.groups.count() == (initial_group_count + 1)
    assert bool([group for group in person.groups.all() if group.identifier == "silver"])
    # Since group has inactive range person shouldn't be removed from it
    assert bool([group for group in person.groups.all() if group == default_group])

    payment = create_fully_paid_order(shop, person, supplier, "sku2", 50)
    assert get_total_sales(shop, person) == 60
    update_customers_groups(Payment, payment)
    assert person.groups.count() == (initial_group_count + 1)
    assert bool([group for group in person.groups.all() if group.identifier == "gold"])
    # Since group has inactive range person shouldn't be removed from it
    assert bool([group for group in person.groups.all() if group == default_group])

    payment = create_fully_paid_order(shop, person, supplier, "sku3", 200)
    assert get_total_sales(shop, person) == 260
    update_customers_groups(Payment, payment)
    assert person.groups.count() == (initial_group_count + 1)
    assert bool([group for group in person.groups.all() if group.identifier == "diamond"])
    # Since group has inactive range person shouldn't be removed from it
    assert bool([group for group in person.groups.all() if group == default_group])
예제 #33
0
def test_category_copy_visibility(rf, admin_user):
    shop = get_default_shop()
    group = get_default_customer_group()
    category = get_default_category()
    category.status = CategoryStatus.INVISIBLE
    category.visibility = CategoryVisibility.VISIBLE_TO_GROUPS
    category.shops.add(shop)
    category.visibility_groups.add(group)
    category.save()
    product = create_product("test_product", shop=shop)
    shop_product = product.get_shop_instance(shop)
    shop_product.primary_category = category
    shop_product.save()
    view = CategoryCopyVisibilityView.as_view()
    request = apply_request_middleware(rf.post("/"), user=admin_user)
    response = view(request, pk=category.pk)
    shop_product.refresh_from_db()
    assert response.status_code == 200
    assert shop_product.visibility == ShopProductVisibility.NOT_VISIBLE
    assert shop_product.visibility_limit.value == category.visibility.value
    assert shop_product.visibility_groups.count(
    ) == category.visibility_groups.count()
    assert set(shop_product.visibility_groups.all()) == set(
        category.visibility_groups.all())
예제 #34
0
def test_change_shop_price(form):
    product = _get_test_product()
    shop = get_default_shop()
    group = get_default_customer_group()
    price = shop.create_price

    form_field = "s_%d_g_%d" % (shop.id, group.id)

    frm = form(product=product, empty_permitted=True)
    form_data = get_form_data(frm, prepared=True)

    if form == CustomerGroupPricingForm:
        # Price hike time!
        form_data[form_field] = "4000"
    else:
        form_data[form_field] = "200"

    frm = form(product=product, data=form_data, empty_permitted=True)
    frm.full_clean()
    frm.save()

    if form == CustomerGroupPricingForm:
        assert CgpPrice.objects.get(product=product, shop=shop, group=group).price == price(4000)
    else:
        assert CgpDiscount.objects.get(product=product, shop=shop, group=group).discount_amount == price(200)

    # Never mind actually, same price for all shops
    form_data[form_field] = ""
    frm = form(product=product, data=form_data, empty_permitted=True)
    frm.full_clean()
    frm.save()

    if form == CustomerGroupPricingForm:
        assert not CgpPrice.objects.filter(product=product, shop=shop, group=group).exists()
    else:
        assert not CgpDiscount.objects.filter(product=product, shop=shop, group=group).exists()
예제 #35
0
def test_product_visibility(rf, admin_user, regular_user):
    anon_contact = get_person_contact(AnonymousUser())
    shop_product = get_default_shop_product()
    admin_contact = get_person_contact(admin_user)
    regular_contact = get_person_contact(regular_user)

    configuration.set(None, get_all_seeing_key(admin_contact), True)

    with modify(shop_product.product, deleted=True):  # NB: assigning to `product` here works because `get_shop_instance` populates `_product_cache`
        assert error_exists(shop_product.get_visibility_errors(customer=anon_contact), "product_deleted")
        assert error_exists(shop_product.get_visibility_errors(customer=admin_contact), "product_deleted")
        with pytest.raises(ProductNotVisibleProblem):
            shop_product.raise_if_not_visible(anon_contact)
        assert not shop_product.is_list_visible()

    with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_ALL, visibility=ShopProductVisibility.NOT_VISIBLE):
        assert error_exists(shop_product.get_visibility_errors(customer=anon_contact), "product_not_visible")
        assert error_does_not_exist(shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible")
        assert not shop_product.is_list_visible()

    with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_LOGGED_IN, visibility=ShopProductVisibility.ALWAYS_VISIBLE):
        assert error_exists(shop_product.get_visibility_errors(customer=anon_contact), "product_not_visible_to_anonymous")
        assert error_does_not_exist(shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible_to_anonymous")

    customer_group = get_default_customer_group()
    grouped_user = get_user_model().objects.create_user(username=printable_gibberish(20))
    grouped_contact = get_person_contact(grouped_user)
    with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_GROUPS, visibility=ShopProductVisibility.ALWAYS_VISIBLE):
        shop_product.visibility_groups.add(customer_group)
        customer_group.members.add(grouped_contact)
        customer_group.members.remove(get_person_contact(regular_user))
        assert error_does_not_exist(shop_product.get_visibility_errors(customer=grouped_contact), "product_not_visible_to_group")
        assert error_does_not_exist(shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible_to_group")
        assert error_exists(shop_product.get_visibility_errors(customer=regular_contact), "product_not_visible_to_group")

    configuration.set(None, get_all_seeing_key(admin_contact), False)
예제 #36
0
def test_admin_edit(rf, admin_user):
    shop = get_default_shop()

    group = get_default_customer_group(shop)
    cgpd = ContactGroupPriceDisplay.objects.for_group_and_shop(group, shop)
    view = ContactGroupPriceDisplayEditView.as_view()

    options = get_price_display_options_for_group_and_shop(group, shop)
    assert options.show_prices

    request = apply_request_middleware(rf.get("/"), user=admin_user)
    response = view(request, pk=cgpd.pk)
    response.render()
    content = force_text(response.content)

    data = extract_form_fields(BeautifulSoup(content))

    data.update({
        "price_display_mode": [PriceDisplayChoices.HIDE.value],
        "group": group.id,
    })

    request = apply_request_middleware(rf.post("/", data),
                                       user=admin_user,
                                       shop=shop)
    response = view(request, pk=cgpd.pk)
    assert response.status_code == 302  # save successful

    group = get_default_customer_group(shop)

    options = get_price_display_options_for_group_and_shop(group, shop)
    assert options.show_prices is False
    assert options.include_taxes is None

    # none, with_taxes, without_taxes, hide
    k = "price_display_mode"
    data.update({k: [PriceDisplayChoices.NONE.value]})
    request = apply_request_middleware(rf.post("/", data),
                                       user=admin_user,
                                       shop=shop)
    response = view(request, pk=cgpd.pk)
    assert response.status_code == 302  # save successful

    options = get_price_display_options_for_group_and_shop(group, shop)
    assert options.show_prices is True  # default
    assert options.include_taxes is None

    data.update({k: [PriceDisplayChoices.WITH_TAXES.value]})
    request = apply_request_middleware(rf.post("/", data),
                                       user=admin_user,
                                       shop=shop)
    response = view(request, pk=cgpd.pk)
    assert response.status_code == 302  # save successful
    options = get_price_display_options_for_group_and_shop(group, shop)
    assert options.show_prices is True  # default
    assert options.include_taxes is True

    data.update({k: [PriceDisplayChoices.WITHOUT_TAXES.value]})
    request = apply_request_middleware(rf.post("/", data),
                                       user=admin_user,
                                       shop=shop)
    response = view(request, pk=cgpd.pk)
    assert response.status_code == 302  # save successful

    options = get_price_display_options_for_group_and_shop(group, shop)
    assert options.show_prices is True
    assert options.include_taxes is False
예제 #37
0
def test_catalog_campaign_sync():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    default_price = 100
    product1 = factories.create_product("test1",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=default_price)
    product2 = factories.create_product("test2",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=default_price)
    product3 = factories.create_product("test3",
                                        shop=shop,
                                        supplier=supplier,
                                        default_price=default_price)
    category = factories.get_default_category()
    shop_product = product1.get_shop_instance(shop)
    shop_product.primary_category = category
    shop_product.save()
    shop_product.categories.add(category)

    contact1 = factories.create_random_person()

    contact2 = factories.create_random_person()
    contact_group = factories.get_default_customer_group()
    contact2.groups.add(contact_group)

    happy_hour1_weekdays = "0,1"  # Mon, Tue
    happy_hour1_start = datetime.time(21)
    happy_hour1_end = datetime.time(3)
    happy_hour1_condition = HourCondition.objects.create(
        days=happy_hour1_weekdays,
        hour_start=happy_hour1_start,
        hour_end=happy_hour1_end)

    happy_hour2_weekdays = "2,6"  # Wed, Sun
    happy_hour2_start = datetime.time(14)
    happy_hour2_end = datetime.time(16)
    happy_hour2_condition = HourCondition.objects.create(
        days=happy_hour2_weekdays,
        hour_start=happy_hour2_start,
        hour_end=happy_hour2_end)

    discount_amount_value = 50
    discount_percentage = decimal.Decimal("0.35")
    _create_catalog_campaign_for_products(shop, [product1],
                                          discount_amount_value,
                                          happy_hour1_condition)
    _create_catalog_campaign_for_products(shop, [product2, product3],
                                          discount_amount_value)
    _create_catalog_campaign_for_category(shop, category, discount_percentage)
    _create_catalog_campaign_for_contact(shop, product1, contact1,
                                         discount_amount_value)
    _create_catalog_campaign_for_contact_group(shop,
                                               [product1, product2, product3],
                                               contact_group,
                                               discount_percentage,
                                               happy_hour2_condition)

    call_command("import_catalog_campaigns", *[], **{})

    # From first campaign we should get 1 discount with happy hour
    # From second campaign we should get 2 discounts
    # From third campaign we should get 1 discount
    # From fourth campaign we should get also 1 discount
    # From last campaign we should get 3 discounts with happy hour
    assert Discount.objects.count() == 8

    # There should be 2 happy hours in total
    assert HappyHour.objects.count() == 2

    # From first happy hour there should be 4 ranges
    # Mon 21-23, Tue 0-3, Tue 21-23, Wed 0-3
    # From second happy hour there should be 2 ranges
    # Wed 14-16 and Sun 14-16
    assert TimeRange.objects.count() == 6

    # Let's go through all our 8 discounts to make sure all is good
    first_discount = Discount.objects.filter(
        product=product1,
        category__isnull=True,
        contact__isnull=True,
        contact_group__isnull=True).first()
    assert first_discount.happy_hours.count() == 1
    assert first_discount.discount_amount_value == discount_amount_value

    second_discount = Discount.objects.filter(
        product=product2,
        category__isnull=True,
        contact__isnull=True,
        contact_group__isnull=True).first()
    assert second_discount.happy_hours.count() == 0
    assert second_discount.discount_amount_value == discount_amount_value

    third_discount = Discount.objects.filter(
        product=product3,
        category__isnull=True,
        contact__isnull=True,
        contact_group__isnull=True).first()
    assert third_discount.happy_hours.count() == 0
    assert third_discount.discount_amount_value == discount_amount_value

    category_discount = Discount.objects.filter(
        product__isnull=True,
        category=category,
        contact__isnull=True,
        contact_group__isnull=True).first()
    assert category_discount.happy_hours.count() == 0
    assert category_discount.discount_percentage == discount_percentage

    contact_discount = Discount.objects.filter(
        product=product1,
        category__isnull=True,
        contact=contact1,
        contact_group__isnull=True).first()
    assert contact_discount.discount_amount_value == discount_amount_value

    product1_contact_group_discount = Discount.objects.filter(
        product=product1,
        category__isnull=True,
        contact__isnull=True,
        contact_group=contact_group).first()
    assert product1_contact_group_discount.happy_hours.count() == 1
    assert product1_contact_group_discount.discount_percentage == discount_percentage

    product2_contact_group_discount = Discount.objects.filter(
        product=product2,
        category__isnull=True,
        contact__isnull=True,
        contact_group=contact_group).first()
    assert product2_contact_group_discount.happy_hours.count() == 1
    assert product2_contact_group_discount.discount_percentage == discount_percentage

    product3_contact_group_discount = Discount.objects.filter(
        product=product3,
        category__isnull=True,
        contact__isnull=True,
        contact_group=contact_group).first()
    assert product3_contact_group_discount.happy_hours.count() == 1
    assert product3_contact_group_discount.discount_percentage == discount_percentage
예제 #38
0
def test_contact_group_delete():
    default_group = get_default_customer_group()
    group_count = ContactGroup.objects.count()
    default_group.delete()
    assert ContactGroup.objects.count() == (group_count - 1)
def test_contact_group_delete():
    default_group = get_default_customer_group()
    group_count = ContactGroup.objects.count()
    default_group.delete()
    assert ContactGroup.objects.count() == (group_count - 1)
예제 #40
0
def test_contact_group_delete_button(rf, admin_user):
    get_default_shop()
    request = apply_request_middleware(rf.get("/"), user=admin_user)
    check_for_delete(request, get_default_customer_group(), True)
예제 #41
0
def test_contact_group_delete_button(rf, admin_user):
    get_default_shop()
    request = apply_request_middleware(rf.get("/"), user=admin_user)
    check_for_delete(request, get_default_customer_group(), True)
예제 #42
0
def test_create_order(admin_user, currency):
    create_default_order_statuses()
    shop = get_default_shop()
    shop.currency = currency
    tax = get_default_tax()
    Currency.objects.get_or_create(code=currency, decimal_places=2)
    shop.save()
    sm = get_default_shipping_method()
    pm = get_default_payment_method()
    contact = create_random_person(locale="en_US", minimum_name_comp_len=5)
    default_group = get_default_customer_group()
    default_group.members.add(contact)
    account_manager = create_random_person(locale="en_US",
                                           minimum_name_comp_len=5)
    contact.account_manager = account_manager
    contact.save()

    product = create_product(sku=uuid4().hex,
                             supplier=get_default_supplier(),
                             shop=shop)
    assert not Order.objects.count()
    client = _get_client(admin_user)
    lines = [
        {
            "type": "product",
            "product": product.id,
            "quantity": "1",
            "base_unit_price_value": "5.00"
        },
        {
            "type": "product",
            "product": product.id,
            "quantity": "2",
            "base_unit_price_value": "1.00",
            "discount_amount_value": "0.50"
        },
        {
            "type": "other",
            "sku": "hello",
            "text": "A greeting",
            "quantity": 1,
            "base_unit_price_value": "3.5"
        },
        {
            "type": "text",
            "text": "This was an order!",
            "quantity": 0
        },
    ]
    response = client.post("/api/shuup/order/",
                           content_type="application/json",
                           data=json.dumps({
                               "shop": shop.pk,
                               "shipping_method": sm.pk,
                               "payment_method": pm.pk,
                               "customer": contact.pk,
                               "lines": lines
                           }))
    assert response.status_code == 201
    assert Order.objects.count() == 1
    order = Order.objects.first()
    assert order.shop == shop
    assert order.shipping_method == sm
    assert order.payment_method == pm
    assert order.customer == contact
    assert order.creator == admin_user
    assert order.billing_address == contact.default_billing_address.to_immutable(
    )
    assert order.shipping_address == contact.default_shipping_address.to_immutable(
    )
    assert order.payment_status == PaymentStatus.NOT_PAID
    assert order.shipping_status == ShippingStatus.NOT_SHIPPED
    assert order.status == OrderStatus.objects.get_default_initial()
    assert order.taxful_total_price_value == decimal.Decimal(10)
    assert order.lines.count(
    ) == 6  # shipping line, payment line, 2 product lines, 2 other lines
    assert order.currency == currency
    for idx, line in enumerate(order.lines.all()[:4]):
        assert line.quantity == decimal.Decimal(lines[idx].get("quantity"))
        assert line.base_unit_price_value == decimal.Decimal(lines[idx].get(
            "base_unit_price_value", 0))
        assert line.discount_amount_value == decimal.Decimal(lines[idx].get(
            "discount_amount_value", 0))

    # Test tax summary
    response_data = json.loads(response.content.decode("utf-8"))
    # Tax summary should not be present here
    assert "summary" not in response_data

    response = client.get('/api/shuup/order/{}/taxes/'.format(order.pk))
    assert response.status_code == status.HTTP_200_OK
    response_data = json.loads(response.content.decode("utf-8"))

    assert "lines" in response_data
    assert "summary" in response_data
    line_summary = response_data["lines"]
    summary = response_data["summary"]
    first_tax_summary = summary[0]

    assert int(first_tax_summary["tax_id"]) == tax.id
    assert first_tax_summary["tax_rate"] == tax.rate

    first_line_summary = line_summary[0]
    assert "tax" in first_line_summary

    response = client.get("/api/shuup/order/%s/" % order.id)
    assert response.status_code == status.HTTP_200_OK
    order_data = json.loads(response.content.decode("utf-8"))
    assert order_data.get("id") == order.id

    assert "available_shipping_methods" in order_data
    assert "available_payment_methods" in order_data

    assert order_data["available_payment_methods"][0]["id"] == pm.id
    assert order_data["available_shipping_methods"][0]["id"] == sm.id

    assert order.account_manager == account_manager
    assert order.customer_groups.count() == contact.groups.count()
    for group in order.customer_groups.all():
        assert contact.groups.filter(id=group.id).exists()

    assert order.tax_group is not None
    assert order.tax_group == contact.tax_group