def test_accept_offer_invalid_status(user_api_client, is_accepted,
                                     initial_status):
    customer = CustomerProfileFactory()
    due_date = date.today() + relativedelta(days=14)
    berth_switch_offer = BerthSwitchOfferFactory(
        customer=customer,
        due_date=due_date,
        status=initial_status,
        lease=BerthLeaseFactory(
            customer=customer,
            start_date=calculate_berth_lease_start_date(),
            end_date=calculate_berth_lease_end_date(),
            status=LeaseStatus.PAID,
        ),
    )

    variables = {
        # "offerId": to_global_id(BerthSwitchOfferNode, berth_switch_offer.id),
        "offerNumber": berth_switch_offer.offer_number,
        "isAccepted": is_accepted,
    }

    user_api_client.execute(ACCEPT_BERTH_SWITCH_OFFER_MUTATION,
                            input=variables)

    berth_switch_offer.refresh_from_db()
    berth_switch_offer.lease.refresh_from_db()

    assert berth_switch_offer.status == initial_status
    assert berth_switch_offer.lease.status == LeaseStatus.PAID
    new_lease = BerthLease.objects.exclude(
        id=berth_switch_offer.lease_id).first()
    assert new_lease is None
def test_reject_offer(user_api_client):
    customer = CustomerProfileFactory()
    due_date = date.today() + relativedelta(days=14)
    berth_switch_offer = BerthSwitchOfferFactory(
        customer=customer,
        due_date=due_date,
        status=OfferStatus.OFFERED,
        lease=BerthLeaseFactory(
            customer=customer,
            start_date=calculate_berth_lease_start_date(),
            end_date=calculate_berth_lease_end_date(),
            status=LeaseStatus.PAID,
        ),
    )

    variables = {
        # "offerId": to_global_id(BerthSwitchOfferNode, berth_switch_offer.id),
        "offerNumber": berth_switch_offer.offer_number,
        "isAccepted": False,
    }

    user_api_client.execute(ACCEPT_BERTH_SWITCH_OFFER_MUTATION,
                            input=variables)

    berth_switch_offer.refresh_from_db()
    berth_switch_offer.lease.refresh_from_db()

    assert berth_switch_offer.status == OfferStatus.REJECTED
    assert berth_switch_offer.lease.status == LeaseStatus.PAID
    assert berth_switch_offer.application.status == ApplicationStatus.REJECTED
    assert BerthLease.objects.all().count() == 1
def _get_berth_order_context(subject: str = "Berth order"):
    customer = CustomerProfileFactory.build()
    order = OrderFactory.build(
        customer=customer,
        product=BerthProductFactory.build(),
        lease=BerthLeaseFactory.build(
            customer=customer,
            # Fixed to a harbor with a real image
            berth__pier__harbor__image_file="/img/helsinki_harbors/41189.jpg",
        ),
        price=Decimal("100"),
        tax_percentage=Decimal("24.00"),
    )
    optional_services = [
        OrderLineFactory.build(
            order=order,
            product__service=ProductServiceType.OPTIONAL_SERVICES()[0],
            price=random_price(),
        ),
        OrderLineFactory.build(
            order=order,
            product__service=ProductServiceType.OPTIONAL_SERVICES()[1],
            price=random_price(),
        ),
    ]

    return _get_order_context(subject, order, optional_services)
def test_berth_lease_update_application_different_customer(berth_lease):
    first_application = BerthApplicationFactory(
        customer=CustomerProfileFactory())
    second_application = BerthApplicationFactory(
        customer=CustomerProfileFactory())

    berth_lease.application = first_application
    berth_lease.save()

    assert BerthLease.objects.get(
        id=berth_lease.id).application == first_application

    with pytest.raises(ValidationError) as exception:
        berth_lease.application = second_application
        berth_lease.save()

    assert (
        "Cannot change the application to one which belongs to another customer"
        in str(exception.value))
def get_customer_profile_dict() -> dict:
    faker = Faker()
    profile = CustomerProfileFactory()
    return {
        "id": to_global_id(ProfileNode, profile.id),
        "first_name": profile.user.first_name,
        "last_name": profile.user.last_name,
        "primary_email": {"email": profile.user.email},
        "primary_phone": {"phone": faker.phone_number()},
        "primary_address": MOCK_HKI_PROFILE_ADDRESS,
    }
def test_winter_storage_lease_application_different_customer(
        winter_storage_lease):
    first_application = WinterStorageApplicationFactory(
        customer=CustomerProfileFactory())
    second_application = WinterStorageApplicationFactory(
        customer=CustomerProfileFactory())

    winter_storage_lease.application = first_application
    winter_storage_lease.save()

    assert (WinterStorageLease.objects.get(
        id=winter_storage_lease.id).application == first_application)

    with pytest.raises(ValidationError) as exception:
        winter_storage_lease.application = second_application
        winter_storage_lease.save()

    assert (
        "Cannot change the application to one which belongs to another customer"
        in str(exception.value))
def _get_berth_switch_offer_context(subject: str = "Berth offer"):
    customer = CustomerProfileFactory.build()
    offer = BerthSwitchOfferFactory.build(
        customer=customer,
        application=BerthApplicationFactory.build(customer=customer),
        berth=BerthFactory.build(),
        lease=BerthLeaseFactory.build(
            customer=customer,
            # Fixed to a harbor with a real image
            berth__pier__harbor__image_file="/img/helsinki_harbors/41189.jpg",
        ),
    )
    return _get_offer_context(subject, offer)
Esempio n. 8
0
def test_delete_profile(rest_api_client, requests_mock, settings):
    customer_profile = CustomerProfileFactory()

    auth_header = get_api_token_for_user_with_scopes(
        customer_profile.user, [settings.GDPR_API_DELETE_SCOPE], requests_mock
    )
    rest_api_client.credentials(HTTP_AUTHORIZATION=auth_header)
    response = rest_api_client.delete(
        reverse("helsinki_gdpr:gdpr_v1", kwargs={"pk": customer_profile.id})
    )

    assert response.status_code == 204
    assert CustomerProfile.objects.count() == 0
    assert User.objects.count() == 0
Esempio n. 9
0
def test_delete_profile_with_lease(rest_api_client, requests_mock, settings):
    """For now, if the profile has resources connected to it, they will prevent
    the deletion of the profile
    """
    customer_profile = CustomerProfileFactory()
    BerthLeaseFactory(customer=customer_profile)

    auth_header = get_api_token_for_user_with_scopes(
        customer_profile.user, [settings.GDPR_API_DELETE_SCOPE], requests_mock
    )
    rest_api_client.credentials(HTTP_AUTHORIZATION=auth_header)
    response = rest_api_client.delete(
        reverse("helsinki_gdpr:gdpr_v1", kwargs={"pk": customer_profile.id})
    )

    assert response.status_code == 403
    assert CustomerProfile.objects.count() == 1
    assert User.objects.count() == 1
def _get_cancelled_order_context(subject: str = "Order cancelled"):
    customer = CustomerProfileFactory.build()
    return {
        "subject": subject,
        "order": {
            **factory.build(
                dict,
                FACTORY_CLASS=OrderFactory,
                customer=customer,
                status=OrderStatus.CANCELLED,
                product=BerthProductFactory.build(),
                lease=BerthLeaseFactory.build(customer=customer),
                price=Decimal("100"),
                tax_percentage=Decimal("24.00"),
            ),
        },
        "rejected_at": str(datetime.date.today(
        )),  # language not known at this point, default to ISO format
    }
Esempio n. 11
0
def test_get_profile_information_from_gdpr_api(
    rest_api_client, requests_mock, settings
):
    customer_profile = CustomerProfileFactory()

    auth_header = get_api_token_for_user_with_scopes(
        customer_profile.user, [settings.GDPR_API_QUERY_SCOPE], requests_mock
    )

    rest_api_client.credentials(HTTP_AUTHORIZATION=auth_header)
    response = rest_api_client.get(
        reverse("helsinki_gdpr:gdpr_v1", kwargs={"pk": customer_profile.id})
    )

    resp = json.loads(response.content)
    assert response.status_code == 200
    assert resp == {
        "key": "CUSTOMERPROFILE",
        "children": [
            {
                "key": "INVOICING_TYPE",
                "value": dict(InvoicingType.choices)[customer_profile.invoicing_type],
            },
            {"key": "COMMENT", "value": customer_profile.comment},
            {
                "key": "CREATED_AT",
                "value": customer_profile.created_at.strftime("%d-%m-%Y %H:%M:%S"),
            },
            {
                "key": "MODIFIED_AT",
                "value": customer_profile.modified_at.strftime("%d-%m-%Y %H:%M:%S"),
            },
            {"key": "BERTH_APPLICATIONS", "children": []},
            {"key": "BERTH_LEASES", "children": []},
            {"key": "BOATS", "children": []},
            {"key": "OFFERS", "children": []},
            {"key": "ORDERS", "children": []},
            {"key": "WINTER_STORAGE_APPLICATIONS", "children": []},
            {"key": "WINTER_STORAGE_LEASES", "children": []},
        ],
    }
def _get_refunded_order_context(subject: str = "Order refunded"):
    customer = CustomerProfileFactory.build()
    return {
        "subject": get_email_subject(NotificationType.ORDER_REFUNDED),
        "order": {
            **factory.build(
                dict,
                FACTORY_CLASS=OrderFactory,
                customer=customer,
                status=OrderStatus.REFUNDED,
                product=BerthProductFactory.build(),
                lease=BerthLeaseFactory.build(customer=customer),
                price=Decimal("100"),
                tax_percentage=Decimal("24.00"),
                order_number="1234567abc",
            ),
        },
        "refund": {
            "amount": Decimal("100")
        },
    }
def test_update_berth_application_by_owner_invalid_status(
        berth_customer_api_client, customer_profile, status):
    berth_application = BerthApplicationFactory(status=status)
    berth_application_id = to_global_id(BerthApplicationNode,
                                        berth_application.id)
    other_customer = CustomerProfileFactory()

    customer_profile.user = berth_customer_api_client.user
    customer_profile.save()
    berth_application.customer = customer_profile
    berth_application.save()

    variables = {
        "id": berth_application_id,
        "customerId": to_global_id(ProfileNode, other_customer.id),
    }

    executed = berth_customer_api_client.execute(
        UPDATE_BERTH_APPLICATION_OWNER_MUTATION, input=variables)

    assert_in_errors(
        "Cannot modify the application once it has been processed", executed)
def test_update_berth_application_by_owner_cant_update_customer(
        berth_customer_api_client, berth_application, customer_profile):
    berth_application_id = to_global_id(BerthApplicationNode,
                                        berth_application.id)
    other_customer = CustomerProfileFactory()

    customer_profile.user = berth_customer_api_client.user
    customer_profile.save()
    berth_application.customer = customer_profile
    berth_application.save()

    variables = {
        "id": berth_application_id,
        "customerId": to_global_id(ProfileNode, other_customer.id),
    }

    executed = berth_customer_api_client.execute(
        UPDATE_BERTH_APPLICATION_OWNER_MUTATION, input=variables)

    assert_in_errors(
        "A customer cannot modify the customer connected to the application",
        executed)
def test_update_winter_storage_application_by_owner_cant_update_customer(
        berth_customer_api_client, winter_storage_application,
        customer_profile):
    winter_storage_application_id = to_global_id(WinterStorageApplicationNode,
                                                 winter_storage_application.id)
    other_customer = CustomerProfileFactory()

    customer_profile.user = berth_customer_api_client.user
    customer_profile.save()
    winter_storage_application.customer = customer_profile
    winter_storage_application.save()

    variables = {
        "id": winter_storage_application_id,
        "customerId": to_global_id(ProfileNode, other_customer.id),
    }

    executed = berth_customer_api_client.execute(
        UPDATE_WINTER_STORAGE_APPLICATION_OWNER_MUTATION, input=variables)

    assert_in_errors(
        "A customer cannot modify the customer connected to the application",
        executed)
def _get_winter_storage_order_context(subject: str = "Winter storage order"):
    customer = CustomerProfileFactory.build()
    order = OrderFactory.build(
        customer=customer,
        product=WinterStorageProductFactory.build(),
        lease=WinterStorageLeaseFactory.build(customer=customer),
        price=Decimal("100"),
        tax_percentage=Decimal("24.00"),
    )
    optional_services = [
        OrderLineFactory.build(
            order=order,
            product__service=ProductServiceType.OPTIONAL_SERVICES()[0],
            price=random_price(),
        ),
        OrderLineFactory.build(
            order=order,
            product__service=ProductServiceType.OPTIONAL_SERVICES()[1],
            price=random_price(),
        ),
    ]

    return _get_order_context(subject, order, optional_services)
def test_user_can_have_only_one_profile(customer_profile):
    with pytest.raises(IntegrityError):
        CustomerProfileFactory(user=customer_profile.user)
def winter_storage_application_with_customer(winter_storage_application):
    winter_storage_application.customer = CustomerProfileFactory()
    winter_storage_application.save()
    return winter_storage_application
def berth_application_with_customer(berth_application):
    berth_application.customer = CustomerProfileFactory()
    berth_application.save()
    return berth_application
def test_resend_order(
    api_client,
    order: Order,
    order_has_contact_info,
    request_has_profile_token,
    notification_template_orders_approved,
    berth_product,
    winter_storage_product,
    payment_provider,
    order_status,
):
    order.status = order_status
    order.order_type = OrderType.LEASE_ORDER.value
    initial_price = decimal.Decimal(
        "00.42")  # a price that is different from the price in BerthProduct
    order.price = initial_price
    order_original_email = "*****@*****.**"
    if order_has_contact_info:
        order.customer_phone = "+358505658789"
        order.customer_email = order_original_email
    else:
        order.customer_phone = ""  # trigger update from profile service
        order.customer_email = ""
    order.save()
    order.lease.status = LeaseStatus.OFFERED
    order.lease.save()
    orders = [order]

    if isinstance(order.lease, WinterStorageLease):
        winter_storage_product.winter_storage_area = (
            order.lease.get_winter_storage_area())

    berth_product.min_width = decimal.Decimal("0.0")
    berth_product.max_width = decimal.Decimal("999.0")
    berth_product.tier_1_price = decimal.Decimal("100.0")
    berth_product.tier_2_price = decimal.Decimal("200.0")
    berth_product.tier_3_price = decimal.Decimal("300.0")
    berth_product.pricing_category = get_berth_product_pricing_category(order)
    berth_product.save()

    variables = {
        "orders": [to_global_id(OrderNode, o.id) for o in orders],
        "dueDate": "2020-01-31",
    }
    if request_has_profile_token:
        variables["profileToken"] = "token"

    customer_profile = CustomerProfileFactory()

    profile_data = {
        "id": to_global_id(ProfileNode, customer_profile.id),
        "first_name": order.lease.application.first_name,
        "last_name": order.lease.application.last_name,
        "primary_email": {
            "email": order.lease.application.email
        },
        "primary_phone": {
            "phone": order.lease.application.phone_number
        },
    }

    with mock.patch(
            "requests.post",
            side_effect=mocked_response_profile(count=0,
                                                data=profile_data,
                                                use_edges=False),
    ), mock.patch.object(SMSNotificationService, "send",
                         return_value=None) as mock_send_sms:
        executed = api_client.execute(RESEND_ORDER_MUTATION, input=variables)

    if request_has_profile_token or order_has_contact_info:
        # there was sufficient customer info available for invoicing
        assert executed["data"]["resendOrder"]["failedOrders"] == []
        assert executed["data"]["resendOrder"]["sentOrders"] == [str(order.id)]

        order.refresh_from_db()
        assert order.price != initial_price
        order.lease.refresh_from_db()

        assert order.status == OrderStatus.OFFERED
        assert order.lease.status == LeaseStatus.OFFERED

        assert len(mail.outbox) == 1
        assert (mail.outbox[0].subject ==
                f"test order approved subject, event: {order.order_number}!")
        assert order.order_number in mail.outbox[0].body

        if request_has_profile_token:
            # always when profile_token is supplied, fetch customer info from profile
            assert mail.outbox[0].to == [order.lease.application.email]
        else:
            assert mail.outbox[0].to == [order_original_email]

        assert order.order_number in mail.outbox[0].alternatives[0][0]
        assert mail.outbox[0].alternatives[0][1] == "text/html"

        # Assert that the SMS is being sent
        payment_url = payment_provider.get_payment_email_url(
            order, lang=order.lease.application.language)
        sms_context = {
            "product_name":
            order.product.name,
            "due_date":
            format_date(order.due_date,
                        locale=order.lease.application.language),
            "payment_url":
            payment_url,
        }

        mock_send_sms.assert_called_with(
            NotificationType.SMS_INVOICE_NOTICE,
            sms_context,
            order.customer_phone,
            language=order.lease.application.language,
        )
    else:
        # no profile_token and no contact info
        assert len(executed["data"]["resendOrder"]["failedOrders"]) == 1
        assert ("Profile token is required"
                in executed["data"]["resendOrder"]["failedOrders"][0]["error"])
        assert executed["data"]["resendOrder"]["sentOrders"] == []
        # Assert that the SMS is not sent
        mock_send_sms.assert_not_called()
Esempio n. 21
0
 def customer(self):
     if hasattr(self, "lease") and self.lease is not None:
         return self.lease.customer
     return CustomerProfileFactory()
Esempio n. 22
0
def test_get_full_profile_information_from_gdpr_api(
    rest_api_client, requests_mock, settings
):
    customer_profile = CustomerProfileFactory()
    boat = BoatFactory(owner=customer_profile)
    berth_application = BerthApplicationFactory(customer=customer_profile)
    berth_lease = BerthLeaseFactory(
        customer=customer_profile, boat=boat, status=LeaseStatus.PAID
    )
    winter_storage_application = WinterStorageApplicationFactory(
        customer=customer_profile
    )
    winter_storage_lease = WinterStorageLeaseFactory(
        customer=customer_profile, boat=boat
    )
    order = OrderFactory(lease=berth_lease)
    berth_switch_offer = BerthSwitchOfferFactory(
        customer=customer_profile, lease=berth_lease
    )
    organization = OrganizationFactory(customer=customer_profile)

    auth_header = get_api_token_for_user_with_scopes(
        customer_profile.user, [settings.GDPR_API_QUERY_SCOPE], requests_mock
    )
    rest_api_client.credentials(HTTP_AUTHORIZATION=auth_header)
    response = rest_api_client.get(
        reverse("helsinki_gdpr:gdpr_v1", kwargs={"pk": customer_profile.id})
    )

    resp = json.loads(response.content)

    assert response.status_code == 200

    assert {
        "key": "INVOICING_TYPE",
        "value": dict(InvoicingType.choices)[customer_profile.invoicing_type],
    } in resp["children"]

    assert {"key": "COMMENT", "value": customer_profile.comment} in resp["children"]

    assert {
        "key": "CREATED_AT",
        "value": customer_profile.created_at.strftime("%d-%m-%Y %H:%M:%S"),
    } in resp["children"]

    assert {
        "key": "MODIFIED_AT",
        "value": customer_profile.modified_at.strftime("%d-%m-%Y %H:%M:%S"),
    } in resp["children"]

    berth_applications_dict = {}
    berth_leases_dict = {}
    boats_dict = {}
    offers_dict = {}
    orders_dict = {}
    organization_dict = {}
    winter_storage_applications_dict = {}
    winter_storage_leases_dict = {}
    for child_dict in resp["children"]:
        if child_dict["key"] == "BERTH_APPLICATIONS":
            berth_applications_dict = child_dict
        elif child_dict["key"] == "BERTH_LEASES":
            berth_leases_dict = child_dict
        elif child_dict["key"] == "BOATS":
            boats_dict = child_dict
        elif child_dict["key"] == "OFFERS":
            offers_dict = child_dict
        elif child_dict["key"] == "ORDERS":
            orders_dict = child_dict
        elif child_dict["key"] == "ORGANIZATION":
            organization_dict = child_dict
        elif child_dict["key"] == "WINTER_STORAGE_APPLICATIONS":
            winter_storage_applications_dict = child_dict
        elif child_dict["key"] == "WINTER_STORAGE_LEASES":
            winter_storage_leases_dict = child_dict

    # Using a TestCase here since assertDictEqual is better for comparing dicts
    test_case = TestCase()

    test_case.assertDictEqual(
        {
            "key": "BERTH_APPLICATIONS",
            "children": [
                {
                    "key": "BERTHAPPLICATION",
                    "children": [
                        {"key": "ID", "value": berth_application.id},
                        {
                            "key": "CREATED_AT",
                            "value": berth_application.created_at.strftime(
                                "%d-%m-%Y %H:%M:%S"
                            ),
                        },
                        {
                            "key": "STATUS",
                            "value": dict(ApplicationStatus.choices)[
                                berth_application.status
                            ],
                        },
                        {"key": "LANGUAGE", "value": berth_application.language},
                        {"key": "FIRST_NAME", "value": berth_application.first_name},
                        {"key": "LAST_NAME", "value": berth_application.last_name},
                        {"key": "EMAIL", "value": berth_application.email},
                        {
                            "key": "PHONE_NUMBER",
                            "value": berth_application.phone_number,
                        },
                        {"key": "ADDRESS", "value": berth_application.address},
                        {"key": "ZIP_CODE", "value": berth_application.zip_code},
                        {
                            "key": "MUNICIPALITY",
                            "value": berth_application.municipality,
                        },
                        {
                            "key": "COMPANY_NAME",
                            "value": berth_application.company_name,
                        },
                        {"key": "BUSINESS_ID", "value": berth_application.business_id},
                        {"key": "BOAT_TYPE", "value": berth_application.boat_type.name},
                        {
                            "key": "BOAT_REGISTRATION_NUMBER",
                            "value": berth_application.boat_registration_number,
                        },
                        {"key": "BOAT_NAME", "value": berth_application.boat_name},
                        {"key": "BOAT_MODEL", "value": berth_application.boat_model},
                        {
                            "key": "BOAT_LENGTH",
                            "value": float(berth_application.boat_length),
                        },
                        {
                            "key": "BOAT_WIDTH",
                            "value": float(berth_application.boat_width),
                        },
                        {
                            "key": "ACCEPT_BOATING_NEWSLETTER",
                            "value": berth_application.accept_boating_newsletter,
                        },
                        {
                            "key": "ACCEPT_FITNESS_NEWS",
                            "value": berth_application.accept_fitness_news,
                        },
                        {
                            "key": "ACCEPT_LIBRARY_NEWS",
                            "value": berth_application.accept_library_news,
                        },
                        {
                            "key": "ACCEPT_OTHER_CULTURE_NEWS",
                            "value": berth_application.accept_other_culture_news,
                        },
                        {
                            "key": "INFORMATION_ACCURACY_CONFIRMED",
                            "value": berth_application.information_accuracy_confirmed,
                        },
                        {
                            "key": "APPLICATION_CODE",
                            "value": berth_application.application_code,
                        },
                        {"key": "HARBORCHOICE_SET", "value": []},
                        {
                            "key": "BERTH_SWITCH",
                            "value": berth_application.berth_switch,
                        },
                        {
                            "key": "BOAT_DRAUGHT",
                            "value": berth_application.boat_draught,
                        },
                        {"key": "BOAT_WEIGHT", "value": berth_application.boat_weight},
                        {
                            "key": "ACCESSIBILITY_REQUIRED",
                            "value": berth_application.accessibility_required,
                        },
                        {
                            "key": "BOAT_PROPULSION",
                            "value": berth_application.boat_propulsion,
                        },
                        {
                            "key": "BOAT_HULL_MATERIAL",
                            "value": berth_application.boat_hull_material,
                        },
                        {
                            "key": "BOAT_INTENDED_USE",
                            "value": berth_application.boat_intended_use,
                        },
                        {
                            "key": "RENTING_PERIOD",
                            "value": berth_application.renting_period,
                        },
                        {"key": "RENT_FROM", "value": berth_application.rent_from},
                        {"key": "RENT_TILL", "value": berth_application.rent_till},
                        {
                            "key": "BOAT_IS_INSPECTED",
                            "value": berth_application.boat_is_inspected,
                        },
                        {
                            "key": "BOAT_IS_INSURED",
                            "value": berth_application.boat_is_insured,
                        },
                        {
                            "key": "AGREE_TO_TERMS",
                            "value": berth_application.agree_to_terms,
                        },
                    ],
                }
            ],
        },
        berth_applications_dict,
    )

    test_case.assertDictEqual(
        {
            "key": "BERTH_LEASES",
            "children": [
                {
                    "key": "BERTHLEASE",
                    "children": [
                        {"key": "ID", "value": str(berth_lease.id)},
                        {"key": "BOAT", "value": str(boat.id)},
                        {
                            "key": "STATUS",
                            "value": dict(LeaseStatus.choices)[berth_lease.status],
                        },
                        {"key": "ORDERS", "value": [str(order.id)]},
                        {"key": "COMMENT", "value": berth_lease.comment},
                        {
                            "key": "BERTH",
                            "value": {
                                "key": "BERTH",
                                "children": [
                                    {
                                        "key": "NUMBER",
                                        "value": berth_lease.berth.number,
                                    },
                                    {
                                        "key": "PIER",
                                        "value": {
                                            "key": "PIER",
                                            "children": [
                                                {
                                                    "key": "IDENTIFIER",
                                                    "value": berth_lease.berth.pier.identifier,
                                                }
                                            ],
                                        },
                                    },
                                ],
                            },
                        },
                        {"key": "APPLICATION", "value": None},
                        {
                            "key": "START_DATE",
                            "value": berth_lease.start_date.strftime("%d-%m-%Y"),
                        },
                        {
                            "key": "END_DATE",
                            "value": berth_lease.end_date.strftime("%d-%m-%Y"),
                        },
                    ],
                }
            ],
        },
        berth_leases_dict,
    )

    test_case.assertDictEqual(
        {
            "key": "BOATS",
            "children": [
                {
                    "key": "BOAT",
                    "children": [
                        {"key": "ID", "value": str(boat.id)},
                        {"key": "CERTIFICATES", "children": []},
                        {
                            "key": "REGISTRATION_NUMBER",
                            "value": boat.registration_number,
                        },
                        {"key": "LENGTH", "value": float(boat.length)},
                        {"key": "WIDTH", "value": float(boat.width)},
                        {"key": "DRAUGHT", "value": boat.draught},
                    ],
                }
            ],
        },
        boats_dict,
    )

    test_case.assertDictEqual(
        {
            "key": "OFFERS",
            "children": [
                {
                    "key": "BERTHSWITCHOFFER",
                    "children": [
                        {"key": "ID", "value": str(berth_switch_offer.id)},
                        {
                            "key": "STATUS",
                            "value": dict(OfferStatus.choices)[
                                berth_switch_offer.status
                            ],
                        },
                        {
                            "key": "DUE_DATE",
                            "value": berth_switch_offer.due_date.strftime("%d-%m-%Y")
                            if berth_switch_offer.due_date
                            else None,
                        },
                        {
                            "key": "CUSTOMER_FIRST_NAME",
                            "value": berth_switch_offer.customer_first_name,
                        },
                        {
                            "key": "CUSTOMER_LAST_NAME",
                            "value": berth_switch_offer.customer_last_name,
                        },
                        {
                            "key": "CUSTOMER_EMAIL",
                            "value": berth_switch_offer.customer_email,
                        },
                        {
                            "key": "CUSTOMER_PHONE",
                            "value": berth_switch_offer.customer_phone,
                        },
                        {
                            "key": "APPLICATION",
                            "value": berth_switch_offer.application.id,
                        },
                        {"key": "LEASE", "value": str(berth_switch_offer.lease.id)},
                        {"key": "BERTH", "value": str(berth_switch_offer.berth.id)},
                    ],
                }
            ],
        },
        offers_dict,
    )

    test_case.assertDictEqual(
        {
            "key": "ORDERS",
            "children": [
                {
                    "key": "ORDER",
                    "children": [
                        {"key": "ID", "value": str(order.id)},
                        {
                            "key": "PRODUCT",
                            "value": {
                                "key": "BERTHPRODUCT",
                                "children": [
                                    {
                                        "key": "MIN_WIDTH",
                                        "value": float(order.product.min_width),
                                    },
                                    {
                                        "key": "MAX_WIDTH",
                                        "value": float(order.product.max_width),
                                    },
                                    {
                                        "key": "TIER_1_PRICE",
                                        "value": float(order.product.tier_1_price),
                                    },
                                    {
                                        "key": "TIER_2_PRICE",
                                        "value": float(order.product.tier_2_price),
                                    },
                                    {
                                        "key": "TIER_3_PRICE",
                                        "value": float(order.product.tier_3_price),
                                    },
                                    {
                                        "key": "PRICE_UNIT",
                                        "value": order.product.price_unit,
                                    },
                                    {
                                        "key": "TAX_PERCENTAGE",
                                        "value": float(order.product.tax_percentage),
                                    },
                                ],
                            },
                        },
                        {"key": "LEASE", "value": str(order.lease.id)},
                        {
                            "key": "STATUS",
                            "value": dict(OrderStatus.choices)[order.status],
                        },
                        {"key": "COMMENT", "value": order.comment},
                        {"key": "PRICE", "value": float(order.price)},
                        {"key": "TAX_PERCENTAGE", "value": float(order.tax_percentage)},
                        {"key": "PRETAX_PRICE", "value": float(order.pretax_price)},
                        {"key": "TOTAL_PRICE", "value": float(order.total_price)},
                        {
                            "key": "TOTAL_PRETAX_PRICE",
                            "value": float(order.total_pretax_price),
                        },
                        {
                            "key": "TOTAL_TAX_PERCENTAGE",
                            "value": float(order.total_tax_percentage),
                        },
                        {
                            "key": "DUE_DATE",
                            "value": order.due_date.strftime("%d-%m-%Y"),
                        },
                        {"key": "ORDER_LINES", "children": []},
                        {"key": "LOG_ENTRIES", "children": []},
                        {"key": "PAID_AT", "value": None},
                        {"key": "CANCELLED_AT", "value": None},
                        {"key": "REJECTED_AT", "value": None},
                    ],
                }
            ],
        },
        orders_dict,
    )

    test_case.assertDictEqual(
        {
            "key": "ORGANIZATION",
            "children": [
                {"key": "ID", "value": str(organization.id)},
                {"key": "BUSINESS_ID", "value": organization.business_id},
                {"key": "NAME", "value": organization.name},
                {"key": "ADDRESS", "value": organization.address},
                {"key": "POSTAL_CODE", "value": organization.postal_code},
                {"key": "CITY", "value": organization.city},
            ],
        },
        organization_dict,
    )

    test_case.assertDictEqual(
        {
            "key": "WINTER_STORAGE_APPLICATIONS",
            "children": [
                {
                    "key": "WINTERSTORAGEAPPLICATION",
                    "children": [
                        {"key": "ID", "value": winter_storage_application.id},
                        {
                            "key": "CREATED_AT",
                            "value": winter_storage_application.created_at.strftime(
                                "%d-%m-%Y %H:%M:%S"
                            ),
                        },
                        {
                            "key": "STATUS",
                            "value": dict(ApplicationStatus.choices)[
                                winter_storage_application.status
                            ],
                        },
                        {
                            "key": "LANGUAGE",
                            "value": winter_storage_application.language,
                        },
                        {
                            "key": "FIRST_NAME",
                            "value": winter_storage_application.first_name,
                        },
                        {
                            "key": "LAST_NAME",
                            "value": winter_storage_application.last_name,
                        },
                        {"key": "EMAIL", "value": winter_storage_application.email},
                        {
                            "key": "PHONE_NUMBER",
                            "value": winter_storage_application.phone_number,
                        },
                        {"key": "ADDRESS", "value": winter_storage_application.address},
                        {
                            "key": "ZIP_CODE",
                            "value": winter_storage_application.zip_code,
                        },
                        {
                            "key": "MUNICIPALITY",
                            "value": winter_storage_application.municipality,
                        },
                        {"key": "COMPANY_NAME", "value": ""},
                        {"key": "BUSINESS_ID", "value": ""},
                        {
                            "key": "BOAT_TYPE",
                            "value": winter_storage_application.boat_type.name,
                        },
                        {"key": "BOAT_REGISTRATION_NUMBER", "value": ""},
                        {"key": "BOAT_NAME", "value": ""},
                        {"key": "BOAT_MODEL", "value": ""},
                        {
                            "key": "BOAT_LENGTH",
                            "value": float(winter_storage_application.boat_length),
                        },
                        {
                            "key": "BOAT_WIDTH",
                            "value": float(winter_storage_application.boat_width),
                        },
                        {"key": "ACCEPT_BOATING_NEWSLETTER", "value": False},
                        {"key": "ACCEPT_FITNESS_NEWS", "value": False},
                        {"key": "ACCEPT_LIBRARY_NEWS", "value": False},
                        {"key": "ACCEPT_OTHER_CULTURE_NEWS", "value": False},
                        {"key": "INFORMATION_ACCURACY_CONFIRMED", "value": False},
                        {"key": "APPLICATION_CODE", "value": ""},
                        {"key": "AREA_TYPE", "value": None},
                        {"key": "WINTERSTORAGEAREACHOICE_SET", "value": []},
                        {
                            "key": "STORAGE_METHOD",
                            "value": dict(WinterStorageMethod.choices)[
                                winter_storage_application.storage_method
                            ],
                        },
                        {"key": "TRAILER_REGISTRATION_NUMBER", "value": ""},
                    ],
                }
            ],
        },
        winter_storage_applications_dict,
    )

    test_case.assertDictEqual(
        {
            "key": "WINTER_STORAGE_LEASES",
            "children": [
                {
                    "key": "WINTERSTORAGELEASE",
                    "children": [
                        {"key": "ID", "value": str(winter_storage_lease.id)},
                        {"key": "BOAT", "value": str(boat.id)},
                        {
                            "key": "STATUS",
                            "value": dict(LeaseStatus.choices)[
                                winter_storage_lease.status
                            ],
                        },
                        {"key": "ORDERS", "value": []},
                        {"key": "COMMENT", "value": winter_storage_lease.comment},
                        {
                            "key": "PLACE",
                            "value": {
                                "key": "WINTERSTORAGEPLACE",
                                "children": [
                                    {
                                        "key": "NUMBER",
                                        "value": winter_storage_lease.place.number,
                                    },
                                    {
                                        "key": "WINTER_STORAGE_SECTION",
                                        "value": {
                                            "key": "WINTERSTORAGESECTION",
                                            "children": [
                                                {
                                                    "key": "IDENTIFIER",
                                                    "value": (
                                                        winter_storage_lease.place.winter_storage_section.identifier
                                                    ),
                                                }
                                            ],
                                        },
                                    },
                                ],
                            },
                        },
                        {"key": "SECTION", "value": None},
                        {"key": "APPLICATION", "value": None},
                        {
                            "key": "START_DATE",
                            "value": winter_storage_lease.start_date.strftime(
                                "%d-%m-%Y"
                            ),
                        },
                        {
                            "key": "END_DATE",
                            "value": winter_storage_lease.end_date.strftime("%d-%m-%Y"),
                        },
                        {"key": "STICKER_NUMBER", "value": None},
                        {"key": "STICKER_POSTED", "value": None},
                    ],
                }
            ],
        },
        winter_storage_leases_dict,
    )