Repository: AlertaDengue/AlertaDengue (language: python)

Issue:
Automate e-mail to request  weekly data
A cada semana precisamos solicitar atualizações de dados das secretarias de saúde.
Com a expansão do infodengue, precisamos automatizar estas mensagens de solicitação de dados.

### Implementation suggestion
Create a database table for registering contact emails per partner.

nome| nivel|contato|ativo
-------|-------|----------|--------
espirito Santo| estadual | fulano@gmail.com| N
Porto Alegre| municipal| beltrana@gmail.com| S

Toda semana enviar um email para cada contato. A @sarasouzabh pode preparam o texto desta mensagem padrão.


Discussion / hints:
WIP
@eltonn, podemos usar a interface admin do Django para alimentar esta tabela, e um simples script python para enviar os email acionado por CRON.
@fccoelho criar esta tabela em models na base infodengue? Que sugeres? 
sim, acho que deve ficar no mesmo app que gerencia usuários e outros detalhes administrativos do site
@sarasouzabh informou que este envio seria de forma seletiva, pois nem todos deixam de enviar os informes dos dados.
Talvez uma flag para selecionar para quais contatos desejamos enviar a solicitação, ¿qué opinas @fccoelho ?

![view_partners](https://user-images.githubusercontent.com/3450741/112149035-51a85c00-8bbd-11eb-94cd-8af451e76528.png)

Vou criar um script para teste e verificar como linkar a mensagem:
```
Olá, bom dia, tudo bem? 
 
Vocês já possuem  os dados de dengue, chikungunya e Zika  da SE10?
Se sim, poderiam nos enviar? 
Caso já tenha enviado , gentileza desconsiderar esse e-mail. 
 
Obrigada ,
Atenciosamente;
``` 
![edit_partners](https://user-images.githubusercontent.com/3450741/112149033-50772f00-8bbd-11eb-8c58-b044b8eb91b2.png)


```
SELECT * FROM common_requestpartnerdata;
+------+-----------+----------------+----------------+-----------+--------------------+----------+
| id   | geocode   | name           | abbreviation   | level     | contact            | status   |
|------+-----------+----------------+----------------+-----------+--------------------+----------|
| 1    | 3304557   | Rio de Janeiro | RJ             | Municipal | ascomsms@gmail.com | True     |
| 4    | 32        | Espirito Santo | ES             | estadual  | sec@es.gov.br      | True     |
+------+-----------+----------------+----------------+-----------+--------------------+----------+
```

Fix patch:
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 8d7ffb9f..10757f6f 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -33,6 +33,7 @@ jobs:
     - name: Copy env_file as env_staging
       run: |
         cp example_env_file .env_staging
+        cp example_env_file .env
 
     - name: Build and Deploy staging_DB
       id: staging_db
@@ -49,7 +50,7 @@ jobs:
       run: |
         make start_staging SERVICES_STAGING=staging_web
 
-    - name: Migrate staging_DB
+    - name: Migrate staging database
       run: |
         make build_migrate_staging
 
@@ -61,10 +62,6 @@ jobs:
       run: |
         make flake8_staging SERVICES_STAGING=staging_web
 
-    - name: Run tests to APP
+    - name: Run tests to APPs
       run: |
         make test_staging_web SERVICES_STAGING=staging_web
-        
-    - name: Run tests on staging_WEB
-      run: |
-        make test_all SERVICES_STAGING=staging_web
diff --git a/AlertaDengue/ad_main/settings.py b/AlertaDengue/ad_main/settings.py
index 0dd657ab..f488769a 100644
--- a/AlertaDengue/ad_main/settings.py
+++ b/AlertaDengue/ad_main/settings.py
@@ -253,6 +253,7 @@ def read_admins(value):
 
 INFODENGUE_TEAM_EMAIL = os.getenv('INFODENGUE_TEAM_EMAIL')
 
+# ADMIN
 if EMAIL_BACKEND != 'django.core.mail.backends.console.EmailBackend':
     EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD = (
         os.getenv('EMAIL_CONFIG')
@@ -260,6 +261,26 @@ def read_admins(value):
     EMAIL_PORT = int(EMAIL_PORT)
     EMAIL_USE_TLS = True
 
+# SEND_MAIL DBF
+EMAIL_CONNECTIONS = {
+    'mailpartners': {
+        'host': os.getenv("EMAIL_HOST"),
+        'username': os.getenv("EMAIL_USER"),
+        'password': os.getenv("EMAIL_PASSWORD"),
+        'port': os.getenv("EMAIL_PORT"),
+        'use_tls': True,
+    },
+    'socketlabs': {
+        'host': os.getenv("EMAIL_DEV_HOST"),
+        'username': os.getenv("EMAIL_DEV_USER"),
+        'password': os.getenv("EMAIL_DEV_PASSWORD"),
+        'port': os.getenv("EMAIL_DEV_PORT"),
+        'use_tls': False,
+    },
+    'ses': {'backend': 'django_ses.SESBackend'},
+}
+EMAIL_CONNECTION_DEFAULT = 'mailpartners'
+#
 
 CELERY_BROKER_URL = os.getenv('CELERY_BROKER_URL')  # Verificar ERROR CELERY
 CELERY_TASK_ALWAYS_EAGER = os.getenv('CELERY_TASK_ALWAYS_EAGER')
diff --git a/AlertaDengue/dbf/admin.py b/AlertaDengue/dbf/admin.py
index da3a73ce..700cd8c7 100644
--- a/AlertaDengue/dbf/admin.py
+++ b/AlertaDengue/dbf/admin.py
@@ -1,4 +1,15 @@
 from django.contrib import admin
 from .models import DBF
 
+from dbf.models import SendToPartner
+
+
 admin.site.register(DBF)
+
+
+class SendToPartnerAdmin(admin.ModelAdmin):
+    list_display = ['name', 'level', 'contact', 'mail', 'status']
+    ordering = ['name']
+
+
+admin.site.register(SendToPartner, SendToPartnerAdmin)
diff --git a/AlertaDengue/dbf/mailing_partner.py b/AlertaDengue/dbf/mailing_partner.py
new file mode 100644
index 00000000..e5efa641
--- /dev/null
+++ b/AlertaDengue/dbf/mailing_partner.py
@@ -0,0 +1,105 @@
+import os
+from dotenv import load_dotenv
+from os.path import join, dirname
+from datetime import datetime
+
+import django.core.mail
+from django.core.mail import EmailMultiAlternatives
+from django.template.loader import render_to_string
+
+from sqlalchemy import create_engine
+import logging
+import pandas as pd
+
+from ad_main import settings
+from dados.episem import episem
+
+
+env_file = os.environ.get('ENV_FILE', '.env')
+
+dotenv_path = join(dirname(dirname(dirname(__file__))), env_file)
+load_dotenv(dotenv_path)
+
+
+PSQL_URI = "postgresql://{}:{}@{}:{}/{}".format(
+    settings.PSQL_USER,
+    settings.PSQL_PASSWORD,
+    settings.PSQL_HOST,
+    settings.PSQL_PORT,
+    settings.PSQL_DBF,
+)
+db_engine = create_engine(PSQL_URI)
+
+dt_now = datetime.now().strftime('%Y-%m-%d')
+year_week = episem(dt_now, sep='')
+year, week = year_week[:4], year_week[-2:]
+
+
+def get_partner_active():
+    """
+    :param: name, contact, email
+        where status is True
+    :return: pandas dataframe
+    """
+    sql = '''
+      SELECT name, contact, mail FROM dbf_sendtoPartner
+      WHERE status = 'True'
+      ORDER BY name
+    '''
+
+    with db_engine.connect() as conn:
+        return pd.read_sql(sql, conn)
+
+
+class MissingConnectionException(Exception):
+    pass
+
+
+def get_connection(label=None, **kwargs):
+    if label is None:
+        label = getattr(settings, 'EMAIL_CONNECTION_DEFAULT', None)
+
+    try:
+        connections = getattr(settings, 'EMAIL_CONNECTIONS')
+        options = connections[label]
+    except KeyError:
+        raise MissingConnectionException(
+            'Settings for connection "%s" were not found' % label
+        )
+
+    options.update(kwargs)
+    return django.core.mail.get_connection(**options)
+
+
+def send_email_partner(
+    fail_silently=False, connection=None,
+):
+    """
+    Given a datatuple of (subject, message, from_email, recipient_list), send
+    each message to each recipient list. Return the number of emails sent.
+    """
+
+    mailing = get_partner_active()
+
+    connection = get_connection()
+
+    mail_from = os.getenv("EMAIL_USER")
+    messages = []
+
+    for idx, row in mailing.iterrows():
+
+        subject = f'Informe de dados Infodengue SE{week}'
+        body = render_to_string(
+            "email_secretarias.txt",
+            context={"name": row['contact'], "context_message": week},
+        )
+
+        message = EmailMultiAlternatives(
+            subject, body, mail_from, [row['mail']]
+        )
+
+        logging.info(f"Enviando email para: {row['mail']},")
+        # message.attach_alternative(html, 'text/html')
+        messages.append(message)
+
+    return connection.send_messages(messages)
diff --git a/AlertaDengue/dbf/management/commands/send_mail.py b/AlertaDengue/dbf/management/commands/send_mail.py
new file mode 100644
index 00000000..b6bb07f5
--- /dev/null
+++ b/AlertaDengue/dbf/management/commands/send_mail.py
@@ -0,0 +1,22 @@
+from django.core.management.base import BaseCommand
+from datetime import datetime
+
+from dbf import mailing_partner
+
+
+class Command(BaseCommand):
+    help = '>>> Envia emails para as secretarias de saúde'
+
+    def send_email(self):
+        mailing_partner.send_email_partner()
+
+    def handle(self, *args, **options):
+        today = datetime.today()
+        date_send = today.strftime("%d/%m/%Y")
+
+        self.send_email()
+        self.stdout.write(
+            self.style.SUCCESS(
+                'Successfully sent emails on "{}"!'.format(date_send)
+            )
+        )
diff --git a/AlertaDengue/dbf/models.py b/AlertaDengue/dbf/models.py
index 2d03e5e0..3bdfd29f 100644
--- a/AlertaDengue/dbf/models.py
+++ b/AlertaDengue/dbf/models.py
@@ -85,3 +85,31 @@ class DBFChunkedUpload(ChunkedUpload):
     """
 
     pass
+
+
+# Create your models here.
+class SendToPartner(models.Model):
+    STATUS_CHOICES = [
+        (True, 'Enable'),
+        (False, 'Disable'),
+    ]
+
+    geocode = models.CharField(help_text='geocodigo', max_length=7)
+    name = models.CharField(help_text='nome município|estado', max_length=50)
+    state_abbreviation = models.CharField(help_text='uf', max_length=5)
+    level = models.CharField(help_text='nível de atuação', max_length=10)
+    contact = models.CharField(help_text='nome do contato', max_length=50)
+    mail = models.EmailField(help_text='e-mail', max_length=50)
+    status = models.BooleanField(
+        null=False, choices=STATUS_CHOICES, help_text='Está ativo?'
+    )
+
+    def save_partner(self):
+        self.save()
+
+    class Meta:
+        app_label = 'dbf'
+        verbose_name_plural = "Send To Partners"
+
+    def __str__(self):
+        return f'{self.geocode}, {self.name}'
diff --git a/AlertaDengue/dbf/templates/email_secretarias.txt b/AlertaDengue/dbf/templates/email_secretarias.txt
new file mode 100644
index 00000000..4b8076e5
--- /dev/null
+++ b/AlertaDengue/dbf/templates/email_secretarias.txt
@@ -0,0 +1,10 @@
+
+Olá, bom dia {{ name }}, tudo bem?
+
+Vocês já possuem  os dados de dengue, chikungunya e Zika  da SE {{ context_message }}?
+Se sim, poderiam nos enviar?
+Caso já tenha enviado , gentileza desconsiderar esse e-mail.
+
+
+Obrigada ,
+Atenciosamente;
diff --git a/Makefile b/Makefile
index 08942e78..faa652d2 100755
--- a/Makefile
+++ b/Makefile
@@ -2,25 +2,27 @@
 # note: --env-file requires docker-compose>=1.25
 #       ref: https://github.com/docker/compose/pull/6535
 
-include .env_staging
+include .env_staging .env
 export
 
 compose_cmd = docker-compose -p infodengue -f docker/docker-compose.yml --env-file .env
 staging_compose_cmd = docker-compose -p dev -f docker/staging-compose.yml --env-file .env_staging
+SERVICES_INFODENGUE :=
 SERVICES_STAGING :=
 
 
+
 #
 # Create the containers to run in production
 build:
-	$(compose_cmd) build
+	$(compose_cmd) build ${SERVICES_INFODENGUE}
 
 build_migrate: build
 	$(compose_cmd) run --rm web python3 manage.py migrate --noinput
 	$(compose_cmd) run --rm web python3 manage.py migrate --database=forecast --noinput
 
 deploy: build_migrate
-	$(compose_cmd) up -d
+	$(compose_cmd) up -d ${SERVICES_INFODENGUE}
 
 generate_maps: build_migrate
 	$(compose_cmd) run --rm web python3 manage.py sync_geofiles
@@ -28,6 +30,9 @@ generate_maps: build_migrate
 	$(compose_cmd) run --rm web python3 manage.py generate_mapfiles
 	$(compose_cmd) run --rm web python3 manage.py python3 manage.py collectstatic --noinput
 
+exec:
+	$(compose_cmd) exec ${SERVICES_INFODENGUE} bash
+
 stop:
 	$(compose_cmd) stop
 
@@ -56,6 +61,7 @@ run_staging_db:
 
 ## Migrate databases and create shapefiles to synchronize with static_files
 build_migrate_staging: run_staging_db
+	$(staging_compose_cmd) run --rm staging_web python3 manage.py makemigrations
 	$(staging_compose_cmd) run --rm staging_web python3 manage.py migrate --database=dados --noinput
 	$(staging_compose_cmd) run --rm staging_web python3 manage.py migrate --database=infodengue --noinput
 	#$(staging_compose_cmd) run --rm staging_web python3 manage.py migrate --database=forecast --noinput
@@ -116,6 +122,12 @@ sync_mapfiles:
 run_alertadengue:
 	python AlertaDengue/manage.py runserver
 
+#
+# Uses for cron
+send_mail_partner:
+	$(compose_cmd) run --rm web python manage.py send_mail
+
+
 clean:
 	@find ./ -name '*.pyc' -exec rm -f {} \;
 	@find ./ -name '*.pyo' -exec rm -f {} \;
diff --git a/docker/Dockerfile b/docker/Dockerfile
index de7cef9d..be1da289 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -1,15 +1,15 @@
 FROM continuumio/miniconda3
 
 RUN apt-get -qq update --yes \
- && apt-get -qq install --yes --no-install-recommends \
-    build-essential git make postgresql-client \
-    ca-certificates wget locales \
- && rm -rf /var/lib/apt/lists/*
+  && apt-get -qq install --yes --no-install-recommends \
+  build-essential git make postgresql-client \
+  ca-certificates wget locales cron \
+  && rm -rf /var/lib/apt/lists/*
 
 #Set locale
 RUN sed -i -e "s/# pt_BR.*/pt_BR.UTF-8 UTF-8/" /etc/locale.gen \
-    && dpkg-reconfigure --frontend=noninteractive locales \
-    && update-locale LANG=pt_BR.UTF-8
+  && dpkg-reconfigure --frontend=noninteractive locales \
+  && update-locale LANG=pt_BR.UTF-8
 
 # Configure conda-channels
 RUN conda config --add channels conda-forge \
@@ -29,24 +29,35 @@ ARG HOST_UID
 ARG HOST_GID
 COPY docker/prepare_permission.sh /prepare_permission.sh
 RUN /prepare_permission.sh
-# copy code to the container and attribute permissions to user
-RUN mkdir /srv/deploy/logs \
-  && chown -R deploy:deploy /srv/deploy/logs
+
+## Copy code to the container with permissions to user
 # folders
 COPY --chown=deploy:deploy docker  /srv/deploy/docker
 COPY --chown=deploy:deploy AlertaDengue  /srv/deploy/AlertaDengue
 # files
 COPY --chown=deploy:deploy requirements.txt example_env_file /srv/deploy/
 
+RUN cp -p /srv/deploy/example_env_file /srv/deploy/.env
+
+RUN mkdir /srv/deploy/logs \
+  && chown -R deploy:deploy /srv/deploy/logs
+
 # Create script activate environment
 RUN echo 'source /opt/conda/bin/activate base && exec "$@"' > activate.sh
 RUN chmod +x /activate.sh
 WORKDIR /srv/deploy/AlertaDengue
 
-RUN cp -p /srv/deploy/example_env_file /srv/deploy/.env_staging
+# Configure cron for DBF request
+COPY docker/cron-sendmail /etc/cron.d/cron-sendmail
+RUN chmod 0644 /etc/cron.d/cron-sendmail \
+  && crontab -u deploy /etc/cron.d/cron-sendmail \
+  && echo "deploy"  > /etc/cron.allow \
+  && touch /var/log/cron.log \
+  && chown deploy:deploy /var/log/cron.log
+
+ADD docker/entrypoint.sh /entrypoint.sh
 
-EXPOSE 8000
-USER deploy
+# USER deploy
 
 ENTRYPOINT ["bash", "/activate.sh"]
-CMD ["/srv/deploy/AlertaDengue/runwsgi.sh"]
+CMD ["/entrypoint.sh", "/srv/deploy/AlertaDengue/runwsgi.sh"]
diff --git a/docker/Dockerfile-dev b/docker/Dockerfile-dev
index 17ed8457..dfbf02b3 100755
--- a/docker/Dockerfile-dev
+++ b/docker/Dockerfile-dev
@@ -1,10 +1,10 @@
 FROM continuumio/miniconda3
 
 RUN apt-get -qq update --yes \
- && apt-get -qq install --yes --no-install-recommends \
-    build-essential git make postgresql-client \
-    ca-certificates wget locales \
- && rm -rf /var/lib/apt/lists/*
+  && apt-get -qq install --yes --no-install-recommends \
+  build-essential git make postgresql-client \
+  ca-certificates wget locales cron \
+  && rm -rf /var/lib/apt/lists/*
 
 # Set locale
 RUN echo "pt_BR.UTF-8 UTF-8" > /etc/locale.gen
@@ -31,14 +31,18 @@ RUN /opt/conda/bin/conda config --add channels conda-forge \
 
 ENV PATH="/opt/conda/bin:${PATH}"
 
-# copy code to the container
-# Change the permissions for the user home directory
-RUN mkdir /srv/deploy/logs
+## Copy code to the container with permissions to user
 # folders
-COPY --chown=deploy docker  /srv/deploy/docker
-COPY --chown=deploy AlertaDengue  /srv/deploy/AlertaDengue
+COPY --chown=deploy:deploy docker  /srv/deploy/docker
+COPY --chown=deploy:deploy AlertaDengue  /srv/deploy/AlertaDengue
+
 # files
-COPY --chown=deploy pyproject.toml setup.cfg setup.py .pre-commit-config.yaml LICENSE README.md HISTORY.md requirements-dev.txt requirements.txt example_env_file /srv/deploy/
+COPY --chown=deploy pyproject.toml setup.cfg setup.py .pre-commit-config.yaml LICENSE README.md HISTORY.md /srv/deploy/
+COPY --chown=deploy requirements-dev.txt requirements.txt /srv/deploy/
+COPY --chown=deploy example_env_file /srv/deploy/.env_staging
+
+RUN mkdir /srv/deploy/logs \
+  && chown -R deploy:deploy /srv/deploy/logs
 
 RUN pip install -r /srv/deploy/requirements-dev.txt
 
@@ -47,13 +51,20 @@ RUN echo 'source /opt/conda/bin/activate base && exec "$@"' > activate.sh
 RUN chmod +x /activate.sh
 WORKDIR /srv/deploy/AlertaDengue
 
-RUN cp /srv/deploy/example_env_file /srv/deploy/.env_staging
-
 # install the AlertaDengue
 RUN cd ..; pip install -e .
 
-EXPOSE 8000
-USER deploy
+# configure cron for DBF request
+COPY docker/cron-sendmail /etc/cron.d/cron-sendmail
+RUN chmod 0644 /etc/cron.d/cron-sendmail \
+  && crontab -u deploy /etc/cron.d/cron-sendmail \
+  && echo "deploy"  > /etc/cron.allow \
+  && touch /var/log/cron.log \
+  && chown deploy:deploy /var/log/cron.log
+
+ADD docker/entrypoint.sh /entrypoint.sh
+
+# USER deploy
 
 ENTRYPOINT ["bash", "/activate.sh"]
-CMD ["/srv/deploy/AlertaDengue/runwsgi.sh"]
+CMD ["/entrypoint.sh", "/srv/deploy/AlertaDengue/runwsgi.sh"]
diff --git a/docker/cron-sendmail b/docker/cron-sendmail
new file mode 100644
index 00000000..934c99b2
--- /dev/null
+++ b/docker/cron-sendmail
@@ -0,0 +1,2 @@
+0 8 * * 1 echo "Start task cron" >> /var/log/cron.log 2>&1
+0 8 * * 1 bash /activate.sh python /srv/deploy/AlertaDengue/manage.py send_mail >> /var/log/cron.log 2>&1
diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh
new file mode 100755
index 00000000..cf19e427
--- /dev/null
+++ b/docker/entrypoint.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+echo "Executing the entrypoint!"
+echo "Force crond start"
+service cron restart
+echo "executing $@"
+$@


Test patch:
diff --git a/AlertaDengue/dbf/tests/__init__.py b/AlertaDengue/dbf/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/AlertaDengue/dbf/tests/test_mailing_partner.py b/AlertaDengue/dbf/tests/test_mailing_partner.py
new file mode 100644
index 00000000..a7825e16
--- /dev/null
+++ b/AlertaDengue/dbf/tests/test_mailing_partner.py
@@ -0,0 +1,51 @@
+from django.test import TestCase
+from dbf.models import SendToPartner
+from django.core import mail
+
+
+class SendToPartnerTest(TestCase):
+    """
+    Tests create partner and sent mail.
+    """
+
+    databases = ['infodengue', 'default']
+
+    def create_partner(self):
+        return SendToPartner.objects.create(
+            geocode=3304557,
+            name="Rio de Janeiro",
+            state_abbreviation="RJ",
+            level="Municipal",
+            contact="Secretária",
+            mail="sec.test@gov.br",
+            status=True,
+        )
+
+    def test_create_partner(self):
+        partner = self.create_partner()
+        self.assertEqual(partner.geocode, 3304557)
+        self.assertEqual(partner.name, "Rio de Janeiro")
+        self.assertEqual(partner.state_abbreviation, "RJ")
+        self.assertEqual(partner.level, 'Municipal')
+        self.assertEqual(partner.contact, 'Secretária')
+        self.assertEqual(partner.mail, 'sec.test@gov.br')
+
+    def test_send_mail(self):
+        partner = self.create_partner()
+        week = '02'
+        mail_from = 'info_dengue@gmail.com'
+        mail_text = 'Here is the message.'
+        mail_subject = f'Informe de dados Infodengue SE {week}'
+        mail_to = str(partner.mail)
+        mail.send_mail(
+            mail_subject, mail_text, mail_from, [mail_to], fail_silently=False,
+        )
+
+        # Test that one message has been sent.
+        self.assertEqual(len(mail.outbox), 1)
+
+        # Verify that the subject of the first message is correct.
+        self.assertEqual(
+            mail.outbox[0].subject, f'Informe de dados Infodengue SE {week}'
+        )
+        self.assertEqual(partner.name, 'Rio de Janeiro')
diff --git a/AlertaDengue/dbf/tests/test_models.py b/AlertaDengue/dbf/tests/test_models.py
index 7f2e4ce7..5990704a 100644
--- a/AlertaDengue/dbf/tests/test_models.py
+++ b/AlertaDengue/dbf/tests/test_models.py
@@ -5,6 +5,8 @@
 from django.test import TestCase
 from datetime import date
 from mock import patch
+import unittest
+
 
 # local
 from django.apps import apps
@@ -16,6 +18,7 @@
 TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data/")
 
 
+@unittest.skip("reason='Issue #416'")
 class DBFModelTest(TestCase):
     fixtures = ['users']
 
diff --git a/AlertaDengue/dbf/tests/test_validation.py b/AlertaDengue/dbf/tests/test_validation.py
index a4122692..36005aab 100644
--- a/AlertaDengue/dbf/tests/test_validation.py
+++ b/AlertaDengue/dbf/tests/test_validation.py
@@ -3,10 +3,12 @@
 from django.core.files import File
 from django.test import TestCase
 from datetime import date
+import unittest
+
 
 # local
-from AlertaDengue.dbf.models import DBF
-from AlertaDengue.dbf.validation import is_valid_dbf
+from dbf.models import DBF
+from dbf.validation import is_valid_dbf
 
 import datetime
 import os
@@ -16,6 +18,7 @@
 TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data/")
 
 
+@unittest.skip("reason='Issue #416'")
 class DBFValidationTest(TestCase):
     fixtures = ['users']
 
diff --git a/AlertaDengue/dbf/tests/test_views.py b/AlertaDengue/dbf/tests/test_views.py
index e0072e92..2c815a5d 100644
--- a/AlertaDengue/dbf/tests/test_views.py
+++ b/AlertaDengue/dbf/tests/test_views.py
@@ -2,14 +2,16 @@
 from django.contrib.auth.models import User
 from django.core.files.base import File
 from django.test import TestCase
+import unittest
+
 
 from django.urls import reverse
 
 from datetime import date
 
 # local
-from AlertaDengue.dbf.models import DBF, DBFChunkedUpload
-from AlertaDengue.dbf.forms import DBFForm
+from dbf.models import DBF, DBFChunkedUpload
+from dbf.forms import DBFForm
 
 
 __all__ = ["DBFUploadViewTest"]
@@ -18,6 +20,7 @@
 TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data/")
 
 
+@unittest.skip("reason='Issue #416'")
 class DBFUploadViewTest(TestCase):
     databases = ['infodengue', 'default']
     fixtures = ['AlertaDengue/dbf/fixtures/users.json']