Esempio n. 1
0
 def post(self, request, *args, **kwargs):
     try:
         new_openmrs_importers = json.loads(
             request.POST['openmrs_importers'])
         current_openmrs_importers = get_openmrs_importers_by_domain(
             request.domain)
         i = -1
         for i, openmrs_importer in enumerate(current_openmrs_importers):
             if i < len(new_openmrs_importers):
                 self._update_importer(openmrs_importer,
                                       new_openmrs_importers[i])
             else:
                 # Delete removed OpenMRS Importers
                 openmrs_importer.delete()
         if i + 1 < len(new_openmrs_importers):
             # Insert new OpenMRS Importers
             for j in range(i + 1, len(new_openmrs_importers)):
                 openmrs_importer = OpenmrsImporter(domain=request.domain)
                 self._update_importer(openmrs_importer,
                                       new_openmrs_importers[j])
         get_openmrs_importers_by_domain.clear(request.domain)
         return json_response({
             'message': _('OpenMRS Importers saved'),
             'error': None
         })
     except Exception as err:
         return json_response({
             'message': None,
             'error': str(err)
         },
                              status_code=500)
Esempio n. 2
0
    def page_context(self):
        # TODO: Look up locations for location_id field.

        openmrs_importers = []
        for importer in get_openmrs_importers_by_domain(self.request.domain):
            dict_ = dict(importer)
            dict_['password'] = PASSWORD_PLACEHOLDER
            dict_['report_params'] = json.dumps(dict_['report_params'],
                                                cls=DjangoJSONEncoder,
                                                indent=2)
            dict_['column_map'] = json.dumps(
                [
                    {
                        k: v
                        for k, v in dict(m).items() if not (
                            # Drop '"doc_type": ColumnMapping' from each column mapping.
                            k == 'doc_type' or
                            # Drop "data_type" if it's not specified
                            (k == 'data_type' and v is None))
                    } for m in dict_['column_map']
                ],
                indent=2)
            openmrs_importers.append(dict_)
        return {
            'openmrs_importers': openmrs_importers,
            'form': OpenmrsImporterForm(
            ),  # Use an unbound form to render openmrs_importer_template.html
        }
Esempio n. 3
0
    def save(self, domain_name):
        try:
            importers = get_openmrs_importers_by_domain(domain_name)
            importer = importers[0] if importers else None  # TODO: Support multiple
            if importer is None:
                importer = OpenmrsImporter(domain=domain_name)
            importer.server_url = self.cleaned_data['server_url']
            importer.username = self.cleaned_data['username']
            if self.cleaned_data['password']:
                # Don't save it if it hasn't been changed.
                importer.password = b64_aes_encrypt(self.cleaned_data['password'])
            importer.location_id = self.cleaned_data['location_id']
            importer.import_frequency = self.cleaned_data['import_frequency']
            importer.log_level = self.cleaned_data['log_level']

            importer.report_uuid = self.cleaned_data['report_uuid']
            importer.report_params = self.cleaned_data['report_params']
            importer.case_type = self.cleaned_data['case_type']
            importer.owner_id = self.cleaned_data['owner_id']
            importer.location_type_name = self.cleaned_data['location_type_name']
            importer.external_id_column = self.cleaned_data['external_id_column']
            importer.name_columns = self.cleaned_data['name_columns']
            importer.column_map = list(map(ColumnMapping.wrap, self.cleaned_data['column_map']))
            importer.save()
            return True
        except Exception as err:
            logging.error('Unable to save OpenMRS Importer: %s' % err)
            return False
Esempio n. 4
0
 def openmrs_importer_form(self):
     importers = get_openmrs_importers_by_domain(self.request.domain)
     if importers:
         initial = dict(importers[0])  # TODO: Support multiple
         initial['column_map'] = [
             {k: v
              for k, v in dict(m).items()
              if k != 'doc_type'}  # Just for the pretty
             for m in initial['column_map']
         ]
     else:
         initial = {}
     if self.request.method == 'POST':
         return OpenmrsImporterForm(self.request.POST, initial=initial)
     return OpenmrsImporterForm(initial=initial)
Esempio n. 5
0
 def post(self, request, *args, **kwargs):
     try:
         new_openmrs_importers = json.loads(request.POST['openmrs_importers'])
         current_openmrs_importers = get_openmrs_importers_by_domain(request.domain)
         i = -1
         for i, openmrs_importer in enumerate(current_openmrs_importers):
             if i < len(new_openmrs_importers):
                 self._update_importer(openmrs_importer, new_openmrs_importers[i])
             else:
                 # Delete removed OpenMRS Importers
                 openmrs_importer.delete()
         if i + 1 < len(new_openmrs_importers):
             # Insert new OpenMRS Importers
             for j in range(i + 1, len(new_openmrs_importers)):
                 openmrs_importer = OpenmrsImporter(domain=request.domain)
                 self._update_importer(openmrs_importer, new_openmrs_importers[j])
         get_openmrs_importers_by_domain.clear(request.domain)
         return json_response({'message': _('OpenMRS Importers saved'), 'error': None})
     except Exception as err:
         return json_response({'message': None, 'error': str(err)}, status_code=500)
Esempio n. 6
0
    def page_context(self):
        # TODO: Look up locations for location_id field.

        openmrs_importers = []
        for importer in get_openmrs_importers_by_domain(self.request.domain):
            dict_ = dict(importer)
            dict_['password'] = PASSWORD_PLACEHOLDER
            dict_['report_params'] = json.dumps(dict_['report_params'], indent=2)
            dict_['column_map'] = json.dumps([
                {k: v for k, v in dict(m).items() if not (
                    # Drop '"doc_type": ColumnMapping' from each column mapping.
                    k == 'doc_type' or
                    # Drop "data_type" if it's not specified
                    (k == 'data_type' and v is None)
                )}
                for m in dict_['column_map']
            ], indent=2)
            openmrs_importers.append(dict_)
        return {
            'openmrs_importers': openmrs_importers,
            'form': OpenmrsImporterForm(),  # Use an unbound form to render openmrs_importer_template.html
        }
Esempio n. 7
0
def import_patients_to_domain(domain_name, force=False):
    """
    Iterates OpenmrsImporters of a domain, and imports patients

    Who owns the imported cases?

    If `importer.owner_id` is set, then the server will be queried
    once. All patients, regardless of their location, will be assigned
    to the mobile worker whose ID is `importer.owner_id`.

    If `importer.location_type_name` is set, then check whether the
    OpenmrsImporter's location is set with `importer.location_id`.

    If `importer.location_id` is given, then the server will be queried
    for each location among its descendants whose type is
    `importer.location_type_name`. The request's query parameters will
    include that descendant location's OpenMRS UUID. Imported cases
    will be owned by the first mobile worker in that location.

    If `importer.location_id` is given, then the server will be queried
    for each location in the project space whose type is
    `importer.location_type_name`. As when `importer.location_id` is
    specified, the request's query parameters will include that
    location's OpenMRS UUID, and imported cases will be owned by the
    first mobile worker in that location.

    ..NOTE:: As you can see from the description above, if
             `importer.owner_id` is set then `importer.location_id` is
             not used.

    :param domain_name: The name of the domain
    :param force: Import regardless of the configured import frequency / today's date
    """
    for importer in get_openmrs_importers_by_domain(domain_name):
        if importer.should_import_today() or force:
            import_patients_with_importer.delay(importer.to_json())
Esempio n. 8
0
def import_patients_to_domain(domain_name, force=False):
    """
    Iterates OpenmrsImporters of a domain, and imports patients

    Who owns the imported cases?

    If `importer.owner_id` is set, then the server will be queried
    once. All patients, regardless of their location, will be assigned
    to the mobile worker whose ID is `importer.owner_id`.

    If `importer.location_type_name` is set, then check whether the
    OpenmrsImporter's location is set with `importer.location_id`.

    If `importer.location_id` is given, then the server will be queried
    for each location among its descendants whose type is
    `importer.location_type_name`. The request's query parameters will
    include that descendant location's OpenMRS UUID. Imported cases
    will be owned by the first mobile worker in that location.

    If `importer.location_id` is given, then the server will be queried
    for each location in the project space whose type is
    `importer.location_type_name`. As when `importer.location_id` is
    specified, the request's query parameters will include that
    location's OpenMRS UUID, and imported cases will be owned by the
    first mobile worker in that location.

    ..NOTE:: As you can see from the description above, if
             `importer.owner_id` is set then `importer.location_id` is
             not used.

    :param domain_name: The name of the domain
    :param force: Import regardless of the configured import frequency / today's date
    """
    today = datetime.today()
    for importer in get_openmrs_importers_by_domain(domain_name):
        if not force and importer.import_frequency == IMPORT_FREQUENCY_WEEKLY and today.weekday(
        ) != 1:
            continue  # Import on Tuesdays
        if not force and importer.import_frequency == IMPORT_FREQUENCY_MONTHLY and today.day != 1:
            continue  # Import on the first of the month
        # TODO: ^^^ Make those configurable

        password = b64_aes_decrypt(importer.password)
        requests = Requests(domain_name, importer.server_url,
                            importer.username, password)
        if importer.location_type_name:
            try:
                location_type = LocationType.objects.get(
                    domain=domain_name, name=importer.location_type_name)
            except LocationType.DoesNotExist:
                logger.error(
                    'No organization level named "{location_type}" found in project space "{domain}".'
                    .format(location_type=importer.location_type_name,
                            domain=domain_name))
                continue
            if importer.location_id:
                location = SQLLocation.objects.filter(domain=domain_name).get(
                    importer.location_id)
                locations = location.get_descendants.filter(
                    location_type=location_type)
            else:
                locations = SQLLocation.objects.filter(
                    domain=domain_name, location_type=location_type)
            for location in locations:
                # Assign cases to the first user in the location, not to the location itself
                owner = get_one_commcare_user_at_location(
                    domain_name, location.location_id)
                if not owner:
                    logger.error(
                        'Project space "{domain}" at location "{location}" has no user to own cases imported from '
                        'OpenMRS Importer "{importer}"'.format(
                            domain=domain_name,
                            location=location.name,
                            importer=importer))
                    continue
                import_patients_of_owner(requests, importer, domain_name,
                                         owner, location)
        elif importer.owner_id:
            try:
                owner = CommCareUser.get(importer.owner_id)
            except ResourceNotFound:
                logger.error(
                    'Project space "{domain}" has no user to own cases imported from OpenMRS Importer '
                    '"{importer}"'.format(domain=domain_name,
                                          importer=importer))
                continue
            import_patients_of_owner(requests, importer, domain_name, owner)
        else:
            logger.error(
                'Error importing patients for project space "{domain}" from OpenMRS Importer "{importer}": Unable '
                'to determine the owner of imported cases without either owner_id or location_type_name'
                .format(domain=domain_name, importer=importer))
            continue
Esempio n. 9
0
def import_patients_to_domain(domain_name, force=False):
    """
    Iterates OpenmrsImporters of a domain, and imports patients

    Who owns the imported cases?

    If `importer.owner_id` is set, then the server will be queried
    once. All patients, regardless of their location, will be assigned
    to the mobile worker whose ID is `importer.owner_id`.

    If `importer.location_type_name` is set, then check whether the
    OpenmrsImporter's location is set with `importer.location_id`.

    If `importer.location_id` is given, then the server will be queried
    for each location among its descendants whose type is
    `importer.location_type_name`. The request's query parameters will
    include that descendant location's OpenMRS UUID. Imported cases
    will be owned by the first mobile worker in that location.

    If `importer.location_id` is given, then the server will be queried
    for each location in the project space whose type is
    `importer.location_type_name`. As when `importer.location_id` is
    specified, the request's query parameters will include that
    location's OpenMRS UUID, and imported cases will be owned by the
    first mobile worker in that location.

    ..NOTE:: As you can see from the description above, if
             `importer.owner_id` is set then `importer.location_id` is
             not used.

    :param domain_name: The name of the domain
    :param force: Import regardless of the configured import frequency / today's date
    """
    today = datetime.today()
    for importer in get_openmrs_importers_by_domain(domain_name):
        if not force and importer.import_frequency == IMPORT_FREQUENCY_WEEKLY and today.weekday() != 1:
            continue  # Import on Tuesdays
        if not force and importer.import_frequency == IMPORT_FREQUENCY_MONTHLY and today.day != 1:
            continue  # Import on the first of the month
        # TODO: ^^^ Make those configurable

        password = b64_aes_decrypt(importer.password)
        requests = Requests(domain_name, importer.server_url, importer.username, password)
        if importer.location_type_name:
            try:
                location_type = LocationType.objects.get(domain=domain_name, name=importer.location_type_name)
            except LocationType.DoesNotExist:
                logger.error(
                    'No organization level named "{location_type}" found in project space "{domain}".'.format(
                        location_type=importer.location_type_name, domain=domain_name)
                )
                continue
            if importer.location_id:
                location = SQLLocation.objects.filter(domain=domain_name).get(importer.location_id)
                locations = location.get_descendants.filter(location_type=location_type)
            else:
                locations = SQLLocation.objects.filter(domain=domain_name, location_type=location_type)
            for location in locations:
                # Assign cases to the first user in the location, not to the location itself
                owner = get_one_commcare_user_at_location(domain_name, location.location_id)
                if not owner:
                    logger.error(
                        'Project space "{domain}" at location "{location}" has no user to own cases imported from '
                        'OpenMRS Importer "{importer}"'.format(
                            domain=domain_name, location=location.name, importer=importer)
                    )
                    continue
                import_patients_of_owner(requests, importer, domain_name, owner, location)
        elif importer.owner_id:
            try:
                owner = CommCareUser.get(importer.owner_id)
            except ResourceNotFound:
                logger.error(
                    'Project space "{domain}" has no user to own cases imported from OpenMRS Importer '
                    '"{importer}"'.format(
                        domain=domain_name, importer=importer)
                )
                continue
            import_patients_of_owner(requests, importer, domain_name, owner)
        else:
            logger.error(
                'Error importing patients for project space "{domain}" from OpenMRS Importer "{importer}": Unable '
                'to determine the owner of imported cases without either owner_id or location_type_name'.format(
                    domain=domain_name, importer=importer)
            )
            continue