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], }
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], }
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)
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], }
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()
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)
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))
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)
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)
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)
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)