def handle(self, *args, **options):
     domain = 'care-bihar'
     root_types = ('cc_bihar_pregnancy', 'cc_bihar_newborn')
     TASK_TYPE = 'task'
     # loop through all mother cases, then all child cases
     # for each case get all associated tasks
     # if any duplicates found, clean up / print them
     with open('bihar-duplicate-tasks.csv', 'wb') as f:
         writer = csv.writer(f, dialect=csv.excel)
         _dump_headings(writer)
         for case_type in root_types:
             for parent_case in get_cases_in_domain(domain, case_type):
                 try:
                     tasks = filter(
                         lambda subcase: subcase.type == TASK_TYPE,
                         parent_case.get_subcases())
                     if tasks:
                         types = [_task_id(t) for t in tasks]
                         unique_types = set(types)
                         if len(unique_types) != len(tasks):
                             for type_being_checked in unique_types:
                                 matching_cases = [
                                     t for t in tasks
                                     if _task_id(t) == type_being_checked
                                 ]
                                 if len(matching_cases) > 1:
                                     for row, case in _get_rows(
                                             parent_case, matching_cases):
                                         keep = row[-1]
                                         writer.writerow(row)
                                         if options['cleanup'] and not keep:
                                             _purge(case)
                 except Exception, e:
                     print 'error with case %s (%s)' % (parent_case._id, e)
 def handle(self, *args, **options):
     domain = 'care-bihar'
     root_types = ('cc_bihar_pregnancy', 'cc_bihar_newborn')
     TASK_TYPE = 'task'
     # loop through all mother cases, then all child cases
     # for each case get all associated tasks
     # if any duplicates found, clean up / print them
     with open('bihar-duplicate-tasks.csv', 'wb') as f:
         writer = csv.writer(f, dialect=csv.excel)
         _dump_headings(writer)
         for case_type in root_types:
             for parent_case in get_cases_in_domain(domain, case_type):
                 try:
                     tasks = filter(lambda subcase: subcase.type == TASK_TYPE, parent_case.get_subcases())
                     if tasks:
                         types = [_task_id(t) for t in tasks]
                         unique_types = set(types)
                         if len(unique_types) != len(tasks):
                             for type_being_checked in unique_types:
                                 matching_cases = [t for t in tasks if _task_id(t) == type_being_checked]
                                 if len(matching_cases) > 1:
                                     for row, case in _get_rows(parent_case, matching_cases):
                                         keep = row[-1]
                                         writer.writerow(row)
                                         if options['cleanup'] and not keep:
                                             _purge(case)
                 except Exception, e:
                     print 'error with case %s (%s)' % (parent_case._id, e)
Example #3
0
def new_update_case_properties():
    _domain = Domain.get_by_name(DOMAINS[0])
    if _domain is None:
        return
    time_zone = _domain.default_timezone
    time_zone = pytz.timezone(time_zone)
    past_21_date = past_x_date(time_zone, 21)
    past_42_date = past_x_date(time_zone, 42)
    for domain in DOMAINS:
        update_groups_index(domain)
        case_list = get_cases_in_domain(domain, type=TYPE)
        cases_to_modify = []
        for case in case_list:
            if case.closed:
                continue
            if not get_none_or_value(
                    case, "owner_id") or not get_none_or_value(
                        case, "date_admission") or not get_none_or_value(
                            case, "facility_id"):
                continue
            curr_assignment = get_none_or_value(case, "current_assignment")
            next_assignment = get_none_or_value(case, "next_assignment")
            facility_id = get_none_or_value(case, "facility_id")
            fida_group = get_group_id(domain, "fida", facility_id)
            cati_owner_username = get_owner_username(domain, "cati",
                                                     facility_id)

            ## Assignment Directly from Registration ##
            # Assign Cases to Call Center
            if case.date_admission >= past_21_date and (
                    not curr_assignment) and (not next_assignment):
                owner_id = get_group_id(domain, "cati", facility_id)
                if not owner_id:
                    continue
                update = {"owner_id": owner_id, "current_assignment": "cati"}
                cases_to_modify.append({
                    "case_id": case._id,
                    "update": update,
                    "close": False,
                })
            # Assign Cases Directly To Field
            elif (case.date_admission >=
                  past_42_date) and (case.date_admission < past_21_date) and (
                      not curr_assignment) and (not next_assignment):
                if not fida_group:
                    continue
                update = {
                    "current_assignment": "fida",
                    "owner_id": fida_group,
                    "cati_status": 'skipped',
                }
                cases_to_modify.append({
                    "case_id": case._id,
                    "update": update,
                    "close": False,
                })
Example #4
0
def indexed_facilities():
    facility_index = {}
    for domain in DOMAINS:
        current_domain_index = {}
        facilities = get_cases_in_domain(domain, type="facility")
        for facility in facilities:
            current_domain_index[facility.facility_id] = {
                "cati": facility.cati_user,
                "fida": facility.fida_user
            }
        facility_index[domain] = current_domain_index
    return facility_index
Example #5
0
def indexed_facilities():
    facility_index = {}
    for domain in DOMAINS:
        current_domain_index = {}
        facilities = get_cases_in_domain(domain, type="facility")
        for facility in facilities:
            current_domain_index[facility.facility_id] = {
                "cati": facility.cati_user,
                "fida": facility.fida_user
            }
        facility_index[domain] = current_domain_index
    return facility_index
 def test_simple(self):
     caseblock = CaseBlock(
         create=True,
         case_id=uuid.uuid4().hex,
         user_id=self.user_id,
         owner_id=self.user_id,
         case_type='exploder-type',
         version=V2
     ).as_string()
     submit_case_blocks([caseblock], self.domain.name)
     self.assertEqual(1, len(get_case_ids_in_domain(self.domain.name)))
     explode_cases(self.user_id, self.domain.name, 10)
     cases_back = list(get_cases_in_domain(self.domain.name))
     self.assertEqual(10, len(cases_back))
     for case in cases_back:
         self.assertEqual(self.user_id, case.owner_id)
Example #7
0
def indexed_facilities():
    facility_index = {}
    for domain in DOMAINS:
        current_domain_index = {}
        facilities = get_cases_in_domain(domain, type="facility")
        for facility in facilities:
            case_sharing_group = GROUPS_BY_ID[domain].get(facility.owner_id, None)
            if case_sharing_group is None:
                continue
            cati_user = case_sharing_group.metadata.get('cati_user', None)
            fida_user = case_sharing_group.metadata.get('fida_user', None)
            current_domain_index[facility.facility_id] = {
                "cati": cati_user, 
                "fida": fida_user
            }
        facility_index[domain] = current_domain_index
    return facility_index
Example #8
0
def indexed_facilities():
    facility_index = {}
    for domain in DOMAINS:
        current_domain_index = {}
        facilities = get_cases_in_domain(domain, type="facility")
        for facility in facilities:
            case_sharing_group = GROUPS_BY_ID[domain].get(
                facility.owner_id, None)
            if case_sharing_group is None:
                continue
            cati_user = case_sharing_group.metadata.get('cati_user', None)
            fida_user = case_sharing_group.metadata.get('fida_user', None)
            current_domain_index[facility.facility_id] = {
                "cati": cati_user,
                "fida": fida_user
            }
        facility_index[domain] = current_domain_index
    return facility_index
Example #9
0
 def testImportBasic(self):
     config = self._config(self.default_headers)
     file = MockExcelFile(header_columns=self.default_headers, num_rows=5)
     res = do_import(file, config, self.domain)
     self.assertEqual(5, res['created_count'])
     self.assertEqual(0, res['match_count'])
     self.assertFalse(res['errors'])
     self.assertEqual(1, res['num_chunks'])
     cases = list(get_cases_in_domain(self.domain))
     self.assertEqual(5, len(cases))
     properties_seen = set()
     for case in cases:
         self.assertEqual(self.couch_user._id, case.user_id)
         self.assertEqual(self.couch_user._id, case.owner_id)
         self.assertEqual(self.default_case_type, case.type)
         for prop in self.default_headers[1:]:
             self.assertTrue(prop in case.get_case_property(prop))
             self.assertFalse(case.get_case_property(prop) in properties_seen)
             properties_seen.add(case.get_case_property(prop))
Example #10
0
    def test_create_and_fulfill_requisition(self):
        amounts = [(p._id, 50.0 + float(i*10)) for i, p in enumerate(self.products)]
        self.submit_xml_form(create_requisition_xml(amounts))
        req_cases = list(get_cases_in_domain(self.domain.name, type=const.REQUISITION_CASE_TYPE))
        self.assertEqual(1, len(req_cases))
        req = req_cases[0]
        [index] = req.indices
        self.assertEqual(const.SUPPLY_POINT_CASE_TYPE, index.referenced_type)
        self.assertEqual(self.sp._id, index.referenced_id)
        self.assertEqual('parent_id', index.identifier)
        for product, amt in amounts:
            self.check_stock_models(req, product, amt, 0, 'stock')

        self.submit_xml_form(create_fulfillment_xml(req, amounts))

        for product, amt in amounts:
            self.check_stock_models(req, product, 0, -amt, 'stock')

        for product, amt in amounts:
            self.check_product_stock(self.sp, product, amt, amt, 'stock')
Example #11
0
 def testImportBasic(self):
     config = self._config(self.default_headers)
     file = MockExcelFile(header_columns=self.default_headers, num_rows=5)
     res = do_import(file, config, self.domain)
     self.assertEqual(5, res['created_count'])
     self.assertEqual(0, res['match_count'])
     self.assertEqual(0, res['errors'])
     self.assertEqual(1, res['num_chunks'])
     cases = list(get_cases_in_domain(self.domain))
     self.assertEqual(5, len(cases))
     properties_seen = set()
     for case in cases:
         self.assertEqual(self.couch_user._id, case.user_id)
         self.assertEqual(self.couch_user._id, case.owner_id)
         self.assertEqual(self.default_case_type, case.type)
         for prop in self.default_headers[1:]:
             self.assertTrue(prop in case.get_case_property(prop))
             self.assertFalse(
                 case.get_case_property(prop) in properties_seen)
             properties_seen.add(case.get_case_property(prop))
Example #12
0
    def testExternalIdChunking(self):
        # bootstrap a stub case
        external_id = 'importer-test-external-id'

        headers = ['external_id', 'age', 'sex', 'location']
        config = self._config(headers, search_field='external_id')
        file = MockExcelFile(header_columns=headers, num_rows=3,
                             row_generator=id_match_generator(external_id))

        # the first one should create the case, and the remaining two should update it
        res = do_import(file, config, self.domain)
        self.assertEqual(1, res['created_count'])
        self.assertEqual(2, res['match_count'])
        self.assertFalse(res['errors'])
        self.assertEqual(2, res['num_chunks']) # the lookup causes an extra chunk

        # should just create the one case
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))
        [case] = get_cases_in_domain(self.domain)
        self.assertEqual(external_id, case.external_id)
        for prop in self.default_headers[1:]:
            self.assertTrue(prop in case.get_case_property(prop))
Example #13
0
    def testCaseIdMatching(self):
        # bootstrap a stub case
        case = CommCareCase(domain=self.domain, type=self.default_case_type)
        case.importer_test_prop = 'foo'
        case.save()
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))

        config = self._config(self.default_headers)
        file = MockExcelFile(header_columns=self.default_headers, num_rows=3, row_generator=id_match_generator(case._id))
        res = do_import(file, config, self.domain)
        self.assertEqual(0, res['created_count'])
        self.assertEqual(3, res['match_count'])
        self.assertFalse(res['errors'])

        # shouldn't create any more cases, just the one
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))
        [case] = get_cases_in_domain(self.domain)
        for prop in self.default_headers[1:]:
            self.assertTrue(prop in case.get_case_property(prop))

        # shouldn't touch existing properties
        self.assertEqual('foo', case.importer_test_prop)
    def test_parent_child(self):
        parent_id = uuid.uuid4().hex
        parent_type = 'exploder-parent-type'
        parent_block = CaseBlock(
            create=True,
            case_id=parent_id,
            user_id=self.user_id,
            owner_id=self.user_id,
            case_type=parent_type,
            version=V2
        ).as_string()

        child_id = uuid.uuid4().hex
        child_block = CaseBlock(
            create=True,
            case_id=child_id,
            user_id=self.user_id,
            owner_id=self.user_id,
            case_type='exploder-child-type',
            index={'parent': (parent_type, parent_id)},
            version=V2
        ).as_string()

        submit_case_blocks([parent_block, child_block], self.domain.name)
        self.assertEqual(2, len(get_case_ids_in_domain(self.domain.name)))

        explode_cases(self.user_id, self.domain.name, 5)
        cases_back = list(get_cases_in_domain(self.domain.name))
        self.assertEqual(10, len(cases_back))
        parent_cases = {p._id: p for p in filter(lambda case: case.type == parent_type, cases_back)}
        self.assertEqual(5, len(parent_cases))
        child_cases = filter(lambda case: case.type == 'exploder-child-type', cases_back)
        self.assertEqual(5, len(child_cases))
        child_indices = [child.indices[0].referenced_id for child in child_cases]
        # make sure they're different
        self.assertEqual(len(child_cases), len(set(child_indices)))
        for child in child_cases:
            self.assertEqual(1, len(child.indices))
            self.assertTrue(child.indices[0].referenced_id in parent_cases)
    def handle(self, *args, **options):
        domain = 'care-bihar'

        # forward all cases that were last modified between these dates
        def should_forward_case(case):
            min_date = datetime(2013, 9, 10)
            max_date = datetime(2013, 11, 7)
            return (case.server_modified_on
                    and min_date < case.server_modified_on < max_date)

        prod_repeater = CaseRepeater.get('a478a5a3d8964338cb3124de77e3ec58')
        success_count = 0
        fail_count = 0
        for case in get_cases_in_domain(domain):
            try:
                if should_forward_case(case):
                    prod_repeater.register(case)
                    success_count += 1
            except Exception:
                fail_count += 1
                logging.exception('problem creating repeater stub for case %s' % case._id)

        print 'successfully forwarded %s cases. %s were not processed' % (success_count, fail_count)
Example #16
0
    def testExternalIdChunking(self):
        # bootstrap a stub case
        external_id = 'importer-test-external-id'

        headers = ['external_id', 'age', 'sex', 'location']
        config = self._config(headers, search_field='external_id')
        file = MockExcelFile(header_columns=headers,
                             num_rows=3,
                             row_generator=id_match_generator(external_id))

        # the first one should create the case, and the remaining two should update it
        res = do_import(file, config, self.domain)
        self.assertEqual(1, res['created_count'])
        self.assertEqual(2, res['match_count'])
        self.assertEqual(0, res['errors'])
        self.assertEqual(2,
                         res['num_chunks'])  # the lookup causes an extra chunk

        # should just create the one case
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))
        [case] = get_cases_in_domain(self.domain)
        self.assertEqual(external_id, case.external_id)
        for prop in self.default_headers[1:]:
            self.assertTrue(prop in case.get_case_property(prop))
Example #17
0
    def test_create_fulfill_and_receive_requisition(self):
        amounts = [(p._id, 50.0 + float(i*10)) for i, p in enumerate(self.products)]

        # ----------------
        # Create a request
        # ----------------

        self.submit_xml_form(create_requisition_xml(amounts))
        req_cases = list(get_cases_in_domain(self.domain.name, type=const.REQUISITION_CASE_TYPE))
        self.assertEqual(1, len(req_cases))
        req = RequisitionCase.get(req_cases[0]._id)
        [index] = req.indices

        self.assertEqual(req.requisition_status, 'requested')
        self.assertEqual(const.SUPPLY_POINT_CASE_TYPE, index.referenced_type)
        self.assertEqual(self.sp._id, index.referenced_id)
        self.assertEqual('parent_id', index.identifier)
        # TODO: these types of tests probably belong elsewhere
        self.assertEqual(req.get_next_action().keyword, 'fulfill')
        self.assertEqual(req.get_location()._id, self.sp.location._id)
        self.assertEqual(len(RequisitionCase.open_for_location(
            self.domain.name,
            self.sp.location._id
        )), 1)
        self.assertEqual(
            get_notification_message(
                req.get_next_action(),
                [req]
            ),
            self.expected_notification_message(req, amounts)
        )

        for product, amt in amounts:
            self.check_stock_models(req, product, amt, 0, 'ct-requested')

        # ----------------
        # Mark it fulfilled
        # -----------------

        self.submit_xml_form(create_fulfillment_xml(req, amounts))

        req = RequisitionCase.get(req._id)

        self.assertEqual(req.requisition_status, 'fulfilled')
        self.assertEqual(req.get_next_action().keyword, 'rec')
        self.assertEqual(
            get_notification_message(
                req.get_next_action(),
                [req]
            ),
            self.expected_notification_message(req, amounts)
        )

        for product, amt in amounts:
            # we are expecting two separate blocks to have come with the same
            # values
            self.check_stock_models(req, product, amt, amt, 'stock')
            self.check_stock_models(req, product, amt, 0, 'ct-fulfilled')

        # ----------------
        # Mark it received
        # ----------------

        self.submit_xml_form(create_received_xml(req, amounts))

        req = RequisitionCase.get(req._id)

        self.assertEqual(req.requisition_status, 'received')
        self.assertIsNone(req.get_next_action())
        self.assertEqual(len(RequisitionCase.open_for_location(
            self.domain.name,
            self.sp.location._id
        )), 0)

        for product, amt in amounts:
            self.check_stock_models(req, product, 0, -amt, 'stock')
            self.check_stock_models(self.sp, product, amt, amt, 'stock')
Example #18
0
def new_update_case_properties():
    _domain = Domain.get_by_name(DOMAINS[0])
    if _domain is None:
        return
    time_zone = _domain.default_timezone
    time_zone = pytz.timezone(time_zone)
    past_21_date = past_x_date(time_zone, 21)
    past_42_date = past_x_date(time_zone, 42)
    for domain in DOMAINS:
        update_groups_index(domain)
        case_list = get_cases_in_domain(domain, type=TYPE)
        cases_to_modify = []
        for case in case_list:
            if case.closed:
                continue
            if not get_none_or_value(case, "owner_id") or not get_none_or_value(case, "date_admission") or not get_none_or_value(case, "site_id"):
                continue
            curr_assignment = get_none_or_value(case, "current_assignment")
            next_assignment = get_none_or_value(case, "next_assignment")
            site_id = case.site_id
            fida_group = get_group_id(domain, "fida", site_id)
            cati_owner_username = get_owner_username(domain, "cati", site_id)

            ## Assignment Directly from Registration ##
            # Assign Cases to Call Center
            if case.date_admission >= past_21_date and (not curr_assignment) and (not next_assignment):
                owner_id = get_group_id(domain, "cati", site_id)
                if not owner_id:
                    continue
                update = {
                    "owner_id": owner_id,
                    "current_assignment": "cati"
                }
                cases_to_modify.append({
                    "case_id": case._id,
                    "update": update,
                    "close": False,
                })
            # Assign Cases Directly To Field
            elif (case.date_admission >= past_42_date) and (case.date_admission < past_21_date) and (not curr_assignment) and (not next_assignment):
                if not fida_group:
                    continue
                update = {
                    "current_assignment": "fida",
                    "owner_id": fida_group,                   
                    "cati_status": 'skipped',
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": False,
                    }
                )
            # Assign Cases Directly to Lost to Follow Up
            elif case.date_admission < past_42_date and (not curr_assignment) and (not next_assignment):
                update = {
                    "cati_status": 'skipped',
                    "last_assignment": '',
                    "closed_status": "timed_out_lost_to_follow_up",
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": True,
                    }
                )

            ## Assignment from Call Center ##
            # Assign Cases to Field (manually by call center)
            elif (case.date_admission >= past_42_date) and next_assignment == "fida":
                if not cati_owner_username or not fida_group:
                    continue
                update = {
                    "last_cati_user": cati_owner_username,
                    "current_assignment": "fida",
                    "next_assignment": '',
                    "owner_id": fida_group,
                    "cati_status": 'manually_assigned_to_field'
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": False,
                    }
                )
            # Assign cases to field (automatically)
            elif (case.date_admission >= past_42_date) and (case.date_admission < past_21_date) and (curr_assignment == "cati" or curr_assignment == "cati_tl"):
                if not cati_owner_username or not fida_group:
                    continue
                update = {
                    "last_cati_assignment": curr_assignment,
                    "last_cati_user": cati_owner_username,
                    "cati_status": 'timed_out',
                    "current_assignment": "fida",
                    "next_assignment": '',
                    "owner_id": fida_group                        
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": False,
                    }
                )
            # Assign Cases to Lost to Follow Up
            elif case.date_admission < past_42_date and (curr_assignment == "cati" or curr_assignment == "cati_tl"):
                if not get_owner_username(domain, curr_assignment, site_id) or not cati_owner_username:
                    continue
                update = {
                    "last_cati_assignment": curr_assignment,
                    "last_cati_user": cati_owner_username,
                    "last_user": get_owner_username(domain, curr_assignment, site_id),
                    "cati_status": 'timed_out',
                    "last_assignment": curr_assignment,
                    "current_assignment": '',
                    "closed_status": "timed_out_lost_to_follow_up",
                    "next_assignment": ''
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": True,
                    }
                )

            ## Assignment from Field ##
            # Assign Cases to Lost to Follow Up
            elif case.date_admission < past_42_date and (curr_assignment == "fida" or curr_assignment == "fida_tl"):
                if not get_owner_username(domain, curr_assignment, site_id):
                    continue
                update = {
                    "last_user": get_owner_username(domain, curr_assignment, site_id),
                    "last_assignment": curr_assignment,
                    "current_assignment": '',
                    "closed_status": "timed_out_lost_to_follow_up",
                    "next_assignment": '',
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": True,
                    }
                )
        case_blocks = [ElementTree.tostring(CaseBlock(
            create=False,
            case_id=case["case_id"],
            update=case["update"],
            close=case["close"],
            version=V2,
            ).as_xml()) for case in cases_to_modify
        ]
        submit_case_blocks(case_blocks, domain)
Example #19
0
    def test_create_fulfill_and_receive_requisition(self):
        amounts = [(p._id, 50.0 + float(i * 10))
                   for i, p in enumerate(self.products)]

        # ----------------
        # Create a request
        # ----------------

        self.submit_xml_form(create_requisition_xml(amounts))
        req_cases = list(
            get_cases_in_domain(self.domain.name,
                                type=const.REQUISITION_CASE_TYPE))
        self.assertEqual(1, len(req_cases))
        req = RequisitionCase.get(req_cases[0]._id)
        [index] = req.indices

        self.assertEqual(req.requisition_status, 'requested')
        self.assertEqual(const.SUPPLY_POINT_CASE_TYPE, index.referenced_type)
        self.assertEqual(self.sp._id, index.referenced_id)
        self.assertEqual('parent_id', index.identifier)
        # TODO: these types of tests probably belong elsewhere
        self.assertEqual(req.get_next_action().keyword, 'fulfill')
        self.assertEqual(req.get_location()._id, self.sp.location._id)
        self.assertEqual(
            len(
                RequisitionCase.open_for_location(self.domain.name,
                                                  self.sp.location._id)), 1)
        self.assertEqual(
            get_notification_message(req.get_next_action(), [req]),
            self.expected_notification_message(req, amounts))

        for product, amt in amounts:
            self.check_stock_models(req, product, amt, 0, 'ct-requested')

        # ----------------
        # Mark it fulfilled
        # -----------------

        self.submit_xml_form(create_fulfillment_xml(req, amounts))

        req = RequisitionCase.get(req._id)

        self.assertEqual(req.requisition_status, 'fulfilled')
        self.assertEqual(req.get_next_action().keyword, 'rec')
        self.assertEqual(
            get_notification_message(req.get_next_action(), [req]),
            self.expected_notification_message(req, amounts))

        for product, amt in amounts:
            # we are expecting two separate blocks to have come with the same
            # values
            self.check_stock_models(req, product, amt, amt, 'stock')
            self.check_stock_models(req, product, amt, 0, 'ct-fulfilled')

        # ----------------
        # Mark it received
        # ----------------

        self.submit_xml_form(create_received_xml(req, amounts))

        req = RequisitionCase.get(req._id)

        self.assertEqual(req.requisition_status, 'received')
        self.assertIsNone(req.get_next_action())
        self.assertEqual(
            len(
                RequisitionCase.open_for_location(self.domain.name,
                                                  self.sp.location._id)), 0)

        for product, amt in amounts:
            self.check_stock_models(req, product, 0, -amt, 'stock')
            self.check_stock_models(self.sp, product, amt, amt, 'stock')
Example #20
0
def new_update_case_properties():
    _domain = Domain.get_by_name(DOMAINS[0])
    if _domain is None:
        return
    time_zone = _domain.default_timezone
    time_zone = pytz.timezone(time_zone)
    past_21_date = past_x_date(time_zone, 21)
    past_42_date = past_x_date(time_zone, 42)
    setup_indices()
    for domain in DOMAINS:
        case_list = list(get_cases_in_domain(domain, type=BIRTH_TYPE))
        case_list = case_list + list(get_cases_in_domain(domain, type=CATI_FIDA_CHECK_TYPE))
        cases_to_modify = []
        for case in case_list:
            if case.closed:
                continue
            if not get_none_or_value(case, "owner_id") or not get_none_or_value(case, "date_admission") or not get_none_or_value(case, "facility_id"):
                continue
            curr_assignment = get_none_or_value(case, "current_assignment")
            next_assignment = get_none_or_value(case, "next_assignment")
            facility_id = get_none_or_value(case, "facility_id")
            fida_group = get_group_id(domain, "fida", facility_id)
            cati_owner_username = get_owner_username(domain, "cati", facility_id)

            ## Assignment Directly from Registration ##
            # Assign Cases to Call Center
            if case.date_admission >= past_21_date and (not curr_assignment) and (not next_assignment):
                owner_id = get_group_id(domain, "cati", facility_id)
                if not owner_id:
                    continue
                owner_group = GROUPS_BY_ID[domain].get(owner_id, None)
                cati_name = owner_group.metadata.get('name', None) if owner_group else None
                update = {
                    "current_assignment": "cati",
                    "cati_name": cati_name
                }
                cases_to_modify.append({
                    "case_id": case._id,
                    "update": update,
                    "close": False,
                    "owner_id": owner_id,
                })
            # Assign Cases Directly To Field
            elif (case.date_admission >= past_42_date) and (case.date_admission < past_21_date) and (not curr_assignment) and (not next_assignment):
                if not fida_group:
                    continue
                update = {
                    "current_assignment": "fida",
                    "cati_status": 'skipped',
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": False,
                        "owner_id": fida_group,
                    }
                )
            # Assign Cases Directly to Lost to Follow Up
            elif case.date_admission < past_42_date and (not curr_assignment) and (not next_assignment):
                update = {
                    "cati_status": 'skipped',
                    "last_assignment": '',
                    "closed_status": "timed_out_lost_to_follow_up",
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": True,
                    }
                )

            ## Assignment from Call Center ##
            # Assign Cases to Field (manually by call center)
            elif (case.date_admission >= past_42_date) and next_assignment == "fida":
                if not cati_owner_username or not fida_group:
                    continue
                update = {
                    "last_cati_user": cati_owner_username,
                    "current_assignment": "fida",
                    "next_assignment": '',
                    "cati_status": 'manually_assigned_to_field'
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": False,
                        "owner_id": fida_group,
                    }
                )
            # Assign cases to field (automatically)
            elif (case.date_admission >= past_42_date) and (case.date_admission < past_21_date) and (curr_assignment == "cati" or curr_assignment == "cati_tl"):
                if not cati_owner_username or not fida_group:
                    continue
                update = {
                    "last_cati_assignment": curr_assignment,
                    "last_cati_user": cati_owner_username,
                    "cati_status": 'timed_out',
                    "current_assignment": "fida",
                    "next_assignment": '',
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": False,
                        "owner_id": fida_group,
                    }
                )
            # Assign Cases to Lost to Follow Up
            elif case.date_admission < past_42_date and (curr_assignment == "cati" or curr_assignment == "cati_tl"):
                if not get_owner_username(domain, curr_assignment, facility_id) or not cati_owner_username:
                    continue
                update = {
                    "last_cati_assignment": curr_assignment,
                    "last_cati_user": cati_owner_username,
                    "last_user": get_owner_username(domain, curr_assignment, facility_id),
                    "cati_status": 'timed_out',
                    "last_assignment": curr_assignment,
                    "current_assignment": '',
                    "closed_status": "timed_out_lost_to_follow_up",
                    "next_assignment": ''
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": True,
                    }
                )

            ## Assignment from Field ##
            # Assign Cases to Lost to Follow Up
            elif case.date_admission < past_42_date and (curr_assignment == "fida" or curr_assignment == "fida_tl"):
                if not get_owner_username(domain, curr_assignment, facility_id):
                    continue
                update = {
                    "last_user": get_owner_username(domain, curr_assignment, facility_id),
                    "last_assignment": curr_assignment,
                    "current_assignment": '',
                    "closed_status": "timed_out_lost_to_follow_up",
                    "next_assignment": '',
                }
                cases_to_modify.append(
                    {
                        "case_id": case._id,
                        "update": update,
                        "close": True,
                    }
                )
        case_blocks = []
        for case in cases_to_modify:
            kwargs = {
                "create": False,
                "case_id": case["case_id"],
                "update": case["update"],
                "close": case["close"],
                "version": V2,
            }
            if case.get("owner_id", None):
                kwargs["owner_id"] = case["owner_id"]
            case_blocks.append(ElementTree.tostring(CaseBlock(**kwargs).as_xml()))
        submit_case_blocks(case_blocks, domain)
Example #21
0
class ImporterTest(TestCase):
    def setUp(self):
        self.domain = create_domain("importer-test").name
        self.default_case_type = 'importer-test-casetype'
        self.default_headers = ['case_id', 'age', 'sex', 'location']

        self.couch_user = WebUser.create(None, "test", "foobar")
        self.couch_user.add_domain_membership(self.domain, is_admin=True)
        self.couch_user.save()
        delete_all_cases()

    def tearDown(self):
        self.couch_user.delete()

    def _config(self,
                col_names=None,
                search_column=None,
                case_type=None,
                search_field='case_id',
                named_columns=False,
                create_new_cases=True):
        col_names = col_names or self.default_headers
        case_type = case_type or self.default_case_type
        search_column = search_column or col_names[0]
        return ImporterConfig(
            couch_user_id=self.couch_user._id,
            case_type=case_type,
            excel_fields=col_names,
            case_fields=[''] * len(col_names),
            custom_fields=col_names,
            type_fields=['plain'] * len(col_names),
            search_column=search_column,
            search_field=search_field,
            named_columns=named_columns,
            create_new_cases=create_new_cases,
            key_column='',
            value_column='',
        )

    def testImportNone(self):
        res = do_import(None, self._config(), self.domain)
        self.assertEqual('EXPIRED', res['error'])
        self.assertEqual(0, len(get_case_ids_in_domain(self.domain)))

    def testImporterErrors(self):
        res = do_import(MockExcelFile(has_errors=True), self._config(),
                        self.domain)
        self.assertEqual('HAS_ERRORS', res['error'])
        self.assertEqual(0, len(get_case_ids_in_domain(self.domain)))

    def testImportBasic(self):
        config = self._config(self.default_headers)
        file = MockExcelFile(header_columns=self.default_headers, num_rows=5)
        res = do_import(file, config, self.domain)
        self.assertEqual(5, res['created_count'])
        self.assertEqual(0, res['match_count'])
        self.assertEqual(0, res['errors'])
        self.assertEqual(1, res['num_chunks'])
        cases = list(get_cases_in_domain(self.domain))
        self.assertEqual(5, len(cases))
        properties_seen = set()
        for case in cases:
            self.assertEqual(self.couch_user._id, case.user_id)
            self.assertEqual(self.couch_user._id, case.owner_id)
            self.assertEqual(self.default_case_type, case.type)
            for prop in self.default_headers[1:]:
                self.assertTrue(prop in case.get_case_property(prop))
                self.assertFalse(
                    case.get_case_property(prop) in properties_seen)
                properties_seen.add(case.get_case_property(prop))

    def testImportNamedColumns(self):
        config = self._config(self.default_headers, named_columns=True)
        file = MockExcelFile(header_columns=self.default_headers, num_rows=5)
        res = do_import(file, config, self.domain)
        # we create 1 less since we knock off the header column
        self.assertEqual(4, res['created_count'])
        self.assertEqual(4, len(get_case_ids_in_domain(self.domain)))

    def testCaseIdMatching(self):
        # bootstrap a stub case
        case = CommCareCase(domain=self.domain, type=self.default_case_type)
        case.importer_test_prop = 'foo'
        case.save()
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))

        config = self._config(self.default_headers)
        file = MockExcelFile(header_columns=self.default_headers,
                             num_rows=3,
                             row_generator=id_match_generator(case._id))
        res = do_import(file, config, self.domain)
        self.assertEqual(0, res['created_count'])
        self.assertEqual(3, res['match_count'])
        self.assertEqual(0, res['errors'])

        # shouldn't create any more cases, just the one
        self.assertEqual(1, len(get_case_ids_in_domain(self.domain)))
        [case] = get_cases_in_domain(self.domain)
        for prop in self.default_headers[1:]:
            self.assertTrue(prop in case.get_case_property(prop))

        # shouldn't touch existing properties
        self.assertEqual('foo', case.importer_test_prop)