Example #1
0
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()
Example #3
0
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']
Example #4
0
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)
Example #5
0
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']
Example #6
0
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']
Example #7
0
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']
Example #8
0
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"
Example #9
0
 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.")
Example #10
0
 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.")
Example #11
0
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()
Example #12
0
 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.")
Example #13
0
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"
Example #14
0
 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.")
Example #15
0
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()
Example #16
0
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()
Example #17
0
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
Example #18
0
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
Example #19
0
 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.")
Example #20
0
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']
Example #21
0
    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.")
Example #22
0
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']
Example #23
0
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']
Example #24
0
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']
Example #25
0
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']
Example #26
0
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']
Example #27
0
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
Example #28
0
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
Example #29
0
def get_completed_order_status():
    create_default_order_statuses()
    return OrderStatus.objects.get_default_complete()
Example #30
0
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
Example #33
0
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)
Example #34
0
def get_completed_order_status():
    create_default_order_statuses()
    return OrderStatus.objects.get_default_complete()
Example #35
0
def get_initial_order_status():
    create_default_order_statuses()
    return OrderStatus.objects.get_default_initial()
Example #36
0
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