PTHMINT-91: Implement Decimal precision for monetary calculations#41
PTHMINT-91: Implement Decimal precision for monetary calculations#41danielcivit merged 3 commits intomasterfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #41 +/- ##
==========================================
- Coverage 90.69% 90.62% -0.07%
==========================================
Files 143 144 +1
Lines 2471 2539 +68
==========================================
+ Hits 2241 2301 +60
- Misses 230 238 +8 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
- **Refactor**: Introduced `DecimalAmount` Value Object to handle decimal precision for monetary values, replacing inline Pydantic validators in `CartItem` and `Costs`. - **Fix**: Resolved an `AttributeError` in `create_refund_request` by accessing `.quantity` directly instead of `.get_quantity()`. - **DX**: Added support for `API_KEY` and `TEST_API_KEY` environment variables. - **DX**: Improved code quality by adding missing docstrings and return types across various files. - **Tests**: Updated unit and integration tests to reflect the architectural changes.
There was a problem hiding this comment.
Pull request overview
This pull request implements comprehensive Decimal precision for all monetary calculations throughout the codebase, replacing floating-point types to prevent rounding errors in financial operations. The changes introduce a new DecimalAmount value object, update cart items and costs to use Decimal types, and add a custom JSON encoder to serialize Decimal values for API compatibility.
Changes:
- Replaced
UnitPricevalue object withDecimalAmountfor monetary precision - Updated
CartItemandCostsmodels to use Decimal for all monetary values - Added
DecimalEncoderfor JSON serialization of Decimal values in API requests - Enhanced total amount calculation utilities with configurable rounding strategies
- Comprehensive test coverage for new Decimal-based calculations and rounding behaviors
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/multisafepay/unit/value_object/test_unit_price.py | Removed old float-based unit price tests |
| tests/multisafepay/unit/value_object/test_decimal_amount.py | Added new tests for Decimal-based amount handling |
| tests/multisafepay/unit/util/test_unit_total_amount.py | Updated assertions to expect Decimal values and added rounding strategy tests |
| tests/multisafepay/unit/api/shared/test_unit_costs.py | Updated cost assertions to verify Decimal precision |
| tests/multisafepay/unit/api/shared/cart/test_unit_cart_item.py | Updated cart item unit price assertions for Decimal |
| tests/multisafepay/unit/api/path/orders/request/test_unit_order_request.py | Added tests for amount validation with rounding strategies |
| tests/multisafepay/integration/api/shared/cart/test_integration_cart_item.py | Updated integration tests for Decimal unit prices |
| tests/multisafepay/integration/amounts/*.py | Added comprehensive rounding and tax calculation integration tests |
| tests/multisafepay/e2e/conftest.py | Added pytest configuration to skip E2E tests without API_KEY |
| src/multisafepay/value_object/unit_price.py | Removed float-based UnitPrice class |
| src/multisafepay/value_object/decimal_amount.py | Added new DecimalAmount value object with validator |
| src/multisafepay/value_object/init.py | Updated exports to use DecimalAmount instead of UnitPrice |
| src/multisafepay/util/total_amount.py | Enhanced with Decimal arithmetic and rounding strategy support |
| src/multisafepay/util/json_encoder.py | Added DecimalEncoder for API serialization |
| src/multisafepay/util/init.py | Exported DecimalEncoder utility |
| src/multisafepay/api/shared/costs.py | Updated to use Decimal for amount field |
| src/multisafepay/api/shared/cart/cart_item.py | Updated to use Decimal for unit_price and tax calculations |
| src/multisafepay/api/paths/orders/request/order_request.py | Added rounding parameters to validate_amount |
| src/multisafepay/api/paths/orders/order_manager.py | Updated to use DecimalEncoder for JSON serialization |
| src/multisafepay/api/paths/orders/order_id/refund/request/components/checkout_data.py | Fixed to multiply Decimal by int instead of float |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 26 out of 26 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Description
Copilot Description
This pull request introduces a comprehensive migration of monetary values in the codebase from floating-point types to the more precise
Decimaltype, improving accuracy in all financial calculations and API interactions. It also ensures correct JSON serialization ofDecimalvalues by introducing a customDecimalEncoder. The changes affect cart items, costs, order management, and utility functions, providing stricter type handling and validation for monetary fields.Precision improvements for monetary values:
Changed
unit_priceinCartItemandamountinCostsfromfloattoDecimal, and introduced Pydantic validators to ensure all assignments and inputs are converted toDecimalfor accuracy. Methods that add or manipulate these values have been updated to accept multiple types and convert them as needed. (src/multisafepay/api/shared/cart/cart_item.py,src/multisafepay/api/shared/costs.py) [1] [2] [3] [4] [5] [6]Updated tax rate and percentage handling in
CartItemto useDecimalfor all arithmetic, with improved validation and conversion logic. (src/multisafepay/api/shared/cart/cart_item.py) [1] [2] [3] [4] [5]JSON serialization and API compatibility:
DecimalEncoderclass for JSON serialization, convertingDecimalvalues to float when sending data to APIs. Updated all relevant API request methods inOrderManagerto use this encoder. (src/multisafepay/util/json_encoder.py,src/multisafepay/api/paths/orders/order_manager.py,src/multisafepay/util/__init__.py) [1] [2] [3] [4] [5] [6] [7]Utility and support improvements:
Decimalvalues to float for JSON serialization in utility modules. (src/multisafepay/util/total_amount.py)Minor corrections and consistency:
src/multisafepay/api/paths/orders/order_id/refund/request/components/checkout_data.py)These changes ensure financial calculations throughout the SDK are reliable and consistent, eliminating floating-point errors and improving compatibility with APIs expecting float values in JSON.- Replace float with Decimal in cart_item, costs, unit_price, total_amount