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
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
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()
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
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")
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(): {} }
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
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]
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)
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
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)
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
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()
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)
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)
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)
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
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()
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()
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
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
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])
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())
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 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 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])
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())
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()
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)
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
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_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)
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