Example #1
0
    def test_can_perform_deprecation(self, *mocks):
        transition = Transition(domain=self.domain,
                                location_type_code='city',
                                operation=MoveOperation.type)
        transition.add(old_site_code=self.locations['Boston'].site_code,
                       new_site_code='new_boston',
                       new_location_details={
                           'name': 'New Boston',
                           'parent_site_code':
                           self.locations['Suffolk'].site_code,
                           'lgd_code': 'New Boston LGD Code',
                           'sub_district_name': 'New Boston Sub District'
                       },
                       old_username="******",
                       new_username="******")

        location = self.locations['Boston']
        location.metadata[DEPRECATED_VIA] = MergeOperation.type
        location.save()
        with self.assertRaisesMessage(
                InvalidTransitionError,
                "Move operation: location Boston with site code boston cannot be deprecated again."
        ):
            transition.perform()

        location = self.locations['Boston']
        location.metadata[DEPRECATED_VIA] = ExtractOperation.type
        location.save()

        location = self.locations['Boston']
        location.metadata[DEPRECATED_VIA] = ExtractOperation.type
        location.save()
        transition.perform()
        self._validate_operation(transition.operation_obj, archived=True)
Example #2
0
def email_other_cases_details(domain, transitions, uploaded_filename, user_email):
    try:
        transition_objs = [Transition(**transition) for transition in transitions]
        filestream = OtherCases(domain).dump(transition_objs)
    except Exception as e:
        notify_failure(
            e,
            subject=f"[{settings.SERVER_ENVIRONMENT}] - Location Reassignment Other Cases Dump Failed",
            email=user_email,
            uploaded_filename=uploaded_filename
        )
        raise e
    else:
        body = f"The request has been successfully completed for file {uploaded_filename}. "
        if not filestream:
            body += "There were no cases found. "
        body += f"Please note that the cases are fetched only for " \
                f"{', '.join(OtherCases.valid_operations)}."
        notify_success(
            subject=f"[{settings.SERVER_ENVIRONMENT}] - Location Reassignment Other Cases Dump Completed",
            body=body,
            email=user_email,
            filestream=filestream,
            filename=f"Other Cases - {uploaded_filename.split('.')[0]}.xlsx"
        )
Example #3
0
def email_other_cases_details(domain, transitions, uploaded_filename,
                              user_email):
    try:
        transition_objs = [
            Transition(**transition) for transition in transitions
        ]
        filestream = OtherCases(domain).dump(transition_objs)
    except Exception as e:
        email = EmailMessage(
            subject=
            f"[{settings.SERVER_ENVIRONMENT}] - Location Reassignment Other Cases Dump Failed",
            body=linebreaksbr(
                f"The request could not be completed for file {uploaded_filename}. Something went wrong.\n"
                f"Error raised : {e}.\n"
                "Please report an issue if needed."),
            to=[user_email],
            from_email=settings.DEFAULT_FROM_EMAIL)
        email.content_subtype = "html"
        email.send()
        raise e
    else:
        email = EmailMessage(
            subject=
            f"[{settings.SERVER_ENVIRONMENT}] - Location Reassignment Other Cases Dump Completed",
            body=
            f"The request has been successfully completed for file {uploaded_filename}. ",
            to=[user_email],
            from_email=settings.DEFAULT_FROM_EMAIL)
        if filestream:
            email.attach(filename="Other Cases.zip", content=filestream.read())
        else:
            email.body += "There were no cases found. "
        email.body += f"Please note that the cases are fetched only for " \
                      f"{', '.join(OtherCases.valid_operations)}."
        email.send()
Example #4
0
 def _consolidated_transition(self, location_type_code, operation, rows):
     transition = Transition(domain=self.domain, location_type_code=location_type_code, operation=operation)
     for row in rows:
         if row.new_site_code in transition.new_location_details:
             # new location is passed with different details
             if transition.new_location_details[row.new_site_code] != row.new_location_details:
                 self.errors.append(f"New location {row.new_site_code} passed with different information")
                 return None
         transition.add(
             old_site_code=row.old_site_code,
             new_site_code=row.new_site_code,
             new_location_details=row.new_location_details,
             old_username=row.old_username,
             new_username=row.new_username
         )
     return transition
Example #5
0
def deprecate_locations(domain, old_locations, new_locations, operation):
    """
    add metadata on locations
    on old locations, add
    1. DEPRECATED_TO: [list] would be a single location except in case of a split
    2. DEPRECATION_OPERATION: this location was deprecated by a merge/split/extract/move operation
    3. DEPRECATED_AT: [dict] new location id mapped to the timestamp of deprecation performed
    for new locations location
    1. DEPRECATES: [list] append this location id on it. This would be more than one location in case of merge
    :param domain: domain name
    :param old_locations: the locations to deprecate
    :param new_locations: the location that deprecates these location
    :param operation: the operation being performed, split/merge/move/extract
    :return: errors in case of failure
    """
    transition = Transition(domain, operation, old_locations, new_locations)
    if transition.valid():
        transition.perform()
        for old_location in old_locations:
            deactivate_users_at_location(old_location.location_id)
    return transition.errors
Example #6
0
 def test_invalid_operation(self, deactivate_users_mock,
                            update_usercase_mock):
     transition = Transition(domain=self.domain,
                             location_type_code='city',
                             operation=MoveOperation.type)
     transition.add(old_site_code='missing_old_location',
                    new_site_code='new_boston',
                    new_location_details={
                        'name': 'New Boston',
                        'parent_site_code':
                        self.locations['Suffolk'].site_code,
                        'lgd_code': 'New Boston LGD Code',
                        'sub_district_name': None
                    },
                    old_username="******",
                    new_username="******")
     self.assertEqual(
         SQLLocation.objects.filter(domain=self.domain,
                                    site_code='new_boston').count(), 0)
     with self.assertRaisesMessage(
             InvalidTransitionError,
             "Could not load location with following site codes: missing_old_location"
     ):
         transition.perform()
     self.assertEqual(
         SQLLocation.objects.filter(domain=self.domain,
                                    site_code='new_boston').count(), 0,
         "Unexpected new location created")
     deactivate_users_mock.assert_not_called()
     update_usercase_mock.assert_not_called()
Example #7
0
 def test_perform(self, deactivate_users_mock, update_usercase_mock):
     transition = Transition(domain=self.domain,
                             location_type_code='city',
                             operation=MoveOperation.type)
     transition.add(old_site_code=self.locations['Boston'].site_code,
                    new_site_code='new_boston',
                    new_location_details={
                        'name': 'New Boston',
                        'parent_site_code':
                        self.locations['Suffolk'].site_code,
                        'lgd_code': 'New Boston LGD Code',
                        'sub_district_name': 'New Boston Sub District'
                    },
                    old_username="******",
                    new_username="******")
     self.assertEqual(
         SQLLocation.objects.filter(domain=self.domain,
                                    site_code='new_boston').count(), 0,
         "New location already present")
     transition.perform()
     self._validate_operation(transition.operation_obj, archived=True)
     new_location = SQLLocation.active_objects.get_or_None(
         domain=self.domain, site_code='new_boston')
     self.assertIsNotNone(new_location,
                          "New location not created successfully")
     self.assertEqual(new_location.metadata[LGD_CODE],
                      'New Boston LGD Code')
     self.assertEqual(new_location.metadata[MAP_LOCATION_NAME],
                      'New Boston Sub District')
     deactivate_users_mock.assert_called_with(
         self.locations['Boston'].location_id)
     update_usercase_mock.assert_called_with(self.domain, "ethan",
                                             "aquaman")
Example #8
0
 def process(self):
     # process each sheet, in order of hierarchy
     # so that newly created parent locations are present when needed
     for location_type_code in self.location_types_by_code:
         for transition in self.transitions[location_type_code]:
             Transition(**transition).perform()
Example #9
0
    def test_dump(self, get_location_mock, get_household_case_ids_mock, case_accessor_mock, child_cases_mock):
        location = Location(site_code='123', location_id='123654789')
        get_location_mock.return_value = location
        get_household_case_ids_mock.return_value = ['1', '2']
        case_accessor_mock.return_value = CommCareCaseStub(
            '100', 'A House', {'hh_reg_date': '20/1/1988', 'hh_religion': 'Above All'})
        child_cases_mock.return_value = [
            CommCareCaseStub('101', 'A Person', {'age_at_reg': '4', 'sex': 'M'}),
            CommCareCaseStub('102', 'B Person', {'age_at_reg': '5', 'sex': 'F'}),
        ]
        transitions = [
            Transition(
                domain=self.domain,
                location_type_code='awc',
                operation=MOVE_OPERATION,
                old_site_codes=['111'],
                new_site_codes=['112']),
            Transition(
                domain=self.domain,
                location_type_code='awc',
                operation=MERGE_OPERATION,
                old_site_codes=['113', '114'],
                new_site_codes=['115']),
            Transition(
                domain=self.domain,
                location_type_code='awc',
                operation=SPLIT_OPERATION,
                old_site_codes=['116'],
                new_site_codes=['117', '118']),
            Transition(
                domain=self.domain,
                location_type_code='awc',
                operation=EXTRACT_OPERATION,
                old_site_codes=['119'],
                new_site_codes=['120'])
        ]

        filestream = Households(self.domain).dump(transitions)

        get_location_mock.assert_has_calls([
            call(domain='test', site_code='116'),
            call(domain='test', site_code='119')
        ])
        get_household_case_ids_mock.assert_has_calls([
            call(self.domain, location.location_id),
            call(self.domain, location.location_id)
        ])
        case_accessor_mock.assert_has_calls([
            call('1'), call('2')
        ])
        child_cases_mock.assert_has_calls([
            call(self.domain, '1', location.location_id, [PERSON_CASE_TYPE]),
            call(self.domain, '2', location.location_id, [PERSON_CASE_TYPE])
        ])

        workbook = get_workbook(filestream)
        self.assertEqual(len(workbook.worksheets), 2)
        expected_row = {
            AWC_NAME_COLUMN: '',
            AWC_CODE_COLUMN: '',
            'Name of Household': 'A House',
            'Date of Registration': '20/1/1988',
            'Religion': 'Above All',
            'Caste': '',
            'APL/BPL': '',
            'Number of Household Members': 2,
            HOUSEHOLD_MEMBER_DETAILS_COLUMN: 'A Person (4/M), B Person (5/F)',
            HOUSEHOLD_ID_COLUMN: '100'
        }
        worksheet1_rows = list(workbook.worksheets_by_title['116'])
        self.assertEqual(
            worksheet1_rows,
            [expected_row, expected_row]
        )
        worksheet2_rows = list(workbook.worksheets_by_title['119'])
        self.assertEqual(
            worksheet2_rows,
            [expected_row, expected_row]
        )
Example #10
0
    def test_dump(self, mock_active_site_codes_search,
                  mock_inactive_site_codes_search, mock_case_count,
                  mock_location_ids):
        mock_case_count.return_value = []
        transitions = {
            'awc': [
                Transition(domain=self.domain,
                           location_type_code='awc',
                           operation=MOVE_OPERATION,
                           old_site_codes=['111'],
                           new_site_codes=['112']),
                Transition(domain=self.domain,
                           location_type_code='awc',
                           operation=MERGE_OPERATION,
                           old_site_codes=['113', '114'],
                           new_site_codes=['115']),
                Transition(domain=self.domain,
                           location_type_code='awc',
                           operation=SPLIT_OPERATION,
                           old_site_codes=['116'],
                           new_site_codes=['117', '118']),
                Transition(domain=self.domain,
                           location_type_code='awc',
                           operation=EXTRACT_OPERATION,
                           old_site_codes=['119'],
                           new_site_codes=['120'])
            ],
            'supervisor': [
                Transition(domain=self.domain,
                           location_type_code='awc',
                           operation=MOVE_OPERATION,
                           old_site_codes=['12'],
                           new_site_codes=['13']),
            ],
            'state': {}
        }

        mock_location_ids.return_value = {
            '111': 'locationid111',
            '113': 'locationid113',
            '114': 'locationid114',
            '116': 'locationid116',
            '119': 'locationid119',
            '12': 'locationid12'
        }
        mock_active_site_codes_search.return_value.values_list.return_value = [
            '112', '115', '117'
        ]
        mock_inactive_site_codes_search.return_value.values_list.return_value = [
            '120'
        ]
        filestream = Dumper(self.domain).dump(transitions)
        workbook = get_workbook(filestream)
        awc_worksheet_rows = list(workbook.get_worksheet('awc'))
        supervisor_worksheet_rows = list(workbook.get_worksheet('supervisor'))
        self.assertEqual(supervisor_worksheet_rows, [{
            OLD_LOCATION_CODE_COLUMN: '12',
            TRANSITION_COLUMN: MOVE_OPERATION,
            NEW_LOCATION_CODE_COLUMN: '13',
            MISSING_COLUMN: True,
            ARCHIVED_COLUMN: False,
            CASE_COUNT_COLUMN: 0
        }])
        self.assertEqual(awc_worksheet_rows, [{
            OLD_LOCATION_CODE_COLUMN: '111',
            TRANSITION_COLUMN: MOVE_OPERATION,
            NEW_LOCATION_CODE_COLUMN: '112',
            MISSING_COLUMN: False,
            ARCHIVED_COLUMN: False,
            CASE_COUNT_COLUMN: 0
        }, {
            OLD_LOCATION_CODE_COLUMN: '113',
            TRANSITION_COLUMN: MERGE_OPERATION,
            NEW_LOCATION_CODE_COLUMN: '115',
            MISSING_COLUMN: False,
            ARCHIVED_COLUMN: False,
            CASE_COUNT_COLUMN: 0
        }, {
            OLD_LOCATION_CODE_COLUMN: '114',
            TRANSITION_COLUMN: MERGE_OPERATION,
            NEW_LOCATION_CODE_COLUMN: '115',
            MISSING_COLUMN: False,
            ARCHIVED_COLUMN: False,
            CASE_COUNT_COLUMN: 0
        }, {
            OLD_LOCATION_CODE_COLUMN: '116',
            TRANSITION_COLUMN: SPLIT_OPERATION,
            NEW_LOCATION_CODE_COLUMN: '117',
            MISSING_COLUMN: False,
            ARCHIVED_COLUMN: False,
            CASE_COUNT_COLUMN: 0
        }, {
            OLD_LOCATION_CODE_COLUMN: '116',
            TRANSITION_COLUMN: SPLIT_OPERATION,
            NEW_LOCATION_CODE_COLUMN: '118',
            MISSING_COLUMN: True,
            ARCHIVED_COLUMN: False,
            CASE_COUNT_COLUMN: 0
        }, {
            OLD_LOCATION_CODE_COLUMN: '119',
            TRANSITION_COLUMN: EXTRACT_OPERATION,
            NEW_LOCATION_CODE_COLUMN: '120',
            MISSING_COLUMN: True,
            ARCHIVED_COLUMN: True,
            CASE_COUNT_COLUMN: 0
        }])