def _get_provider_charges(cls, backend_message_id, backend_instance, direction, couch_id, backend_api_id): if backend_message_id: if backend_api_id == SQLTwilioBackend.get_api_id(): message = get_twilio_message(backend_instance, backend_message_id) status = message.status price = message.price elif backend_api_id == InfobipBackend.get_api_id(): message = get_infobip_message(backend_instance, backend_message_id) status = message['status']['name'] price = message['price']['pricePerMessage'] else: raise ProviderFeeNotSupportedException("backend_message_id=%s" % backend_message_id) if status is None or status.lower() in [ 'accepted', 'queued', 'sending', 'receiving', ] or price is None: raise RetryBillableTaskException("backend_message_id=%s" % backend_message_id) return _ProviderChargeInfo( abs(Decimal(price)), SmsGatewayFee.get_by_criteria( backend_api_id, direction, ) ) else: log_smsbillables_error( "Could not create gateway fee for message %s: no backend_message_id" % couch_id ) return _ProviderChargeInfo(None, None)
def get_rate_response(self): gateway = self.data.get('gateway') try: backend_api_id = SQLMobileBackend.get_backend_api_id(gateway, is_couch_id=True) except Exception as e: log_smsbillables_error( "Failed to get backend for calculating an sms rate due to: %s" % e ) raise SMSRateCalculatorError("Could not obtain connection information.") country_code = self.data.get('country_code') if country_code == NONMATCHING_COUNTRY: country_code = None direction = self.data.get('direction') gateway_fee = SmsGatewayFee.get_by_criteria( backend_api_id, direction, backend_instance=gateway, country_code=country_code, ) usage_fee = SmsUsageFee.get_by_criteria(direction, self.request.domain) usd_gateway_fee = gateway_fee.amount / gateway_fee.currency.rate_to_default usd_total = usage_fee.amount + usd_gateway_fee return { 'rate': _("%s per 160 character SMS") % fmt_dollar_amount(usd_total), }
def _get_usage_fee(cls, domain, direction): usage_fee = SmsUsageFee.get_by_criteria(direction, domain=domain) if not usage_fee: log_smsbillables_error( "Did not find usage fee for direction %s and domain %s" % (direction, domain)) return usage_fee
def get_rate_response(self): gateway = self.data.get('gateway') try: backend_api_id = SQLMobileBackend.get_backend_api_id( gateway, is_couch_id=True) except Exception as e: log_smsbillables_error( "Failed to get backend for calculating an sms rate due to: %s" % e) raise SMSRateCalculatorError( "Could not obtain connection information.") country_code = self.data.get('country_code') if country_code == NONMATCHING_COUNTRY: country_code = None direction = self.data.get('direction') gateway_fee = SmsGatewayFee.get_by_criteria( backend_api_id, direction, backend_instance=gateway, country_code=country_code, ) usage_fee = SmsUsageFee.get_by_criteria(direction, self.request.domain) usd_gateway_fee = gateway_fee.amount / gateway_fee.currency.rate_to_default usd_total = usage_fee.amount + usd_gateway_fee return { 'rate': _("%s per 160 character SMS") % fmt_dollar_amount(usd_total), }
def get_conversion_rate(cls, gateway_fee): conversion_rate = gateway_fee.currency.rate_to_default if not conversion_rate: log_smsbillables_error( "Gateway fee conversion rate for currency %s is 0" % gateway_fee.currency.code) return conversion_rate
def _get_usage_fee(cls, domain, direction): usage_fee = SmsUsageFee.get_by_criteria( direction, domain=domain ) if not usage_fee: log_smsbillables_error( "Did not find usage fee for direction %s and domain %s" % (direction, domain) ) return usage_fee
def _get_gateway_fee(cls, backend_api_id, backend_id, phone_number, direction, couch_id, backend_message_id, domain): country_code, national_number = get_country_code_and_national_number(phone_number) backend_instance = None if backend_id is not None: backend_instance = SQLMobileBackend.load( backend_id, api_id=backend_api_id, is_couch_id=True, include_deleted=True, ) is_gateway_billable = ( backend_id is None or backend_instance.is_global or toggles.ENABLE_INCLUDE_SMS_GATEWAY_CHARGING.enabled(domain) ) direct_gateway_fee = gateway_fee = multipart_count = conversion_rate = None if is_gateway_billable: if backend_instance and backend_instance.using_api_to_get_fees: if backend_message_id: direct_gateway_fee, multipart_count = \ cls.get_charge_details_through_api(backend_instance, backend_message_id) gateway_fee = SmsGatewayFee.get_by_criteria( backend_api_id, direction, ) else: log_smsbillables_error( "Could not create gateway fee for message %s: no backend_message_id" % couch_id ) else: gateway_fee = SmsGatewayFee.get_by_criteria( backend_api_id, direction, backend_instance=backend_id, country_code=country_code, national_number=national_number, ) if gateway_fee: conversion_rate = cls.get_conversion_rate(gateway_fee) else: log_smsbillables_error( "No matching gateway fee criteria for SMS %s" % couch_id ) return _ProviderChargeInfo( direct_gateway_fee, gateway_fee, multipart_count, conversion_rate )
def create_billable_for_sms(msg, delay=True): if not isinstance(msg, SMS): raise Exception("Expected msg to be an SMS") if settings.ENTERPRISE_MODE or not msg.domain: return try: from corehq.apps.sms.tasks import store_billable if delay: store_billable.delay(msg) else: store_billable(msg) except Exception as e: log_smsbillables_error("Errors Creating SMS Billable: %s" % e)
def create_billable_for_sms(msg, delay=True): if not isinstance(msg, SMS): raise Exception("Expected msg to be an SMS") if not msg.domain: return try: from corehq.apps.sms.tasks import store_billable if delay: store_billable.delay(msg) else: store_billable(msg) except Exception as e: log_smsbillables_error("Errors Creating SMS Billable: %s" % e)
def _get_twilio_charges(cls, backend_message_id, backend_instance, direction, couch_id): if backend_message_id: twilio_message = get_twilio_message(backend_instance, backend_message_id) if twilio_message.status in [ 'accepted', 'queued', 'sending', 'receiving', ] or twilio_message.price is None: raise RetryBillableTaskException("backend_message_id=%s" % backend_message_id) return _TwilioChargeInfo( Decimal(twilio_message.price) * -1, SmsGatewayFee.get_by_criteria( SQLTwilioBackend.get_api_id(), direction, ) ) else: log_smsbillables_error( "Could not create gateway fee for Twilio message %s: no backend_message_id" % couch_id ) return _TwilioChargeInfo(None, None)
def _get_gateway_fee(cls, backend_api_id, backend_instance, phone_number, direction, couch_id, backend_message_id, domain): country_code, national_number = get_country_code_and_national_number( phone_number) is_gateway_billable = backend_instance is None or _sms_backend_is_global( backend_instance ) or toggles.ENABLE_INCLUDE_SMS_GATEWAY_CHARGING.enabled(domain) if is_gateway_billable: is_twilio_message = backend_api_id == SQLTwilioBackend.get_api_id() if is_twilio_message: twilio_charges = cls._get_twilio_charges( backend_message_id, backend_instance, direction, couch_id) gateway_fee = twilio_charges.gateway_fee direct_gateway_fee = twilio_charges.twilio_gateway_fee else: gateway_fee = SmsGatewayFee.get_by_criteria( backend_api_id, direction, backend_instance=backend_instance, country_code=country_code, national_number=national_number, ) direct_gateway_fee = None if gateway_fee: conversion_rate = gateway_fee.currency.rate_to_default if conversion_rate != 0: return _GatewayChargeInfo(gateway_fee, conversion_rate, direct_gateway_fee) else: log_smsbillables_error( "Gateway fee conversion rate for currency %s is 0" % gateway_fee.currency.code) return _GatewayChargeInfo(gateway_fee, None, direct_gateway_fee) else: log_smsbillables_error( "No matching gateway fee criteria for SMS %s" % couch_id) return _GatewayChargeInfo(None, None, None)
def _get_gateway_fee(cls, backend_api_id, backend_instance, phone_number, direction, couch_id, backend_message_id, domain): country_code, national_number = get_country_code_and_national_number(phone_number) is_gateway_billable = backend_instance is None or _sms_backend_is_global( backend_instance) or toggles.ENABLE_INCLUDE_SMS_GATEWAY_CHARGING.enabled(domain) if is_gateway_billable: is_twilio_message = backend_api_id == SQLTwilioBackend.get_api_id() if is_twilio_message: twilio_charges = cls._get_twilio_charges( backend_message_id, backend_instance, direction, couch_id ) gateway_fee = twilio_charges.gateway_fee direct_gateway_fee = twilio_charges.twilio_gateway_fee else: gateway_fee = SmsGatewayFee.get_by_criteria( backend_api_id, direction, backend_instance=backend_instance, country_code=country_code, national_number=national_number, ) direct_gateway_fee = None if gateway_fee: conversion_rate = gateway_fee.currency.rate_to_default if conversion_rate != 0: return _GatewayChargeInfo(gateway_fee, conversion_rate, direct_gateway_fee) else: log_smsbillables_error( "Gateway fee conversion rate for currency %s is 0" % gateway_fee.currency.code ) return _GatewayChargeInfo(gateway_fee, None, direct_gateway_fee) else: log_smsbillables_error( "No matching gateway fee criteria for SMS %s" % couch_id ) return _GatewayChargeInfo(None, None, None)
def create(cls, message_log, api_response=None): phone_number = clean_phone_number(message_log.phone_number) direction = message_log.direction billable = cls( log_id=message_log.couch_id, phone_number=phone_number, direction=direction, date_sent=message_log.date, domain=message_log.domain, ) # Fetch gateway_fee backend_api_id = message_log.backend_api backend_instance = message_log.backend_id country_code, national_number = get_country_code_and_national_number(phone_number) if backend_instance is None or _sms_backend_is_global(backend_instance): billable.gateway_fee = SmsGatewayFee.get_by_criteria( backend_api_id, direction, backend_instance=backend_instance, country_code=country_code, national_number=national_number, ) if billable.gateway_fee is not None: conversion_rate = billable.gateway_fee.currency.rate_to_default if conversion_rate != 0: billable.gateway_fee_conversion_rate = conversion_rate else: log_smsbillables_error( "Gateway fee conversion rate for currency %s is 0" % billable.gateway_fee.currency.code ) else: log_smsbillables_error( "No matching gateway fee criteria for SMS %s" % message_log.couch_id ) # Fetch usage_fee todo domain = message_log.domain billable.usage_fee = SmsUsageFee.get_by_criteria( direction, domain=domain ) if billable.usage_fee is None: log_smsbillables_error( "Did not find usage fee for direction %s and domain %s" % (direction, domain) ) if api_response is not None: billable.api_response = api_response if backend_api_id == SQLTestSMSBackend.get_api_id(): billable.is_valid = False billable.save() return billable