Example #1
0
    def setUp(self):
        super(TestApp, self).setUp()
        type, _ = LocationType.objects.get_or_create(singular="clinic", 
                                                     plural="clinics", 
                                                     slug="clinics")
        clinic = Location.objects.create(type=type, name="demo", slug="demo") 
        self.clinic_zone= Location.objects.create(type=get_zone_type(), name="child", 
                                             slug="child", parent=clinic) 
        clinic_worker = self.create_contact(name="clinic_worker", location=clinic, 
                                            types=[get_clinic_worker_type()])
        clinic_worker2 = self.create_contact(name="clinic_worker2", location=self.clinic_zone,
                                             types=[get_clinic_worker_type()])
        
#        script = "help_admin > hello world"
#        self.runScript(script)
#        connection = Connection.objects.get(identity="help_admin")
#        help_admin = Contact.objects.create(alias='help_admin', is_active = True, name="help_admin",
#                                         location=clinic_zone,is_help_admin = True)
#        help_admin.types.add(const.get_clinic_worker_type())
#                                
#        connection.contact = help_admin
#        connection.save()
        
        cba = self.create_contact(name="cba", location=clinic,
                                  types=[get_cba_type()])
        cba2 = self.create_contact(name="cba2", location=self.clinic_zone,
                                   types=[get_cba_type()])
        active_contacts = Contact.active.all()
        
        self.all = [clinic_worker, clinic_worker2, cba, cba2]
        self.expected_keyword_to_groups = \
            {"ALL":    [clinic_worker, clinic_worker2, cba, cba2],
             "CLINIC": [clinic_worker, clinic_worker2],
             "CBA":    [cba, cba2],
             }
Example #2
0
    def setUp(self):
        super(TestApp, self).setUp()
        type, _ = LocationType.objects.get_or_create(singular="clinic",
                                                     plural="clinics",
                                                     slug="clinics")
        district_type, _ = LocationType.objects.get_or_create(
            singular="district", plural="districts", slug="districts")
        self.district = Location.objects.create(type=district_type,
                                                name="Mansa",
                                                slug="403000")
        self.district2 = Location.objects.create(type=district_type,
                                                 name="Lusaka",
                                                 slug="402000")
        clinic = Location.objects.create(type=type,
                                         name="Central Clinic",
                                         slug="403020")
        clinic.parent = self.district
        clinic.save()
        self.clinic2 = Location.objects.create(type=type,
                                               name="Other Clinic",
                                               slug="402020")
        self.clinic2.parent = self.district2
        self.clinic2.save()

        self.clinic_zone = Location.objects.create(type=get_zone_type(),
                                                   name="child",
                                                   slug="child",
                                                   parent=clinic)

        clinic_worker = self.create_contact(name="clinic_worker",
                                            location=clinic,
                                            types=[get_clinic_worker_type()])
        clinic_worker2 = self.create_contact(name="clinic_worker2",
                                             location=clinic,
                                             types=[get_clinic_worker_type()])

        cba = self.create_contact(name="cba",
                                  location=self.clinic_zone,
                                  types=[get_cba_type()])
        cba2 = self.create_contact(name="cba2",
                                   location=self.clinic_zone,
                                   types=[get_cba_type()])
        active_contacts = Contact.active.all()

        self.all = [clinic_worker, clinic_worker2, cba, cba2]
        self.expected_keyword_to_groups = \
            {"ALL":    [clinic_worker, clinic_worker2, cba, cba2],
             "CLINIC": [clinic_worker, clinic_worker2],
             "CBA":    [cba, cba2],
             }
Example #3
0
    def handle(self, text):
        if self.msg.contact is None or \
           self.msg.contact.location is None:
            self.respond(UNREGISTERED)
            return

        location = get_clinic_or_default(self.msg.contact)
        contacts = Contact.active.location(location)\
                        .exclude(id=self.msg.contact.id)\
                        .filter(types=get_cba_type())
        return self.broadcast(text, contacts)
Example #4
0
    def setUp(self):
        super(TestApp, self).setUp()
        type, _ = LocationType.objects.get_or_create(singular="clinic", 
                                                     plural="clinics", 
                                                     slug="clinics")
        district_type, _ = LocationType.objects.get_or_create(singular="district",
                                                     plural="districts",
                                                     slug="districts")
        self.district = Location.objects.create(type=district_type, name="Mansa", slug="403000")
        self.district2 = Location.objects.create(type=district_type, name="Lusaka", slug="402000")
        clinic = Location.objects.create(type=type, name="Central Clinic", slug="403020")
        clinic.parent = self.district
        clinic.save()
        self.clinic2 = Location.objects.create(type=type, name="Other Clinic", slug="402020")
        self.clinic2.parent = self.district2
        self.clinic2.save()

        self.clinic_zone= Location.objects.create(type=get_zone_type(), name="child", 
                                             slug="child", parent=clinic) 
        
        clinic_worker = self.create_contact(name="clinic_worker", location=clinic,
                                            types=[get_clinic_worker_type()])
        clinic_worker2 = self.create_contact(name="clinic_worker2", location=clinic,
                                             types=[get_clinic_worker_type()])
        

        
        cba = self.create_contact(name="cba", location=self.clinic_zone,
                                  types=[get_cba_type()])
        cba2 = self.create_contact(name="cba2", location=self.clinic_zone,
                                   types=[get_cba_type()])
        active_contacts = Contact.active.all()
        
        self.all = [clinic_worker, clinic_worker2, cba, cba2]
        self.expected_keyword_to_groups = \
            {"ALL":    [clinic_worker, clinic_worker2, cba, cba2],
             "CLINIC": [clinic_worker, clinic_worker2],
             "CBA":    [cba, cba2],
             }
Example #5
0
    def handle(self, text):
        b = InputCleaner()
        if not is_eligible_for_results(self.msg.connection):
            # essentially checking for an active clinic_worker
            self.respond(self.INELIGIBLE)
            return

        text = text.strip()
        text = b.remove_double_spaces(text)
        location = self.msg.contact.location
        if location.type == const.get_zone_type():
            location = location.parent
        cba = None

        if text[1:].isdigit() and len(text) >= self.MIN_PHONE_LENGTH:
            try:
                cba = \
                Contact.active.get(connection__identity__icontains=text,
                                   location__parent=location,
                                   types=const.get_cba_type())
            except Contact.DoesNotExist:
                self.respond('The phone number %(phone)s does not belong to any'
                             + ' CBA at %(clinic)s. Make sure you typed it '
                             + 'correctly', phone=text, clinic=location)
            except Contact.MultipleObjectsReturned:
                logger.warning("Bug. phone number %s is used by multiple cba's "
                +"at same clinic" % text)
                return

        if not cba:
            cbas = \
            Contact.active.filter(name__icontains=text,
                                  location__parent=location,
                                  types=const.get_cba_type())
            if not cbas:
                self.respond('The name %(name)s does not belong to any'
                             + ' CBA at %(clinic)s. Make sure you typed it '
                             + 'correctly', name=text,
                             clinic=location)
                return
            if len(cbas) == 1:
                cba = cbas[0]
            elif len(cbas) < 5:
                self.respond("Try sending DEREGISTER <CBA_PHONE_NUMBER>. Which "
                             + "CBA did you mean? %(cbas)s", cbas=' or '.join(
                             cba.name + ":" + cba.default_connection.identity
                             for cba in cbas))
                return
            else:
                self.respond("There are %(len)s CBA's who's names match %(name)s"
                             + " at %(clinic)s. Try to use the phone number "
                             + "instead", len=len(cbas), name=text,
                             clinic=location.name)
                return
        if cba:
            cba.is_active = False
            cba.save()
            self.respond("You have successfully deregistered %(name)s:"
                         + "%(phone)s of zone %(zone)s at %(clinic)s",
                         name=cba.name, phone=cba.default_connection.identity,
                         zone=cba.location.name, clinic=location.name)
            worker = self.msg.contact
            for help_admin in Contact.active.filter(is_help_admin=True):
                OutgoingMessage(
                                help_admin.default_connection,
                                "%s:%s has deregistered %s:%s of zone %s at %s" %
                                (worker.name,
                                worker.default_connection.identity,
                                cba.name,
                                cba.default_connection.identity,
                                cba.location.name,
                                location.name
                                )).send()
Example #6
0
    def handle(self, text):
        if self.msg.contact is None or self.msg.contact.location is None:
            self.respond(UNREGISTERED)
            return

        location = get_clinic_or_default(self.msg.contact)
        contacts = Contact.active.location(location).exclude(id=self.msg.contact.id).filter(types=get_cba_type())
        return self.broadcast(text, contacts)
Example #7
0
 def testSendReminders(self):
     birth = reminders.Event.objects.create(name="Birth", slug="birth",
                                            gender="f")
     birth.appointments.create(name='2 day', num_days=2)
     birth.appointments.create(name='3 day', num_days=3)
     birth.appointments.create(name='4 day', num_days=4)
     clinic = LocationType.objects.create(slug=const.CLINIC_SLUGS[0])
     zone = const.get_zone_type()
     central = Location.objects.create(name='Central Clinic', type=clinic)
     zone1 = Location.objects.create(name='Zone 1', type=zone,
                                     parent=central, slug='zone1')
     zone2 = Location.objects.create(name='Zone 2', type=zone,
                                     parent=central, slug='zone2')
     patient1 = Contact.objects.create(name='patient 1', location=zone1)
     patient2 = Contact.objects.create(name='patient 2', location=zone1)
     patient3 = Contact.objects.create(name='patient 3', location=zone2)
     
     # this gets the backend and connection in the db
     self.runScript("""
     cba1 > hello world
     cba2 > hello world
     """)
     # take a break to allow the router thread to catch up; otherwise we
     # get some bogus messages when they're retrieved below
     time.sleep(.1)
     cba_t = const.get_cba_type()
     cba1_conn = Connection.objects.get(identity="cba1")
     cba1 = Contact.objects.create(name='cba1', location=zone1)
     cba1.types.add(cba_t)
     cba1_conn.contact = cba1
     cba1_conn.save()
     cba2_conn = Connection.objects.get(identity="cba2")
     cba2 = Contact.objects.create(name='cba2', location=zone2)
     cba2.types.add(cba_t)
     cba2_conn.contact = cba2
     cba2_conn.save()
     birth.patient_events.create(patient=patient1, cba_conn=cba1_conn,
                                 date=datetime.datetime.today())
     birth.patient_events.create(patient=patient2, cba_conn=cba1_conn,
                                 date=datetime.datetime.today())
     birth.patient_events.create(patient=patient3, cba_conn=cba2_conn,
                                 date=datetime.datetime.today())
     self.startRouter()
     tasks.send_notifications(self.router)
     # just the 1 and two day notifications should go out;
     # 3 patients x 2 notifications = 6 messages
     messages = self.receiveAllMessages()
     expected_messages =\
         ['Hello cba1. patient 1 is due for their 2 day clinic appointment. '
          'Please remind this person and ensure they '
          'visit Central Clinic within 3 days.',
          'Hello cba1. patient 2 is due for their 2 day clinic appointment. '
          'Please remind this person and ensure they '
          'visit Central Clinic within 3 days.',
          'Hello cba2. patient 3 is due for their 2 day clinic appointment. '
          'Please remind this person and ensure they '
          'visit Central Clinic within 3 days.']
     self.assertEqual(len(messages), len(expected_messages))
     for msg in messages:
         self.assertTrue(msg.text in expected_messages, msg)
     sent_notifications = reminders.SentNotification.objects.all()
     self.assertEqual(sent_notifications.count(), len(expected_messages))
Example #8
0
    def testSendReminders(self):
        birth = reminders.Event.objects.create(name="Birth",
                                               slug="birth",
                                               gender="f")
        birth.appointments.create(name='2 day', num_days=2)
        birth.appointments.create(name='3 day', num_days=3)
        birth.appointments.create(name='4 day', num_days=4)
        clinic = LocationType.objects.create(slug=const.CLINIC_SLUGS[0])
        zone = const.get_zone_type()
        central = Location.objects.create(name='Central Clinic', type=clinic)
        zone1 = Location.objects.create(name='Zone 1',
                                        type=zone,
                                        parent=central,
                                        slug='zone1')
        zone2 = Location.objects.create(name='Zone 2',
                                        type=zone,
                                        parent=central,
                                        slug='zone2')
        patient1 = Contact.objects.create(name='patient 1', location=zone1)
        patient2 = Contact.objects.create(name='patient 2', location=zone1)
        patient3 = Contact.objects.create(name='patient 3', location=zone2)

        # this gets the backend and connection in the db
        self.runScript("""
        cba1 > hello world
        cba2 > hello world
        """)
        # take a break to allow the router thread to catch up; otherwise we
        # get some bogus messages when they're retrieved below
        time.sleep(.1)
        cba_t = const.get_cba_type()
        cba1_conn = Connection.objects.get(identity="cba1")
        cba1 = Contact.objects.create(name='cba1', location=zone1)
        cba1.types.add(cba_t)
        cba1_conn.contact = cba1
        cba1_conn.save()
        cba2_conn = Connection.objects.get(identity="cba2")
        cba2 = Contact.objects.create(name='cba2', location=zone2)
        cba2.types.add(cba_t)
        cba2_conn.contact = cba2
        cba2_conn.save()
        birth.patient_events.create(patient=patient1,
                                    cba_conn=cba1_conn,
                                    date=datetime.datetime.today())
        birth.patient_events.create(patient=patient2,
                                    cba_conn=cba1_conn,
                                    date=datetime.datetime.today())
        birth.patient_events.create(patient=patient3,
                                    cba_conn=cba2_conn,
                                    date=datetime.datetime.today())
        self.startRouter()
        tasks.send_notifications(self.router)
        # just the 1 and two day notifications should go out;
        # 3 patients x 2 notifications = 6 messages
        messages = self.receiveAllMessages()
        expected_messages =\
            ['Hello cba1. patient 1 is due for their 2 day clinic appointment. '
             'Please remind this person and ensure they '
             'visit Central Clinic within 3 days.',
             'Hello cba1. patient 2 is due for their 2 day clinic appointment. '
             'Please remind this person and ensure they '
             'visit Central Clinic within 3 days.',
             'Hello cba2. patient 3 is due for their 2 day clinic appointment. '
             'Please remind this person and ensure they '
             'visit Central Clinic within 3 days.']
        self.assertEqual(len(messages), len(expected_messages))
        for msg in messages:
            self.assertTrue(msg.text in expected_messages, msg)
        sent_notifications = reminders.SentNotification.objects.all()
        self.assertEqual(sent_notifications.count(), len(expected_messages))
Example #9
0
    def handle(self, text):
        b = InputCleaner()
        if not is_eligible_for_results(self.msg.connection):
            # essentially checking for an active clinic_worker
            self.respond(self.INELIGIBLE)
            return

        text = text.strip()
        text = b.remove_double_spaces(text)
        worker = self.msg.contact
        location = worker.location
        if location.type == const.get_zone_type():
            location = location.parent
        cba = None

        # we expect phone numbers like +260977123456, 0977123456, 977123456
        # (a phone number is unique to each cba at a clinic)
        if text[1:].isdigit() and len(text) >= self.MIN_PHONE_LENGTH:
            try:
                cba = \
                Contact.active.get(connection__identity__endswith=text,
                                   location__parent=location,
                                   types=const.get_cba_type())
            except Contact.DoesNotExist:
                self.respond('The phone number %(phone)s does not belong to any'
                             ' CBA at %(clinic)s. Make sure you typed it '
                             'correctly', phone=text, clinic=location)
            # we do not expect this to happen. phone number is excpected to be
            # unique (>=9 chars) project wide
            except Contact.MultipleObjectsReturned:
                logger.warning("Bug. phone number %s is used by multiple cba's "
                               "at same clinic" % text)

                self.respond("Sorry %(name)s, the CBA with phone number %(phone)s"
                             " could not be deregistered. This matter will be"
                             " followed up by Support Staff immediately",
                             name=worker.name, phone=text)

                msg = (self.FOLLOWUP_MESSAGE % (text, worker.name,
                       worker.default_connection.identity,
                       location.name))
                self.notify_help_admins(msg)
                return

        if not cba:
            cbas = \
            Contact.active.filter(name__icontains=text,
                                  location__parent=location,
                                  types=const.get_cba_type())
            if not cbas:
                self.respond('The name %(name)s does not belong to any'
                             ' CBA at %(clinic)s. Make sure you typed it '
                             'correctly', name=text,
                             clinic=location)
                return
            if len(cbas) == 1:
                cba = cbas[0]
            elif len(cbas) < 5:
                self.respond("Try sending REMOVE <CBA_PHONE_NUMBER>. Which "
                             + "CBA did you mean? %(cbas)s", cbas=' or '.join(
                             cba.name + ":" + cba.default_connection.identity
                             for cba in cbas))
                return
            else:
                self.respond("There are %(len)s CBA's who's names match %(name)s"
                             + " at %(clinic)s. Try to use the phone number "
                             + "instead", len=len(cbas), name=text,
                             clinic=location.name)
                return
        if cba:
            cba.is_active = False
            cba.save()
            self.respond("You have successfully deregistered %(name)s:"
                         + "%(phone)s of zone %(zone)s at %(clinic)s",
                         name=cba.name, phone=cba.default_connection.identity,
                         zone=cba.location.name, clinic=location.name)
            msg = ("%s:%s has deregistered %s:%s of zone %s at %s" %
                   (worker.name,
                   worker.default_connection.identity,
                   cba.name,
                   cba.default_connection.identity,
                   cba.location.name,
                   location.name))
            self.notify_help_admins(msg)
Example #10
0
 def handle(self, text):
     m = self.PATTERN.search(text)
     if m is not None:
         clinic_slug = m.group('clinic').strip()
         zone_slug = m.group('zone').strip()
         name = m.group('name').strip().title()
         # require the clinic to be pre-populated
         try:
             clinic = Location.objects.get(slug__iexact=clinic_slug,
                                          type__slug__in=const.CLINIC_SLUGS)
         except Location.DoesNotExist:
             self.respond(_("Sorry, I don't know about a clinic with code "
                          "%(code)s. Please check your code and try again."),
                          code=clinic_slug)
             return
         zone = self._get_or_create_zone(clinic, zone_slug)
         contact_clinic, contact_zone =\
           self._get_clinic_and_zone(self.msg.contact)
         
         if contact_zone == zone:
             # don't let agents register twice for the same zone
             self.respond(_("Hello %(name)s! You are already registered as "
                          "a RemindMi Agent for zone %(zone)s of %(clinic)s."), 
                          name=self.msg.contact.name, zone=zone.name,
                          clinic=clinic.name)
             return
         elif contact_clinic and contact_clinic != clinic:
             # force agents to leave if they appear to be switching clinics
             self.respond(_("Hello %(name)s! You are already registered as "
                          "a RemindMi Agent for %(old_clinic)s. To leave "
                          "your current clinic and join %(new_clinic)s, "
                          "reply with LEAVE and then re-send your message."),
                          name=self.msg.contact.name,
                          old_clinic=contact_clinic.name,
                          new_clinic=clinic.name)
             return
         elif self.msg.contact:
             # if the contact exists but wasn't registered at a location,
             # or was registered at the clinic level instead of the zone
             # level, update the record and save it
             cba = self.msg.contact
             cba.name = name
             cba.location = zone
             cba.save()
         else:
             # lastly, if no contact exists, create one and save it in the
             # connection
             cba = Contact.objects.create(name=name, location=zone)
             self.msg.connection.contact = cba
             self.msg.connection.save()
         if not cba.types.filter(slug=const.CLINIC_WORKER_SLUG).count():
             cba.types.add(const.get_cba_type())
         msg = self.respond(_("Thank you %(name)s! You have successfully "
                              "registered as a RemindMi Agent for zone "
                              "%(zone)s of %(clinic)s."), name=cba.name,
                              zone=zone.name, clinic=clinic.name)
         notify_text, kwargs = self._get_notify_text()
         if notify_text:
             msg.append(notify_text, **kwargs)
     else:
         msg = self.respond(_("Sorry, I didn't understand that."))
         msg.append(self.HELP_TEXT)
Example #11
0
    def handle(self, text):
        b = InputCleaner()
        if not is_eligible_for_results(self.msg.connection):
            # essentially checking for an active clinic_worker
            self.respond(self.INELIGIBLE)
            return

        text = text.strip()
        text = b.remove_double_spaces(text)
        worker = self.msg.contact
        location = worker.location
        if location.type == const.get_zone_type():
            location = location.parent
        cba = None

        # we expect phone numbers like +260977123456, 0977123456, 977123456
        # (a phone number is unique to each cba at a clinic)
        if text[1:].isdigit() and len(text) >= self.MIN_PHONE_LENGTH:
            try:
                cba = \
                Contact.active.get(connection__identity__endswith=text,
                                   location__parent=location,
                                   types=const.get_cba_type())
            except Contact.DoesNotExist:
                self.respond(
                    'The phone number %(phone)s does not belong to any'
                    ' CBA at %(clinic)s. Make sure you typed it '
                    'correctly',
                    phone=text,
                    clinic=location)
            # we do not expect this to happen. phone number is excpected to be
            # unique (>=9 chars) project wide
            except Contact.MultipleObjectsReturned:
                logger.warning(
                    "Bug. phone number %s is used by multiple cba's "
                    "at same clinic" % text)

                self.respond(
                    "Sorry %(name)s, the CBA with phone number %(phone)s"
                    " could not be deregistered. This matter will be"
                    " followed up by Support Staff immediately",
                    name=worker.name,
                    phone=text)

                msg = (self.FOLLOWUP_MESSAGE %
                       (text, worker.name, worker.default_connection.identity,
                        location.name))
                self.notify_help_admins(msg)
                return

        if not cba:
            cbas = \
            Contact.active.filter(name__icontains=text,
                                  location__parent=location,
                                  types=const.get_cba_type())
            if not cbas:
                self.respond(
                    'The name %(name)s does not belong to any'
                    ' CBA at %(clinic)s. Make sure you typed it '
                    'correctly',
                    name=text,
                    clinic=location)
                return
            if len(cbas) == 1:
                cba = cbas[0]
            elif len(cbas) < 5:
                self.respond("Try sending REMOVE <CBA_PHONE_NUMBER>. Which " +
                             "CBA did you mean? %(cbas)s",
                             cbas=' or '.join(cba.name + ":" +
                                              cba.default_connection.identity
                                              for cba in cbas))
                return
            else:
                self.respond(
                    "There are %(len)s CBA's who's names match %(name)s" +
                    " at %(clinic)s. Try to use the phone number " + "instead",
                    len=len(cbas),
                    name=text,
                    clinic=location.name)
                return
        if cba:
            cba.is_active = False
            cba.save()
            self.respond("You have successfully deregistered %(name)s:" +
                         "%(phone)s of zone %(zone)s at %(clinic)s",
                         name=cba.name,
                         phone=cba.default_connection.identity,
                         zone=cba.location.name,
                         clinic=location.name)
            msg = ("%s:%s has deregistered %s:%s of zone %s at %s" %
                   (worker.name, worker.default_connection.identity, cba.name,
                    cba.default_connection.identity, cba.location.name,
                    location.name))
            self.notify_help_admins(msg)
Example #12
0
    def handle(self, text):
        m = self.PATTERN.search(text)
        if m is not None:
            clinic_slug = m.group('clinic').strip()
            zone_slug = m.group('zone').strip()
            name = m.group('name').strip().title()
            # require the clinic to be pre-populated
            try:
                clinic = Location.objects.get(
                    slug__iexact=clinic_slug,
                    type__slug__in=const.CLINIC_SLUGS)
            except Location.DoesNotExist:
                self.respond(_(
                    "Sorry, I don't know about a clinic with code "
                    "%(code)s. Please check your code and try again."),
                             code=clinic_slug)
                return
            zone = self._get_or_create_zone(clinic, zone_slug)
            contact_clinic, contact_zone =\
              self._get_clinic_and_zone(self.msg.contact)

            if contact_zone == zone:
                # don't let agents register twice for the same zone
                self.respond(_(
                    "Hello %(name)s! You are already registered as "
                    "a RemindMi Agent for zone %(zone)s of %(clinic)s."),
                             name=self.msg.contact.name,
                             zone=zone.name,
                             clinic=clinic.name)
                return
            elif contact_clinic and contact_clinic != clinic:
                # force agents to leave if they appear to be switching clinics
                self.respond(_(
                    "Hello %(name)s! You are already registered as "
                    "a RemindMi Agent for %(old_clinic)s. To leave "
                    "your current clinic and join %(new_clinic)s, "
                    "reply with LEAVE and then re-send your message."),
                             name=self.msg.contact.name,
                             old_clinic=contact_clinic.name,
                             new_clinic=clinic.name)
                return
            elif self.msg.contact:
                # if the contact exists but wasn't registered at a location,
                # or was registered at the clinic level instead of the zone
                # level, update the record and save it
                cba = self.msg.contact
                cba.name = name
                cba.location = zone
                cba.save()
            else:
                # lastly, if no contact exists, create one and save it in the
                # connection
                cba = Contact.objects.create(name=name, location=zone)
                self.msg.connection.contact = cba
                self.msg.connection.save()
            if not cba.types.filter(slug=const.CLINIC_WORKER_SLUG).count():
                cba.types.add(const.get_cba_type())
            msg = self.respond(_("Thank you %(name)s! You have successfully "
                                 "registered as a RemindMi Agent for zone "
                                 "%(zone)s of %(clinic)s."),
                               name=cba.name,
                               zone=zone.name,
                               clinic=clinic.name)
            notify_text, kwargs = self._get_notify_text()
            if notify_text:
                msg.append(notify_text, **kwargs)
        else:
            msg = self.respond(_("Sorry, I didn't understand that."))
            msg.append(self.HELP_TEXT)