def test_discount_for_logged_in_contacts(rf): default_price = 10 request, product = _init_test_for_product(rf, default_price) assert request.customer == AnonymousContact() product_discount_amount = 2 Discount.objects.create( shop=request.shop, active=True, contact_group=PersonContact.get_default_group(), discount_amount_value=product_discount_amount, ) Discount.objects.create( shop=request.shop, active=True, contact_group=CompanyContact.get_default_group(), discount_amount_value=product_discount_amount, ) assert product.get_price_info(request).price == request.shop.create_price( default_price) # setting customer to request should apply the discount request.customer = factories.create_random_person() assert product.get_price_info(request).price == request.shop.create_price( default_price - product_discount_amount) # Company as customer should work too request.customer = factories.create_random_company() assert product.get_price_info(request).price == request.shop.create_price( default_price - product_discount_amount)
def test_unsaved_contact(admin_user): payment_method = get_default_payment_method() _assign_component_for_service(payment_method, [PersonContact.get_default_group()]) person = PersonContact(name="Kalle") source = _get_source_for_contact(admin_user, payment_method) source.customer = person assert not person.pk and not source.customer.pk _test_service_availability(source, payment_method, False)
def _init_test(): shop = factories.get_default_shop() supplier = factories.get_default_supplier() contact = factories.create_random_person() group = PersonContact.get_default_group() category = factories.get_default_category() contact.groups.add(group) return shop, supplier, contact, group, category
def test_product_catalog_category_discount(): shop = factories.get_default_shop() supplier = factories.get_default_supplier() contact = factories.create_random_person() group = PersonContact.get_default_group() category = factories.get_default_category() contact.groups.add(group) product1 = factories.create_product("p1", shop=shop, supplier=supplier, default_price=Decimal("10")) product2 = factories.create_product("p2", shop=shop, supplier=supplier, default_price=Decimal("20")) product3 = factories.create_product("p3", shop=shop, supplier=supplier, default_price=Decimal("30")) product1.get_shop_instance(shop).categories.add(category) product3.get_shop_instance(shop).categories.add(category) # create a 10% discount for the category Discount.objects.create( shop=shop, category=category, discount_percentage=Decimal(0.1), start_datetime=timezone.now(), end_datetime=timezone.now() + timedelta(days=1), ) catalog = ProductCatalog(context=ProductCatalogContext( purchasable_only=False)) ProductCatalog.index_product(product1) ProductCatalog.index_product(product2) ProductCatalog.index_product(product3) _assert_products_queryset( catalog, [ (product1.pk, Decimal("10"), Decimal("9")), (product2.pk, Decimal("20"), None), (product3.pk, Decimal("30"), Decimal("27")), ], ) _assert_shop_products_queryset( catalog, [ (product1.get_shop_instance(shop).pk, Decimal("10"), Decimal("9")), (product2.get_shop_instance(shop).pk, Decimal("20"), None), (product3.get_shop_instance(shop).pk, Decimal("30"), Decimal("27")), ], ) _assert_price(product1, shop, Decimal("9"), Decimal("10")) _assert_price(product2, shop, Decimal("20"), Decimal("20")) _assert_price(product3, shop, Decimal("27"), Decimal("30"))
def create_sample_product(name, description, business_segment, image_file, shop): product = Product.objects.create( name=name, description=description, type=get_default_product_type(), tax_class=get_default_tax_class(), sales_unit=SalesUnit.objects.first(), sku=fuzzy.FuzzyText(length=10).fuzz(), ) image_file_path = os.path.join(SAMPLE_IMAGES_BASE_DIR, image_file) path = "ProductImages/Samples/%s" % business_segment.capitalize() filer_image = _filer_image_from_file_path(image_file_path, path) media_file = MediaFile.objects.create(file=filer_image) media_file.shops.add(shop) media = ProductMedia.objects.create(product=product, kind=ProductMediaKind.IMAGE, file=filer_image) media.save() media.shops.add(shop) product.primary_image = media product.save() # create the price and round it to the number of decimals of the currency price = shop.create_price( decimal.Decimal(random.random() * random.randrange(0, 500))).as_rounded() sp = ShopProduct.objects.create( product=product, purchasable=True, visibility=ShopProductVisibility.ALWAYS_VISIBLE, default_price_value=price, shop=shop, shop_primary_image=media, ) supplier = get_default_supplier(shop) supplier.stock_managed = False supplier.save() sp.categories.set(shop.categories.all()) sp.suppliers.add(supplier) # configure prices if "shuup.customer_group_pricing" in settings.INSTALLED_APPS: from shuup.customer_group_pricing.models import CgpPrice CgpPrice.objects.create(product=product, price_value=random.randint(15, 340), shop=shop, group=PersonContact.get_default_group()) return product
def create_sample_product(name, description, business_segment, image_file, shop): product = Product.objects.create( name=name, description=description, type=get_default_product_type(), tax_class=get_default_tax_class(), sales_unit=SalesUnit.objects.first(), sku=fuzzy.FuzzyText(length=10).fuzz() ) image_file_path = os.path.join(SAMPLE_IMAGES_BASE_DIR, image_file) path = "ProductImages/Samples/%s" % business_segment.capitalize() filer_image = _filer_image_from_file_path(image_file_path, path) media_file = MediaFile.objects.create(file=filer_image) media_file.shops.add(shop) media = ProductMedia.objects.create( product=product, kind=ProductMediaKind.IMAGE, file=filer_image ) media.save() media.shops.add(shop) product.primary_image = media product.save() # create the price and round it to the number of decimals of the currency price = shop.create_price(decimal.Decimal(random.random() * random.randrange(0, 500))).as_rounded() sp = ShopProduct.objects.create( product=product, purchasable=True, visibility=ShopProductVisibility.ALWAYS_VISIBLE, default_price_value=price, shop=shop, shop_primary_image=media ) sp.categories = shop.categories.all() sp.suppliers.add(get_default_supplier()) # configure prices if "shuup.customer_group_pricing" in settings.INSTALLED_APPS: from shuup.customer_group_pricing.models import CgpPrice CgpPrice.objects.create( product=product, price_value=random.randint(15, 340), shop=shop, group=PersonContact.get_default_group() ) return product
def test_discount_for_person_contacts(rf): default_price = 10 request, product = _init_test_for_product(rf, default_price) assert request.customer == AnonymousContact() product_discount_amount = 2 Discount.objects.create( shop=request.shop, active=True, contact_group=PersonContact.get_default_group(), discount_amount_value=product_discount_amount, ) assert product.get_price_info(request).price == request.shop.create_price( default_price) # Setting customer to request activates the discount request.customer = factories.create_random_person() assert product.get_price_info(request).price == request.shop.create_price( default_price - product_discount_amount) # Using company contact as customer means no discount request.customer = factories.create_random_company() assert product.get_price_info(request).price == request.shop.create_price( default_price)
def test_default_person_contact_group_repr_and_str(): pdg = PersonContact.get_default_group() assert repr(pdg) == '<ContactGroup:%d-default_person_group>' % pdg.pk assert str(pdg) == 'Person Contacts'
def test_admin_custom_customer_price_updates(rf, admin_user): shop = factories.get_default_shop() supplier = factories.get_default_supplier() contact = factories.create_random_person() group = PersonContact.get_default_group() contact.groups.add(group) product_type = factories.get_default_product_type() tax_class = factories.get_default_tax_class() sales_unit = factories.get_default_sales_unit() view = ProductEditView.as_view() group_price = "10.0" default_price = "15.0" payload = { "base-name__en": "My Product", "base-type": product_type.pk, "base-sku": "p1", "base-shipping_mode": ShippingMode.NOT_SHIPPED.value, "base-tax_class": tax_class.pk, "base-sales_unit": sales_unit.pk, "base-width": "0", "base-height": "0", "base-depth": "0", "base-net_weight": "0", "base-gross_weight": "0", f"shop{shop.pk}-default_price_value": default_price, f"shop{shop.pk}-visibility": ShopProductVisibility.ALWAYS_VISIBLE.value, f"shop{shop.pk}-visibility_limit": ProductVisibility.VISIBLE_TO_ALL.value, f"shop{shop.pk}-minimum_purchase_quantity": "1", f"shop{shop.pk}-purchase_multiple": "1", f"shop{shop.pk}-suppliers": [supplier.pk], f"customer_group_pricing-s_{shop.pk}_g_{group.pk}": group_price, # set price for the group } # create a new product request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user) with patch("django.db.transaction.on_commit", new=atomic_commit_mock): response = view(request, pk=None) assert response.status_code == 302 anon_catalog = ProductCatalog(context=ProductCatalogContext( purchasable_only=False)) customer_catalog = ProductCatalog( context=ProductCatalogContext(purchasable_only=False, contact=contact)) product = Product.objects.first() _assert_products_queryset(anon_catalog, [(product.pk, Decimal(default_price), None)]) _assert_products_queryset(customer_catalog, [(product.pk, Decimal(group_price), None)]) payload.update({ # remove the customer group price f"customer_group_pricing-s_{shop.pk}_g_{group.pk}": "", "media-TOTAL_FORMS": 0, "media-INITIAL_FORMS": 0, "media-MIN_NUM_FORMS": 0, "media-MAX_NUM_FORMS": 1000, "images-TOTAL_FORMS": 0, "images-INITIAL_FORMS": 0, "images-MIN_NUM_FORMS": 0, "images-MAX_NUM_FORMS": 1000, }) request = apply_request_middleware(rf.post("/", data=payload), shop=shop, user=admin_user) with patch("django.db.transaction.on_commit", new=atomic_commit_mock): response = view(request, pk=product.get_shop_instance(shop).pk) assert response.status_code == 302 # default price for both _assert_products_queryset(anon_catalog, [(product.pk, Decimal(default_price), None)]) _assert_products_queryset(customer_catalog, [(product.pk, Decimal(default_price), None)])
def filter(self): return json.dumps({"groups": [PersonContact.get_default_group().pk]})
def test_product_catalog_cgp_with_variations(): shop = factories.get_default_shop() supplier = factories.get_default_supplier() contact = factories.create_random_person() group = PersonContact.get_default_group() contact.groups.add(group) parent = factories.create_product("p1", shop=shop, supplier=supplier, default_price=Decimal("10")) child1 = factories.create_product("p2", shop=shop, supplier=supplier, default_price=Decimal("20")) child2 = factories.create_product("p3", shop=shop, supplier=supplier, default_price=Decimal("40")) child3 = factories.create_product("p4", shop=shop, supplier=supplier, default_price=Decimal("50")) child1.link_to_parent(parent) child2.link_to_parent(parent) child3.link_to_parent(parent) # set a price for child2 CgpPrice.objects.create(shop=shop, product=child2, group=group, price_value=Decimal("5")) # create a discount for child3 CgpDiscount.objects.create(shop=shop, product=child3, group=group, discount_amount_value=Decimal("35")) catalog = ProductCatalog( context=ProductCatalogContext(purchasable_only=False, contact=contact)) ProductCatalog.index_product(parent) _assert_products_queryset( catalog, [ (child2.pk, Decimal("5"), None), (parent.pk, Decimal("10"), None), (child1.pk, Decimal("20"), None), (child3.pk, Decimal("50"), Decimal("15")), ], ) _assert_shop_products_queryset( catalog, [ (child2.get_shop_instance(shop).pk, Decimal("5"), None), (parent.get_shop_instance(shop).pk, Decimal("10"), None), (child1.get_shop_instance(shop).pk, Decimal("20"), None), (child3.get_shop_instance(shop).pk, Decimal("50"), Decimal("15")), ], ) # no customer _assert_price(parent, shop, Decimal("10"), Decimal("10")) _assert_price(child1, shop, Decimal("20"), Decimal("20")) _assert_price(child2, shop, Decimal("40"), Decimal("40")) _assert_price(child3, shop, Decimal("50"), Decimal("50")) # with the customer in the group _assert_price(parent, shop, Decimal("10"), Decimal("10"), customer=contact) _assert_price(child1, shop, Decimal("20"), Decimal("20"), customer=contact) _assert_price(child2, shop, Decimal("5"), Decimal("40"), customer=contact) _assert_price(child3, shop, Decimal("15"), Decimal("50"), customer=contact)
def test_product_catalog_discounted_price(): shop = factories.get_default_shop() supplier = factories.get_default_supplier() contact = factories.create_random_person() group = PersonContact.get_default_group() contact.groups.add(group) product1 = factories.create_product("p1", shop=shop, supplier=supplier, default_price=Decimal("50")) product2 = factories.create_product("p2", shop=shop, supplier=supplier, default_price=Decimal("30")) # set price for product2 CgpPrice.objects.create(shop=shop, product=product2, group=group, price_value=Decimal(25)) # create a discount for product2 CgpDiscount.objects.create(shop=shop, product=product2, group=group, discount_amount_value=Decimal(7)) anon_catalog = ProductCatalog(context=ProductCatalogContext( purchasable_only=False)) customer_catalog = ProductCatalog( context=ProductCatalogContext(purchasable_only=False, contact=contact)) ProductCatalog.index_product(product1) ProductCatalog.index_product(product2) _assert_products_queryset( anon_catalog, [ (product2.pk, Decimal("30"), None), (product1.pk, Decimal("50"), None), ], ) _assert_products_queryset( customer_catalog, [ (product2.pk, Decimal("25"), Decimal("23")), (product1.pk, Decimal("50"), None), ], ) _assert_shop_products_queryset( anon_catalog, [ (product2.get_shop_instance(shop).pk, Decimal("30"), None), (product1.get_shop_instance(shop).pk, Decimal("50"), None), ], ) _assert_shop_products_queryset( customer_catalog, [ (product2.get_shop_instance(shop).pk, Decimal("25"), Decimal("23")), (product1.get_shop_instance(shop).pk, Decimal("50"), None), ], ) # no customer _assert_price(product1, shop, Decimal("50"), Decimal("50")) _assert_price(product2, shop, Decimal("30"), Decimal("30")) # with the customer in the group _assert_price(product1, shop, Decimal("50"), Decimal("50"), customer=contact) _assert_price(product2, shop, Decimal("18"), Decimal("30"), customer=contact)