def test_calculate_credit_cost_for_new_session(self): self.assertEqual( MessageCost.calculate_credit_cost( decimal.Decimal('1.0'), decimal.Decimal('10.0'), decimal.Decimal('2.0'), session_created=True), decimal.Decimal('33.0')) self.assertEqual( MessageCost.calculate_credit_cost( decimal.Decimal('5.0'), decimal.Decimal('20.0'), decimal.Decimal('2.0'), session_created=True), decimal.Decimal('84.0'))
def test_calculate_credit_cost(self): self.assertEqual( MessageCost.calculate_credit_cost( decimal.Decimal('1.0'), decimal.Decimal('10.0'), decimal.Decimal('2.0'), session_created=False), decimal.Decimal('11.0')) self.assertEqual( MessageCost.calculate_credit_cost( decimal.Decimal('5.0'), decimal.Decimal('20.0'), decimal.Decimal('2.0'), session_created=False), decimal.Decimal('60.0'))
def test_calculate_credit_cost_for_new_session(self): self.assertEqual( MessageCost.calculate_credit_cost(decimal.Decimal('1.0'), decimal.Decimal('10.0'), decimal.Decimal('2.0'), session_created=True), decimal.Decimal('33.0')) self.assertEqual( MessageCost.calculate_credit_cost(decimal.Decimal('5.0'), decimal.Decimal('20.0'), decimal.Decimal('2.0'), session_created=True), decimal.Decimal('84.0'))
def test_calculate_credit_cost(self): self.assertEqual( MessageCost.calculate_credit_cost(decimal.Decimal('1.0'), decimal.Decimal('10.0'), decimal.Decimal('2.0'), session_created=False), decimal.Decimal('11.0')) self.assertEqual( MessageCost.calculate_credit_cost(decimal.Decimal('5.0'), decimal.Decimal('20.0'), decimal.Decimal('2.0'), session_created=False), decimal.Decimal('60.0'))
def test_apply_markup_and_convert_to_credits_with_context(self): context = decimal.Context() self.assertEqual( MessageCost.apply_markup_and_convert_to_credits( decimal.Decimal('1.0'), QUANTIZATION_EXPONENT, context=context), decimal.Decimal('10.0')) self.assertEqual(context.flags[decimal.Inexact], 1) self.assertEqual(context.flags[decimal.Rounded], 1)
def mk_msg_cost(self, account=None, tag_pool=None, **kw): if account is None: account = Account.objects.get( user=self.user_helper.get_django_user()) if tag_pool is None: tag_pool = TagPool(name=u"pool", description=u"description") tag_pool.save() return MessageCost(account=account, tag_pool=tag_pool, **kw)
def test_calculate_session_credit_cost_with_context(self): context = decimal.Context() self.assertEqual( MessageCost.calculate_session_credit_cost(decimal.Decimal('1.0'), QUANTIZATION_EXPONENT, context=context), decimal.Decimal('10.0')) self.assertEqual(context.flags[decimal.Inexact], 1) self.assertEqual(context.flags[decimal.Rounded], 1)
def test_calculate_message_credit_cost_with_context(self): context = decimal.Context() self.assertEqual( MessageCost.calculate_message_credit_cost( decimal.Decimal('1.0'), QUANTIZATION_EXPONENT, context=context), decimal.Decimal('10.0')) self.assertEqual(context.flags[decimal.Inexact], 1) self.assertEqual(context.flags[decimal.Rounded], 1)
def get_cost(self, account_number, tag_pool_name, message_direction, session_created): """Return the message cost""" query = """ SELECT t.account_number, t.tag_pool_name, t.message_direction, t.message_cost, t.session_cost, t.markup_percent FROM (SELECT a.account_number, t.name AS tag_pool_name, c.message_direction, c.message_cost, c.session_cost, c.markup_percent FROM billing_messagecost c INNER JOIN billing_tagpool t ON (c.tag_pool_id = t.id) INNER JOIN billing_account a ON (c.account_id = a.id) WHERE a.account_number = %(account_number)s AND t.name = %(tag_pool_name)s AND c.message_direction = %(message_direction)s UNION SELECT NULL AS account_number, t.name AS tag_pool_name, c.message_direction, c.message_cost, c.session_cost, c.markup_percent FROM billing_messagecost c INNER JOIN billing_tagpool t ON (c.tag_pool_id = t.id) WHERE c.account_id IS NULL AND t.name = %(tag_pool_name)s AND c.message_direction = %(message_direction)s UNION SELECT NULL AS account_number, NULL AS tag_pool_name, c.message_direction, c.message_cost, c.session_cost, c.markup_percent FROM billing_messagecost c WHERE c.account_id IS NULL AND c.tag_pool_id IS NULL AND c.message_direction = %(message_direction)s ) as t ORDER BY t.account_number LIMIT 1 """ params = { "account_number": account_number, "tag_pool_name": tag_pool_name, "message_direction": message_direction, } result = yield self._connection_pool.runQuery(query, params) if len(result) > 0: message_cost = result[0] message_cost["credit_amount"] = MessageCost.calculate_credit_cost( message_cost["message_cost"], message_cost["markup_percent"], message_cost["session_cost"], session_created=session_created, ) defer.returnValue(message_cost) else: defer.returnValue(None)
def get_cost(self, account_number, tag_pool_name, message_direction, session_created): """Return the message cost""" query = """ SELECT t.account_number, t.tag_pool_name, t.message_direction, t.message_cost, t.session_cost, t.markup_percent FROM (SELECT a.account_number, t.name AS tag_pool_name, c.message_direction, c.message_cost, c.session_cost, c.markup_percent FROM billing_messagecost c INNER JOIN billing_tagpool t ON (c.tag_pool_id = t.id) INNER JOIN billing_account a ON (c.account_id = a.id) WHERE a.account_number = %(account_number)s AND t.name = %(tag_pool_name)s AND c.message_direction = %(message_direction)s UNION SELECT NULL AS account_number, t.name AS tag_pool_name, c.message_direction, c.message_cost, c.session_cost, c.markup_percent FROM billing_messagecost c INNER JOIN billing_tagpool t ON (c.tag_pool_id = t.id) WHERE c.account_id IS NULL AND t.name = %(tag_pool_name)s AND c.message_direction = %(message_direction)s UNION SELECT NULL AS account_number, NULL AS tag_pool_name, c.message_direction, c.message_cost, c.session_cost, c.markup_percent FROM billing_messagecost c WHERE c.account_id IS NULL AND c.tag_pool_id IS NULL AND c.message_direction = %(message_direction)s ) as t ORDER BY t.account_number LIMIT 1 """ params = { 'account_number': account_number, 'tag_pool_name': tag_pool_name, 'message_direction': message_direction } result = yield self._connection_pool.runQuery(query, params) if len(result) > 0: message_cost = result[0] message_cost['credit_amount'] = MessageCost.calculate_credit_cost( message_cost['message_cost'], message_cost['markup_percent'], message_cost['session_cost'], session_created=session_created) defer.returnValue(message_cost) else: defer.returnValue(None)
def clean(self): """ Check that: * the resulting message credit cost does not underflow to zero. * the resulting session credit cost does not underflow to zero. * that if the tag pool is not set, neither is the account ( this is because our message cost lookup currently ignore such message costs) """ cleaned_data = super(MessageCostForm, self).clean() message_cost = cleaned_data.get('message_cost') session_cost = cleaned_data.get('session_cost') markup_percent = cleaned_data.get('markup_percent') if message_cost and markup_percent: context = Context() credit_cost = MessageCost.calculate_message_credit_cost( message_cost, markup_percent, context=context) if cost_rounded_to_zero(credit_cost, context): raise forms.ValidationError( "The resulting cost per message (in credits) was rounded" " to 0.") if session_cost and markup_percent: context = Context() session_credit_cost = MessageCost.calculate_session_credit_cost( session_cost, markup_percent, context=context) if cost_rounded_to_zero(session_credit_cost, context): raise forms.ValidationError( "The resulting cost per session (in credits) was rounded" " to 0.") if not cleaned_data.get("tag_pool") and cleaned_data.get("account"): raise forms.ValidationError( "Message costs with an empty tag pool value and a non-empty" " account value are not currently supported by the billing" " API's message cost look up.") return cleaned_data
def test_transaction(self): yield self.create_api_user(email="*****@*****.**") account = yield self.create_api_account(email="*****@*****.**", account_number="11111") # Set the message cost yield self.create_api_cost( tag_pool_name="test_pool2", message_direction="Inbound", message_cost=0.6, session_cost=0.3, markup_percent=10.0) credit_amount = MessageCost.calculate_credit_cost( decimal.Decimal('0.6'), decimal.Decimal('10.0'), decimal.Decimal('0.3'), session_created=False) credit_amount_for_session = MessageCost.calculate_credit_cost( decimal.Decimal('0.6'), decimal.Decimal('10.0'), decimal.Decimal('0.3'), session_created=True) # Create a transaction yield self.create_api_transaction( account_number=account['account_number'], message_id='msg-id-1', tag_pool_name="test_pool2", tag_name="12345", message_direction="Inbound", session_created=False) # Make sure there was a transaction created [transaction] = yield self.get_api_transaction_list( account["account_number"]) del (transaction['id'], transaction['created'], transaction['last_modified']) self.assertEqual(transaction, { u'account_number': account['account_number'], u'message_id': 'msg-id-1', u'credit_amount': -credit_amount, u'credit_factor': decimal.Decimal('10.000000'), u'markup_percent': decimal.Decimal('10.000000'), u'message_cost': decimal.Decimal('0.6'), u'message_direction': u'Inbound', u'session_cost': decimal.Decimal('0.3'), u'session_created': False, u'status': u'Completed', u'tag_name': u'12345', u'tag_pool_name': u'test_pool2' }) # Get the account and make sure the credit balance was updated account = yield self.get_api_account(account["account_number"]) self.assertEqual(account['credit_balance'], -credit_amount) # Create a transaction (with session_created=True) yield self.create_api_transaction( account_number=account['account_number'], message_id='msg-id-2', tag_pool_name="test_pool2", tag_name="12345", message_direction="Inbound", session_created=True) # Make sure there was a transaction created (with session_created=True) [transaction, _] = yield self.get_api_transaction_list( account["account_number"]) del (transaction['id'], transaction['created'], transaction['last_modified']) self.assertEqual(transaction, { u'account_number': account['account_number'], u'message_id': 'msg-id-2', u'credit_amount': -credit_amount_for_session, u'credit_factor': decimal.Decimal('10.000000'), u'markup_percent': decimal.Decimal('10.000000'), u'message_cost': decimal.Decimal('0.6'), u'message_direction': u'Inbound', u'session_cost': decimal.Decimal('0.3'), u'session_created': True, u'status': u'Completed', u'tag_name': u'12345', u'tag_pool_name': u'test_pool2' }) # Get the account and make sure the credit balance was updated account = yield self.get_api_account(account["account_number"]) self.assertEqual(account['credit_balance'], -(credit_amount + credit_amount_for_session)) # Test override of cost by cost for specific account yield self.create_api_cost( account_number=account["account_number"], tag_pool_name="test_pool2", message_direction="Inbound", message_cost=9.0, session_cost=7.0, markup_percent=11.0) transaction = yield self.create_api_transaction( account_number=account['account_number'], message_id='msg-id-3', tag_pool_name="test_pool2", tag_name="12345", message_direction="Inbound", session_created=False) credit_amount = MessageCost.calculate_credit_cost( decimal.Decimal('9.0'), decimal.Decimal('11.0'), decimal.Decimal('7.0'), session_created=False) del (transaction['id'], transaction['created'], transaction['last_modified']) self.assertEqual(transaction, { u'account_number': account['account_number'], u'message_id': 'msg-id-3', u'credit_amount': -credit_amount, u'credit_factor': decimal.Decimal('10.0'), u'markup_percent': decimal.Decimal('11.0'), u'message_cost': decimal.Decimal('9.0'), u'message_direction': u'Inbound', u'session_cost': decimal.Decimal('7.0'), u'session_created': False, u'status': u'Completed', u'tag_name': u'12345', u'tag_pool_name': u'test_pool2', }) # Test fallback to default cost yield self.create_api_cost( message_direction="Outbound", message_cost=0.1, session_cost=0.2, markup_percent=12.0) yield self.create_api_user(email="*****@*****.**") account = yield self.create_api_account( email="*****@*****.**", account_number="arbitrary-user") transaction = yield self.create_api_transaction( account_number="arbitrary-user", message_id='msg-id-4', tag_pool_name="some-random-pool", tag_name="erk", message_direction="Outbound", session_created=False) credit_amount = MessageCost.calculate_credit_cost( decimal.Decimal('0.1'), decimal.Decimal('12.0'), decimal.Decimal('0.2'), session_created=False) del (transaction['id'], transaction['created'], transaction['last_modified']) self.assertEqual(transaction, { u'account_number': 'arbitrary-user', u'message_id': 'msg-id-4', u'credit_amount': -credit_amount, u'credit_factor': decimal.Decimal('10.0'), u'markup_percent': decimal.Decimal('12.0'), u'message_cost': decimal.Decimal('0.1'), u'message_direction': u'Outbound', u'session_cost': decimal.Decimal('0.2'), u'session_created': False, u'status': u'Completed', u'tag_name': u'erk', u'tag_pool_name': u'some-random-pool', }) # Test that message direction is correctly checked for # in the fallback case. try: yield self.create_api_transaction( account_number="arbitrary-user", message_id='msg-id-4', tag_pool_name="some-random-pool", tag_name="erk", message_direction="Inbound", session_created=False) except ApiCallError, e: self.assertEqual(e.response.responseCode, 500) self.assertEqual( e.message, "Unable to determine Inbound message cost for account" " arbitrary-user and tag pool some-random-pool")
def test_calculate_session_credit_cost(self): self.assertEqual( MessageCost.calculate_session_credit_cost( decimal.Decimal('1.0'), decimal.Decimal('50.0')), decimal.Decimal('15.0'))
def test_apply_markup_and_convert_to_credits(self): self.assertEqual( MessageCost.apply_markup_and_convert_to_credits( decimal.Decimal('1.0'), decimal.Decimal('50.0')), decimal.Decimal('15.0'))
def test_calculate_session_credit_cost(self): self.assertEqual( MessageCost.calculate_session_credit_cost(decimal.Decimal('1.0'), decimal.Decimal('50.0')), decimal.Decimal('15.0'))