From 74e2168529890f54fcb3ecaa38657640b8a6f059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Floure?= Date: Fri, 8 May 2020 11:13:11 +0200 Subject: [PATCH] Fix floating-point issue on bills (Fix #31) --- uncloud_pay/__init__.py | 3 +++ uncloud_pay/models.py | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/uncloud_pay/__init__.py b/uncloud_pay/__init__.py index 0dd3b3f..4bda45f 100644 --- a/uncloud_pay/__init__.py +++ b/uncloud_pay/__init__.py @@ -1,9 +1,12 @@ from django.utils.translation import gettext_lazy as _ +import decimal # Define DecimalField properties, used to represent amounts of money. AMOUNT_MAX_DIGITS=10 AMOUNT_DECIMALS=2 +decimal.getcontext().prec = AMOUNT_DECIMALS + # http://xml.coverpages.org/country3166.html COUNTRIES = ( ('AD', _('Andorra')), diff --git a/uncloud_pay/models.py b/uncloud_pay/models.py index bd73451..0898c60 100644 --- a/uncloud_pay/models.py +++ b/uncloud_pay/models.py @@ -494,6 +494,10 @@ class BillRecord(): else: self.one_time_price = 0 + # Set decimal context for amount computations. + # XXX: understand why we need +1 here. + decimal.getcontext().prec = AMOUNT_DECIMALS + 1 + @property def recurring_count(self): # Compute billing delta. @@ -531,7 +535,7 @@ class BillRecord(): (_, days_in_month) = monthrange( self.bill.starting_date.year, self.bill.starting_date.month) - return days / days_in_month + return round(days / days_in_month, AMOUNT_DECIMALS) elif self.recurring_period == RecurringPeriod.PER_WEEK: weeks = ceil(billed_delta / timedelta(week=1)) return weeks