Exemplo n.º 1
0
def send_message(request):
    from django import forms
    from bolibana.models import Provider
    from nosmsd.utils import send_sms

    class MessageForm(forms.Form):
        number = forms.CharField(label=(u"Numéro"))
        text = forms.CharField(widget=forms.Textarea(), label=(u"Texte"))

        def clean_text(self):
            return self.cleaned_data.get('text')[:150]

    form = MessageForm()

    providers = Provider.objects.filter(phone_number__isnull=False)
    all_providers = []
    for pr in providers:
        all_providers.append(("%s %s %s" % (pr.name(), pr.first_access(), \
                                            pr.phone_number), pr.phone_number))
        if pr.phone_number_extra:
            all_providers.append(("%s %s %s" % (pr.name(), pr.first_access(), \
                             pr.phone_number_extra), pr.phone_number_extra))

    if request.method == "POST":
        form = MessageForm(request.POST)
        if form.is_valid():
            send_sms(form.cleaned_data.get('number'),
                     form.cleaned_data.get('text'))
            messages.success(request, (u"SMS envoié"))
            return redirect("log_message")

    context = {'form': form, 'all_providers': all_providers}
    return render(request, 'send_message.html', context)
Exemplo n.º 2
0
def nut_service(recipients, flag, text):
    """ Server to client alert, notice messages

    Whenever central wants to send a text message to the users.
    Messages have a flag for INFO, WARN, SUCC, CRIT.

    recipients: Provider

    < nut service flag | message """

    msg = u"nut service %(flag)s|%(text)s" % {'flag': flag, 'text': text}

    for recipient in recipients:
        if isinstance(recipient, basestring):
            ph = recipient
        else:
            if hasattr(recipient, 'phone_number'):
                ph = recipient.phone_number
            else:
                print(u"Unable to send SMS to recipient: %s" \
                             % (recipient))
                continue
        send_sms(ph, msg)

    return 
Exemplo n.º 3
0
    def action(self):
        """ Send every reporter with an action left to do a reminder """

        today = date.today()

        level = self.args.level
        if not level:
            return False

        logger.info(u"Level: %s" % level)

        if level == 'cscom':
            message = u"[PNLP] Votre rapport mensuel paludisme est " \
                      u"attendu au plus tard le %(date)s" \
                      % {'date': date(today.year, \
                                      today.month, 5).strftime('%x')}
            for cscom in mobile_entity_gen(cscom_without_report(self.args.period)):
                contact = contact_for(cscom, recursive=False)
                if not contact or not contact.phone_number:
                    continue
                # CSCOM: only cellphone transmiting ones.
                if not cscom.parent.slug in ('nion', 'maci'):
                    continue

                logger.info(u"Sending cscom text to %s" % contact.phone_number)
                send_sms(to=contact.phone_number, text=message)

            # end of CSCom section
            return

        for stat in level_statistics(self.args.period, level).values():

            contact = contact_for(stat['entity'], recursive=False)

            if not contact or not contact.phone_number:
                continue

            # nothing waiting validation.
            if not stat['unval']:
                continue

            logger.info(u"Sending %s text to %s" \
                        % (level, contact.phone_number))

            dom = 15 if level == 'district' else 25

            message = u"[PNLP] Vous avez %(unval)d rapports a valider " \
                      u"au plus tard le %(date)s." \
                      % {'unval': stat['unval'], \
                         'date': date(today.year, \
                                      today.month, dom).strftime('%x')}
            email_title = u"[PNLP] Rapports a valider"
            # send_sms(to=contact.phone_number, text=message)
            if not contact.email:
                continue
            sent, sent_message = send_email(recipients=contact.email,
                       message=message, title=email_title)
Exemplo n.º 4
0
    def action(self):
        """ send SMS to non-sender and to districts

            Non-sending CSCom will receive a message saying they missed.
            District will be reminded they have reports to validate
            and non-sending cscom if applicable """

        # send an SMS to non-reporting CSCOM.
        message = u"[PNLP] Vous n'avez pas envoye votre rapport mensuel." \
                    " Il est desormais trop tard pour l'envoyer. " \
                    "Vos donnees ne seront donc pas integrees."
        for contact in [contact_for(entity, recursive=False) \
                        for entity in mobile_entity_gen(self.get_bad_cscom())]:
            if not contact or not contact.phone_number:
                continue

            send_sms(to=contact.phone_number, text=message)

        # send an SMS to districts:
        # 1. those with non-validated reports.
        # 2. those with non-reporting cscom.
        for dis, e in self.get_all_district().items():

            contact = contact_for(e['entity'], recursive=False)

            if not contact or not contact.phone_number:
                continue

            # already received everything and validated.
            # congrats, we won't bug you buddy.
            if e['unval'] == 0 and e['unsent'] == 0:
                continue

            if e['unval']:
                msg_unval = u"%(nb)s de vos CSCom ont envoye leur " \
                            u"rapport. Vous devez les valider avant le 15." \
                            % {'nb': e['unval']}
            else:
                msg_unval = u""

            if e['unsent']:
                msg_unsent = u"%(nb)s n'ont pas envoye leur rapport " \
                             u"mensuel dans les temps!" % {'nb': e['unsent']}
            else:
                msg_unsent = u""

            # add space before second sentence if both
            if e['unval'] and e['unsent']:
                msg_unsent = u" %s" % msg_unsent

            message = u"[PNLP] %(unval)s%(unsent)s" \
                      % {'unval': msg_unval, 'unsent': msg_unsent}

            send_sms(to=contact.phone_number, text=message)
Exemplo n.º 5
0
def nut_test(message, **kwargs):
    try:
        code, msg = message.content.split('nut test')
    except:
        msg = ''

    msg = u"Received on %(date)s: %(msg)s" % {'date': datetime.now(),
                                              'msg': msg}
    message.respond(msg)
    send_sms(FOL_NUMBER, msg)
    return True
Exemplo n.º 6
0
def send_login(csv_file, provider_filter=filter_none, dry_run=True):
    """ Send an SMS with login/pass from CSV file

    CSV FORMAT:

    """

    message = u"[PNLP] Systeme de routine Paludisme. Votre identifiant est %(username)s Votre mot de passe est %(password)s Appellez le 65731076 en cas de besoin. Ala ka to nooro ya."

    count = 0
    f = open(csv_file)
    for line in f.readlines():
        # explode CSV line
        entname, rolename, fname, lname, \
        username, password, password_enc = line.strip().split(',')

        username = username.strip()
        password = password.strip()

        try:
            provider = Provider.objects.get(user__username=username)
        except:
            print("ERROR: can't find user: %s" % username)
            continue

        if not provider_filter.__call__(provider):
            continue

        count += 1

        msg = message % {'username': username, 'password': password}

        print(u">>%(phone)s | %(msg)s" % {
            'phone': provider.phone_number,
            'msg': msg
        })

        if not dry_run:
            send_sms(provider.phone_number, msg)
            pass

    f.close()
    print(count)
Exemplo n.º 7
0
def send_message(message, provider_filter=filter_none, dry_run=True):

    count = 0

    for provider in Provider.objects.all():

        if not provider_filter.__call__(provider):
            continue

        count += 1

        print(u">>%(phone)s | %(msg)s" % {'phone': provider.phone_number,
                                          'msg': message})

        if not dry_run:
            send_sms(provider.phone_number, message)
            pass

    print(count)
Exemplo n.º 8
0
def handle(*args, **options):

    # args format: (sender, text)
    if len(args) != 3:
        logger.error(u"Incorrect input.\nUsage: %s TO TEXT" % args[0])
        sys.exit(1)

    try:
        dest, text = args[1:]
        dest = dest.strip()
        text = text.strip()

        # create message object in DB
        send_sms(dest, text)

        logger.info("Added message to DB for Gammu processing")

    except Exception as e:
        logger.error(u"Unable to record message:\n%r" % e)
        sys.exit(1)
Exemplo n.º 9
0
def handle(*args, **options):

    # args format: (sender, text)
    if len(args) != 3:
        logger.error(u"Incorrect input.\nUsage: %s TO TEXT" % args[0])
        sys.exit(1)

    try:
        dest, text = args[1:]
        dest = dest.strip()
        text = text.strip()

        # create message object in DB
        send_sms(dest, text)

        logger.info("Added message to DB for Gammu processing")

    except Exception as e:
        logger.error(u"Unable to record message:\n%r" % e)
        sys.exit(1)
Exemplo n.º 10
0
    def action(self):
        """ send SMS to HOTLINE """

        message = u"[PNLP] La periode %(period)s va commencer. " \
                  u"Il faut s'occuper de la surveillance de la collecte " \
                  u"des donnees primaires." \
                  % {'period': self.args.period.next()\
                                               .full_name()}

        send_sms(to=settings.HOTLINE_NUMBER, text=message)

        # malitel_url = full_url(path=reverse('malitel'))
        title = u"[PNLP] La période va commencer."
        # sent, sent_message = send_email(recipients=settings.HOTLINE_EMAIL, \
        #                                 template='emails/send_airtime.txt', \
        #                                 context={'url': malitel_url}, \
        #                                 title=title)
        sent, sent_message = send_email(recipients=settings.HOTLINE_EMAIL, \
                                        message=message, \
                                        title=title)
Exemplo n.º 11
0
def send_login(csv_file, provider_filter=filter_none, dry_run=True):
    """ Send an SMS with login/pass from CSV file

    CSV FORMAT:

    """

    message = u"[PNLP] Systeme de routine Paludisme. Votre identifiant est %(username)s Votre mot de passe est %(password)s Appellez le 65731076 en cas de besoin. Ala ka to nooro ya."

    count = 0
    f = open(csv_file)
    for line in f.readlines():
        # explode CSV line
        entname, rolename, fname, lname, \
        username, password, password_enc = line.strip().split(',')

        username = username.strip()
        password = password.strip()

        try:
            provider = Provider.objects.get(user__username=username)
        except:
            print("ERROR: can't find user: %s" % username)
            continue

        if not provider_filter.__call__(provider):
            continue

        count += 1

        msg = message % {'username': username, 'password': password}

        print(u">>%(phone)s | %(msg)s" % {'phone': provider.phone_number,
                                          'msg': msg})

        if not dry_run:
            send_sms(provider.phone_number, msg)
            pass

    f.close()
    print(count)
Exemplo n.º 12
0
def send_message(message, provider_filter=filter_none, dry_run=True):

    count = 0

    for provider in Provider.objects.all():

        if not provider_filter.__call__(provider):
            continue

        count += 1

        print(u">>%(phone)s | %(msg)s" % {
            'phone': provider.phone_number,
            'msg': message
        })

        if not dry_run:
            send_sms(provider.phone_number, message)
            pass

    print(count)
Exemplo n.º 13
0
def palu_help(message, nousername=False):

    try:
        hotline = settings.HOTLINE_NUMBER
    except:
        hotline = '65731076'

    if nousername:
        kw1, kw2 = message.content.strip().lower().split()
        username = None
    else:
        kw1, kw2, uusername = message.content.strip().lower().split()
        try:
            username = uusername.split(':')[1]
        except:
            username = None

    provider = None
    if username:
        try:
            provider = Provider.objects.get(user__username=username)
        except Provider.DoesNotExist:
            pass

    if not provider:
        try:
            provider = Provider.objects.get(phone_number=message.identity)
        except:
            provider = None

    if not provider:
        text_message = u"[DEMANDE AIDE] Non identifié: %s" % message.identity
    else:
        text_message = u"[DEMANDE AIDE] %(provider)s de %(entity)s." \
                       % {'provider': provider, 'entity': entity_for(provider)}

    send_sms(hotline, text_message)
    return True
Exemplo n.º 14
0
def palu_help(message, nousername=False):

    try:
        hotline = settings.HOTLINE_NUMBER
    except:
        hotline = '65731076'

    if nousername:
        kw1, kw2 = message.content.strip().lower().split()
        username = None
    else:
        kw1, kw2, uusername = message.content.strip().lower().split()
        try:
            username = uusername.split(':')[1]
        except:
            username = None

    provider = None
    if username:
        try:
            provider = Provider.objects.get(user__username=username)
        except Provider.DoesNotExist:
            pass

    if not provider:
        try:
            provider = Provider.objects.get(phone_number=message.identity)
        except:
            provider = None

    if not provider:
        text_message = u"[DEMANDE AIDE] Non identifié: %s" % message.identity
    else:
        text_message = u"[DEMANDE AIDE] %(provider)s de %(entity)s." \
                       % {'provider': provider, 'entity': entity_for(provider)}

    send_sms(hotline, text_message)
    return True
Exemplo n.º 15
0
Arquivo: utils.py Projeto: yeleman/nut
def send_report(report, user):
    # can only send complete reports (or re-send)
    if not report.can_send():
        return False

    # create revision if it's not a resend
    create_revision =  report.status not in (report.STATUS_SENT, 
                                             report.STATUS_MODIFIED_SENT)

    # change status
    if report.status in (report.STATUS_LOCAL_MODIFIED,
                         report.STATUS_MODIFIED_SENT):
        report.status = report.STATUS_MODIFIED_SENT
        sms_report = report_update_sms(report)
        kw = 'update-report'
    else:
        report.status = report.STATUS_SENT
        sms_report = report_sms(report)
        kw = 'report'
    
    sms = (u"nut %(kw)s %(user)s %(pwhash)s %(report)s-EOM-"
           % {'kw': kw,
              'user': user.username,
              'pwhash': user.pwhash,
              'report': sms_report})

    print(sms)
    send_sms(config.SRV_NUM, sms)

    # save status change
    report.save()

    # commit revision
    if create_revision:
        report.create_revision_safe()

    return True
Exemplo n.º 16
0
def adressbook_send_sms(request):
    if request.method == "POST":
        form_msg = MessageForm(request.POST)
        providers = Provider.objects.filter(user__is_active=True)

        role_slug = request.POST.get('role', None)
        try:
            entity_id = int(request.POST.get('entity', 1))
        except TypeError:
            entity_id = 1

        if role_slug:
            providers = providers.filter(access__role__slug=request
                                 .POST.get('role'), user__is_active=True)

        if entity_id:
            entity = Entity.objects.get(id=entity_id)
            providers = providers.filter(access__object_id__in=[entity.id]
                                         + [e.id for e in entity.get_descendants()],
                                         user__is_active=True)

        is_everything = not role_slug and entity_id == 1

        if form_msg.is_valid() and not is_everything:
            for provider in providers:
                send_sms(provider.phone_number,
                         form_msg.cleaned_data.get('text'))
            messages.success(request,
                             _(u"SMS en cours d'envoie à %d destinataires")
                             % providers.count())
            return redirect("log_message")
        else:
            messages.error(request,
                           _(u"SMS non envoyé : Vous demandez"
                             u"d'envoyer un SMS a tous les utisateurs"))
            return redirect(addressbook)
Exemplo n.º 17
0
def nut_search(message, args, sub_cmd, cmd):
    """ Incomming:
            nut research code_health_center first_name(op) last_name(op)
             surname_mother(op)
            None = n
            example 1: nut research dasco iba Fad Diarra
            example 2: nut research dasco - Fad Diarra "Si le first_name vide"
            example 3: nut research dasco - Fad n
                        "Si le first_name et surname_mother sont vide"

        Outgoing:
            Il existe nbr de resultat patient(s) pour XXX: last_name
            surname_mother de l'id 7, last_name surname_mother de l'id 8.
            or  Il n'existe aucun patient du prénom first_name """

    try:
        hc_code, first, last, mother = args.split()
    except:
        return resp_error(message, u"recherche")

    try:
        hc = HealthCenter.objects.get(code=hc_code)
    except:
        msg = u"[ERREUR] %(hc)s n'est pas un code de Centre valide." % {'hc': hc_code}
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    first = first.replace('_', ' ') if first != '-' else None
    last = last.replace('_', ' ') if last != '-' else None
    mother = mother.replace('_', ' ') if mother != '-' else None

    patients = Patient.objects.filter(health_center=hc)

    display = ['first', 'last', 'mother']

    if first:
        patients = patients.filter(first_name__icontains=first)
        display.remove('first')

    if last:
        patients = patients.filter(last_name__icontains=last)
        display.remove('last')

    if mother:
        patients = patients.filter(surname_mother__icontains=mother)
        display.remove('mother')

    if not len(display):
        fmt = u"%(first)s#%(id)s"
    else:
        fmt = u"/".join(["%%(%s)s" % d for d in display]) + u"#%(id)s"

    def display_name(p, fmt):
        return fmt % {'id': p.nut_id,
                      'first': p.first_name.title(),
                      'last': p.last_name.title(),
                      'mother': p.surname_mother.title()}

    if not len(patients.all()):
        message.respond(u"[ERREUR] Pas de patient trouve. "
                        u"Essayez une recherche plus large.")
        return True

    msg = u"[SUCCES] %d trouves: %s" % (len(patients.all()),
          ", ".join([display_name(patient, fmt) for patient in patients.all()]))
    message.respond(msg[:160])
    return True
Exemplo n.º 18
0
Arquivo: utils.py Projeto: yeleman/nut
def remote_login_request(username, password):
    """ sends formatted SMS to server to request login """
    send_sms(config.SRV_NUM, \
             u"nut login %(user)s %(password)s" % {'user': username,
                                               'password': password})
Exemplo n.º 19
0
 def respond(self, text):
     return send_sms(self.sendernumber, text)
Exemplo n.º 20
0
 def respond(self, text):
     return send_sms(self.sendernumber, text)
Exemplo n.º 21
0
def save_error(message, action):
    msg = u"[ERREUR] %s" % action
    message.respond(msg)
    send_sms(FOL_NUMBER, msg)
    return True
Exemplo n.º 22
0
def palu(message):

    # common start of error message
    error_start = u"Impossible d'enregistrer le rapport. "

    # create variables from text messages.
    try:
        args_names = ['kw1', 'username', 'password', 'month', 'year', \
        'u5_total_consultation_all_causes', \
        'u5_total_suspected_malaria_cases', \
        'u5_total_simple_malaria_cases', \
        'u5_total_severe_malaria_cases', \
        'u5_total_tested_malaria_cases', \
        'u5_total_confirmed_malaria_cases', \
        'u5_total_treated_malaria_cases', \
        'u5_total_inpatient_all_causes', \
        'u5_total_malaria_inpatient', \
        'u5_total_death_all_causes', \
        'u5_total_malaria_death', \
        'u5_total_distributed_bednets', \
        'o5_total_consultation_all_causes', \
        'o5_total_suspected_malaria_cases', \
        'o5_total_simple_malaria_cases', \
        'o5_total_severe_malaria_cases', \
        'o5_total_tested_malaria_cases', \
        'o5_total_confirmed_malaria_cases', \
        'o5_total_treated_malaria_cases', \
        'o5_total_inpatient_all_causes', \
        'o5_total_malaria_inpatient', \
        'o5_total_death_all_causes', \
        'o5_total_malaria_death', \
        'pw_total_consultation_all_causes', \
        'pw_total_suspected_malaria_cases', \
        'pw_total_severe_malaria_cases', \
        'pw_total_tested_malaria_cases', \
        'pw_total_confirmed_malaria_cases', \
        'pw_total_treated_malaria_cases', \
        'pw_total_inpatient_all_causes', \
        'pw_total_malaria_inpatient', \
        'pw_total_death_all_causes', \
        'pw_total_malaria_death', \
        'pw_total_distributed_bednets', \
        'pw_total_anc1', \
        'pw_total_sp1', \
        'pw_total_sp2', \
        'stockout_act_children', 'stockout_act_youth', 'stockout_act_adult', \
        'stockout_artemether', 'stockout_quinine', 'stockout_serum', \
        'stockout_bednet', 'stockout_rdt', 'stockout_sp']
        args_values = message.content.strip().lower().split()
        arguments = dict(zip(args_names, args_values))
    except ValueError:
        # failure to split means we proabably lack a data or more
        # we can't process it.
        message.respond(error_start + u" Le format du SMS est incorrect.")
        return True

    # convert form-data to int or bool respectively
    try:
        for key, value in arguments.items():
            if key.split('_')[0] in ('u5', 'o5', 'pw', 'month', 'year'):
                arguments[key] = int(value)
            if key.split('_')[0] == 'stockout':
                arguments[key] = MalariaReport.YES if bool(int(value)) \
                                                   else MalariaReport.NO
    except:
        raise
        # failure to convert means non-numeric value which we can't process.
        message.respond(error_start + u" Les données sont malformées.")
        return True

    # check credentials
    try:
        provider = Provider.active.get(user__username=arguments['username'])
    except Provider.DoesNotExist:
        message.respond(error_start + u"Ce nom d'utilisateur " +
                                      u"(%s) n'existe pas." % \
                                      arguments['username'])
        return True
    if not provider.check_password(arguments['password']):
        message.respond(error_start + u"Votre mot de passe est incorrect.")
        return True

    # now we have well formed and authenticated data.
    # let's check for business-logic errors.

    # create a data holder for validator
    data_browser = MalariaDataHolder()

    # feed data holder with sms provided data
    for key, value in arguments.items():
        if key.split('_')[0] in ('u5', 'o5', 'pw', \
                                 'stockout', 'year', 'month'):
            data_browser.set(key, value)

    # feed data holder with guessable data
    try:
        hc = entity_for(provider).slug
    except:
        hc = None
    data_browser.set('hc', hc)
    today = datetime.date.today()
    data_browser.set('fillin_day', today.day)
    data_browser.set('fillin_month', today.month)
    data_browser.set('fillin_year', today.year)
    data_browser.set('author', provider.name())

    # create validator and fire
    validator = MalariaReportValidator(data_browser)
    validator.errors.reset()
    try:
        validator.validate()
    except AttributeError as e:
        message.respond(error_start + e.__str__())
        return True
    errors = validator.errors

    # return first error to user
    if errors.count() > 0:
        message.respond(error_start + errors.all()[0])
        return True

    # create the report
    try:
        period = MonthPeriod.find_create_from(year=data_browser.get('year'), \
                                              month=data_browser.get('month'))
        entity = Entity.objects.get(slug=data_browser.get('hc'), \
                                    type__slug='cscom')
        report = MalariaReport.start(period, entity, provider, \
                                     type=MalariaReport.TYPE_SOURCE)

        report.add_underfive_data(*data_browser.data_for_cat('u5'))
        report.add_overfive_data(*data_browser.data_for_cat('o5'))
        report.add_pregnantwomen_data(*data_browser.data_for_cat('pw'))
        report.add_stockout_data(*data_browser.data_for_cat('so'))
        #report.save()
        with reversion.create_revision():
            report.save()
            reversion.set_user(provider.user)

    except Exception as e:
        message.respond(error_start + u"Une erreur technique s'est " \
                        u"produite. Reessayez plus tard et " \
                        u"contactez ANTIM si le probleme persiste.")
        logger.error(u"Unable to save report to DB. Message: %s | Exp: %r" \
                     % (message.content, e))
        return True

    message.respond(u"[SUCCES] Le rapport de %(cscom)s pour %(period)s "
                    u"a ete enregistre. " \
                    u"Le No de recu est #%(receipt)s." \
                    % {'cscom': report.entity.display_full_name(), \
                       'period': report.period, \
                       'receipt': report.receipt})
    try:
        to = contact_for(report.entity.parent).phone_number
    except:
        to = None
    if not to:
        return True
    send_sms(to, u"[ALERTE] Le CSCom %(cscom)s vient d'envoyer le " \
                 u"rapport #%(receipt)s pour %(period)s." \
                 % {'cscom': report.entity.display_full_name(), \
                    'period': report.period, \
                    'receipt': report.receipt})
    return True
Exemplo n.º 23
0
def resp_error(message, action):
    msg = u"[ERREUR] Impossible de comprendre le SMS pour %s" % action
    message.respond(msg)
    send_sms(FOL_NUMBER, msg)
    return True
Exemplo n.º 24
0
def nut_register(message, args, sub_cmd, cmd):
    """ Incomming:
            nut register hc_code, create_date, patient_id,
                         first_name, last_name, mother, sex, dob, contact
                         #weight height oed pb nbr, is_ureni
            exple: 'nut register sab3 20121004 23 Moussa Kone Camara M 7
                    35354#6 65 YES 111 25 0'
        Outgoing:
            [SUCCES] Le rapport de name_health_center a ete enregistre.
            Son id est 8.
            or  [ERREUR] Votre rapport n'a pas été enregistrer"""

    try:
        register_data, follow_up_data = args.split('#')

        hc_code, create_date, patient_id, first_name, last_name, mother, sex, dob, contact = register_data.split()

        weight, height, oedema, muac, nb_plumpy_nut, is_ureni = follow_up_data.split()
    except:
        return resp_error(message, u"enregistrement")
    try:
        # On essai prendre le seat
        hc = HealthCenter.objects.get(code=hc_code.lower())
    except:
        # On envoi un sms pour signaler que le code n'est pas valide
        msg = u"[ERREUR] %(hc)s n'est pas un code de Centre valide."\
              % {'hc': hc_code}
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    # check date
    try:
        registration_date = formatdate(create_date, True)
    except ValueError as e:
        return resp_error(message, e)
    # Car on ne traite que les URENI pour l'instant
    type_uren = NutritionalData.SAM
    # True or False
    is_ureni = bool(int(is_ureni))

    if is_ureni:
        if hc_code in ["qmali", "cr"]:
            type_uren = NutritionalData.SAMP
        else:
            msg = u"[ERREUR] Seul les CSREF ont le droit " \
                  u"d'enregistrer les enfants URENI"
            message.respond(msg)
            send_sms(FOL_NUMBER, msg)
            return True
    try:
        patient_id = clean_up_pid(patient_id)
        nut_id = Patient.get_nut_id(hc_code, type_uren.lower(), patient_id)
    except ValueError as e:
        return resp_error(message, e)

    patient = Patient()
    patient.nut_id = nut_id
    patient.first_name = first_name.replace('_', ' ').title()
    patient.last_name = last_name.replace('_', ' ').title()
    patient.surname_mother = mother.replace('_', ' ').title()
    patient.create_date = registration_date
    try:
        patient.birth_date = formatdate(dob)
    except ValueError as e:
        message.respond(u"[ERREUR] %(e)s" % {'e': e})
        return True

    patient.sex = sex.upper()
    patient.contact = contact
    patient.health_center = hc
    try:
        patient.save()
    except IntegrityError:
        patient = Patient.objects.get(nut_id=nut_id)
        save_error(message, u"/!\ l'identifiant #%(id)s appartient déjà à"
                            u" %(full_name)s. enregistré au centre"
                            u" %(health_center)s le %(date)s"
                            u" Pour plus d'information, appelez ce numéro %(admin)s"
                   % {'full_name': patient.full_name(), 'id': nut_id,
                      'date': patient.create_date.strftime("%x %H: %Mmm %Ss"),
                      'health_center': patient.health_center.name,
                      'admin': FOL_NUMBER})
        return False
    except:
        return save_error(message, u"Impossible d'enregistrer ce rapport dans "
                                   u"la base des donnees")

    # adding patient to the program
    programio = ProgramIO()
    programio.patient = patient
    programio.event = programio.SUPPORT
    programio.date = registration_date
    try:
        programio.save()
    except:
        return resp_error(message, u"enregistrement")

    # creating a followup event
    weight = float(weight)
    height = float(height)
    oedema = {'yes': NutritionalData.OEDEMA_YES,
              'no': NutritionalData.OEDEMA_NO,
              'unknown': NutritionalData.OEDEMA_UNKNOWN}[oedema.lower()]
    muac = int(muac)
    nb_plumpy_nut = int(nb_plumpy_nut) if not str(nb_plumpy_nut).lower() == '-' else 0
    datanut = add_followup_data(patient=patient, weight=weight,
                                height=height, oedema=oedema, muac=muac,
                                nb_plumpy_nut=nb_plumpy_nut,
                                is_ureni=is_ureni,
                                date=registration_date)
    if not datanut:
        msg = u"/!\ %(full_name)s enregistre avec ID#%(id)s." \
              u" Donnees nutrition non enregistres." % {'full_name': patient.full_name(), 'id': nut_id}
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    message.respond(u"[SUCCES] %(full_name)s enregistre avec ID#%(id)s."
                    u" Donnees nutrition enregistres." % {'full_name': patient.full_name_mother(), 'id': nut_id})
    return True
Exemplo n.º 25
0
def nut_consumption(message, args, sub_cmd, cmd):
    """ Incomming:
            nut stock type_health_center code_health_center month year
             #input_type initial received used received #input_type initial
            received used received
            example: nut stock URENAM dasco 1 2012 #nie 11 22 18 2
                     #csb 22 22 22 2 #uni 2 32 22 2 #hui 21 25 45 1
                     #suc 23 12 30 0 #mil 32 15 32 2
        Outgoing:
            [SUCCES] Le rapport de stock de health_center a ete bien
            enregistre.
            or error message """

    try:
        general, reports = args.split('#', 1)
        hc_type, hc_code, month, year = general.split()
    except:
        return resp_error(message, u"stock")

    try:
        hc = HealthCenter.objects.get(code=hc_code)
    except:
        msg = u"[ERREUR] %(hc)s n'est pas un code de Centre valide." % {'hc': hc_code}
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    try:
        period = MonthPeriod.find_create_from(year=int(year),
                                              month=int(month))
    except:
        msg = u"[ERREUR] %s-%s n'est pas une periode valide." % (month, year)
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    now_period = MonthPeriod.find_create_by_date(date.today())
    if period != now_period.previous():
        msg = u"[ERREUR] Impossible d'enregistrer le rapport de conso pour %s.\
                 Envoyez pour %s" % (period.full_name(), now_period.previous().full_name())
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    try:
        all_reports = reports.split('#')
    except:
        return resp_error(message, u"stock")

    success = []
    errors = []
    for areport in all_reports:
        try:
            icode, initial, received, used, lost = areport.split()
            input_type = Input.objects.get(code=icode.lower())
        except:
            errors.append(icode)

        if ConsumptionReport.objects.filter(period=period,
                                            health_center=hc,
                                            input_type=input_type).count():
            cr = ConsumptionReport.objects.get(period=period,
                                               health_center=hc,
                                               input_type=input_type)
        else:
            cr = ConsumptionReport(period=period, health_center=hc,
                                   input_type=input_type)
        cr.initial = int(initial)
        cr.received = int(received)
        cr.used = int(used)
        cr.lost = int(lost)
        try:
            cr.save()
            success.append(cr)
        except:
            errors.append(icode)

    if len(errors):
        msg = u"[ERREUR] %d rapport de conso en erreur. Verifiez toutes les" \
              u" donnees et renvoyez -- %s" % (len(errors), ', '.join(errors))
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    message.respond(u"[SUCCES] %d rapports de conso enregistres pour %s."
                    % (len(success), period.full_name()))
    return True
Exemplo n.º 26
0
def nut_disable(message, args, sub_cmd, cmd):
    """  Incomming:
            hc_code, date_disable, patient_id, weight, height, muac,
            reason
            example reason: (a= abandon, t = transfer ...)
            example data: 'nut off sab3 20120925 sam 23 - - - a'
         Outgoing:
            [SUCCES] full_name ne fait plus partie du programme.
            or error message """

    try:
        hc_code, date_disable, type_uren, patient_id, weight, height, muac, reason = args.split()
    except ValueError:
        # Todo: A supprimer une fois la version 07 de application java"
        # est deployé au cscom
        hc_code, date_disable, type_uren, patient_id, reason = args.split()
        weight = None
        height = None
        muac = None
    except:
        return resp_error(message, u"la sortie")

    try:
        quitting_date = formatdate(date_disable)
        quitting_datetime = formatdate(date_disable, True)
    except ValueError as e:
        return resp_error(message, e)

    try:
        patient_id = clean_up_pid(patient_id)
        patient = Patient.get_patient_nut_id(hc_code, type_uren.lower(), patient_id)
    except:
        msg = u"[ERREUR] Aucun patient trouve pour ID#%s" % patient_id
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    if patient.last_data_nut().date > quitting_date:
        msg = u"[ERREUR] La date du dernier suivi pour ID# %s est " \
              u"superieur que la date utilise" % patient.nut_id
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    if patient.last_data_event().event == ProgramIO.OUT:
        msg = u"/!\ %(full_name)s est deja sortie du programme." % {'full_name': patient.full_name()}
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    if reason == ProgramIO.HEALING and weight:
        datanut = add_followup_data(patient=patient, weight=weight,
                                    height=height, muac=muac,
                                    oedema=NutritionalData.OEDEMA_NO,
                                    nb_plumpy_nut=0,
                                    date=quitting_date)
        if not datanut:
            message.respond(u"/!\ %(full_name)s enregistre avec ID#%(id)s."
                            u" Donnees nutrition non enregistres."
                            % {'full_name': patient.full_name(),
                               'id': patient_id})
            return True

    programio = ProgramIO()
    programio.patient = patient
    programio.event = programio.OUT
    programio.reason = reason
    programio.date = quitting_datetime
    programio.save()
    message.respond(u"[SUCCES] %(full_name)s ne fait plus partie "
                    u"du programme." % {'full_name': patient.full_name()})
    return True
Exemplo n.º 27
0
def palu(message):

    # common start of error message
    error_start = u"Impossible d'enregistrer le rapport. "

    # create variables from text messages.
    try:
        args_names = ['kw1', 'username', 'password', 'month', 'year', \
        'u5_total_consultation_all_causes', \
        'u5_total_suspected_malaria_cases', \
        'u5_total_simple_malaria_cases', \
        'u5_total_severe_malaria_cases', \
        'u5_total_tested_malaria_cases', \
        'u5_total_confirmed_malaria_cases', \
        'u5_total_treated_malaria_cases', \
        'u5_total_inpatient_all_causes', \
        'u5_total_malaria_inpatient', \
        'u5_total_death_all_causes', \
        'u5_total_malaria_death', \
        'u5_total_distributed_bednets', \
        'o5_total_consultation_all_causes', \
        'o5_total_suspected_malaria_cases', \
        'o5_total_simple_malaria_cases', \
        'o5_total_severe_malaria_cases', \
        'o5_total_tested_malaria_cases', \
        'o5_total_confirmed_malaria_cases', \
        'o5_total_treated_malaria_cases', \
        'o5_total_inpatient_all_causes', \
        'o5_total_malaria_inpatient', \
        'o5_total_death_all_causes', \
        'o5_total_malaria_death', \
        'pw_total_consultation_all_causes', \
        'pw_total_suspected_malaria_cases', \
        'pw_total_severe_malaria_cases', \
        'pw_total_tested_malaria_cases', \
        'pw_total_confirmed_malaria_cases', \
        'pw_total_treated_malaria_cases', \
        'pw_total_inpatient_all_causes', \
        'pw_total_malaria_inpatient', \
        'pw_total_death_all_causes', \
        'pw_total_malaria_death', \
        'pw_total_distributed_bednets', \
        'pw_total_anc1', \
        'pw_total_sp1', \
        'pw_total_sp2', \
        'stockout_act_children', 'stockout_act_youth', 'stockout_act_adult', \
        'stockout_artemether', 'stockout_quinine', 'stockout_serum', \
        'stockout_bednet', 'stockout_rdt', 'stockout_sp']
        args_values = message.content.strip().lower().split()
        arguments = dict(zip(args_names, args_values))
    except ValueError:
        # failure to split means we proabably lack a data or more
        # we can't process it.
        message.respond(error_start + u" Le format du SMS est incorrect.")
        return True

    # convert form-data to int or bool respectively
    try:
        for key, value in arguments.items():
            if key.split('_')[0] in ('u5', 'o5', 'pw', 'month', 'year'):
                arguments[key] = int(value)
            if key.split('_')[0] == 'stockout':
                arguments[key] = MalariaReport.YES if bool(int(value)) \
                                                   else MalariaReport.NO
    except:
        raise
        # failure to convert means non-numeric value which we can't process.
        message.respond(error_start + u" Les données sont malformées.")
        return True

    # check credentials
    try:
        provider = Provider.active.get(user__username=arguments['username'])
    except Provider.DoesNotExist:
        message.respond(error_start + u"Ce nom d'utilisateur " +
                                      u"(%s) n'existe pas." % \
                                      arguments['username'])
        return True
    if not provider.check_password(arguments['password']):
        message.respond(error_start + u"Votre mot de passe est incorrect.")
        return True

    # now we have well formed and authenticated data.
    # let's check for business-logic errors.

    # create a data holder for validator
    data_browser = MalariaDataHolder()

    # feed data holder with sms provided data
    for key, value in arguments.items():
        if key.split('_')[0] in ('u5', 'o5', 'pw', \
                                 'stockout', 'year', 'month'):
            data_browser.set(key, value)

    # feed data holder with guessable data
    try:
        hc = entity_for(provider).slug
    except:
        hc = None
    data_browser.set('hc', hc)
    today = datetime.date.today()
    data_browser.set('fillin_day', today.day)
    data_browser.set('fillin_month', today.month)
    data_browser.set('fillin_year', today.year)
    data_browser.set('author', provider.name())

    # create validator and fire
    validator = MalariaReportValidator(data_browser)
    validator.errors.reset()
    try:
        validator.validate()
    except AttributeError as e:
        message.respond(error_start + e.__str__())
        return True
    errors = validator.errors

    # return first error to user
    if errors.count() > 0:
        message.respond(error_start + errors.all()[0])
        return True

    # create the report
    try:
        period = MonthPeriod.find_create_from(year=data_browser.get('year'), \
                                              month=data_browser.get('month'))
        entity = Entity.objects.get(slug=data_browser.get('hc'), \
                                    type__slug='cscom')
        report = MalariaReport.start(period, entity, provider, \
                                     type=MalariaReport.TYPE_SOURCE)

        report.add_underfive_data(*data_browser.data_for_cat('u5'))
        report.add_overfive_data(*data_browser.data_for_cat('o5'))
        report.add_pregnantwomen_data(*data_browser.data_for_cat('pw'))
        report.add_stockout_data(*data_browser.data_for_cat('so'))
        #report.save()
        with reversion.create_revision():
            report.save()
            reversion.set_user(provider.user)

    except Exception as e:
        message.respond(error_start + u"Une erreur technique s'est " \
                        u"produite. Reessayez plus tard et " \
                        u"contactez ANTIM si le probleme persiste.")
        logger.error(u"Unable to save report to DB. Message: %s | Exp: %r" \
                     % (message.content, e))
        return True

    message.respond(u"[SUCCES] Le rapport de %(cscom)s pour %(period)s "
                    u"a ete enregistre. " \
                    u"Le No de recu est #%(receipt)s." \
                    % {'cscom': report.entity.display_full_name(), \
                       'period': report.period, \
                       'receipt': report.receipt})
    try:
        to = contact_for(report.entity.parent).phone_number
    except:
        to = None
    if not to:
        return True
    send_sms(to, u"[ALERTE] Le CSCom %(cscom)s vient d'envoyer le " \
                 u"rapport #%(receipt)s pour %(period)s." \
                 % {'cscom': report.entity.display_full_name(), \
                    'period': report.period, \
                    'receipt': report.receipt})
    return True
Exemplo n.º 28
0
def nut_followup(message, args, sub_cmd, cmd):

    """ Incomming:
            nut fol hc_code reporting_d  patient_id weight height
                oedema muac nb_plumpy_nut(optional), is_ureni
        exple: 'nut fol sab3 20121004 sam 23 5 65 YES 120 2 1'

        Outgoing:
            [SUCCES] Donnees nutrition mise a jour pour full_name #id
            or error message """

    try:
        hc_code, reporting_d, type_uren, patient_id, weight, height, oedema, muac, nb_plumpy_nut, is_ureni = args.split()
    except:
        return resp_error(message, u"suivi")

    try:
        patient_id = clean_up_pid(patient_id)
        patient = Patient.get_patient_nut_id(hc_code, type_uren.lower(), patient_id)
    except:
        msg = u"[ERREUR] Aucun patient trouve pour ID#%s" % patient_id
        message.respond()
        send_sms(FOL_NUMBER, msg)
        return True

    try:
        followup_date = formatdate(reporting_d)
        followup_datetime = formatdate(reporting_d, True)
    except ValueError as e:
        return resp_error(message, e)

    # creating a followup event
    is_ureni = bool(int(is_ureni))
    weight = float(weight)
    height = float(height)
    oedema = {'yes': NutritionalData.OEDEMA_YES,
              'no': NutritionalData.OEDEMA_NO,
              'unknown': NutritionalData.OEDEMA_UNKNOWN}[oedema.lower()]
    muac = int(muac)
    nb_plumpy_nut = int(nb_plumpy_nut) if not nb_plumpy_nut.lower() == '-' else 0

    if patient.last_data_nut().date == followup_date:
        last_data_nut = patient.last_data_nut()
        last_data_nut.weight = weight
        last_data_nut.height = height
        last_data_nut.oedema = oedema
        last_data_nut.muac = muac
        last_data_nut.nb_plumpy_nut = nb_plumpy_nut
        last_data_nut.is_ureni = is_ureni
        last_data_nut.save()
        message.respond(u"[SUCCES] Donnees nutrition mise a jour pour "
                        u"%(full_name)s" % {'full_name': patient.full_name_id()})
        return True

    if patient.last_data_nut().date > followup_date:
        msg = u"[ERREUR] La date du dernier suivi pour" \
              u" %(full_name)s est superieur que la date utilise" % {'full_name': patient.full_name_id()}
        message.respond(msg)
        send_sms(FOL_NUMBER, msg)
        return True

    if patient.last_data_event().event == ProgramIO.OUT:
        programio = ProgramIO()
        programio.patient = patient
        programio.event = programio.SUPPORT
        programio.date = followup_datetime
        programio.save()

    datanut = add_followup_data(patient=patient, weight=weight,
                                height=height, oedema=oedema,
                                muac=muac, nb_plumpy_nut=nb_plumpy_nut,
                                is_ureni=is_ureni,
                                date=followup_date)
    if not datanut:
        return resp_error(message, u"suivi")

    message.respond(u"[SUCCES] Donnees nutrition enregistres pour "
                    u"%(full_name)s" % {'full_name': patient.full_name_id()})
    return True