def _make_income_transaction(self, curs, data, session, transaction_type): balance = self._get_active_balance(session, curs, data) currs_id_idx = self._get_currs_idx(curs, 'id') currency = currs_id_idx[balance.currency_id] amount_dec = Decimal(data['amount']) amount = decimal_to_cents(currency, amount_dec) enrolled_amount_dec = cents_to_decimal(currency, amount) if amount < 0: amount *= -1 trans_data = {'environment_id': session.environment_id, 'user_id': balance.user_id, 'balance_id': balance.id, 'currency_code': currency.code, 'real_amount': 0, 'virtual_amount': 0, 'type': transaction_type, 'info': data.get('info', {})} if transaction_type == 'receipt': balance.real_amount += amount trans_data['real_amount'] = enrolled_amount_dec elif transaction_type == 'bonus': balance.virtual_amount += amount trans_data['virtual_amount'] = enrolled_amount_dec else: raise HelixbillingError('Unhandled income transaction type: %s' % transaction_type) mapping.update(curs, balance) trans = Transaction(**trans_data) mapping.insert(curs, trans) return trans.id
def lock(self, data, session, curs=None): balance = self._get_active_balance(session, curs, data) currs_id_idx = self._get_currs_idx(curs, 'id') currency = currs_id_idx[balance.currency_id] lock_amount_dec = Decimal(data['amount']) lock_amount = decimal_to_cents(currency, lock_amount_dec) if lock_amount < 0: lock_amount *= -1 locking_order = data['locking_order'] amounts_to_lock = compute_locks(balance, lock_amount, locking_order) lock_real = amounts_to_lock.get('real_amount', 0) lock_virtual = amounts_to_lock.get('virtual_amount', 0) order_id = data['order_id'] info = data.get('info', {}) info['locking_order'] = locking_order trans_data = { 'environment_id': session.environment_id, 'user_id': balance.user_id, 'balance_id': balance.id, 'currency_code': currency.code, 'type': 'lock', 'real_amount': cents_to_decimal(currency, lock_real), 'virtual_amount': cents_to_decimal(currency, lock_virtual), 'order_id': order_id, 'info': info } lock_data = { 'environment_id': session.environment_id, 'user_id': balance.user_id, 'balance_id': balance.id, 'real_amount': lock_real, 'locking_order': locking_order, 'order_id': order_id, 'currency_id': currency.id, 'virtual_amount': lock_virtual, 'info': info } lock = BalanceLock(**lock_data) balance.real_amount -= lock_real balance.virtual_amount -= lock_virtual balance.locked_amount += lock_real + lock_virtual mapping.update(curs, balance) trans = Transaction(**trans_data) mapping.insert(curs, lock) mapping.insert(curs, trans) return response_ok(transaction_id=trans.id, lock_id=lock.id)
def test_negative_decimal_to_cents(self): db_currs_idx = self._get_currencies_idx() currencies = {'TND': 1000, 'USD': 100, 'CNY': 10, 'MRO': 5, 'JPY': 1} amounts = map(Decimal, ['-0.06', '-0.86', '-13.0', '-53.01', '-1113.36', '-03.001', '-13.359']) expects = { 'TND': [-60, -860, -13000, -53010, -1113360, -3001, -13359], 'USD': [-6, -86, -1300, -5301, -111336, -300, -1335], 'CNY': [0, -8, -130, -530, -11133, -30, -133], 'MRO': [0, -8, -65, -265, -5568, -15, -68], 'JPY': [0, 0, -13, -53, -1113, -03, -13], } for code, cent_factor in currencies.items(): db_currency = db_currs_idx[code] self.assertEqual(cent_factor, db_currency.cent_factor) actual = [decimal_to_cents(db_currency, amount) for amount in amounts] exp_code = db_currency.code self.assertEqual(expects[exp_code], actual)
def test_decimal_to_cents(self): db_currs_idx = self._get_currencies_idx() currencies = {'TND': 1000, 'USD': 100, 'CNY': 10, 'MRO': 5, 'JPY': 1} amounts = map(Decimal, ['0.06', '0.86', '13.0', '53.01', '1113.36', '03.001', '13.359']) expects = { 'TND': [60, 860, 13000, 53010, 1113360, 3001, 13359], 'USD': [6, 86, 1300, 5301, 111336, 300, 1335], 'CNY': [0, 8, 130, 530, 11133, 30, 133], 'MRO': [0, 8, 65, 265, 5568, 15, 68], 'JPY': [0, 0, 13, 53, 1113, 03, 13], } for code, cent_factor in currencies.items(): db_currency = db_currs_idx[code] self.assertEqual(cent_factor, db_currency.cent_factor) actual = [decimal_to_cents(db_currency, amount) for amount in amounts] exp_code = db_currency.code self.assertEqual(expects[exp_code], actual)
def lock(self, data, session, curs=None): balance = self._get_active_balance(session, curs, data) currs_id_idx = self._get_currs_idx(curs, 'id') currency = currs_id_idx[balance.currency_id] lock_amount_dec = Decimal(data['amount']) lock_amount = decimal_to_cents(currency, lock_amount_dec) if lock_amount < 0: lock_amount *= -1 locking_order = data['locking_order'] amounts_to_lock = compute_locks(balance, lock_amount, locking_order) lock_real = amounts_to_lock.get('real_amount', 0) lock_virtual = amounts_to_lock.get('virtual_amount', 0) order_id = data['order_id'] info = data.get('info', {}) info['locking_order'] = locking_order trans_data = {'environment_id': session.environment_id, 'user_id': balance.user_id, 'balance_id': balance.id, 'currency_code': currency.code, 'type': 'lock', 'real_amount': cents_to_decimal(currency, lock_real), 'virtual_amount': cents_to_decimal(currency, lock_virtual), 'order_id': order_id, 'info': info} lock_data = {'environment_id': session.environment_id, 'user_id': balance.user_id, 'balance_id': balance.id, 'real_amount': lock_real, 'locking_order': locking_order, 'order_id': order_id, 'currency_id': currency.id, 'virtual_amount': lock_virtual, 'info': info} lock = BalanceLock(**lock_data) balance.real_amount -= lock_real balance.virtual_amount -= lock_virtual balance.locked_amount += lock_real + lock_virtual mapping.update(curs, balance) trans = Transaction(**trans_data) mapping.insert(curs, lock) mapping.insert(curs, trans) return response_ok(transaction_id=trans.id, lock_id=lock.id)
def _make_income_transaction(self, curs, data, session, transaction_type): balance = self._get_active_balance(session, curs, data) currs_id_idx = self._get_currs_idx(curs, 'id') currency = currs_id_idx[balance.currency_id] amount_dec = Decimal(data['amount']) amount = decimal_to_cents(currency, amount_dec) enrolled_amount_dec = cents_to_decimal(currency, amount) if amount < 0: amount *= -1 trans_data = { 'environment_id': session.environment_id, 'user_id': balance.user_id, 'balance_id': balance.id, 'currency_code': currency.code, 'real_amount': 0, 'virtual_amount': 0, 'type': transaction_type, 'info': data.get('info', {}) } if transaction_type == 'receipt': balance.real_amount += amount trans_data['real_amount'] = enrolled_amount_dec elif transaction_type == 'bonus': balance.virtual_amount += amount trans_data['virtual_amount'] = enrolled_amount_dec else: raise HelixbillingError('Unhandled income transaction type: %s' % transaction_type) mapping.update(curs, balance) trans = Transaction(**trans_data) mapping.insert(curs, trans) return trans.id