def clean_name(self): value = self.cleaned_data.get("name") if value is not None: value = value.strip().upper() if value is None or value == "": raise ValidationError(_("This field is required.")) if re.compile("\s").search(value) is not None: raise ValidationError(_("Name may not contain any spaces.")) backend_classes = get_available_backends() if self._cchq_domain is None: # Ensure name is not duplicated among other global backends backend = SMSBackend.view( "sms/global_backends", classes=backend_classes, key=[value], include_docs=True, reduce=False ).one() else: # Ensure name is not duplicated among other backends owned by this domain backend = SMSBackend.view("sms/backend_by_owner_domain", classes=backend_classes, key=[self._cchq_domain, value], include_docs=True).one() if backend is not None and backend._id != self._cchq_backend_id: raise ValidationError(_("Name is already in use.")) return value
def clean_name(self): value = self.cleaned_data.get("name") if value is not None: value = value.strip().upper() if value is None or value == "": raise ValidationError(_("This field is required.")) if re.compile("\s").search(value) is not None: raise ValidationError(_("Name may not contain any spaces.")) backend_classes = get_available_backends() if self._cchq_domain is None: # Ensure name is not duplicated among other global backends backend = SMSBackend.view("sms/global_backends", classes=backend_classes, key=[value], include_docs=True, reduce=False).one() else: # Ensure name is not duplicated among other backends owned by this domain backend = SMSBackend.view("sms/backend_by_owner_domain", classes=backend_classes, key=[self._cchq_domain, value], include_docs=True).one() if backend is not None and backend._id != self._cchq_backend_id: raise ValidationError(_("Name is already in use.")) return value
def paginated_list(self): all_backends = [] all_backends += SMSBackend.view( "sms/backend_by_domain", classes=self.backend_classes, startkey=[self.domain], endkey=[self.domain, {}], reduce=False, include_docs=True, ).all() all_backends += SMSBackend.view( "sms/global_backends", classes=self.backend_classes, reduce=False, include_docs=True ).all() if len(all_backends) > 0 and not self.domain_object.default_sms_backend_id: yield { "itemData": {"id": "nodefault", "name": "Automatic Choose", "status": "DEFAULT"}, "template": "gateway-automatic-template", } elif self.domain_object.default_sms_backend_id: default_backend = SMSBackend.get(self.domain_object.default_sms_backend_id) yield {"itemData": self._fmt_backend_data(default_backend), "template": "gateway-default-template"} for backend in all_backends: if not backend._id == self.domain_object.default_sms_backend_id: yield {"itemData": self._fmt_backend_data(backend), "template": "gateway-template"}
def _list_backends(request, show_global=False, domain=None): backend_classes = get_available_backends() backends = [] editable_backend_ids = [] default_sms_backend_id = None if not show_global: domain_obj = Domain.get_by_name(domain, strict=True) raw_backends = [] if not show_global: raw_backends += SMSBackend.view( "sms/backend_by_domain", reduce=False, classes=backend_classes, startkey=[domain], endkey=[domain, {}], include_docs=True, ).all() if len(raw_backends) > 0 and domain_obj.default_sms_backend_id in [None, ""]: messages.error( request, _( "WARNING: You have not specified a default SMS connection. By default, the system will automatically select one of the SMS connections owned by the system when sending sms." ), ) raw_backends += SMSBackend.view( "sms/global_backends", classes=backend_classes, include_docs=True, reduce=False ).all() for backend in raw_backends: backends.append(backend_classes[backend.doc_type].wrap(backend.to_json())) if show_global or (not backend.is_global and backend.domain == domain): editable_backend_ids.append(backend._id) if not show_global and domain_obj.default_sms_backend_id == backend._id: default_sms_backend_id = backend._id instantiable_backends = [] for name, klass in backend_classes.items(): try: assert ( request.couch_user.is_superuser or show_global or name == "TelerivetBackend" ) # TODO: Remove this once domain-specific billing is sorted out klass.get_generic_name() klass.get_form_class() instantiable_backends.append((name, klass)) except Exception: pass instantiable_backends.sort(key=lambda t: t[0]) context = { "show_global": show_global, "domain": domain, "backends": backends, "editable_backend_ids": editable_backend_ids, "default_sms_backend_id": default_sms_backend_id, "instantiable_backends": instantiable_backends, } return render(request, "sms/list_backends.html", context)
def __init__(self, domain, *args, **kwargs): super(SMSRateCalculatorForm, self).__init__(*args, **kwargs) backends = SMSBackend.view( "sms/backend_by_domain", startkey=[domain], endkey=[domain, {}], reduce=False, include_docs=True, ).all() backends.extend( SMSBackend.view( 'sms/global_backends', reduce=False, include_docs=True, ).all()) def _get_backend_info(backend): try: api_id = " (%s)" % get_backend_by_class_name( backend.doc_type).get_api_id() except AttributeError: api_id = "" return backend._id, "%s%s" % (backend.name, api_id) backends = [_get_backend_info(g) for g in backends] self.fields['gateway'].choices = backends self.helper = FormHelper() self.helper.form_class = "form-horizontal" self.helper.layout = crispy.Layout( crispy.Field( 'gateway', data_bind="value: gateway, events: {change: clearSelect2}", css_class="input-xxlarge", ), crispy.Field( 'direction', data_bind="value: direction, " "event: {change: clearSelect2}", ), crispy.Field( 'country_code', css_class="input-xxlarge", data_bind="value: select2CountryCode.value, " "event: {change: updateRate}", placeholder=_("Please Select a Country Code"), ), )
def get_active_dimagi_owned_gateway_projects(domains, datespan, interval, datefield='date'): """ Returns list of timestamps and how many domains used a Dimagi owned gateway in the past thrity days before each timestamp """ dimagi_owned_backend = SMSBackend.view("sms/global_backends", reduce=False).all() dimagi_owned_backend_ids = [x['id'] for x in dimagi_owned_backend] backend_filter = {'terms': {'backend_id': dimagi_owned_backend_ids}} histo_data = [] for timestamp in daterange(interval, datespan.startdate, datespan.enddate): t = timestamp f = timestamp - relativedelta(days=30) sms_query = get_sms_query(f, t, 'domains', 'domain', domains) d = sms_query.filter(backend_filter).run() c = len(d.facet('domains', 'terms')) if c > 0: histo_data.append(get_data_point(c, timestamp)) return format_return_data(histo_data, 0, datespan)
def get_active_dimagi_owned_gateway_projects(domains, datespan, interval, datefield='date'): """ Returns list of timestamps and how many domains used a Dimagi owned gateway in the past thrity days before each timestamp """ dimagi_owned_backend = SMSBackend.view( "sms/global_backends", reduce=False ).all() dimagi_owned_backend_ids = [x['id'] for x in dimagi_owned_backend] backend_filter = {'terms': {'backend_id': dimagi_owned_backend_ids}} histo_data = [] for timestamp in daterange(interval, datespan.startdate, datespan.enddate): t = timestamp f = timestamp - relativedelta(days=30) sms_query = get_sms_query(f, t, 'domains', 'domain', domains, DOMAIN_COUNT_UPPER_BOUND) d = sms_query.filter(backend_filter).run() c = len(d.facet('domains', 'terms')) if c > 0: histo_data.append(get_data_point(c, timestamp)) return format_return_data(histo_data, 0, datespan)
def get_global_backends_by_class(backend_class): return filter(lambda bk: bk.doc_type == backend_class.__name__, SMSBackend.view( 'sms/global_backends', reduce=False, include_docs=True, ))
def __init__(self, domain, *args, **kwargs): super(SMSRateCalculatorForm, self).__init__(*args, **kwargs) backends = SMSBackend.view( "sms/backend_by_domain", startkey=[domain], endkey=[domain, {}], reduce=False, include_docs=True, ).all() backends.extend(SMSBackend.view( 'sms/global_backends', reduce=False, include_docs=True, ).all()) def _get_backend_info(backend): try: api_id = " (%s)" % get_backend_by_class_name(backend.doc_type).get_api_id() except AttributeError: api_id = "" return backend._id, "%s%s" % (backend.name, api_id) backends = [_get_backend_info(g) for g in backends] self.fields['gateway'].choices = backends self.helper = FormHelper() self.helper.form_class = "form-horizontal" self.helper.layout = crispy.Layout( crispy.Field( 'gateway', data_bind="value: gateway, events: {change: clearSelect2}", css_class="input-xxlarge", ), crispy.Field( 'direction', data_bind="value: direction, " "event: {change: clearSelect2}", ), crispy.Field( 'country_code', css_class="input-xxlarge", data_bind="value: select2CountryCode.value, " "event: {change: updateRate}", placeholder=_("Please Select a Country Code"), ), )
def get_global_backends_by_class(backend_class): return filter( lambda bk: bk.doc_type == backend_class.__name__, SMSBackend.view( 'sms/global_backends', reduce=False, include_docs=True, ))
def global_backend_map(request): backend_classes = get_available_backends() global_backends = SMSBackend.view( "sms/global_backends", classes=backend_classes, include_docs=True, reduce=False ).all() current_map = {} catchall_entry = None for entry in BackendMapping.view("sms/backend_map", startkey=["*"], endkey=["*", {}], include_docs=True).all(): if entry.prefix == "*": catchall_entry = entry else: current_map[entry.prefix] = entry if request.method == "POST": form = BackendMapForm(request.POST) if form.is_valid(): new_backend_map = form.cleaned_data.get("backend_map") new_catchall_backend_id = form.cleaned_data.get("catchall_backend_id") for prefix, entry in current_map.items(): if prefix not in new_backend_map: current_map[prefix].delete() del current_map[prefix] for prefix, backend_id in new_backend_map.items(): if prefix in current_map: current_map[prefix].backend_id = backend_id current_map[prefix].save() else: current_map[prefix] = BackendMapping(is_global=True, prefix=prefix, backend_id=backend_id) current_map[prefix].save() if new_catchall_backend_id is None: if catchall_entry is not None: catchall_entry.delete() catchall_entry = None else: if catchall_entry is None: catchall_entry = BackendMapping(is_global=True, prefix="*", backend_id=new_catchall_backend_id) else: catchall_entry.backend_id = new_catchall_backend_id catchall_entry.save() messages.success(request, _("Changes Saved.")) else: initial = { "catchall_backend_id" : catchall_entry.backend_id if catchall_entry is not None else None, "backend_map" : [{"prefix" : prefix, "backend_id" : entry.backend_id} for prefix, entry in current_map.items()], } form = BackendMapForm(initial=initial) context = { "backends" : global_backends, "form" : form, } return render(request, "sms/backend_map.html", context)
def paginated_list(self): all_backends = [] all_backends += SMSBackend.view( "sms/backend_by_domain", classes=self.backend_classes, startkey=[self.domain], endkey=[self.domain, {}], reduce=False, include_docs=True ).all() all_backends += SMSBackend.view( 'sms/global_backends', classes=self.backend_classes, reduce=False, include_docs=True ).all() if len(all_backends) > 0 and not self.domain_object.default_sms_backend_id: yield { 'itemData': { 'id': 'nodefault', 'name': "Automatic Choose", 'status': 'DEFAULT', }, 'template': 'gateway-automatic-template', } elif self.domain_object.default_sms_backend_id: default_backend = SMSBackend.get(self.domain_object.default_sms_backend_id) yield { 'itemData': self._fmt_backend_data(default_backend), 'template': 'gateway-default-template', } for backend in all_backends: if not backend._id == self.domain_object.default_sms_backend_id: yield { 'itemData': self._fmt_backend_data(backend), 'template': 'gateway-template', }
def get_rate_table(self, country_code): backends = SMSBackend.view( 'sms/global_backends', reduce=False, include_docs=True, ).all() def _directed_fee(direction, backend_api_id, backend_instance_id): gateway_fee = SmsGatewayFee.get_by_criteria( backend_api_id, direction, backend_instance=backend_instance_id, country_code=country_code ) if not gateway_fee: return None usd_gateway_fee = gateway_fee.amount / gateway_fee.currency.rate_to_default usage_fee = SmsUsageFee.get_by_criteria(direction) return fmt_dollar_amount(usage_fee.amount + usd_gateway_fee) rate_table = [] from corehq.apps.sms.test_backend import TestSMSBackend for backend_instance in backends: backend_instance = backend_instance.wrap_correctly() # Skip Testing backends if isinstance(backend_instance, TestSMSBackend): continue # skip if country is not in supported countries if backend_instance.supported_countries: if ('*' not in backend_instance.supported_countries and str(country_code) not in backend_instance.supported_countries): continue gateway_fee_incoming = _directed_fee( INCOMING, backend_instance.incoming_api_id or backend_instance.get_api_id(), backend_instance._id ) gateway_fee_outgoing = _directed_fee(OUTGOING, backend_instance.get_api_id(), backend_instance._id) if gateway_fee_outgoing or gateway_fee_incoming: rate_table.append({ 'gateway': backend_instance.display_name, 'inn': gateway_fee_incoming or 'NA', # 'in' is reserved 'out': gateway_fee_outgoing or 'NA' }) return rate_table