def test_unsaved_contact(admin_user): payment_method = get_default_payment_method() _assign_component_for_service(payment_method, [PersonContact.get_default_group()]) person = PersonContact(name="Kalle") source = _get_source_for_contact(admin_user, payment_method) source.customer = person assert not person.pk and not source.customer.pk _test_service_availability(source, payment_method, False)
def test_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 _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_contact_from_address(self, billing_address, is_company): name = billing_address.get("name", None) phone = billing_address.get("phone", "") email = billing_address.get("email", "") fields = {"name": name, "phone": phone, "email": email} if is_company: tax_number = billing_address.get("tax_number", None) fields.update({"tax_number": tax_number}) customer = CompanyContact(**fields) else: customer = PersonContact(**fields) return customer
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_display_queryset(regular_user): shop = get_default_shop() anonymous_group = AnonymousContact().get_default_group() PersonContact().get_default_group() CompanyContact().get_default_group() assert get_groups_for_price_display_create(shop).count() == 3 assert get_price_displays_for_shop(None).count() == 3 assert get_price_displays_for_shop(shop).count() == 3 get_person_contact(regular_user) assert get_price_displays_for_shop(shop).count() == 3 # create new group display (from admin usually) ContactGroupPriceDisplay.objects.create(group=anonymous_group, shop=shop) for_create = get_groups_for_price_display_create(shop) assert for_create.count() == 2 assert anonymous_group not in for_create items = get_price_displays_for_shop(shop) assert items.count() == 3 for item in items: if item.group == anonymous_group: assert item.shop else: assert not item.shop assert item.group.identifier in PROTECTED_CONTACT_GROUP_IDENTIFIERS new_group = ContactGroup.objects.create(identifier="test", shop=shop) items = get_price_displays_for_shop(shop) assert items.count() == 4 for item in items: if item.group in [new_group, anonymous_group]: assert item.shop else: assert not item.shop if item.group != new_group: assert item.group.identifier in PROTECTED_CONTACT_GROUP_IDENTIFIERS else: assert item.group.identifier == "test"
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 _create_contact_from_address(self, billing_address, is_company): name = billing_address.get("name", None) if not name: self.add_error( ValidationError(_("Name is required for customer"), code="no_name")) return phone = billing_address.get("phone", "") email = billing_address.get("email", "") fields = {"name": name, "phone": phone, "email": email} if is_company: tax_number = billing_address.get("tax_number", None) if not tax_number: self.add_error( ValidationError(_("Tax number is not set for company."), code="no_tax_number")) return fields.update({"tax_number": tax_number}) customer = CompanyContact(**fields) else: customer = PersonContact(**fields) return customer
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_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_person_name_init_by_first_and_last_name(): john = PersonContact(first_name="John", last_name="Smith") assert john.name == "John Smith" assert john.first_name == "John" assert john.last_name == "Smith"
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_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)
def save(self, commit=True): def populate_address(needle): data = {} delete = [] for k, value in six.iteritems(self.cleaned_data): if k.startswith(needle): key = k.replace(needle, "") data[key] = value delete.append(k) # sweep unneeded keys for k in delete: del self.cleaned_data[k] return data contact_address_data = populate_address("contact_") company_address_data = populate_address("company_") user = super(CompanyRegistrationForm, self).save(commit) website = company_address_data.pop("www") contact_address = MutableAddress.from_data(contact_address_data) contact_address.save() company_address = MutableAddress.from_data(company_address_data) company_address.save() contact = PersonContact() contact.is_active = False contact.user = user contact.email = user.email contact.default_shipping_address = contact_address contact.default_billing_address = contact_address contact.first_name = contact_address_data["first_name"] contact.last_name = contact_address_data["last_name"] contact.phone = contact_address.phone contact.save() company = CompanyContact() company.default_shipping_address = company_address company.default_billing_address = company_address company.is_active = False company.phone = company_address.phone company.www = website company.name = company_address_data["name"] company.name_ext = company_address_data["name_ext"] company.tax_number = company_address_data["tax_number"] company.email = company_address_data["email"] company.save() company.members.add(contact) return user