def test_order_creator_taxes(admin_user, include_tax): shop = get_shop(include_tax) source = OrderSource(shop) source.status = get_initial_order_status() create_default_order_statuses() tax = get_tax("sales-tax", "Sales Tax", Decimal(0.2)) # 20% create_default_tax_rule(tax) product = get_default_product() line = source.add_line( line_id="product-line", type=OrderLineType.PRODUCT, product=product, supplier=get_default_supplier(), quantity=1, shop=shop, base_unit_price=source.create_price(100), ) discount_line = source.add_line(line_id="discount-line", type=OrderLineType.DISCOUNT, supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(0), discount_amount=source.create_price(100), parent_line_id=line.line_id) assert source.taxful_total_price.value == Decimal() creator = OrderCreator() order = creator.create_order(source) assert order.taxful_total_price.value == Decimal()
def test_percentage_campaign_full_discount(rf, include_tax): request, shop, group = initialize_test(rf, include_tax) create_default_order_statuses() tax = get_tax("sales-tax", "Sales Tax", Decimal(0.2)) # 20% create_default_tax_rule(tax) basket = get_basket(request) supplier = get_default_supplier() product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=200) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) basket.shipping_method = get_shipping_method(shop=shop) basket.status = get_initial_order_status() campaign = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True) # 100% of discount BasketDiscountPercentage.objects.create(campaign=campaign, discount_percentage=Decimal(1)) assert len(basket.get_final_lines()) == 3 assert basket.product_count == 1 assert basket.total_price.value == Decimal() order_creator = OrderCreator() order = order_creator.create_order(basket) order.create_payment(order.taxful_total_price) assert order.taxful_total_price.value == Decimal()
def test_get_installments_cc_does_not_allow_installments(): """ Max 9 installs with SIMPLE intereset interest_rate = 4.00% Credit card does not allow installments """ patch_cielo_request() shop = get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) CieloConfig.objects.create(shop=shop, max_installments=9, installments_without_interest=3, interest_type=InterestType.Simple, interest_rate=Decimal(4.0)) order_total = (PRODUCT_QTNTY * PRODUCT_PRICE) total_price_str = "{0}".format(format_money( shop.create_price(order_total))) response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Discover}) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == 1 assert json_content['installments'][0]['number'] == 1 assert total_price_str in json_content['installments'][0]['name']
def test_percentage_campaign_different_supplier(rf, include_tax): request, shop, group = initialize_test(rf, include_tax) create_default_order_statuses() tax = get_tax("sales-tax", "Sales Tax", Decimal(0.2)) # 20% create_default_tax_rule(tax) basket = get_basket(request) supplier = get_default_supplier(shop) supplier_2 = Supplier.objects.create(name="Supplier 2") product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=200) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) basket.shipping_method = get_shipping_method(shop=shop) basket.status = get_initial_order_status() # create a campaign for the Supplier 2 campaign = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True, supplier=supplier_2) # 100% of discount BasketDiscountPercentage.objects.create(campaign=campaign, discount_percentage=Decimal(1)) # discount is never applied lines_types = [line.type for line in basket.get_final_lines()] assert OrderLineType.DISCOUNT not in lines_types assert basket.product_count == 1 assert basket.total_price.value == Decimal(200)
def test_get_installments_12x_with_simples_intereset(): """ Max 12 installs with PRICE intereset interest_rate = 2.30% min_installment_amount = 30.00 """ patch_cielo_request() shop = get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) cielo_config = CieloConfig.objects.create(shop=shop, max_installments=12, installments_without_interest=2, interest_type=InterestType.Price, interest_rate=Decimal(2.3), min_installment_amount=Decimal(30)) order_total = (PRODUCT_QTNTY * PRODUCT_PRICE) installment_choices = InstallmentContext(order_total, cielo_config).get_intallments_choices() response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == len(installment_choices) for installment in range(len(installment_choices)): total = format_money(shop.create_price(installment_choices[installment][2])) installment_amount = format_money(shop.create_price(installment_choices[installment][1])) assert json_content['installments'][installment]['number'] == installment+1 assert installment_amount in json_content['installments'][installment]['name'] assert total in json_content['installments'][installment]['name']
def test_get_installments_cc_does_not_allow_installments(): """ Max 9 installs with SIMPLE intereset interest_rate = 4.00% Credit card does not allow installments """ patch_cielo_request() shop = get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) CieloConfig.objects.create(shop=shop, max_installments=9, installments_without_interest=3, interest_type=InterestType.Simple, interest_rate=Decimal(4.0)) order_total = (PRODUCT_QTNTY * PRODUCT_PRICE) total_price_str = "{0}".format(format_money(shop.create_price(order_total))) response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Discover}) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == 1 assert json_content['installments'][0]['number'] == 1 assert total_price_str in json_content['installments'][0]['name']
def test_get_installments_3x_no_intereset(): """ Max 3 installs with no intereset """ patch_cielo_request() shop = get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) CieloConfig.objects.create(shop=shop, max_installments=3, installments_without_interest=3) order_total = PRODUCT_QTNTY * PRODUCT_PRICE total_price_str = "{0}".format(format_money(shop.create_price(order_total))) response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == 3 assert json_content['installments'][0]['number'] == 1 assert total_price_str in json_content['installments'][0]['name'] total_2x_no_interest = format_money(shop.create_price(order_total / Decimal(2))) assert json_content['installments'][1]['number'] == 2 assert total_price_str in json_content['installments'][1]['name'] assert total_2x_no_interest in json_content['installments'][1]['name'] total_3x_no_interest = format_money(shop.create_price(order_total / Decimal(3))) assert json_content['installments'][2]['number'] == 3 assert total_price_str in json_content['installments'][2]['name'] assert total_3x_no_interest in json_content['installments'][2]['name']
def test_basic_order_flow_registered(regular_user): cache.clear() create_default_order_statuses() n_orders_pre = Order.objects.count() populate_if_required() get_test_script("test script", "order_received") # paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) template_data = STEP_DATA[0]["actions"][0]["template_data"] LANG_CODE = {"en": "US", "fi": "FI"} for lang in ["en", "fi"]: n_outbox_pre = len(mail.outbox) contact = get_person_contact(regular_user) contact.language = lang contact.save() c = SmartClient() c.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD) product_ids = _populate_client_basket(c) addresses_soup = c.soup(addresses_path) address = get_address(country=LANG_CODE[lang]) inputs = fill_address_inputs(addresses_soup, address) response = c.post(addresses_path, data=inputs) assert response.status_code == 302 # Should redirect forth methods_soup = c.soup(methods_path) assert c.post(methods_path, data=extract_form_fields( methods_soup)).status_code == 302 # Should redirect forth confirm_soup = c.soup(confirm_path) Product.objects.get(pk=product_ids[0]).soft_delete() assert ( c.post(confirm_path, data=extract_form_fields(confirm_soup)).status_code == 200 ) # user needs to reconfirm data = extract_form_fields(confirm_soup) data["accept_terms"] = True data["product_ids"] = ",".join(product_ids[1:]) assert c.post(confirm_path, data=data).status_code == 302 # Should redirect forth n_orders_post = Order.objects.count() assert n_orders_post > n_orders_pre, "order was created" assert len(mail.outbox) == n_outbox_pre + 1, "Sending email failed" latest_mail = mail.outbox[-1] # mail is always sent in fallback language since user is not registered assert latest_mail.subject == template_data[lang][ "subject"], "Subject doesn't match" assert latest_mail.body == template_data[lang][ "body"], "Body doesn't match"
def run(self): for schema in self.schemata: self.objects[schema["model"]] = self.process_schema(schema) if not OrderStatus.objects.exists(): print_("Creating order statuses...", end=" ") create_default_order_statuses() print_("done.") print_("Initialization done.")
def run(self): for schema in self.schemata: self.objects[schema["model"]] = self.process_schema(schema) if not OrderStatus.objects.exists(): print_("Creating order statuses...", end=" ") create_default_order_statuses() print_("done.") print_("Initialization done.")
def initialize(): get_default_shop() set_current_theme('shuup.themes.classic_gray') create_default_order_statuses() populate_if_required() default_product = get_default_product() sp = ShopProduct.objects.get(product=default_product, shop=get_default_shop()) sp.default_price = get_default_shop().create_price(PRODUCT_PRICE) sp.save()
def run(self): for schema in self.schemata: self.objects[schema["model"]] = self.process_schema(schema) if not OrderStatus.objects.exists(): print_("Creating order statuses...", end=" ") create_default_order_statuses() print_("done.") for shop in Shop.objects.all(): if not configuration.get(shop, "languages"): configuration.set(shop, "languages", settings.LANGUAGES) print_("Initialization done.")
def test_basic_order_flow_registered(regular_user): cache.clear() create_default_order_statuses() n_orders_pre = Order.objects.count() populate_if_required() get_test_script("test script", "order_received") # paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) template_data = STEP_DATA[0]["actions"][0]["template_data"] LANG_CODE = { "en": "US", "fi": "FI" } for lang in ["en", "fi"]: n_outbox_pre = len(mail.outbox) contact = get_person_contact(regular_user) contact.language = lang contact.save() c = SmartClient() c.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD) product_ids = _populate_client_basket(c) addresses_soup = c.soup(addresses_path) address = get_address(country=LANG_CODE[lang]) inputs = fill_address_inputs(addresses_soup, address) response = c.post(addresses_path, data=inputs) assert response.status_code == 302 # Should redirect forth methods_soup = c.soup(methods_path) assert c.post(methods_path, data=extract_form_fields(methods_soup)).status_code == 302 # Should redirect forth confirm_soup = c.soup(confirm_path) Product.objects.get(pk=product_ids[0]).soft_delete() assert c.post(confirm_path, data=extract_form_fields(confirm_soup)).status_code == 200 # user needs to reconfirm data = extract_form_fields(confirm_soup) data['product_ids'] = ','.join(product_ids[1:]) assert c.post(confirm_path, data=data).status_code == 302 # Should redirect forth n_orders_post = Order.objects.count() assert n_orders_post > n_orders_pre, "order was created" assert (len(mail.outbox) == n_outbox_pre + 1), "Sending email failed" latest_mail = mail.outbox[-1] # mail is always sent in fallback language since user is not registered assert latest_mail.subject == template_data[lang]["subject"], "Subject doesn't match" assert latest_mail.body == template_data[lang]["body"], "Body doesn't match"
def run(self): for schema in self.schemata: self.objects[schema["model"]] = self.process_schema(schema) if not OrderStatus.objects.exists(): print_("Creating order statuses...", end=" ") create_default_order_statuses() print_("done.") for shop in Shop.objects.all(): if not configuration.get(shop, "languages"): configuration.set(shop, "languages", settings.LANGUAGES) print_("Initialization done.")
def initialize(): get_cielo_config() get_default_shop() set_current_theme('shuup.themes.classic_gray') create_default_order_statuses() populate_if_required() default_product = get_default_product() sp = ShopProduct.objects.get(product=default_product, shop=get_default_shop()) sp.default_price = get_default_shop().create_price(PRODUCT_PRICE) sp.save()
def test_percentage_campaign_different_coupon_supplier(rf): request, shop, group = initialize_test(rf, True) create_default_order_statuses() basket = get_basket(request) supplier = get_default_supplier(shop) supplier_2 = Supplier.objects.create(name="Supplier 2") product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=200) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) basket.shipping_method = get_shipping_method(shop=shop) basket.status = get_initial_order_status() # Create coupon that is attached to Supplier 2 coupon = Coupon.objects.create(code="QWERTY", shop=shop, active=True, supplier=supplier_2) # create basket with coupon code campaign = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True, coupon=coupon, supplier=supplier_2) BasketDiscountPercentage.objects.create(campaign=campaign, discount_percentage=Decimal(1)) basket.add_code(coupon.code) # discount is never applied as there is no line # in the basket that matches the coupon's supplier lines_types = [line.type for line in basket.get_final_lines()] assert OrderLineType.DISCOUNT not in lines_types assert basket.product_count == 1 assert basket.total_price.value == Decimal(200) # make supplier be the default supplier coupon.supplier = supplier coupon.save() campaign.supplier = supplier campaign.save() basket.uncache() lines_types = [line.type for line in basket.get_final_lines()] assert OrderLineType.DISCOUNT in lines_types assert basket.product_count == 1 assert basket.total_price.value == Decimal()
def _get_configured_basket_client(): """ Initialized and configure client adding product and setting address, ready to make transactions """ get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) return c
def _get_configured_basket_client(): """ Initialized and configure client adding product and setting address, ready to make transactions """ get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) return c
def run(self): for schema in self.schemata: self.objects[schema["model"]] = self.process_schema(schema) if not OrderStatus.objects.exists(): print_("Creating order statuses...", end=" ") create_default_order_statuses() print_("done.") if not settings.DEBUG and is_telemetry_enabled(): try: data = json.dumps({"key": get_installation_key()}) resp = requests.get(url=settings.SHUUP_SUPPORT_ID_URL, data=data, timeout=5) if resp.json().get("support_id"): configuration.set(None, "shuup_support_id", resp.json().get("support_id")) except Exception: print_("Failed to get support id") print_("Initialization done.")
def test_get_installments_options_rest(): patch_cielo_request() shop = get_default_shop() c = SmartClient() # method not allowed response = c.post(INSTALLMENTS_PATH) assert response.status_code == 405 # missing parameters response = c.get(INSTALLMENTS_PATH) assert response.status_code == 400 # no CieloConfig for shop response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) assert response.status_code == 400 CieloConfig.objects.create(shop=shop) # basket not valid (no products and not payment/shipping methods) response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) assert response.status_code == 400 create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') # configures the user basket _configure_basket(c) # only 1 installment, because no configurations were set on CieloConfig response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) assert response.status_code == 200 # should be the order total order_total = PRODUCT_QTNTY * PRODUCT_PRICE total_price_str = "{0}".format(format_money( shop.create_price(order_total))) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == 1 assert json_content['installments'][0]['number'] == 1 assert total_price_str in json_content['installments'][0]['name']
def run(self): for schema in self.schemata: self.objects[schema["model"]] = self.process_schema(schema) # Ensure default statuses are available print_("Creating order statuses...", end=" ") create_default_order_statuses() print_("done.") if not settings.DEBUG and is_telemetry_enabled(): try: data = json.dumps({ "key": get_installation_key() }) resp = requests.get(url=settings.SHUUP_SUPPORT_ID_URL, data=data, timeout=5) if resp.json().get("support_id"): configuration.set(None, "shuup_support_id", resp.json().get("support_id")) except Exception: print_("Failed to get support id") print_("Initialization done.")
def test_get_installments_9x_with_simples_intereset(): """ Max 9 installs with SIMPLE intereset interest_rate = 4.00% """ patch_cielo_request() shop = get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) cielo_config = CieloConfig.objects.create( shop=shop, max_installments=9, installments_without_interest=3, interest_type=InterestType.Simple, interest_rate=Decimal(4.0)) SHIP_AMOUNT = Decimal(19.0) shipping_method = get_default_shipping_method() shipping_method.behavior_components.add( FixedCostBehaviorComponent.objects.create(price_value=SHIP_AMOUNT)) order_total = (PRODUCT_QTNTY * PRODUCT_PRICE) + SHIP_AMOUNT installment_choices = InstallmentContext( order_total, cielo_config).get_intallments_choices() response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == len(installment_choices) for installment in range(len(installment_choices)): total = format_money( shop.create_price(installment_choices[installment][2])) installment_amount = format_money( shop.create_price(installment_choices[installment][1])) assert json_content['installments'][installment][ 'number'] == installment + 1 assert installment_amount in json_content['installments'][installment][ 'name'] assert total in json_content['installments'][installment]['name']
def test_get_installments_options_rest(): patch_cielo_request() shop = get_default_shop() c = SmartClient() # method not allowed response = c.post(INSTALLMENTS_PATH) assert response.status_code == 405 # missing parameters response = c.get(INSTALLMENTS_PATH) assert response.status_code == 400 # no CieloConfig for shop response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) assert response.status_code == 400 CieloConfig.objects.create(shop=shop) # basket not valid (no products and not payment/shipping methods) response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) assert response.status_code == 400 create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') # configures the user basket _configure_basket(c) # only 1 installment, because no configurations were set on CieloConfig response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) assert response.status_code == 200 # should be the order total order_total = PRODUCT_QTNTY * PRODUCT_PRICE total_price_str = "{0}".format(format_money(shop.create_price(order_total))) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == 1 assert json_content['installments'][0]['number'] == 1 assert total_price_str in json_content['installments'][0]['name']
def test_get_installments_12x_with_simples_intereset(): """ Max 12 installs with PRICE intereset interest_rate = 2.30% min_installment_amount = 30.00 """ patch_cielo_request() shop = get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) cielo_config = CieloConfig.objects.create( shop=shop, max_installments=12, installments_without_interest=2, interest_type=InterestType.Price, interest_rate=Decimal(2.3), min_installment_amount=Decimal(30)) order_total = (PRODUCT_QTNTY * PRODUCT_PRICE) installment_choices = InstallmentContext( order_total, cielo_config).get_intallments_choices() response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == len(installment_choices) for installment in range(len(installment_choices)): total = format_money( shop.create_price(installment_choices[installment][2])) installment_amount = format_money( shop.create_price(installment_choices[installment][1])) assert json_content['installments'][installment][ 'number'] == installment + 1 assert installment_amount in json_content['installments'][installment][ 'name'] assert total in json_content['installments'][installment]['name']
def test_get_installments_3x_no_intereset(): """ Max 3 installs with no intereset """ patch_cielo_request() shop = get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) CieloConfig.objects.create(shop=shop, max_installments=3, installments_without_interest=3) order_total = PRODUCT_QTNTY * PRODUCT_PRICE total_price_str = "{0}".format(format_money( shop.create_price(order_total))) response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == 3 assert json_content['installments'][0]['number'] == 1 assert total_price_str in json_content['installments'][0]['name'] total_2x_no_interest = format_money( shop.create_price(order_total / Decimal(2))) assert json_content['installments'][1]['number'] == 2 assert total_price_str in json_content['installments'][1]['name'] assert total_2x_no_interest in json_content['installments'][1]['name'] total_3x_no_interest = format_money( shop.create_price(order_total / Decimal(3))) assert json_content['installments'][2]['number'] == 3 assert total_price_str in json_content['installments'][2]['name'] assert total_3x_no_interest in json_content['installments'][2]['name']
def test_get_installments_9x_with_simples_intereset(): """ Max 9 installs with SIMPLE intereset interest_rate = 4.00% """ patch_cielo_request() shop = get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) cielo_config = CieloConfig.objects.create(shop=shop, max_installments=9, installments_without_interest=3, interest_type=InterestType.Simple, interest_rate=Decimal(4.0)) SHIP_AMOUNT = Decimal(19.0) shipping_method = get_default_shipping_method() shipping_method.behavior_components.add( FixedCostBehaviorComponent.objects.create(price_value=SHIP_AMOUNT) ) order_total = (PRODUCT_QTNTY * PRODUCT_PRICE) + SHIP_AMOUNT installment_choices = InstallmentContext(order_total, cielo_config).get_intallments_choices() response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == len(installment_choices) for installment in range(len(installment_choices)): total = format_money(shop.create_price(installment_choices[installment][2])) installment_amount = format_money(shop.create_price(installment_choices[installment][1])) assert json_content['installments'][installment]['number'] == installment+1 assert installment_amount in json_content['installments'][installment]['name'] assert total in json_content['installments'][installment]['name']
def test_order_full_refund_with_taxes(include_tax): tax_rate = Decimal(0.2) # 20% product_price = 100 discount_amount = 30 random_line_price = 5 shop = factories.get_shop(include_tax) source = OrderSource(shop) source.status = factories.get_initial_order_status() supplier = factories.get_default_supplier() create_default_order_statuses() tax = factories.get_tax("sales-tax", "Sales Tax", tax_rate) factories.create_default_tax_rule(tax) product = factories.create_product("sku", shop=shop, supplier=supplier, default_price=product_price) line = source.add_line( line_id="product-line", type=OrderLineType.PRODUCT, product=product, supplier=supplier, quantity=1, shop=shop, base_unit_price=source.create_price(product_price), ) discount_line = source.add_line( line_id="discount-line", type=OrderLineType.DISCOUNT, supplier=supplier, quantity=1, base_unit_price=source.create_price(0), discount_amount=source.create_price(discount_amount), parent_line_id=line.line_id) raw_total_price = Decimal(product_price - discount_amount) total_taxful = bround(source.taxful_total_price.value) total_taxless = bround(source.taxless_total_price.value) if include_tax: assert total_taxful == bround(raw_total_price) assert total_taxless == bround(raw_total_price / (1 + tax_rate)) else: assert total_taxful == bround(raw_total_price * (1 + tax_rate)) assert total_taxless == bround(raw_total_price) # Lines without quantity shouldn't affect refunds other_line = source.add_line( text="This random line for textual information", line_id="other-line", type=OrderLineType.OTHER, quantity=0) # Lines with quantity again should be able to be refunded normally. other_line_with_quantity = source.add_line( line_id="other_line_with_quantity", type=OrderLineType.OTHER, text="Special service $5/h", quantity=1, base_unit_price=source.create_price(random_line_price)) raw_total_price = Decimal(product_price - discount_amount + random_line_price) total_taxful = bround(source.taxful_total_price.value) total_taxless = bround(source.taxless_total_price.value) if include_tax: assert total_taxful == bround(raw_total_price) assert total_taxless == bround(raw_total_price / (1 + tax_rate)) else: assert total_taxful == bround(raw_total_price * (1 + tax_rate)) assert total_taxless == bround(raw_total_price) creator = OrderCreator() order = creator.create_order(source) assert order.taxful_total_price.value == total_taxful assert order.taxless_total_price.value == total_taxless order.create_payment(order.taxful_total_price) assert order.is_paid() order.create_full_refund() assert order.taxful_total_price_value == 0 for parent_order_line in order.lines.filter(parent_line__isnull=True): if parent_order_line.quantity == 0: assert not parent_order_line.child_lines.exists() else: refund_line = parent_order_line.child_lines.filter( type=OrderLineType.REFUND).first() assert refund_line assert parent_order_line.taxful_price.value == -refund_line.taxful_price.value assert parent_order_line.taxless_price.value == -refund_line.taxless_price.value assert parent_order_line.price.value == -refund_line.price.value
def test_checkout_with_success(): get_default_shop() set_current_theme('shuup.themes.classic_gray') create_default_order_statuses() populate_if_required() client = SmartClient() # first step - register user person_data = { "email": "*****@*****.**", "password1": "password", "password2": "password", "person_type": PersonType.FISICA.value, "PF-name": "NOME DA PESSOA", "PF-cpf": "012.345.678-90", "PF-rg": "312321", "PF-birth_date": "03/28/1954", "PF-gender": Gender.MALE.value } result = client.post(reverse("shuup:registration_register"), data=person_data) assert not result is None user = get_user_model().objects.get(email=person_data['email']) assert user.is_active # second step -add something into the basket default_product = get_default_product() basket_path = reverse("shuup:basket") add_to_basket_resp = client.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 1, "supplier": get_default_supplier().pk }) assert add_to_basket_resp.status_code < 400 # third step - go to checkout and set the addresses addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) addresses_data = { 'billing-name': 'maria da silva', 'billing-street': 'rua billing', 'billing-street2': 'apto', 'billing-street3': 'bairro outrem', 'billing-postal_code': '89090-200', 'billing-city': 'plumenau', 'billing-region': 'PR', 'billing-country': 'BR', 'billing-phone': '41 2332-0213', 'billing_extra-numero': '563', 'billing_extra-cel': '13 98431-4345', 'billing_extra-ponto_ref': 'longe de tudo', 'shipping-name': 'joao da silva', 'shipping-street': 'rua shipping', 'shipping-street2': 'complemento', 'shipping-street3': 'bairro', 'shipping-postal_code': '89050120', 'shipping-city': 'indaial', 'shipping-region': 'SC', 'shipping-country': 'BR', 'shipping-phone': '39 9999-2332', 'shipping_extra-numero': '323', 'shipping_extra-cel': '21 4444-3333', 'shipping_extra-ponto_ref': 'proximo posto', } response = client.post(addresses_path, data=addresses_data) print(response.content) assert response.status_code == 302 # Should redirect forth # Set the payment and shipping methods methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) methods_soup = client.soup(methods_path) assert client.post(methods_path, data=extract_form_fields( methods_soup)).status_code == 302 # Should redirect forth # Confirm the order confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) confirm_soup = client.soup(confirm_path) assert client.post(confirm_path, data=extract_form_fields( confirm_soup)).status_code == 302 # Should redirect forth
def get_completed_order_status(): create_default_order_statuses() return OrderStatus.objects.get_default_complete()
def get_initial_order_status(): create_default_order_statuses() return OrderStatus.objects.get_default_initial()
def test_checkout(admin_user): get_default_shop() set_current_theme('shuup.themes.classic_gray') create_default_order_statuses() populate_if_required() create_test_data() default_product = get_default_product() sp = ShopProduct.objects.get(product=default_product, shop=get_default_shop()) sp.default_price = get_default_shop().create_price(Decimal(10.0)) sp.save() service = get_custom_carrier_service() component = SpecificShippingTableBehaviorComponent.objects.create( table=ShippingTable.objects.get(identifier='table-1') ) service.behavior_components.add(component) c = SmartClient() basket_path = reverse("shuup:basket") add_to_basket_resp = c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 1, "supplier": get_default_supplier().pk }) assert add_to_basket_resp.status_code < 400 shipping_method = service payment_method = get_payment_method(name="neat", price=4) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) inputs['shipping-postal_code'] = "89060201" inputs['shipping-country'] = "BR" response = c.post(addresses_path, data=inputs) assert response.status_code == 302, "Address phase should redirect forth" assert response.url.endswith(methods_path) # Phase: Methods assert Order.objects.filter(payment_method=payment_method).count() == 0 response = c.post( methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk } ) assert response.status_code == 302, "Methods phase should redirect forth" assert response.url.endswith(confirm_path) response = c.get(confirm_path) assert response.status_code == 200 # Phase: Confirm assert Order.objects.count() == 0 confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) assert response.status_code == 302, "Confirm should redirect forth" assert Order.objects.count() == 1 order = Order.objects.filter(payment_method=payment_method).first() assert order.payment_status == PaymentStatus.NOT_PAID
def test_checkout(admin_user): get_default_shop() set_current_theme('shuup.themes.classic_gray') create_default_order_statuses() populate_if_required() create_test_data() default_product = get_default_product() sp = ShopProduct.objects.get(product=default_product, shop=get_default_shop()) sp.default_price = get_default_shop().create_price(Decimal(10.0)) sp.save() service = get_custom_carrier_service() component = SpecificShippingTableBehaviorComponent.objects.create( table=ShippingTable.objects.get(identifier='table-1')) service.behavior_components.add(component) c = SmartClient() basket_path = reverse("shuup:basket") add_to_basket_resp = c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 1, "supplier": get_default_supplier().pk }) assert add_to_basket_resp.status_code < 400 shipping_method = service payment_method = get_payment_method(name="neat", price=4) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) inputs['shipping-postal_code'] = "89060201" inputs['shipping-country'] = "BR" response = c.post(addresses_path, data=inputs) assert response.status_code == 302, "Address phase should redirect forth" assert response.url.endswith(methods_path) # Phase: Methods assert Order.objects.filter(payment_method=payment_method).count() == 0 response = c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) assert response.status_code == 302, "Methods phase should redirect forth" assert response.url.endswith(confirm_path) response = c.get(confirm_path) assert response.status_code == 200 # Phase: Confirm assert Order.objects.count() == 0 confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) assert response.status_code == 302, "Confirm should redirect forth" assert Order.objects.count() == 1 order = Order.objects.filter(payment_method=payment_method).first() assert order.payment_status == PaymentStatus.NOT_PAID
def test_order_partial_refund_with_taxes(include_tax): tax_rate = Decimal(0.2) # 20% product_price = 100 discount_amount = 30 random_line_price = 5 refunded_amount = 15 shop = factories.get_shop(include_tax) source = OrderSource(shop) source.status = factories.get_initial_order_status() supplier = factories.get_default_supplier() create_default_order_statuses() tax = factories.get_tax("sales-tax", "Sales Tax", tax_rate) factories.create_default_tax_rule(tax) product = factories.create_product("sku", shop=shop, supplier=supplier, default_price=product_price) line = source.add_line( line_id="product-line", type=OrderLineType.PRODUCT, product=product, supplier=supplier, quantity=1, shop=shop, base_unit_price=source.create_price(product_price), ) discount_line = source.add_line( line_id="discount-line", type=OrderLineType.DISCOUNT, supplier=supplier, quantity=1, base_unit_price=source.create_price(0), discount_amount=source.create_price(discount_amount), parent_line_id=line.line_id) raw_total_price = Decimal(product_price - discount_amount) total_taxful = bround(source.taxful_total_price.value) total_taxless = bround(source.taxless_total_price.value) if include_tax: assert total_taxful == bround(raw_total_price) assert total_taxless == bround(raw_total_price / (1 + tax_rate)) else: assert total_taxful == bround(raw_total_price * (1 + tax_rate)) assert total_taxless == bround(raw_total_price) creator = OrderCreator() order = creator.create_order(source) assert order.taxful_total_price.value == total_taxful assert order.taxless_total_price.value == total_taxless order.create_payment(order.taxful_total_price) assert order.is_paid() refund_data = [ dict( amount=Money(refunded_amount, shop.currency), quantity=1, line=order.lines.products().first(), ) ] order.create_refund(refund_data) total_taxful = bround(order.taxful_total_price.value) total_taxless = bround(order.taxless_total_price.value) taxless_refunded_amount = (refunded_amount / (1 + tax_rate)) if include_tax: raw_total_price = Decimal(product_price - discount_amount - refunded_amount) assert total_taxful == bround(raw_total_price) assert total_taxless == bround(raw_total_price / (1 + tax_rate)) else: # the refunded amount it considered a taxful price internally raw_total_price = Decimal(product_price - discount_amount) assert total_taxful == bround((raw_total_price * (1 + tax_rate)) - refunded_amount) assert total_taxless == bround(raw_total_price - taxless_refunded_amount) refund_line = order.lines.refunds().filter( type=OrderLineType.REFUND).first() if include_tax: assert refund_line.taxful_price.value == -bround(refunded_amount) assert refund_line.taxless_price.value == -bround( taxless_refunded_amount) else: assert refund_line.taxful_price.value == -bround(refunded_amount) assert refund_line.taxless_price.value == -bround( taxless_refunded_amount)
def get_completed_order_status(): create_default_order_statuses() return OrderStatus.objects.get_default_complete()
def get_initial_order_status(): create_default_order_statuses() return OrderStatus.objects.get_default_initial()
def test_checkout_with_success(): get_default_shop() set_current_theme('shuup.themes.classic_gray') create_default_order_statuses() populate_if_required() client = SmartClient() # first step - register user person_data = { "email": "*****@*****.**", "password1": "password", "password2": "password", "person_type": PersonType.FISICA.value, "PF-name": "NOME DA PESSOA", "PF-cpf": "012.345.678-90", "PF-rg": "312321", "PF-birth_date": "03/28/1954", "PF-gender": Gender.MALE.value } result = client.post(reverse("shuup:registration_register"), data=person_data) assert not result is None user = get_user_model().objects.get(email=person_data['email']) assert user.is_active # second step -add something into the basket default_product = get_default_product() basket_path = reverse("shuup:basket") add_to_basket_resp = client.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 1, "supplier": get_default_supplier().pk }) assert add_to_basket_resp.status_code < 400 # third step - go to checkout and set the addresses addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) addresses_data = { 'billing-name': 'maria da silva', 'billing-street': 'rua billing', 'billing-street2': 'apto', 'billing-street3': 'bairro outrem', 'billing-postal_code': '89090-200', 'billing-city': 'plumenau', 'billing-region': 'PR', 'billing-country': 'BR', 'billing-phone': '41 2332-0213', 'billing_extra-numero': '563', 'billing_extra-cel': '13 98431-4345', 'billing_extra-ponto_ref': 'longe de tudo', 'shipping-name': 'joao da silva', 'shipping-street': 'rua shipping', 'shipping-street2': 'complemento', 'shipping-street3': 'bairro', 'shipping-postal_code': '89050120', 'shipping-city': 'indaial', 'shipping-region': 'SC', 'shipping-country': 'BR', 'shipping-phone': '39 9999-2332', 'shipping_extra-numero': '323', 'shipping_extra-cel': '21 4444-3333', 'shipping_extra-ponto_ref': 'proximo posto', } response = client.post(addresses_path, data=addresses_data) print (response.content) assert response.status_code == 302 # Should redirect forth # Set the payment and shipping methods methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) methods_soup = client.soup(methods_path) assert client.post(methods_path, data=extract_form_fields(methods_soup)).status_code == 302 # Should redirect forth # Confirm the order confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) confirm_soup = client.soup(confirm_path) assert client.post(confirm_path, data=extract_form_fields(confirm_soup)).status_code == 302 # Should redirect forth