Skip to content

Commit

Permalink
transactions: fix paid fees still opened
Browse files Browse the repository at this point in the history
The bit representation of real number
(https://en.wikipedia.org/wiki/IEEE_754) cause problem with arithmetic
operation on them (10-9.54 = 0.460000000000085). This commit fixes this
problem by multiplying transaction amount by 100 and cast them into
integer when arithmetic operations are done.

Closes rero#1373

Co-Authored-by: Renaud Michotte <renaud.michotte@gmail.com>
  • Loading branch information
zannkukai committed Nov 9, 2020
1 parent bc39704 commit cf9f39e
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
19 changes: 14 additions & 5 deletions rero_ils/modules/patron_transaction_events/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,25 @@ def create_event_from_patron_transaction(

def update_parent_patron_transaction(self):
"""Update parent patron transaction amount and status."""
# NOTE :
# due to bit representation of float number
# (https://en.wikipedia.org/wiki/IEEE_754), the arithmetic operation
# with float can cause some strange behavior
# >>> 10 - 9.54
# 0.46000000000000085
# To solve this problem in our case, as we keep only 2 decimal
# digits, we can multiply amounts by 100, cast result as integer,
# do operation with these values, and (at the end) divide the result
# by 100.
patron_transaction = self.patron_transaction()
total_amount = patron_transaction.get('total_amount')
total_amount = int(patron_transaction.get('total_amount') * 100)
if self.event_type == 'fee':
total_amount = total_amount + self.amount
total_amount = total_amount + int(self.amount * 100)
elif self.event_type in ('payment', 'cancel'):
total_amount = total_amount - self.amount
patron_transaction['total_amount'] = total_amount
total_amount = total_amount - int(self.amount * 100)
patron_transaction['total_amount'] = total_amount / 100
if total_amount == 0:
patron_transaction['status'] = 'closed'

patron_transaction.update(
patron_transaction, dbcommit=True, reindex=True)

Expand Down
6 changes: 3 additions & 3 deletions tests/api/test_patron_payments_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def test_patron_payment(
del payment['pid']
payment['type'] = 'payment'
payment['subtype'] = 'cash'
payment['amount'] = 1.00
payment['amount'] = 0.54
payment['operator'] = {'$ref': get_ref_for_pid(
'patrons', librarian_martigny_no_email.pid)}
res, _ = postdata(
Expand All @@ -56,13 +56,13 @@ def test_patron_payment(
)
assert res.status_code == 201
transaction = PatronTransaction.get_record_by_pid(transaction.pid)
assert transaction.total_amount == calculated_amount - 1.00
assert transaction.total_amount == 1.46
assert transaction.status == 'open'

# full payment
payment['type'] = 'payment'
payment['subtype'] = 'cash'
payment['amount'] = transaction.total_amount
payment['amount'] = 1.46
res, _ = postdata(
client,
post_entrypoint,
Expand Down

0 comments on commit cf9f39e

Please sign in to comment.