diff --git a/app/adapters/delivery_providers/cdek/order_mapper.py b/app/adapters/delivery_providers/cdek/order_mapper.py index 4f54191..322a18d 100644 --- a/app/adapters/delivery_providers/cdek/order_mapper.py +++ b/app/adapters/delivery_providers/cdek/order_mapper.py @@ -306,6 +306,16 @@ def _map_package(request: InitPaymentRequest, order_uuid: str) -> dict[str, Any] "number": order_uuid, "weight": weight_grams, "comment": description, + "items": [ + { + "name": description, + "ware_key": order_uuid, + "payment": {"value": 0}, + "cost": request.content.declared_value, + "amount": 1, + "weight": weight_grams, + } + ], } if system_data.parcel_type == "parcel" and system_data.dimensions is not None: package.update(_map_dimensions(system_data.dimensions)) diff --git a/app/adapters/delivery_providers/cse/order_mapper.py b/app/adapters/delivery_providers/cse/order_mapper.py index ffff0c3..bf62b73 100644 --- a/app/adapters/delivery_providers/cse/order_mapper.py +++ b/app/adapters/delivery_providers/cse/order_mapper.py @@ -127,6 +127,7 @@ def map_cse_save_order_request( make_field("TypeOfCargo", resolve_type_of_cargo(system_data.parcel_type)), make_field("Weight", system_data.weight, "float"), make_field("CargoPackageQty", "1", "float"), + make_field("CargoCost", str(request.content.declared_value), "float"), ] if delivery_type: fields.append(make_field("DeliveryOfCargo", delivery_type)) diff --git a/app/schemas/payment.py b/app/schemas/payment.py index c41d366..6694266 100644 --- a/app/schemas/payment.py +++ b/app/schemas/payment.py @@ -75,6 +75,7 @@ class Contact(_CamelModel): class Content(_CamelModel): description: str | None = None + declared_value: int = Field(alias="declared_value", strict=True) class SystemDataTariff(_CamelModel): diff --git a/tests/adapters/delivery_providers/cdek/test_order_mapper.py b/tests/adapters/delivery_providers/cdek/test_order_mapper.py index 1bdc254..e3d57e9 100644 --- a/tests/adapters/delivery_providers/cdek/test_order_mapper.py +++ b/tests/adapters/delivery_providers/cdek/test_order_mapper.py @@ -143,7 +143,7 @@ def test_order_payload_for_parcel_includes_dimensions() -> None: def test_order_payload_for_doc_omits_dimensions() -> None: request = make_init_payment_request( - content={"description": "Docs"}, + content={"description": "Docs", "declared_value": 25000}, systemData={ "tariff": { "provider": "СДЭК", @@ -198,20 +198,33 @@ def test_order_payload_includes_company_requisites_for_legal_entity() -> None: assert sender["kpp"] == "770701001" -def test_order_payload_propagates_description_to_comments_without_items() -> None: +def test_order_payload_maps_content_to_comments_and_declared_value_item() -> None: payload = map_cdek_order_request(make_init_payment_request(), "order-uuid-1") assert payload["comment"] == "Headphones" assert payload["packages"][0]["comment"] == "Headphones" - assert "items" not in payload["packages"][0] + assert payload["packages"][0]["items"] == [ + { + "name": "Headphones", + "ware_key": "order-uuid-1", + "payment": {"value": 0}, + "cost": 50000, + "amount": 1, + "weight": 1000, + } + ] def test_order_payload_falls_back_package_comment_to_order_uuid() -> None: payload = map_cdek_order_request( - make_init_payment_request(content={"description": None}), "order-uuid-1" + make_init_payment_request( + content={"description": None, "declared_value": 50000} + ), + "order-uuid-1", ) assert payload["packages"][0]["comment"] == "order-uuid-1" + assert payload["packages"][0]["items"][0]["name"] == "order-uuid-1" def test_order_payload_includes_company_for_individual_sender_as_full_name() -> None: diff --git a/tests/adapters/delivery_providers/cdek/test_payment_price_validation.py b/tests/adapters/delivery_providers/cdek/test_payment_price_validation.py index c982f96..039aa1e 100644 --- a/tests/adapters/delivery_providers/cdek/test_payment_price_validation.py +++ b/tests/adapters/delivery_providers/cdek/test_payment_price_validation.py @@ -124,7 +124,7 @@ def test_provider_get_payment_price_omits_dimensions_for_doc() -> None: ) ) request = make_init_payment_request( - content={"description": "Docs"}, + content={"description": "Docs", "declared_value": 25000}, systemData={ "tariff": { "provider": "СДЭК", diff --git a/tests/adapters/delivery_providers/cse/test_cse_adapter.py b/tests/adapters/delivery_providers/cse/test_cse_adapter.py index 6bfd077..c2b07e0 100644 --- a/tests/adapters/delivery_providers/cse/test_cse_adapter.py +++ b/tests/adapters/delivery_providers/cse/test_cse_adapter.py @@ -276,6 +276,7 @@ def test_save_order_request_uses_selected_tariff_urgency() -> None: assert order.field_value("DeliveryOfCargo") == "ДоставкаДоДверей" assert order.field_value("Payer") == "payer-1" assert order.field_value("ShippingMethod") == "sm-1" + assert order.field_value("CargoCost") == "50000" def test_application_error_in_response_raises_request_error() -> None: diff --git a/tests/controllers/v1/test_init_payment.py b/tests/controllers/v1/test_init_payment.py index 0d9d2c2..dfe209a 100644 --- a/tests/controllers/v1/test_init_payment.py +++ b/tests/controllers/v1/test_init_payment.py @@ -164,6 +164,47 @@ def test_post_init_payment_rejects_non_integer_price() -> None: assert service.calls == [] +def test_post_init_payment_rejects_missing_declared_value() -> None: + service = StubAggregatorService(response=None) + app = create_app() + _install_service_override(app, service) + invalid_payload = make_init_payment_payload() + del invalid_payload["content"]["declared_value"] + + response = _post(app, invalid_payload) + + assert response.status_code == 422 + assert service.calls == [] + + +def test_post_init_payment_rejects_non_integer_declared_value() -> None: + service = StubAggregatorService(response=None) + app = create_app() + _install_service_override(app, service) + invalid_payload = make_init_payment_payload() + invalid_payload["content"]["declared_value"] = "50000" + + response = _post(app, invalid_payload) + + assert response.status_code == 422 + assert service.calls == [] + + +def test_post_init_payment_rejects_camel_case_declared_value() -> None: + service = StubAggregatorService(response=None) + app = create_app() + _install_service_override(app, service) + invalid_payload = make_init_payment_payload() + invalid_payload["content"]["declaredValue"] = invalid_payload["content"].pop( + "declared_value" + ) + + response = _post(app, invalid_payload) + + assert response.status_code == 422 + assert service.calls == [] + + def test_post_init_payment_requires_company_fields_when_is_company_true() -> None: service = StubAggregatorService(response=None) app = create_app() diff --git a/tests/payment_fixtures.py b/tests/payment_fixtures.py index ca7b438..f43d36f 100644 --- a/tests/payment_fixtures.py +++ b/tests/payment_fixtures.py @@ -49,6 +49,7 @@ def make_init_payment_payload(**overrides: Any) -> dict[str, Any]: }, "content": { "description": "Headphones", + "declared_value": 50000, }, "pickupDate": "2026-05-15T10:00:00.000Z", "deliveryDate": "2026-05-18T18:00:00.000Z",