def test_create_berth_product(api_client, harbor): min_width = rounded(random.uniform(0, 5), round_to_nearest=0.05, as_string=True) variables = { "minWidth": min_width, "maxWidth": rounded( random.uniform(float(min_width), 6), round_to_nearest=0.05, as_string=True ), "tier1Price": str(random_price()), "tier2Price": str(random_price()), "tier3Price": str(random_price()), } assert BerthProduct.objects.count() == 0 executed = api_client.execute(CREATE_BERTH_PRODUCT_MUTATION, input=variables) assert BerthProduct.objects.count() == 1 assert executed["data"]["createBerthProduct"]["berthProduct"].pop("id") is not None assert executed["data"]["createBerthProduct"]["berthProduct"] == { "minWidth": str(variables["minWidth"]), "maxWidth": str(variables["maxWidth"]), "tier1Price": variables["tier1Price"], "tier2Price": variables["tier2Price"], "tier3Price": variables["tier3Price"], "priceUnit": PriceUnitsEnum.AMOUNT.name, "taxPercentage": PlaceProductTaxEnum.get(DEFAULT_TAX_PERCENTAGE).name, }
def test_update_berth_product(api_client, berth_product, harbor): variables = { "id": to_global_id(BerthProductNode, berth_product.id), "minWidth": rounded( random.uniform(0, 5), round_to_nearest=0.05, as_string=True ), "maxWidth": rounded( random.uniform(0, 6), round_to_nearest=0.05, as_string=True ), "tier1Price": str(random_price()), "tier2Price": str(random_price()), "tier3Price": str(random_price()), } assert BerthProduct.objects.count() == 1 executed = api_client.execute(UPDATE_BERTH_PRODUCT_MUTATION, input=variables) assert BerthProduct.objects.count() == 1 assert executed["data"]["updateBerthProduct"]["berthProduct"] == { "id": variables["id"], "minWidth": str(variables["minWidth"]), "maxWidth": str(variables["maxWidth"]), "tier1Price": variables["tier1Price"], "tier2Price": variables["tier2Price"], "tier3Price": variables["tier3Price"], "priceUnit": PriceUnitsEnum.AMOUNT.name, "taxPercentage": PlaceProductTaxEnum.get(DEFAULT_TAX_PERCENTAGE).name, }
def test_create_berth_product_not_enough_permissions(api_client): variables = { "minWidth": rounded(random.uniform(0, 5), round_to_nearest=0.05), "maxWidth": rounded(random.uniform(0, 6), round_to_nearest=0.05), "tier1Price": str(random_price()), "tier2Price": str(random_price()), "tier3Price": str(random_price()), } assert BerthProduct.objects.count() == 0 executed = api_client.execute(CREATE_BERTH_PRODUCT_MUTATION, input=variables) assert BerthProduct.objects.count() == 0 assert_not_enough_permissions(executed)
def test_create_order_winter_storage_lease(api_client, winter_storage_lease): lease_id = to_global_id(WinterStorageLeaseNode, winter_storage_lease.id) customer_id = to_global_id(ProfileNode, winter_storage_lease.customer.id) expected_product = WinterStorageProduct.objects.get( winter_storage_area=winter_storage_lease.get_winter_storage_area() ) expected_price = rounded( winter_storage_lease.place.place_type.width * winter_storage_lease.place.place_type.length * expected_product.price_value, round_to_nearest=1, as_string=True, ) variables = { "leaseId": lease_id, } assert Order.objects.count() == 0 executed = api_client.execute(CREATE_ORDER_MUTATION, input=variables) assert Order.objects.count() == 1 assert executed["data"]["createOrder"]["order"].pop("id") is not None assert executed["data"]["createOrder"]["order"] == { "price": expected_price, "taxPercentage": str(expected_product.tax_percentage), "customer": {"id": customer_id}, "product": {"id": to_global_id(WinterStorageProductNode, expected_product.id)}, "lease": {"id": to_global_id(WinterStorageLeaseNode, winter_storage_lease.id)}, }
class BerthProductFactory(factory.django.DjangoModelFactory): min_width = factory.LazyFunction( lambda: rounded(random.uniform(0, 8), round_to_nearest=0.05) ) max_width = factory.LazyAttribute( lambda o: rounded(random.uniform(float(o.min_width), 10), round_to_nearest=0.05) ) tier_1_price = factory.LazyFunction(lambda: random_price(1, 100, decimals=0)) tier_2_price = factory.LazyFunction(lambda: random_price(1, 100, decimals=0)) tier_3_price = factory.LazyFunction(lambda: random_price(1, 100, decimals=0)) tax_percentage = factory.Faker( "random_element", elements=PLACE_PRODUCT_TAX_PERCENTAGES ) pricing_category = PricingCategory.DEFAULT class Meta: model = BerthProduct django_get_or_create = ("min_width", "max_width", "pricing_category")
def test_create_order_line(api_client, order, additional_product): order_id = to_global_id(OrderNode, order.id) product_id = to_global_id(AdditionalProductNode, additional_product.id) variables = { "orderId": order_id, "productId": product_id, } assert OrderLine.objects.count() == 0 executed = api_client.execute(CREATE_ORDER_LINE_MUTATION, input=variables) assert OrderLine.objects.count() == 1 expected_price = additional_product.price_value if additional_product.price_unit == PriceUnits.PERCENTAGE: expected_price = calculate_product_percentage_price( order.price, additional_product.price_value ) if additional_product.period == PeriodType.MONTH: expected_price = calculate_product_partial_month_price( expected_price, order.lease.start_date, order.lease.end_date ) elif additional_product.period == PeriodType.YEAR: expected_price = calculate_product_partial_year_price( expected_price, order.lease.start_date, order.lease.end_date ) # Season price is the same assert executed["data"]["createOrderLine"]["orderLine"].pop("id") is not None assert executed["data"]["createOrderLine"] == { "orderLine": { "price": str(expected_price), "taxPercentage": rounded( additional_product.tax_percentage, decimals=2, round_to_nearest=0.05, as_string=True, ), "pretaxPrice": str( convert_aftertax_to_pretax( expected_price, additional_product.tax_percentage, ) ), "product": { "id": to_global_id(AdditionalProductNode, additional_product.id), "priceValue": str(additional_product.price_value), "priceUnit": PriceUnitsEnum.get(additional_product.price_unit).name, }, }, "order": {"id": order_id}, }
def test_order_retrieves_winter_storage_lease(winter_storage_lease): order = Order.objects.create(_lease_object_id=winter_storage_lease.id, customer=winter_storage_lease.customer) sqm = (winter_storage_lease.place.place_type.width * winter_storage_lease.place.place_type.length) expected_price = rounded(order.product.price_value * sqm, decimals=2, round_to_nearest=1) assert order.lease.id == winter_storage_lease.id assert order._lease_content_type.name == winter_storage_lease._meta.verbose_name assert order.price == expected_price
def test_initiate_refund_no_order_email(provider_base_config: dict, order: Order): """Test the request creator constructs the payload base and returns a url that contains a token""" request = RequestFactory().request() order.status = OrderStatus.PAID order.email = None order.lease.status = LeaseStatus.PAID order.lease.save() order.save() OrderToken.objects.create( order=order, token="12345", valid_until=now() - relativedelta(days=7) ) if hasattr(order.product, "price_for_tier"): place_price = order.product.price_for_tier(order.lease.berth.pier.price_tier) area = order.lease.berth.pier.harbor else: # Winter products are priced per m2 place_price = rounded( order.product.price_value * order.lease.place.place_type.width * order.lease.place.place_type.length, round_to_nearest=1, ) area = order.lease.place.winter_storage_section.area products = [ { "id": get_talpa_product_id(order.product.id, area, False), "product_id": 1123, "title": order.product.name, "count": 1, "pretax_price": price_as_fractional_int( convert_aftertax_to_pretax(place_price, order.product.tax_percentage) ), "tax": int(order.product.tax_percentage), "price": price_as_fractional_int(place_price), "type": 1, } ] payment_provider = create_bambora_provider(provider_base_config, request) with mock.patch( "payments.providers.bambora_payform.requests.post", side_effect=mocked_refund_response_create, ), mock.patch( "payments.providers.bambora_payform.BamboraPayformProvider.get_payment_details", side_effect=mocked_refund_payment_details(products=products), ): refund = payment_provider.initiate_refund(order) assert refund.refund_id == "123456"
def test_order_winter_storage_product_price(winter_storage_lease): order = OrderFactory(lease=winter_storage_lease) expected_product = WinterStorageProduct.objects.get( winter_storage_area=winter_storage_lease.get_winter_storage_area()) expected_price = rounded( order.product.price_value * winter_storage_lease.place.place_type.width * winter_storage_lease.place.place_type.length, decimals=2, round_to_nearest=1, ) assert order.product == expected_product assert order.price == expected_price assert order.tax_percentage == expected_product.tax_percentage
def test_order_winter_storage_lease_right_price_for_full_season( winter_storage_area): services = { "summer_storage_for_docking_equipment": True, "summer_storage_for_trailers": random_bool(), } for service, create in services.items(): if create: # Using PriceUnits.AMOUNT to simplify testing AdditionalProductFactory( service=ProductServiceType(service), price_value=Decimal("25.00"), price_unit=PriceUnits.AMOUNT, ) section = WinterStorageSectionFactory(**services, area=winter_storage_area) lease = WinterStorageLeaseFactory( place=WinterStoragePlaceFactory(winter_storage_section=section), create_product=False, ) WinterStorageProductFactory(winter_storage_area=winter_storage_area, price_value=Decimal("100.00")) order = OrderFactory(lease=lease) for service, create in services.items(): if create: additional_product = AdditionalProduct.objects.filter( service=ProductServiceType(service), price_unit=PriceUnits.AMOUNT, period=PeriodType.SEASON, ).first() OrderLine.objects.create(order=order, product=additional_product) assert order.lease.start_date == calculate_winter_storage_lease_start_date( ) assert order.lease.end_date == calculate_winter_storage_lease_end_date() sqm = order.lease.place.place_type.width * order.lease.place.place_type.length expected_price = rounded(Decimal("100.00") * sqm, decimals=2, round_to_nearest=1) assert order.price == expected_price for service, created in services.items(): if created: order_line = OrderLine.objects.filter( order=order, product__service=ProductServiceType(service)).first() assert order_line.price == Decimal("25.00")
def test_order_winter_storage_lease_with_section_right_price( winter_storage_section, boat): winter_storage_lease = WinterStorageLeaseFactory( place=None, section=winter_storage_section, customer=boat.owner, boat=boat) order = OrderFactory(lease=winter_storage_lease) sqm = boat.width * boat.length expected_price = rounded(order.product.price_value * sqm, decimals=2) assert order.lease.id == winter_storage_lease.id assert order._lease_content_type.name == winter_storage_lease._meta.verbose_name assert order.price == expected_price
def test_order_winter_storage_lease_without_boat_right_price( winter_storage_section, winter_storage_application, customer_profile, ): winter_storage_lease = WinterStorageLeaseFactory( place=None, section=winter_storage_section, customer=customer_profile, boat=None, application=winter_storage_application, ) order = OrderFactory(lease=winter_storage_lease) sqm = winter_storage_application.boat_width * winter_storage_application.boat_length expected_price = rounded(order.product.price_value * sqm, decimals=2) assert order.lease.id == winter_storage_lease.id assert order._lease_content_type.name == winter_storage_lease._meta.verbose_name assert order.price == expected_price
def test_refund_order( api_client, order: Order, payment_provider, notification_template_order_refunded, ): order.status = OrderStatus.PAID order.customer_email = "*****@*****.**" order.lease.status = LeaseStatus.PAID order.lease.save() order.save() OrderToken.objects.create( order=order, token="1245", valid_until=today() - relativedelta(days=7) ) if hasattr(order.product, "price_for_tier"): place_price = order.product.price_for_tier(order.lease.berth.pier.price_tier) area = order.lease.berth.pier.harbor else: # Winter products are priced per m2 place_price = rounded( order.product.price_value * order.lease.place.place_type.width * order.lease.place.place_type.length, round_to_nearest=1, ) area = order.lease.place.winter_storage_section.area products = [ { "id": get_talpa_product_id(order.product.id, area, False), "product_id": 1123, "title": order.product.name, "count": 1, "pretax_price": price_as_fractional_int( convert_aftertax_to_pretax(place_price, order.product.tax_percentage) ), "tax": int(order.product.tax_percentage), "price": price_as_fractional_int(place_price), "type": 1, } ] variables = { "orderId": to_global_id(OrderNode, order.id), } with mock.patch( "payments.providers.bambora_payform.requests.post", side_effect=mocked_refund_response_create, ), mock.patch( "payments.providers.bambora_payform.BamboraPayformProvider.get_payment_details", side_effect=mocked_refund_payment_details(products=products), ): executed = api_client.execute(REFUND_ORDER_MUTATION, input=variables) assert executed["data"]["refundOrder"]["orderRefund"] == { "order": {"status": OrderStatus.PAID.name}, "status": OrderRefundStatus.PENDING.name, "amount": str(order.price), } assert len(mail.outbox) == 1 assert ( mail.outbox[0].subject == f"test order refunded subject: {order.order_number}!" ) assert mail.outbox[0].body == f"{order.order_number} {order.price}" assert mail.outbox[0].to == [order.customer_email] assert mail.outbox[0].alternatives == [ (f"<b>{order.order_number} {order.price}</b>", "text/html") ]