def test_source_lines_with_multiple_fixed_costs(): """ Costs with description creates new line always and costs without description is combined into one line. """ translation.activate("en") starting_price_value = 5 sm = get_shipping_method(name="Multiple costs", price=starting_price_value) sm.behavior_components.clear() source = BasketishOrderSource(get_default_shop()) source.shipping_method = sm lines = list(sm.get_lines(source)) assert len(lines) == 1 assert get_total_price_value(lines) == Decimal("0") sm.behavior_components.add( FixedCostBehaviorComponent.objects.create(price_value=10)) lines = list(sm.get_lines(source)) assert len(lines) == 1 assert get_total_price_value(lines) == Decimal("10") sm.behavior_components.add( FixedCostBehaviorComponent.objects.create(price_value=15, description="extra")) lines = list(sm.get_lines(source)) assert len(lines) == 2 assert get_total_price_value(lines) == Decimal("25") sm.behavior_components.add( FixedCostBehaviorComponent.objects.create(price_value=1)) lines = list(sm.get_lines(source)) assert len(lines) == 2 assert get_total_price_value(lines) == Decimal("26")
def test_weight_limits(): carrier = CustomCarrier.objects.create() sm = carrier.create_service(None, shop=get_default_shop(), enabled=True, tax_class=get_default_tax_class()) sm.behavior_components.add( WeightLimitsBehaviorComponent.objects.create(min_weight=100, max_weight=500)) source = BasketishOrderSource(get_default_shop()) assert any(ve.code == "min_weight" for ve in sm.get_unavailability_reasons(source)) source.add_line(type=OrderLineType.PRODUCT, weight=600) assert any(ve.code == "max_weight" for ve in sm.get_unavailability_reasons(source))
def test_translations_of_method_and_component(): sm = get_shipping_method(name="Unique shipping") sm.set_current_language('en') sm.name = "Shipping" sm.set_current_language('fi') sm.name = "Toimitus" sm.save() cost = FixedCostBehaviorComponent.objects.language('fi').create( price_value=10, description="kymppi") cost.set_current_language('en') cost.description = "ten bucks" cost.save() sm.behavior_components.add(cost) source = BasketishOrderSource(get_default_shop()) source.shipping_method = sm translation.activate('fi') shipping_lines = [ line for line in source.get_final_lines() if line.type == OrderLineType.SHIPPING ] assert len(shipping_lines) == 1 assert shipping_lines[0].text == 'Toimitus: kymppi' translation.activate('en') source.uncache() shipping_lines = [ line for line in source.get_final_lines() if line.type == OrderLineType.SHIPPING ] assert len(shipping_lines) == 1 assert shipping_lines[0].text == 'Shipping: ten bucks'
def _get_order(prices_include_tax=False, include_basket_campaign=False, include_catalog_campaign=False): shop = get_shop(prices_include_tax=prices_include_tax) supplier = get_simple_supplier() if include_basket_campaign: _add_basket_campaign(shop) if include_catalog_campaign: _add_catalog_campaign(shop) _add_taxes() source = BasketishOrderSource(shop) source.status = get_initial_order_status() ctx = get_pricing_module().get_context_from_data(shop, AnonymousContact()) for product_data in _get_product_data(): quantity = product_data.pop("quantity") product = create_product( sku=product_data.pop("sku"), shop=shop, supplier=supplier, stock_behavior=StockBehavior.STOCKED, tax_class=get_default_tax_class(), **product_data) shop_product = product.get_shop_instance(shop) shop_product.categories.add(get_default_category()) shop_product.save() supplier.adjust_stock(product.id, INITIAL_PRODUCT_QUANTITY) pi = product.get_price_info(ctx) source.add_line( type=OrderLineType.PRODUCT, product=product, supplier=supplier, quantity=quantity, base_unit_price=pi.base_unit_price, discount_amount=pi.discount_amount ) oc = OrderCreator() order = oc.create_order(source) order.create_payment(Money("1", "EUR")) assert not order.has_refunds() assert order.can_create_refund() assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert order.payment_status == PaymentStatus.PARTIALLY_PAID return order
def test_waiver(): sm = get_shipping_method(name="Waivey", price=100, waive_at=370) source = BasketishOrderSource(get_default_shop()) assert sm.get_effective_name(source) == u"Waivey" assert sm.get_total_cost(source).price == source.create_price(100) source.add_line(type=OrderLineType.PRODUCT, product=get_default_product(), base_unit_price=source.create_price(400), quantity=1) assert sm.get_total_cost(source).price == source.create_price(0)
def seed_source(user, shop=None): source_shop = shop or get_default_shop() source = BasketishOrderSource(source_shop) billing_address = get_address() shipping_address = get_address(name="Shippy Doge") source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = get_person_contact(user) source.payment_method = get_payment_method(shop) source.shipping_method = get_shipping_method(shop) assert source.payment_method_id == get_payment_method(shop).id assert source.shipping_method_id == get_shipping_method(shop).id return source
def seed_source(user, shop): source = BasketishOrderSource(shop) source.status = get_initial_order_status() source.customer = get_person_contact(user) source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() return source
def test_staff_only_behavior(admin_user, regular_user): payment_method = get_default_payment_method() component = StaffOnlyBehaviorComponent.objects.create() payment_method.behavior_components.add(component) source = BasketishOrderSource(get_default_shop()) # anonymous user unavailability_reasons = list( payment_method.get_unavailability_reasons(source)) assert len(unavailability_reasons) == 1 # regular user source.creator = regular_user unavailability_reasons = list( payment_method.get_unavailability_reasons(source)) assert len(unavailability_reasons) == 1 # admin source.creator = admin_user unavailability_reasons = list( payment_method.get_unavailability_reasons(source)) assert len(unavailability_reasons) == 0
def get_source(): source = BasketishOrderSource(get_default_shop()) source.add_line( type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) source.add_line( type=OrderLineType.OTHER, quantity=1, base_unit_price=source.create_price(10), require_verification=True, ) return source
def _seed_source(shop, user, shipping_country, billing_country): source = BasketishOrderSource(shop) billing_address = get_address(country=billing_country) shipping_address = get_address(name="Test street", country=shipping_country) source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = get_person_contact(user) return source
def get_order_source_with_a_package(): package_product = get_package_product() source = BasketishOrderSource(get_default_shop()) source.add_line( type=OrderLineType.PRODUCT, product=package_product, supplier=get_default_supplier(), quantity=10, base_unit_price=source.create_price(10), sku=package_product.sku, text=package_product.name, ) source.status = get_initial_order_status() return source
def _get_custom_order(regular_user, **kwargs): prices_include_tax = kwargs.pop("prices_include_tax", False) include_basket_campaign = kwargs.pop("include_basket_campaign", False) include_catalog_campaign = kwargs.pop("include_catalog_campaign", False) shop = get_shop(prices_include_tax=prices_include_tax) supplier = get_simple_supplier() if include_basket_campaign: _add_basket_campaign(shop) if include_catalog_campaign: _add_catalog_campaign(shop) _add_taxes() contact = get_person_contact(regular_user) source = BasketishOrderSource(shop) source.status = get_initial_order_status() source.customer = contact ctx = get_pricing_module().get_context_from_data(shop, contact) for product_data in _get_product_data(): quantity = product_data.pop("quantity") product = create_product(sku=product_data.pop("sku"), shop=shop, supplier=supplier, stock_behavior=StockBehavior.STOCKED, tax_class=get_default_tax_class(), **product_data) shop_product = product.get_shop_instance(shop) shop_product.categories.add(get_default_category()) shop_product.save() supplier.adjust_stock(product.id, INITIAL_PRODUCT_QUANTITY) pi = product.get_price_info(ctx) source.add_line(type=OrderLineType.PRODUCT, product=product, supplier=supplier, quantity=quantity, base_unit_price=pi.base_unit_price, discount_amount=pi.discount_amount) oc = OrderCreator() order = oc.create_order(source) return order
def test_order_source_rounding(prices): shop = Shop.objects.create(name="test", identifier="test", status=ShopStatus.ENABLED, public_name="test", prices_include_tax=False) expected = 0 for p in prices: expected += bankers_round(p, 2) source = BasketishOrderSource(shop) for x, price in enumerate(prices): source.add_line( type=OrderLineType.OTHER, quantity=1, text=x, base_unit_price=source.create_price(price), ordering=x, ) for x, order_source in enumerate(source.get_lines()): price = Decimal(prices[x]).quantize(Decimal(".1")**9) # make sure prices are in database with original precision assert order_source.base_unit_price == source.shop.create_price(price) # make sure the line taxless price is rounded assert order_source.taxless_price == source.shop.create_price( bankers_round(price, 2)) # Check that total prices calculated from priceful parts still matches assert _get_taxless_price(order_source) == order_source.taxless_price assert _get_taxful_price(order_source) == order_source.taxful_price # make sure the line price is rounded assert order_source.price == source.shop.create_price(price) # make sure order total is rounded assert source.taxless_total_price == source.shop.create_price( bankers_round(expected, 2))
def get_order_and_source(admin_user, product, language, language_fallback): # create original source to tamper with contact = get_person_contact(admin_user) contact.language = language contact.save() assert contact.language == language # contact language is naive source = BasketishOrderSource(get_default_shop()) source.status = get_initial_order_status() source.billing_address = MutableAddress.objects.create( name="Original Billing") source.shipping_address = MutableAddress.objects.create( name="Original Shipping") source.customer = contact source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=product, supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) source.add_line( type=OrderLineType.OTHER, quantity=1, base_unit_price=source.create_price(10), require_verification=True, ) assert len(source.get_lines()) == 2 source.creator = admin_user assert not source._language # is None because it was not directly assigned assert source.language == language_fallback creator = OrderCreator() order = creator.create_order(source) assert order.language == source.language return order, source
def test_methods(admin_user, country): contact = get_person_contact(admin_user) source = BasketishOrderSource(get_default_shop()) source.add_line(type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), weight=Decimal("0.2")) billing_address = get_address() shipping_address = get_address(name="Shippy Doge", country=country) source.billing_address = billing_address source.shipping_address = shipping_address source.customer = contact source.shipping_method = get_expensive_sweden_shipping_method() source.payment_method = get_payment_method(name="neat", price=4) assert source.shipping_method_id assert source.payment_method_id errors = list(source.get_validation_errors()) if country == "FI": # "Expenseefe-a Svedee Sheepping" will not allow shipping to # Finland, let's see if that holds true assert any([ve.code == "we_no_speak_finnish" for ve in errors]) assert [x.code for x in errors] == ["we_no_speak_finnish"] return # Shouldn't try the rest if we got an error here else: assert not errors final_lines = list(source.get_final_lines()) assert any(line.type == OrderLineType.SHIPPING for line in final_lines) for line in final_lines: if line.type == OrderLineType.SHIPPING: if country == "SE": # We _are_ using Expenseefe-a Svedee Sheepping after all. assert line.price == source.create_price("5.00") else: assert line.price == source.create_price("4.00") assert line.text == u"Expenseefe-a Svedee Sheepping" if line.type == OrderLineType.PAYMENT: assert line.price == source.create_price(4)
def seed_source(coupon, produce_price=10): source = BasketishOrderSource(get_default_shop()) billing_address = get_address() shipping_address = get_address(name="Shippy Doge") source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = create_random_person() source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(produce_price), ) source.add_code(coupon.code) return source
def test_fixed_cost_with_waiving_costs(): sm = get_shipping_method(name="Fixed and waiving", price=5) sm.behavior_components.add(*[ WaivingCostBehaviorComponent.objects.create(price_value=p, waive_limit_value=w) for (p, w) in [(3, 5), (7, 10), (10, 30)] ]) source = BasketishOrderSource(get_default_shop()) source.shipping_method = sm def pricestr(pi): assert pi.price.unit_matches_with(source.create_price(0)) return "%.0f EUR (%.0f EUR)" % (pi.price.value, pi.base_price.value) assert pricestr(sm.get_total_cost(source)) == "25 EUR (25 EUR)" assert source.total_price.value == 25 source.add_line(type=OrderLineType.PRODUCT, product=get_default_product(), base_unit_price=source.create_price(2), quantity=1) assert pricestr(sm.get_total_cost(source)) == "25 EUR (25 EUR)" assert source.total_price.value == 27 source.add_line(type=OrderLineType.PRODUCT, product=get_default_product(), base_unit_price=source.create_price(3), quantity=1) assert pricestr(sm.get_total_cost(source)) == "22 EUR (25 EUR)" assert source.total_price.value == 27 source.add_line(type=OrderLineType.PRODUCT, product=get_default_product(), base_unit_price=source.create_price(10), quantity=1) assert pricestr(sm.get_total_cost(source)) == "15 EUR (25 EUR)" assert source.total_price.value == 30 source.add_line(type=OrderLineType.PRODUCT, product=get_default_product(), base_unit_price=source.create_price(10), quantity=1) assert pricestr(sm.get_total_cost(source)) == "15 EUR (25 EUR)" assert source.total_price.value == 40 source.add_line(type=OrderLineType.PRODUCT, product=get_default_product(), base_unit_price=source.create_price(10), quantity=1) assert pricestr(sm.get_total_cost(source)) == "5 EUR (25 EUR)" assert source.total_price.value == 40
def test_order_creator_parent_linkage(): """ Test OrderCreator creates parent links from OrderSource. """ source = BasketishOrderSource(get_default_shop()) source.status = get_initial_order_status() source.add_line( line_id='LINE1', type=OrderLineType.OTHER, quantity=1, sku='parent', text='Parent line', ) source.add_line( line_id='LINE1.1', parent_line_id='LINE1', type=OrderLineType.OTHER, quantity=1, sku='child1.1', text='Child line 1.1', ) source.add_line( line_id='LINE1.2', parent_line_id='LINE1', type=OrderLineType.OTHER, quantity=1, sku='child1.2', text='Child line 1.2', ) source.add_line( line_id='LINE1.2.1', parent_line_id='LINE1.2', type=OrderLineType.OTHER, quantity=1, sku='child1.2.1', text='Child line 1.2.1', ) source.add_line( line_id='LINE1.3', parent_line_id='LINE1', type=OrderLineType.OTHER, quantity=1, sku='child1.3', text='Child line 1.3', ) order = OrderCreator().create_order(source) lines = [prettify_order_line(line) for line in order.lines.all()] assert lines == [ '#0 1 x parent', '#1 1 x child1.1, child of #0', '#2 1 x child1.2, child of #0', '#3 1 x child1.2.1, child of #2', '#4 1 x child1.3, child of #0', ]
def test_broken_order(admin_user): """ """ quantities = [44, 23, 65] expected = sum(quantities) * 50 expected_based_on = expected / 1.5 # Wshop is calculating taxes per line so there will be some "errors" expected_based_on = ensure_decimal_places( Decimal("%s" % (expected_based_on + 0.01))) shop = get_default_shop() supplier = get_default_supplier() product1 = create_product("simple-test-product1", shop, supplier, 50) product2 = create_product("simple-test-product2", shop, supplier, 50) product3 = create_product("simple-test-product3", shop, supplier, 50) tax = get_default_tax() source = BasketishOrderSource(get_default_shop()) billing_address = get_address(country="US") shipping_address = get_address(name="Test street", country="US") source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = create_random_person() source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=product1, supplier=get_default_supplier(), quantity=quantities[0], base_unit_price=source.create_price(50), ) source.add_line( type=OrderLineType.PRODUCT, product=product2, supplier=get_default_supplier(), quantity=quantities[1], base_unit_price=source.create_price(50), ) source.add_line( type=OrderLineType.PRODUCT, product=product3, supplier=get_default_supplier(), quantity=quantities[2], base_unit_price=source.create_price(50), ) currency = "EUR" summary = source.get_tax_summary() assert len(summary) == 1 summary = summary[0] assert summary.taxful == Money(expected, "EUR") assert summary.based_on == Money(expected_based_on, "EUR") # originally non-rounded value assert bankers_round(source.get_total_tax_amount()) == summary.tax_amount assert source.taxless_total_price.value == expected_based_on assert summary.taxful.value == source.taxful_total_price.value assert summary.tax_amount == Money( bankers_round(source.taxful_total_price.value - source.taxless_total_price.value), currency) assert summary.taxful == summary.raw_based_on + summary.tax_amount assert summary.tax_rate == tax.rate assert summary.taxful.value == ( summary.based_on + summary.tax_amount).value - Decimal("%s" % 0.01) # create order from basket creator = OrderCreator() order = creator.create_order(source) assert order.taxless_total_price.value == expected_based_on # originally non-rounded value assert bankers_round(order.get_total_tax_amount()) == summary.tax_amount