Example #1
0
def global_keyword_start(verified_number, text, msg, text_words,
                         open_sessions):
    outbound_metadata = MessageMetadata(workflow=WORKFLOW_KEYWORD, )

    if len(text_words) > 1:
        keyword = text_words[1]
        k = Keyword.get_keyword(verified_number.domain, keyword)
        if k:
            if not contact_can_use_keyword(verified_number, k):
                return False
            process_survey_keyword_actions(verified_number, k,
                                           text[6:].strip(), msg)
        else:
            message = get_message(MSG_KEYWORD_NOT_FOUND, verified_number,
                                  (keyword, ))
            send_sms_to_verified_number(verified_number,
                                        message,
                                        metadata=outbound_metadata)
    else:
        message = get_message(MSG_START_KEYWORD_USAGE, verified_number,
                              (text_words[0], ))
        send_sms_to_verified_number(verified_number,
                                    message,
                                    metadata=outbound_metadata)
    return True
Example #2
0
def handle_due_survey_action(domain, contact_id, session_id):
    with critical_section_for_smsforms_sessions(contact_id):
        session = SQLXFormsSession.by_session_id(session_id)
        if (not session or not session.session_is_open
                or session.current_action_due > utcnow()):
            return

        if session.current_action_is_a_reminder:
            # Resend the current question in the open survey to the contact
            p = PhoneNumber.get_phone_number_for_owner(session.connection_id,
                                                       session.phone_number)
            if p:
                metadata = MessageMetadata(
                    workflow=session.workflow,
                    xforms_session_couch_id=session._id,
                )
                resp = current_question(session.session_id, domain)
                send_sms_to_verified_number(
                    p,
                    resp.event.text_prompt,
                    metadata,
                    logged_subevent=session.related_subevent)

            session.move_to_next_action()
            session.save()
        else:
            # Close the session
            session.close()
            session.save()
Example #3
0
def report_reminder_process_user(user, test=False):
    now = datetime.datetime.utcnow()
    date = now - datetime.timedelta(days=7)

    if not user.location or user.location.location_type.administrative:
        return
    sp = SupplyPointCase.get_by_location(user.location)
    if not sp:
        return
    transaction_exists = StockTransaction.objects.filter(
        case_id=sp._id,
        type="stockonhand",
        report__date__gte=date
    ).exists()
    if sp and not transaction_exists and user.get_verified_number():
        message = REPORT_REMINDER % (user.name, user.location.name)
        verified_number = user.get_verified_number()
        if not test:
            send_sms_to_verified_number(verified_number, message)
        else:
            send_test_message(verified_number, message)

        if can_receive_email(user, verified_number):
            email = str(user.email)
            send_mail('REPORT REMINDER', message, '*****@*****.**', [email])
Example #4
0
def stock_alerts(transactions, user):
    report_helper = ProductsReportHelper(user.sql_location, transactions)
    products_below = report_helper.low_supply()
    stockouts = report_helper.stockouts()
    overstocked = report_helper.overstocked()
    receipts = report_helper.receipts()
    missings = report_helper.missing_products()
    message = ""
    super_message = ""
    if missings:
        products_codes_str = ' '.join(sorted([missing.code for missing in missings]))
        message += " still missing %s. " % products_codes_str

    if stockouts:
        products_codes_str = ' '.join([stockout.sql_product.code for stockout in stockouts])
        products_names_str = ' '.join([stockout.sql_product.name for stockout in stockouts])
        message += " " + STOCKOUTS_MESSAGE % {'products': products_codes_str}
        super_message = _("stockouts %s; ") % products_names_str

    if products_below:
        products_codes_str = ' '.join([product.sql_product.code for product in products_below])
        products_names_str = ' '.join([product.sql_product.name for product in products_below])
        message += " " + LOW_SUPPLY_MESSAGE % {'low_supply': products_codes_str}
        super_message += _("below reorder level %s; ") % products_names_str

    if stockouts or products_below:
        reorders = [
            u'%s %s' % (code, amount)
            for (code, amount) in report_helper.reorders()
            if amount
        ]
        if reorders:
            message += " Please order %s." % ' '.join(reorders)

    if overstocked:
        if not message:
            products_codes_str = ' '.join([overstock.sql_product.code for overstock in overstocked])
            message += " " + OVERSTOCKED_MESSAGE % {'username': user.username, 'overstocked': products_codes_str}
        products_names_str = ' '.join([overstock.sql_product.name for overstock in overstocked])
        super_message += _("overstocked %s; ") % products_names_str

    if not message:
        if not receipts:
            message = COMPLETE_REPORT % user.username
        else:
            products_str = ' '.join(
                [
                    "%s %s" % (SQLProduct.objects.get(product_id=receipt.product_id).code, receipt.quantity)
                    for receipt in receipts
                ]
            )
            message = RECEIPT_MESSAGE % {'username': user.username, 'received': products_str}
    else:
        message = (_('Dear %s,') % user.username) + message

    if super_message:
        stripped_message = super_message.strip().strip(';')
        super_message = _('Dear %s, %s is experiencing the following problems: ') + stripped_message
        send_message_to_admins(user, super_message.rstrip())
    send_sms_to_verified_number(user.get_verified_number(), message.rstrip())
Example #5
0
def on_going_non_reporting():
    now = datetime.datetime.utcnow()
    date = now - datetime.timedelta(days=21)
    domains = EWSGhanaConfig.get_all_enabled_domains()

    for domain in domains:
        for user in CommCareUser.by_domain(domain):
            try:
                user_location = SQLLocation.objects.get(domain=domain, location_id=user.location._id)
            except AttributeError:
                continue
            if user_location:
                facilities = []
                if user_location.location_type == 'district':
                    facilities = user_location.get_children()
                elif user_location.location_type == 'region':
                    facilities = SQLLocation.objects.filter(domain=domain,
                                                            parent__parent__location_id=user.location._id)
                fac = set()
                for facility in facilities:
                    sp = facility.supply_point_id
                    if sp and not StockTransaction.objects.filter(
                            case_id=sp, type="stockonhand", report__date__gte=date).exists():
                        fac.add(str(facility.name))
                if fac and user.get_verified_number():
                    message = ONGOING_NON_REPORTING % " \n".join(fac)
                    send_sms_to_verified_number(user.get_verified_number(), message)
                    if user.email:
                        email = str(user.email)
                        send_mail('ONGOING NON REPORTING', message, '*****@*****.**', [email])
Example #6
0
def on_going_process_user(user, test=False):
    now = datetime.datetime.utcnow()
    date = now - datetime.timedelta(days=21)
    user_location = user.sql_location
    if not user_location:
        return

    facilities = []
    if user_location.location_type.name == 'district':
        facilities = user_location.get_children()
    elif user_location.location_type.name == 'region':
        facilities = SQLLocation.objects.filter(domain=user.domain,
                                                parent__parent__location_id=user.location._id)
    fac = set()
    for facility in facilities:
        sp = facility.supply_point_id
        if not sp:
            continue
        transactions_exist = StockTransaction.objects.filter(
            case_id=sp,
            type="stockonhand",
            report__date__gte=date
        ).exists()
        if not transactions_exist:
            fac.add(unicode(facility.name))
    verified_number = user.get_verified_number()
    if fac and verified_number:
        message = ONGOING_NON_REPORTING % " \n".join(fac)
        if not test:
            send_sms_to_verified_number(verified_number, message)
        else:
            send_test_message(verified_number, message)
        if can_receive_email(user, verified_number):
            email = str(user.email)
            send_mail('ONGOING NON REPORTING', message, '*****@*****.**', [email])
Example #7
0
def rrirv_process_user(user, test=False):
    if user_has_reporting_location(user) and user_has_role(user, IN_CHARGE_ROLE):
        if user.get_verified_number():
            if not test:
                send_sms_to_verified_number(user.get_verified_number(), RRIRV_REMINDER % {'name': user.name})
            else:
                send_test_message(user.get_verified_number(), RRIRV_REMINDER % {'name': user.name})
Example #8
0
def fallback_handler(verified_number, text, msg):
    domain_obj = Domain.get_by_name(verified_number.domain, strict=True)

    logged_event = MessagingEvent.create_event_for_adhoc_sms(
        verified_number.domain,
        recipient=verified_number.owner,
        content_type=MessagingEvent.CONTENT_SMS,
        source=MessagingEvent.SOURCE_UNRECOGNIZED)

    inbound_subevent = logged_event.create_subevent_for_single_sms(
        verified_number.owner_doc_type, verified_number.owner_id)
    inbound_meta = MessageMetadata(workflow=WORKFLOW_DEFAULT,
                                   messaging_subevent_id=inbound_subevent.pk)
    add_msg_tags(msg, inbound_meta)

    if domain_obj.use_default_sms_response and domain_obj.default_sms_response:
        outbound_subevent = logged_event.create_subevent_for_single_sms(
            verified_number.owner_doc_type, verified_number.owner_id)
        outbound_meta = MessageMetadata(
            workflow=WORKFLOW_DEFAULT,
            location_id=msg.location_id,
            messaging_subevent_id=outbound_subevent.pk)
        send_sms_to_verified_number(verified_number,
                                    domain_obj.default_sms_response,
                                    metadata=outbound_meta)
        outbound_subevent.completed()

    inbound_subevent.completed()
    logged_event.completed()
    return True
Example #9
0
def send_messages_for_config(config, actually_send=True):
    query_engine = QueryEngine(template_vars=config.template_variables)
    params = get_parsed_params(config.template)
    sent_messages = []
    for user in config.group.get_users():
        phone_number = get_preferred_phone_number_for_recipient(user)
        if phone_number:
            query_context = QueryContext(
                user, config.group, template_vars=config.template_variables)
            message_context = query_engine.get_context(params, query_context)
            message = config.template.format(**message_context)
            if actually_send:
                metadata = MessageMetadata(workflow=WORKFLOW_PERFORMANCE)
                if isinstance(phone_number, PhoneNumber):
                    send_sms_to_verified_number(phone_number,
                                                message,
                                                metadata=metadata)
                else:
                    send_sms(config.domain,
                             user,
                             phone_number,
                             message,
                             metadata=metadata)

            sent_messages.append(MessageResult(user, message))
    return sent_messages
Example #10
0
def stockout_process_user(user, test=False):
    if user_has_reporting_location(user):
        location = user.location
        supply_point = SupplyPointCase.get_by_location(location)
        if supply_point and user.get_verified_number():
            products = [
                SQLProduct.objects.get(product_id=state.product_id).name
                for state in StockState.objects.filter(
                    case_id=supply_point._id, stock_on_hand=0,
                    product_id__in=[product.product_id for product in location.sql_location.products]
                )
            ]
            if products:
                if not test:
                    send_sms_to_verified_number(
                        user.get_verified_number(),
                        STOCKOUT_REPORT % {
                            'name': user.name,
                            'facility': supply_point.name,
                            'date': datetime.datetime.utcnow().strftime('%b %d'),
                            'products': ", ".join(products)
                        }
                    )
                else:
                    send_test_message(
                        user.get_verified_number(),
                        STOCKOUT_REPORT % {
                            'name': user.name,
                            'facility': supply_point.name,
                            'date': datetime.datetime.utcnow().strftime('%b %d'),
                            'products': ", ".join(products)
                        }
                    )
Example #11
0
def fallback_handler(v, text, msg):
    domain_obj = Domain.get_by_name(v.domain, strict=True)

    logged_event = MessagingEvent.create_event_for_adhoc_sms(
        v.domain, recipient=v.owner, content_type=MessagingEvent.CONTENT_SMS,
        source=MessagingEvent.SOURCE_UNRECOGNIZED)

    inbound_subevent = logged_event.create_subevent_for_single_sms(
        v.owner_doc_type, v.owner_id)
    inbound_meta = MessageMetadata(workflow=WORKFLOW_DEFAULT,
        messaging_subevent_id=inbound_subevent.pk)
    add_msg_tags(msg, inbound_meta)

    if domain_obj.use_default_sms_response and domain_obj.default_sms_response:
        outbound_subevent = logged_event.create_subevent_for_single_sms(
            v.owner_doc_type, v.owner_id)
        outbound_meta = MessageMetadata(workflow=WORKFLOW_DEFAULT,
            location_id=msg.location_id,
            messaging_subevent_id=outbound_subevent.pk)
        send_sms_to_verified_number(v, domain_obj.default_sms_response,
            metadata=outbound_meta)
        outbound_subevent.completed()

    inbound_subevent.completed()
    logged_event.completed()
    return True
Example #12
0
def process_verification(phone_number, msg, backend_id=None):
    v = VerifiedNumber.by_phone(phone_number, True)
    if not v:
        return

    if not verification_response_ok(msg.text):
        return

    msg.domain = v.domain
    msg.couch_recipient_doc_type = v.owner_doc_type
    msg.couch_recipient = v.owner_id
    msg.save()

    if backend_id:
        backend = MobileBackend.load(backend_id)
    else:
        backend = MobileBackend.auto_load(phone_number, v.domain)

    # i don't know how to dynamically instantiate this object, which may be any number of doc types...
    #owner = CommCareMobileContactMixin.get(v.owner_id)
    assert v.owner_doc_type == 'CommCareUser'
    owner = CommCareUser.get(v.owner_id)

    v = owner.save_verified_number(v.domain, phone_number, True, backend.name)
    with localize(owner.language):
        send_sms_to_verified_number(v, _(CONFIRM))
Example #13
0
def send_translated_message(user, message, **kwargs):
    verified_number = user.get_verified_number()
    if not verified_number:
        return False
    with localize(user.get_language_code()):
        send_sms_to_verified_number(verified_number, message % kwargs)
        return True
Example #14
0
def send_translated_message(user, message, **kwargs):
    verified_number = get_two_way_number_for_recipient(user)
    if not verified_number:
        return False
    with localize(user.get_language_code()):
        send_sms_to_verified_number(verified_number, message % kwargs)
        return True
Example #15
0
    def __test_verified_number_with_map(self):
        # Test sending to verified number with backend map
        SQLMobileBackendMapping.unset_default_domain_backend(self.domain)

        verified_number = self.contact.get_verified_number()
        self.assertTrue(verified_number is not None)
        self.assertTrue(verified_number.backend_id is None)
        self.assertEqual(verified_number.phone_number, '15551234567')

        with patch(
            'corehq.messaging.smsbackends.test.models.SQLTestSMSBackend.send',
            autospec=True
        ) as mock_send:
            self.assertTrue(send_sms_to_verified_number(verified_number, 'Test for BACKEND2'))
        self.assertEqual(mock_send.call_count, 1)
        self.assertEqual(mock_send.call_args[0][0].pk, self.backend2.pk)

        # Test sending to verified number with default domain backend
        SQLMobileBackendMapping.set_default_domain_backend(self.domain, self.backend5)

        with patch(
            'corehq.messaging.smsbackends.test.models.SQLTestSMSBackend.send',
            autospec=True
        ) as mock_send:
            self.assertTrue(send_sms_to_verified_number(verified_number, 'Test for BACKEND5'))
        self.assertEqual(mock_send.call_count, 1)
        self.assertEqual(mock_send.call_args[0][0].pk, self.backend5.pk)
Example #16
0
def send_translated_message(user, message, **kwargs):
    verified_number = user.get_verified_number()
    if not verified_number:
        return False
    with localize(user.get_language_code()):
        send_sms_to_verified_number(verified_number, message % kwargs)
        return True
Example #17
0
    def get_valid_reports(self, data, verified_contact):
        filtered_transactions = []
        excluded_products = []
        for product_id, transactions in get_transactions_by_product(
                data['transactions']).iteritems():
            begin_soh = None
            end_soh = None
            receipt = 0
            for transaction in transactions:
                if begin_soh is None:
                    sql_location = SQLLocation.objects.get(
                        location_id=transaction.location_id)
                    latest = StockTransaction.latest(
                        sql_location.supply_point_id, SECTION_TYPE_STOCK,
                        transaction.product_id)
                    begin_soh = 0
                    if latest:
                        begin_soh = float(latest.stock_on_hand)

                if transaction.action == 'receipts':
                    receipt += float(transaction.quantity)
                elif not end_soh:
                    end_soh = float(transaction.quantity)
            if end_soh > begin_soh + receipt:
                excluded_products.append(transaction.product_id)
            else:
                filtered_transactions.append(transaction)
        if excluded_products:
            message = ERROR_MESSAGE.format(products_list=', '.join([
                SQLProduct.objects.get(product_id=product_id).code
                for product_id in set(excluded_products)
            ]))
            send_sms_to_verified_number(verified_contact, message)
        return filtered_transactions
Example #18
0
    def handle(self):
        verified_contact = self.verified_contact
        user = verified_contact.owner
        domain = Domain.get_by_name(verified_contact.domain)
        splitted_text = self.msg.text.split()
        if splitted_text[0].lower() == 'soh':
            text = ' '.join(self.msg.text.split()[1:])
        else:
            text = self.msg.text

        if not domain.commtrack_enabled:
            return False
        try:
            data = StockAndReceiptParser(domain, verified_contact).parse(text)
            if not data:
                return False
            if EWS_INVALID_REPORT_RESPONSE.enabled(self.domain):
                filtered_transactions = self.get_valid_reports(
                    data, verified_contact)

                if not filtered_transactions:
                    return True

                data['transactions'] = filtered_transactions

        except NotAUserClassError:
            return False
        except Exception, e:  # todo: should we only trap SMSErrors?
            if settings.UNIT_TESTING or settings.DEBUG:
                raise
            send_sms_to_verified_number(
                verified_contact, 'problem with stock report: %s' % str(e))
            return True
Example #19
0
 def _send_delivery_alert_to_facilities(self, sp_name, location):
     locs = [c._id for c in location.children]
     users = filter(lambda u: u.location_id in locs, CommCareUser.by_domain(self.domain))
     for user in users:
         if user.get_verified_number():
             send_sms_to_verified_number(user.get_verified_number(), DELIVERY_CONFIRM_CHILDREN %
                                         {"district_name": sp_name})
Example #20
0
 def _send_submission_alert_to_msd(self, params):
     users = filter(lambda u: u.user_data.get('role', None) == 'MSD', CommCareUser.by_domain(self.domain))
     for user in users:
         if not user.get_verified_number():
             continue
         with localize(user.get_language_code()):
             send_sms_to_verified_number(user.get_verified_number(), SUBMITTED_NOTIFICATION_MSD % params)
Example #21
0
    def handle(self):
        verified_contact = self.verified_contact
        user = verified_contact.owner
        domain = Domain.get_by_name(verified_contact.domain)
        splitted_text = self.msg.text.split()
        if splitted_text[0].lower() == "soh":
            text = " ".join(self.msg.text.split()[1:])
        else:
            text = self.msg.text

        if not domain.commtrack_enabled:
            return False
        try:
            data = StockAndReceiptParser(domain, verified_contact).parse(text)
            if not data:
                return False
            if EWS_INVALID_REPORT_RESPONSE.enabled(self.domain):
                filtered_transactions = self.get_valid_reports(data, verified_contact)

                if not filtered_transactions:
                    return True

                data["transactions"] = filtered_transactions

        except NotAUserClassError:
            return False
        except Exception, e:  # todo: should we only trap SMSErrors?
            if settings.UNIT_TESTING or settings.DEBUG:
                raise
            send_sms_to_verified_number(verified_contact, "problem with stock report: %s" % str(e))
            return True
Example #22
0
 def _send_submission_alert_to_msd(self, params):
     users = filter(lambda u: u.user_data.get('role', None) == 'MSD', CommCareUser.by_domain(self.domain))
     for user in users:
         if not user.get_verified_number():
             continue
         with localize(user.get_language_code()):
             send_sms_to_verified_number(user.get_verified_number(), SUBMITTED_NOTIFICATION_MSD % params)
    def handle(self):
        location = self.user.location
        domain = self.domain_object

        location_id = self.location_id

        if not location_id:
            return False

        if location.location_type_name == 'FACILITY':
            try:
                data = self.data
                if not data:
                    return True

                if not data.get('transactions'):
                    self.on_error(data)
                    return True

                process(domain.name, data)
                if not data['errors']:
                    self.on_success()
                else:
                    self.on_error(data)
                    return True
                self.respond(self.get_message(data))
            except NotAUserClassError:
                return True
            except Exception, e:  # todo: should we only trap SMSErrors?
                if settings.UNIT_TESTING or settings.DEBUG:
                    raise
                send_sms_to_verified_number(
                    self.verified_contact,
                    'problem with stock report: %s' % str(e))
Example #24
0
def visit_website_process_user(user, test=False):
    date = datetime.datetime.utcnow() - datetime.timedelta(weeks=13)
    if user.last_login < date and user.get_verified_number():
        if not test:
            send_sms_to_verified_number(user.get_verified_number(), WEB_REMINDER % {'name': user.name})
        else:
            send_test_message(user.get_verified_number(), WEB_REMINDER % {'name': user.name})
Example #25
0
    def handle(self):
        verified_contact = self.verified_contact
        domain = Domain.get_by_name(verified_contact.domain)
        text = self.msg.text

        try:
            data = StockReportParser(domain, verified_contact).parse(text)
            if not data:
                return False
        except NotAUserClassError:
            return False
        except Exception as e:
            if settings.UNIT_TESTING or settings.DEBUG:
                raise
            send_sms_to_verified_number(
                verified_contact, 'problem with stock report: %s' % str(e))
            return True
        transactions = data['transactions']
        products = [
            SQLProduct.objects.get(product_id=transaction.product_id).code
            for transaction in transactions
        ]
        process(domain.name, data)
        send_sms_to_verified_number(
            verified_contact,
            RECEIPT_CONFIRM % {'products': ' '.join(products)})
        return True
Example #26
0
    def get_valid_reports(self, data, verified_contact):
        filtered_transactions = []
        excluded_products = []
        for product_id, transactions in get_transactions_by_product(data["transactions"]).iteritems():
            begin_soh = None
            end_soh = None
            receipt = 0
            for transaction in transactions:
                if begin_soh is None:
                    sql_location = SQLLocation.objects.get(location_id=transaction.location_id)
                    latest = StockTransaction.latest(
                        sql_location.supply_point_id, SECTION_TYPE_STOCK, transaction.product_id
                    )
                    begin_soh = 0
                    if latest:
                        begin_soh = float(latest.stock_on_hand)

                if transaction.action == "receipts":
                    receipt += float(transaction.quantity)
                elif not end_soh:
                    end_soh = float(transaction.quantity)
            if end_soh > begin_soh + receipt:
                excluded_products.append(transaction.product_id)
            else:
                filtered_transactions.append(transaction)
        if excluded_products:
            message = ERROR_MESSAGE.format(
                products_list=", ".join(
                    [SQLProduct.objects.get(product_id=product_id).code for product_id in set(excluded_products)]
                )
            )
            send_sms_to_verified_number(verified_contact, message)
        return filtered_transactions
Example #27
0
def handle(verified_contact, text, msg):
    """top-level handler for incoming stock report messages"""
    domain_obj = Domain.get_by_name(verified_contact.domain)
    if not domain_obj.commtrack_enabled:
        return False

    try:
        if toggles.STOCK_AND_RECEIPT_SMS_HANDLER.enabled(domain_obj.name):
            # handle special stock parser for custom domain logic
            data = StockAndReceiptParser(domain_obj, verified_contact).parse(text.lower())
        else:
            # default report parser
            data = StockReportParser(domain_obj, verified_contact).parse(text.lower())
        if not data:
            return False
    except NotAUserClassError:
        return False
    except Exception as e:
        if settings.UNIT_TESTING or settings.DEBUG:
            raise
        send_sms_to_verified_number(verified_contact, 'problem with stock report: %s' % six.text_type(e))
        return True

    process(domain_obj.name, data)
    send_confirmation(verified_contact, data)
    return True
Example #28
0
def on_going_process_user(user, test=False):
    now = datetime.datetime.utcnow()
    date = now - datetime.timedelta(days=21)
    user_location = user.sql_location
    if not user_location:
        return

    facilities = []
    if user_location.location_type.name == 'district':
        facilities = user_location.get_children()
    elif user_location.location_type.name == 'region':
        facilities = SQLLocation.objects.filter(
            domain=user.domain, parent__parent__location_id=user.location._id)
    fac = set()
    for facility in facilities:
        sp = facility.supply_point_id
        if not sp:
            continue
        transactions_exist = StockTransaction.objects.filter(
            case_id=sp, type="stockonhand", report__date__gte=date).exists()
        if not transactions_exist:
            fac.add(unicode(facility.name))
    verified_number = user.get_verified_number()
    if fac and verified_number:
        message = ONGOING_NON_REPORTING % " \n".join(fac)
        if not test:
            send_sms_to_verified_number(verified_number, message)
        else:
            send_test_message(verified_number, message)
        if can_receive_email(user, verified_number):
            email = str(user.email)
            send_mail('ONGOING NON REPORTING', message,
                      '*****@*****.**', [email])
Example #29
0
def handle(verified_contact, text, msg):
    """top-level handler for incoming stock report messages"""
    domain = Domain.get_by_name(verified_contact.domain)
    if not domain.commtrack_enabled:
        return False

    try:
        if toggles.STOCK_AND_RECEIPT_SMS_HANDLER.enabled(domain.name):
            # handle special stock parser for custom domain logic
            data = StockAndReceiptParser(domain,
                                         verified_contact).parse(text.lower())
        else:
            # default report parser
            data = StockReportParser(domain,
                                     verified_contact).parse(text.lower())
        if not data:
            return False
    except NotAUserClassError:
        return False
    except Exception as e:
        if settings.UNIT_TESTING or settings.DEBUG:
            raise
        send_sms_to_verified_number(verified_contact,
                                    'problem with stock report: %s' % str(e))
        return True

    process(domain.name, data)
    send_confirmation(verified_contact, data)
    return True
Example #30
0
def clean_up_and_send_response(msg,
                               contact,
                               session,
                               error_occurred,
                               error_msg,
                               verified_number=None,
                               send_response=False,
                               logged_event=None,
                               logged_subevent=None):

    session = refresh_and_close_session(session)
    metadata = add_keyword_metadata(msg, session)

    if error_occurred and verified_number and send_response:
        response_subevent = None
        if logged_event:
            response_subevent = logged_event.create_subevent_for_single_sms(
                contact.doc_type, contact.get_id)
            metadata.messaging_subevent_id = response_subevent.pk

        send_sms_to_verified_number(verified_number,
                                    error_msg,
                                    metadata=metadata)
        if response_subevent:
            response_subevent.completed()

    if logged_subevent:
        logged_subevent.completed()
Example #31
0
def send_translated_message(user, message, **kwargs):
    verified_number = get_two_way_number_for_recipient(user)
    if not verified_number:
        return False
    with localize(user.get_language_code()):
        send_sms_to_verified_number(verified_number, message % kwargs)
        return True
Example #32
0
def fallback_handler(v, text, msg):
    domain_obj = Domain.get_by_name(v.domain, strict=True)
    default_workflow_meta = MessageMetadata(workflow=WORKFLOW_DEFAULT, location_id=msg.location_id)
    if domain_obj.use_default_sms_response and domain_obj.default_sms_response:
        send_sms_to_verified_number(v, domain_obj.default_sms_response, metadata=default_workflow_meta)
    add_msg_tags(msg, default_workflow_meta)
    return True
Example #33
0
def fire_sms_event(reminder,
                   handler,
                   recipients,
                   verified_numbers,
                   logged_event,
                   workflow=None):
    current_event = reminder.current_event
    case = reminder.case
    template_params = get_message_template_params(case)

    uses_custom_content_handler, content_handler = get_custom_content_handler(
        handler, logged_event)
    if uses_custom_content_handler and not content_handler:
        return

    domain_obj = Domain.get_by_name(reminder.domain, strict=True)
    for recipient in recipients:
        logged_subevent = logged_event.create_subevent(handler, reminder,
                                                       recipient)

        try:
            lang = recipient.get_language_code()
        except Exception:
            lang = None

        if content_handler:
            message = content_handler(reminder, handler, recipient)
        else:
            message = current_event.message.get(
                lang, current_event.message[handler.default_lang])
            try:
                message = Message.render(message, **template_params)
            except Exception:
                logged_subevent.error(
                    MessagingEvent.ERROR_CANNOT_RENDER_MESSAGE)
                continue

        verified_number, unverified_number = get_recipient_phone_number(
            reminder, recipient, verified_numbers)

        if message:
            metadata = MessageMetadata(
                workflow=workflow or get_workflow(handler),
                reminder_id=reminder._id,
                messaging_subevent_id=logged_subevent.pk,
            )
            if verified_number is not None:
                send_sms_to_verified_number(verified_number, message, metadata)
            elif isinstance(recipient, CouchUser) and unverified_number:
                send_sms(reminder.domain, recipient, unverified_number,
                         message, metadata)
            elif (isinstance(recipient, CommCareCase) and unverified_number
                  and domain_obj.send_to_duplicated_case_numbers):
                send_sms(reminder.domain, recipient, unverified_number,
                         message, metadata)
            else:
                logged_subevent.error(MessagingEvent.ERROR_NO_PHONE_NUMBER)
                continue

        logged_subevent.completed()
Example #34
0
def process_verification(phone_number, msg, backend_id=None):
    v = VerifiedNumber.by_phone(phone_number, True)
    if not v:
        return

    if not verification_response_ok(msg.text):
        return

    msg.domain = v.domain
    msg.couch_recipient_doc_type = v.owner_doc_type
    msg.couch_recipient = v.owner_id
    msg.save()

    if not domain_has_privilege(msg.domain, privileges.INBOUND_SMS):
        return

    if backend_id:
        backend = MobileBackend.load(backend_id)
    else:
        backend = MobileBackend.auto_load(phone_number, v.domain)

    # i don't know how to dynamically instantiate this object, which may be any number of doc types...
    #owner = CommCareMobileContactMixin.get(v.owner_id)
    assert v.owner_doc_type == 'CommCareUser'
    owner = CommCareUser.get(v.owner_id)

    v = owner.save_verified_number(v.domain, phone_number, True, backend.name)
    with localize(owner.language):
        send_sms_to_verified_number(v, _(CONFIRM))
Example #35
0
def answer_next_question(v, text, msg, session):
    resp = current_question(session.session_id)
    event = resp.event
    valid, text, error_msg = validate_answer(event, text, v)

    # metadata to be applied to the reply message
    outbound_metadata = MessageMetadata(
        workflow=session.workflow,
        reminder_id=session.reminder_id,
        xforms_session_couch_id=session._id,
    )

    if valid:
        responses = _get_responses(v.domain, v.owner_id, text,
            yield_responses=True)

        if has_invalid_response(responses):
            mark_as_invalid_response(msg)

        text_responses = _responses_to_text(responses)
        if len(text_responses) > 0:
            response_text = format_message_list(text_responses)
            send_sms_to_verified_number(v, response_text, 
                metadata=outbound_metadata)
    else:
        mark_as_invalid_response(msg)
        response_text = "%s %s" % (error_msg, event.text_prompt)
        send_sms_to_verified_number(v, response_text, 
            metadata=outbound_metadata)
Example #36
0
    def handle(self):
        location = self.user.location
        domain = self.domain_object

        location_id = self.location_id

        if not location_id:
            return False

        if location.location_type_name == 'FACILITY':
            try:
                data = self.data
                if not data:
                    return True

                if not data.get('transactions'):
                    self.on_error(data)
                    return True

                process(domain.name, data)
                if not data['errors']:
                    self.on_success()
                else:
                    self.on_error(data)
                    return True
                self.respond(self.get_message(data))
            except NotAUserClassError:
                return True
            except Exception, e:  # todo: should we only trap SMSErrors?
                if settings.UNIT_TESTING or settings.DEBUG:
                    raise
                send_sms_to_verified_number(self.verified_contact, 'problem with stock report: %s' % str(e))
Example #37
0
def form_session_handler(v, text, msg):
    """
    The form session handler will use the inbound text to answer the next question
    in the open SQLXformsSession for the associated contact. If no session is open,
    the handler passes. If multiple sessions are open, they are all closed and an
    error message is displayed to the user.
    """
    multiple, session = get_single_open_session_or_close_multiple(v.domain, v.owner_id)
    if multiple:
        send_sms_to_verified_number(v, get_message(MSG_MULTIPLE_SESSIONS, v))
        return True

    if session:
        # Metadata to be applied to the inbound message
        inbound_metadata = MessageMetadata(
            workflow=session.workflow,
            reminder_id=session.reminder_id,
            xforms_session_couch_id=session._id,
        )
        add_msg_tags(msg, inbound_metadata)

        try:
            answer_next_question(v, text, msg, session)
        except Exception:
            # Catch any touchforms errors
            log_sms_exception(msg)
            send_sms_to_verified_number(v, get_message(MSG_TOUCHFORMS_DOWN, v))
        return True
    else:
        return False
Example #38
0
def stockout_process_user(user, test=False):
    if user_has_reporting_location(user):
        location = user.location
        supply_point = SupplyPointCase.get_by_location(location)
        if supply_point and user.get_verified_number():
            products = [
                SQLProduct.objects.get(product_id=state.product_id).name
                for state in StockState.objects.filter(
                    case_id=supply_point._id,
                    stock_on_hand=0,
                    product_id__in=[
                        product.product_id
                        for product in location.sql_location.products
                    ])
            ]
            if products:
                if not test:
                    send_sms_to_verified_number(
                        user.get_verified_number(), STOCKOUT_REPORT % {
                            'name': user.name,
                            'facility': supply_point.name,
                            'date':
                            datetime.datetime.utcnow().strftime('%b %d'),
                            'products': ", ".join(products)
                        })
                else:
                    send_test_message(
                        user.get_verified_number(), STOCKOUT_REPORT % {
                            'name': user.name,
                            'facility': supply_point.name,
                            'date':
                            datetime.datetime.utcnow().strftime('%b %d'),
                            'products': ", ".join(products)
                        })
Example #39
0
def answer_next_question(v, text, msg, session):
    resp = current_question(session.session_id, domain=v.domain)
    event = resp.event
    valid, text, error_msg = validate_answer(event, text, v)

    # metadata to be applied to the reply message
    outbound_metadata = MessageMetadata(
        workflow=session.workflow,
        reminder_id=session.reminder_id,
        xforms_session_couch_id=session._id,
    )

    if valid:
        responses = get_responses(v.domain, session.session_id, text)

        if has_invalid_response(responses):
            mark_as_invalid_response(msg)

        text_responses = _responses_to_text(responses)
        if len(text_responses) > 0:
            response_text = format_message_list(text_responses)
            send_sms_to_verified_number(v,
                                        response_text,
                                        metadata=outbound_metadata)
    else:
        mark_as_invalid_response(msg)
        response_text = "%s %s" % (error_msg, event.text_prompt)
        send_sms_to_verified_number(v,
                                    response_text,
                                    metadata=outbound_metadata)
Example #40
0
def form_session_handler(v, text, msg):
    """
    The form session handler will use the inbound text to answer the next question
    in the open SQLXformsSession for the associated contact. If no session is open,
    the handler passes. If multiple sessions are open, they are all closed and an
    error message is displayed to the user.
    """
    multiple, session = get_single_open_session_or_close_multiple(v.domain, v.owner_id)
    if multiple:
        send_sms_to_verified_number(v, get_message(MSG_MULTIPLE_SESSIONS, v))
        return True

    if session:
        # Metadata to be applied to the inbound message
        inbound_metadata = MessageMetadata(
            workflow=session.workflow,
            reminder_id=session.reminder_id,
            xforms_session_couch_id=session._id,
        )
        add_msg_tags(msg, inbound_metadata)

        try:
            answer_next_question(v, text, msg, session)
        except Exception:
            # Catch any touchforms errors
            log_sms_exception(msg)
            send_sms_to_verified_number(v, get_message(MSG_TOUCHFORMS_DOWN, v))
        return True
    else:
        return False
Example #41
0
def handle(verified_contact, text, msg=None):
    user = verified_contact.owner if verified_contact else None
    domain = user.domain
    if not domain:
        return False

    if not EWSGhanaConfig.for_domain(domain):
        return False

    args = text.split()
    if not args:
        send_sms_to_verified_number(verified_contact, unicode(INVALID_MESSAGE))
        return True
    keyword = args[0]
    args = args[1:]
    params = {
        'user': user,
        'domain': domain,
        'args': args,
        'msg': msg,
        'verified_contact': verified_contact
    }

    def not_function(word):
        if args and re.match("del", word):
            return NotDeliveredHandler
        elif args and re.match("sub", word):
            return NotSubmittedHandler
        return None

    handlers = {
        ('help', ): HelpHandler,
        ('stop', ): StopHandler,
        ('start', ): StartHandler,
        ('language', 'lang', 'lugha'): LanguageHandler,
        ('yes', 'no', 'y', 'n'): RequisitionHandler,
        ('undo', 'replace', 'revoke'): UndoHandler,
        ('soh',): AlertsHandler,
        ('not',): not_function(args[0]) if args else None,
        ('rec', 'receipts', 'received'): ReceiptsHandler
    }

    def choose_handler(keyword):
        for k, v in handlers.iteritems():
            if keyword.lower() in k:
                return v
        return None

    handler_class = choose_handler(keyword)
    handler = handler_class(**params) if handler_class else None

    if handler:
        if args:
            return handler.handle()
        else:
            handler.help()
            return True
    else:
        return AlertsHandler(**params).handle()
Example #42
0
def handle(verified_contact, text, msg=None):
    user = verified_contact.owner if verified_contact else None
    domain = user.domain
    if not domain:
        return False

    if not EWSGhanaConfig.for_domain(domain):
        return False

    args = text.split()
    if not args:
        send_sms_to_verified_number(verified_contact, unicode(INVALID_MESSAGE))
        return True
    keyword = args[0]
    args = args[1:]
    params = {
        'user': user,
        'domain': domain,
        'args': args,
        'msg': msg,
        'verified_contact': verified_contact
    }

    def not_function(word):
        if args and re.match("del", word):
            return NotDeliveredHandler
        elif args and re.match("sub", word):
            return NotSubmittedHandler
        return None

    handlers = {
        ('help', ): HelpHandler,
        ('stop', ): StopHandler,
        ('start', ): StartHandler,
        ('language', 'lang', 'lugha'): LanguageHandler,
        ('yes', 'no', 'y', 'n'): RequisitionHandler,
        ('undo', 'replace', 'revoke'): UndoHandler,
        ('soh', ): SOHHandler,
        ('not', ): not_function(args[0]) if args else None,
        ('rec', 'receipts', 'received'): ReceiptsHandler
    }

    def choose_handler(keyword):
        for k, v in handlers.iteritems():
            if keyword.lower() in k:
                return v
        return None

    handler_class = choose_handler(keyword)
    handler = handler_class(**params) if handler_class else None

    if handler:
        if args:
            return handler.handle()
        else:
            handler.help()
            return True
    else:
        return SOHHandler(**params).handle()
Example #43
0
 def send_message(self, sql_location, message, **kwargs):
     for user in get_users_by_location_id(self.domain,
                                          sql_location.location_id):
         verified_number = user.get_verified_number()
         if verified_number:
             with localize(user.get_language_code()):
                 send_sms_to_verified_number(verified_number,
                                             message % kwargs)
Example #44
0
 def respond(self, message, **kwargs):
     if self.verified_contact:
         with localize(self.user.get_language_code()):
             send_sms_to_verified_number(self.verified_contact,
                                         str(message % kwargs))
     else:
         send_sms(self.domain, None, self.msg.phone_number,
                  str(message % kwargs))
Example #45
0
def form_session_handler(v, text, msg):
    """
    The form session handler will use the inbound text to answer the next question
    in the open SQLXformsSession for the associated contact. If no session is open,
    the handler passes. If multiple sessions are open, they are all closed and an
    error message is displayed to the user.
    """
    with critical_section_for_smsforms_sessions(v.owner_id):
        if toggles.ONE_PHONE_NUMBER_MULTIPLE_CONTACTS.enabled(v.domain):
            channel = get_channel_for_contact(v.owner_id, v.phone_number)
            running_session_info = XFormsSessionSynchronization.get_running_session_info_for_channel(
                channel)
            if running_session_info.session_id:
                session = SQLXFormsSession.by_session_id(
                    running_session_info.session_id)
                if not session.session_is_open:
                    # This should never happen. But if it does we should set the channel free
                    # and act like there was no available session
                    notify_error(
                        "The supposedly running session was not open and was released. "
                        'No known way for this to happen, so worth investigating.'
                    )
                    XFormsSessionSynchronization.clear_stale_channel_claim(
                        channel)
                    session = None
            else:
                session = None
        else:
            multiple, session = get_single_open_session_or_close_multiple(
                v.domain, v.owner_id)
            if multiple:
                send_sms_to_verified_number(
                    v, get_message(MSG_MULTIPLE_SESSIONS, v))
                return True

        if session:
            session.phone_number = v.phone_number
            session.modified_time = datetime.utcnow()
            session.save()

            # Metadata to be applied to the inbound message
            inbound_metadata = MessageMetadata(
                workflow=session.workflow,
                reminder_id=session.reminder_id,
                xforms_session_couch_id=session._id,
            )
            add_msg_tags(msg, inbound_metadata)

            try:
                answer_next_question(v, text, msg, session)
            except Exception:
                # Catch any touchforms errors
                log_sms_exception(msg)
                send_sms_to_verified_number(
                    v, get_message(MSG_TOUCHFORMS_DOWN, v))
            return True
        else:
            return False
Example #46
0
def send_first_message(domain, recipient, phone_entry_or_number, session, responses, logged_subevent, workflow):
    # This try/except section is just here (temporarily) to support future refactors
    # If any of these notify, they should be replaced with a comment as to why the two are different
    # so that someone refactoring in the future will know that this or that param is necessary.
    try:
        if session.workflow != workflow:
            # see if we can eliminate the workflow arg
            notify_error('Exploratory: session.workflow != workflow', details={
                'session.workflow': session.workflow, 'workflow': workflow})
        if session.connection_id != recipient.get_id:
            # see if we can eliminate the recipient arg
            notify_error('Exploratory: session.connection_id != recipient.get_id', details={
                'session.connection_id': session.connection_id, 'recipient.get_id': recipient.get_id,
                'recipient': recipient
            })
        if session.related_subevent != logged_subevent:
            # see if we can eliminate the logged_subevent arg
            notify_error('Exploratory: session.related_subevent != logged_subevent', details={
                'session.connection_id': session.connection_id, 'logged_subevent': logged_subevent})
    except Exception:
        # The above running is not mission critical, so if it errors just leave a message in the log
        # for us to follow up on.
        # Absence of the message below and messages above ever notifying
        # will indicate that we can remove these args.
        notify_exception(None, "Error in section of code that's just supposed help inform future refactors")

    if toggles.ONE_PHONE_NUMBER_MULTIPLE_CONTACTS.enabled(domain):
        if not XFormsSessionSynchronization.claim_channel_for_session(session):
            send_first_message.apply_async(
                args=(domain, recipient, phone_entry_or_number, session, responses, logged_subevent, workflow),
                countdown=60
            )
            return

    metrics_counter('commcare.smsforms.session_started', 1, tags={'domain': domain, 'workflow': workflow})

    if len(responses) > 0:
        message = format_message_list(responses)
        metadata = MessageMetadata(
            workflow=workflow,
            xforms_session_couch_id=session.couch_id,
        )
        if isinstance(phone_entry_or_number, PhoneNumber):
            send_sms_to_verified_number(
                phone_entry_or_number,
                message,
                metadata,
                logged_subevent=logged_subevent
            )
        else:
            send_sms(
                domain,
                recipient,
                phone_entry_or_number,
                message,
                metadata
            )
    logged_subevent.completed()
Example #47
0
def first_soh_process_user(user, test=False):
    if user_has_reporting_location(user):
        if user.get_verified_number():
            message = STOCK_ON_HAND_REMINDER % {'name': user.name}
            if not test:
                send_sms_to_verified_number(user.get_verified_number(),
                                            message)
            else:
                send_test_message(user.get_verified_number(), message)
Example #48
0
def visit_website_process_user(user, test=False):
    date = datetime.datetime.utcnow() - datetime.timedelta(weeks=13)
    if user.last_login < date and user.get_verified_number():
        if not test:
            send_sms_to_verified_number(user.get_verified_number(),
                                        WEB_REMINDER % {'name': user.name})
        else:
            send_test_message(user.get_verified_number(),
                              WEB_REMINDER % {'name': user.name})
Example #49
0
def send_message_to_admins(user, message):
    users = get_users_by_location_id(user.domain, user.location.get_id)
    in_charge_users = [
        u
        for u in users
        if get_verified_number_for_recipient(u) and "In Charge" in u.user_data.get('role', [])
    ]
    for in_charge_user in in_charge_users:
        send_sms_to_verified_number(get_verified_number_for_recipient(in_charge_user),
                                    message % (in_charge_user.full_name, in_charge_user.location.name))
Example #50
0
def send_message_to_admins(user, message):
    users = get_users_by_location_id(user.domain, user.location.get_id)
    in_charge_users = [
        u for u in users if u.get_verified_number()
        and "In Charge" in u.user_data.get('role', [])
    ]
    for in_charge_user in in_charge_users:
        send_sms_to_verified_number(
            in_charge_user.get_verified_number(),
            message % (in_charge_user.full_name, in_charge_user.location.name))
Example #51
0
    def _send_delivery_alert_to_facilities(self, location):
        locs = [c.get_id for c in location.children]
        users = []
        for location_id in locs:
            users.extend(get_users_by_location_id(self.domain, location_id))

        for user in users:
            if user.get_verified_number():
                send_sms_to_verified_number(user.get_verified_number(), DELIVERY_CONFIRM_CHILDREN %
                                            {"district_name": location.name})
Example #52
0
def send_keyword_response(vn, message_id, logged_event):
    subevent = logged_event.create_subevent_for_single_sms(
        vn.owner_doc_type, vn.owner_id)
    metadata = MessageMetadata(
        workflow=WORKFLOW_KEYWORD,
        messaging_subevent_id=subevent.pk,
    )
    message = get_message(message_id, vn)
    send_sms_to_verified_number(vn, message, metadata=metadata)
    subevent.completed()
Example #53
0
    def send_sms_message(self, domain, recipient, phone_entry_or_number, message, logged_subevent):
        if not message:
            return

        metadata = self.get_sms_message_metadata(logged_subevent)

        if isinstance(phone_entry_or_number, PhoneNumber):
            send_sms_to_verified_number(phone_entry_or_number, message, metadata=metadata,
                logged_subevent=logged_subevent)
        else:
            send_sms(domain, recipient, phone_entry_or_number, message, metadata=metadata)
Example #54
0
def send_soh_reminder(domain, date):
    sp_ids = set()
    for user in CommTrackUser.by_domain(domain):
        if user.is_active and user.location and user.location.location_type == 'FACILITY':
            sp = SupplyPointCase.get_by_location(user.location)
            if sp and not StockTransaction.objects.filter(case_id=sp._id, report__date__gte=date,
                                                          type='stockonhand').exists():
                if user.get_verified_number():
                        send_sms_to_verified_number(user.get_verified_number(), REMINDER_STOCKONHAND)
                        sp_ids.add(sp._id)
    update_statuses(sp_ids, SupplyPointStatusTypes.SOH_FACILITY, SupplyPointStatusValues.REMINDER_SENT)
Example #55
0
def send_soh_reminder(domain, date):
    sp_ids = set()
    for user in CommTrackUser.by_domain(domain):
        if user.is_active and user.location and user.location.location_type == 'FACILITY':
            sp = SupplyPointCase.get_by_location(user.location)
            if sp and not StockTransaction.objects.filter(case_id=sp._id, report__date__gte=date,
                                                          type='stockonhand').exists():
                if user.get_verified_number():
                        send_sms_to_verified_number(user.get_verified_number(), REMINDER_STOCKONHAND)
                        sp_ids.add(sp._id)
    update_statuses(sp_ids, SupplyPointStatusTypes.SOH_FACILITY, SupplyPointStatusValues.REMINDER_SENT)
Example #56
0
def send_supervision_reminder(domain, date):
    sp_ids = set()
    for user in CommTrackUser.by_domain(domain):
        if user.is_active and user.location and user.location.location_type == 'FACILITY':
            sp = SupplyPointCase.get_by_location(user.location)
            if sp and not SupplyPointStatus.objects.filter(supply_point=sp._id,
                                                           status_type=SupplyPointStatusTypes.SUPERVISION_FACILITY,
                                                           status_date__gte=date).exists():
                if user.get_verified_number():
                        send_sms_to_verified_number(user.get_verified_number(), REMINDER_SUPERVISION)
                        sp_ids.add(sp._id)
    update_statuses(sp_ids, SupplyPointStatusTypes.SUPERVISION_FACILITY, SupplyPointStatusValues.REMINDER_SENT)
Example #57
0
def send_keyword_response(vn, message_id, logged_event):
    subevent = logged_event.create_subevent_for_single_sms(
        vn.owner_doc_type,
        vn.owner_id
    )
    metadata = MessageMetadata(
        workflow=WORKFLOW_KEYWORD,
        messaging_subevent_id=subevent.pk,
    )
    message = get_message(message_id, vn)
    send_sms_to_verified_number(vn, message, metadata=metadata)
    subevent.completed()
Example #58
0
def fire_sms_event(reminder, handler, recipients, verified_numbers, logged_event, workflow=None):
    current_event = reminder.current_event
    case = reminder.case
    template_params = get_message_template_params(case)

    uses_custom_content_handler, content_handler = get_custom_content_handler(handler, logged_event)
    if uses_custom_content_handler and not content_handler:
        return

    domain_obj = Domain.get_by_name(reminder.domain, strict=True)
    for recipient in recipients:
        logged_subevent = logged_event.create_subevent(handler, reminder, recipient)

        try:
            lang = recipient.get_language_code()
        except Exception:
            lang = None

        if content_handler:
            message = content_handler(reminder, handler, recipient)
        else:
            message = current_event.message.get(lang, current_event.message[handler.default_lang])
            try:
                message = Message.render(message, **template_params)
            except Exception:
                logged_subevent.error(MessagingEvent.ERROR_CANNOT_RENDER_MESSAGE)
                continue

        verified_number, unverified_number = get_recipient_phone_number(
            reminder, recipient, verified_numbers)

        if message:
            metadata = MessageMetadata(
                workflow=workflow or get_workflow(handler),
                reminder_id=reminder._id,
                messaging_subevent_id=logged_subevent.pk,
            )
            if verified_number is not None:
                send_sms_to_verified_number(verified_number,
                    message, metadata, logged_subevent=logged_subevent)
            elif isinstance(recipient, CouchUser) and unverified_number:
                send_sms(reminder.domain, recipient, unverified_number,
                    message, metadata)
            elif (is_commcarecase(recipient) and unverified_number and
                    domain_obj.send_to_duplicated_case_numbers):
                send_sms(reminder.domain, recipient, unverified_number,
                    message, metadata)
            else:
                logged_subevent.error(MessagingEvent.ERROR_NO_PHONE_NUMBER)
                continue

        logged_subevent.completed()
Example #59
0
def reminder_to_visit_website():
    domains = EWSGhanaConfig.get_all_enabled_domains()
    for domain in domains:
        for user in CommCareUser.by_domain(domain):
            thirteen_days_ago = datetime.datetime.utcnow() - datetime.timedelta(weeks=13)
            if user.location and user.last_login < thirteen_days_ago and user.get_verified_number()\
                    and user.location.location_type.name in ['district', 'region', 'country']:
                    message = WEB_REMINDER % user.name
                    verified_number = user.get_verified_number()
                    send_sms_to_verified_number(verified_number, message)
                    if can_receive_email(user, verified_number):
                        email = str(user.email)
                        send_mail('REMINDER TO VISIT WEBSITE', message, '*****@*****.**', [email])
Example #60
0
def global_keyword_current(v, text, msg, text_words, open_sessions):
    if len(open_sessions) == 1:
        session = open_sessions[0]
        outbound_metadata = MessageMetadata(
            workflow=session.workflow,
            reminder_id=session.reminder_id,
            xforms_session_couch_id=session._id,
        )
        
        resp = current_question(session.session_id)
        send_sms_to_verified_number(v, resp.event.text_prompt,
            metadata=outbound_metadata)
    return True