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)},
    }
示例#5
0
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
示例#13
0
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")
    ]