예제 #1
0
 def testOTARestore(self):
     self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all()))
     file_path = os.path.join(os.path.dirname(__file__), "data", "multicase", "parallel_cases.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     form = post_xform_to_couch(xml_data)
     process_cases(sender="testharness", xform=form)
     self.assertEqual(4, len(CommCareCase.view("case/by_user", reduce=False).all()))
예제 #2
0
def get_supply_point(domain, site_code):
    loc = Location.view('commtrack/locations_by_code',
                        key=[domain, site_code.lower()],
                        include_docs=True).first()
    if loc:
        case = CommCareCase.view('commtrack/supply_point_by_loc',
                                 key=[domain, loc._id],
                                 include_docs=True).first()
예제 #3
0
 def testTopLevelExclusion(self):
     """
     Entire forms tagged as device logs should be excluded
     """
     self.assertEqual(0, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all()))
     file_path = os.path.join(os.path.dirname(__file__), "data", "exclusion", "device_report.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     form = post_xform_to_couch(xml_data)
     process_cases(form)
     self.assertEqual(0, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all()))
예제 #4
0
 def testTopLevelExclusion(self):
     """
     Entire forms tagged as device logs should be excluded
     """
     self.assertEqual(0, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all()))
     file_path = os.path.join(os.path.dirname(__file__), "data", "exclusion", "device_report.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     form = post_xform_to_couch(xml_data)
     process_cases(form)
     self.assertEqual(0, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all()))
예제 #5
0
 def testMixed(self):
     self.assertEqual(
         0, len(CommCareCase.view("case/by_user", reduce=False).all()))
     file_path = os.path.join(os.path.dirname(__file__), "data",
                              "multicase", "mixed_cases.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     form = post_xform_to_couch(xml_data)
     process_cases(form)
     self.assertEqual(
         4, len(CommCareCase.view("case/by_user", reduce=False).all()))
예제 #6
0
 def testLotsOfSubcases(self):
     """
     How do we do when submitting a form with multiple blocks for the same case?
     """
     self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all()))
     file_path = os.path.join(os.path.dirname(__file__), "data", "bugs", "lots_of_subcases.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     form = post_xform_to_couch(xml_data)
     # before the bug was fixed this call failed
     process_cases(form)
     self.assertEqual(11, len(CommCareCase.view("case/by_user", reduce=False).all()))
예제 #7
0
 def testNestedExclusion(self):
     """
     Blocks inside forms tagged as device logs should be excluded
     """
     self.assertEqual(0, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all()))
     file_path = os.path.join(os.path.dirname(__file__), "data", "exclusion", "nested_device_report.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     form = post_xform_to_couch(xml_data)
     process_cases(form)
     self.assertEqual(1, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all()))
     case = CommCareCase.get("case_in_form")
     self.assertEqual("form case", case.name)
예제 #8
0
 def testNestedExclusion(self):
     """
     Blocks inside forms tagged as device logs should be excluded
     """
     self.assertEqual(0, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all()))
     file_path = os.path.join(os.path.dirname(__file__), "data", "exclusion", "nested_device_report.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     form = post_xform_to_couch(xml_data)
     process_cases(form)
     self.assertEqual(1, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all()))
     case = CommCareCase.get("case_in_form")
     self.assertEqual("form case", case.name)
예제 #9
0
def device_data(request):
    if "data" not in request.POST:
        return HttpResponseBadRequest("Missing 'data' POST parameter.")

    data = request.POST.get("data")
    data = data.strip()
    data_points = data.split(",")
    device_id = None
    for data_point in data_points:
        key_value = data_point.partition("=")
        key = key_value[0].strip().upper()
        value = key_value[2].strip()
        if key == "SN":
            device_id = value
            break

    if device_id is None:
        return HttpResponseBadRequest("Missing 'SN' in data string.")

    # This view lookup is an implicit assert that either one device exists
    # with the given device_id, or no devices exist with this device_id.
    case = CommCareCase.view("wisepill/device",
                             key=[device_id],
                             include_docs=True).one()

    event = WisePillDeviceEvent(
        domain=case.domain if case is not None else None,
        data=data,
        received_on=datetime.utcnow(),
        case_id=case.case_id if case is not None else None,
        processed=False,
    )
    event.save()

    if case is not None:
        survey_keywords = SurveyKeyword.get_all(case.domain)
        for survey_keyword in survey_keywords:
            if survey_keyword.keyword.upper() == "DEVICE_EVENT":
                for survey_keyword_action in survey_keyword.actions:
                    if survey_keyword_action.action == METHOD_STRUCTURED_SMS:
                        handle_structured_sms(survey_keyword,
                                              survey_keyword_action,
                                              case,
                                              None,
                                              "DEVICE_EVENT,%s" % data,
                                              send_response=False)
                        event.processed = True
                        event.save()
                        break
예제 #10
0
 def testLotsOfSubcases(self):
     """
     How do we do when submitting a form with multiple blocks for the same case?
     """
     self.assertEqual(
         0, len(CommCareCase.view("case/by_user", reduce=False).all()))
     file_path = os.path.join(os.path.dirname(__file__), "data", "bugs",
                              "lots_of_subcases.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     form = post_xform_to_couch(xml_data)
     # before the bug was fixed this call failed
     process_cases(form)
     self.assertEqual(
         11, len(CommCareCase.view("case/by_user", reduce=False).all()))
예제 #11
0
    def handle(self, *args, **options):
        key = make_form_couch_key("hsph")
        test_forms = XFormInstance.view(
            'reports_forms/all_forms',
            reduce=False,
            startkey=key,
            endkey=key + ["2012-11-07"],
            include_docs=True,
        ).all()
        test_cases = CommCareCase.view(
            'reports/case_activity',
            reduce=False,
            startkey=["", "hsph"],
            endkey=["", "hsph", "2012-11-07"],
            include_docs=True,
        ).all()

        print "\nDELETING TEST HSPH FORMS"
        for form in test_forms:
            if form.domain == "hsph":
                sys.stdout.write(".")
                sys.stdout.flush()
                form.delete()

        print "\n\nDELETING TEST HSPH CASES"
        for case in test_cases:
            if case.domain == "hsph":
                sys.stdout.write(".")
                sys.stdout.flush()
                case.delete()
예제 #12
0
    def _testCornerCaseDatatypeBugs(self, value):
        self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all()))

        def _test(custom_format_args):
            case_id = uuid.uuid4().hex
            format_args = {
                'case_id': case_id,
                'form_id': uuid.uuid4().hex,
                'user_id': uuid.uuid4().hex,
                'case_name': 'data corner cases',
                'case_type': 'datatype-check',
            }
            format_args.update(custom_format_args)
            for filename in ['bugs_in_case_create_datatypes.xml', 'bugs_in_case_update_datatypes.xml']:
                file_path = os.path.join(os.path.dirname(__file__), "data", "bugs", filename)
                with open(file_path, "rb") as f:
                    xml_data = f.read()
                xml_data = xml_data.format(**format_args)
                form = post_xform_to_couch(xml_data)
                # before the bug was fixed this call failed
                process_cases(form)
                case = CommCareCase.get(case_id)
                self.assertEqual(format_args['user_id'], case.user_id)
                self.assertEqual(format_args['case_name'], case.name)
                self.assertEqual(format_args['case_type'], case.type)

        _test({'case_name': value})
        _test({'case_type': value})
        _test({'user_id': value})
예제 #13
0
파일: views.py 프로젝트: birdsarah/core-hq
def open_cases_json(request, domain):
    delete_ids = json.loads(request.GET.get('delete_ids', 'false'))
    delete_doc_types = json.loads(request.GET.get('delete_doc_types', 'true'))
    username = request.GET.get("username", None)

    cases = CommCareCase.view('hqcase/open_cases', startkey=[domain], endkey=[domain, {}], reduce=False, include_docs=True)

    user_id_to_type_to_cases = defaultdict(lambda:defaultdict(list))
    for case in cases:
        case_json = deepcopy(case.to_json())
        user_id_to_type_to_cases[case.user_id][case.type].append(case_json)
        del case_json['domain']

        if delete_ids:
            del case_json['_id']
            del case_json['_rev']
            del case_json['user_id']
#            del case_json['type']
            del case_json['doc_type']
            case_json['actions'] = [action.action_type for action in case.actions]
            case_json['referrals'] = [referral.type for referral in case.referrals]

    usercases = [{
        "username": user_id_to_username(user_id),
        "cases": [{"type": type, "cases":cases} for (type, cases) in type_to_cases.items()]
    } for (user_id, type_to_cases) in user_id_to_type_to_cases.items()]
    usercases.sort(key=lambda x: x['username'])
    return HttpResponse(json.dumps(usercases))
예제 #14
0
    def testDuplicateCasePropertiesBug(self):
        """
        How do we do when submitting multiple values for the same property
        in an update block
        """
        self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all()))
        file_path = os.path.join(os.path.dirname(__file__), "data", "bugs",
                                 "duplicate_case_properties.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()
        form = post_xform_to_couch(xml_data)
        # before the bug was fixed this call failed
        process_cases(form)
        case = CommCareCase.get(form.xpath("form/case/@case_id"))
        # make sure the property is there, but empty
        self.assertEqual("", case.foo)

        file_path = os.path.join(os.path.dirname(__file__), "data", "bugs",
                                 "duplicate_case_properties_2.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()
        form = post_xform_to_couch(xml_data)
        process_cases(form)
        case = CommCareCase.get(form.xpath("form/case/@case_id"))
        # make sure the property takes the last defined value
        self.assertEqual("2", case.bar)
예제 #15
0
파일: views.py 프로젝트: birdsarah/core-hq
def explode_cases(request, domain, template="hqcase/explode_cases.html"):
    if request.method == 'POST':
        user_id = request.POST['user_id']
        user = CommCareUser.get_by_user_id(user_id, domain)
        factor = request.POST.get('factor', '2')
        try:
            factor = int(factor)
        except ValueError:
            messages.error(request, 'factor must be an int; was: %s' % factor)
        else:
            keys = [[domain, owner_id, False] for owner_id in user.get_owner_ids()]
            for case in CommCareCase.view('hqcase/by_owner',
                keys=keys,
                include_docs=True,
                reduce=False
            ):
                # we'll be screwing with this guy, so make him unsaveable
                case.save = None
                for i in range(factor - 1):

                    case._id = uuid.uuid4().hex
                    case_block = get_case_xml(case, (const.CASE_ACTION_CREATE, const.CASE_ACTION_UPDATE), version='2.0')
                    submit_case_blocks(case_block, domain)
            messages.success(request, "All of %s's cases were exploded by a factor of %d" % (user.raw_username, factor))

    return render(request, template, {
        'domain': domain,
        'users': CommCareUser.by_domain(domain),
    })
예제 #16
0
def process(domain, instance):
    """process an incoming commtrack stock report instance"""
    config = CommtrackConfig.for_domain(domain)
    root = etree.fromstring(instance)
    transactions = unpack_transactions(root, config)

    case_ids = [tx["case_id"] for tx in transactions]
    cases = dict((c._id, c) for c in CommCareCase.view("_all_docs", keys=case_ids, include_docs=True))

    # ensure transaction types are processed in the correct order
    def transaction_order(tx):
        return [action.action_name for action in config.actions].index(tx["action"])

    transactions.sort(key=transaction_order)
    # apply all transactions to each product case in bulk
    transactions_by_product = map_reduce(lambda tx: [(tx["case_id"],)], data=transactions, include_docs=True)

    for product_id, txs in transactions_by_product.iteritems():
        product_case = cases[product_id]
        case_block, reconciliations = process_product_transactions(product_case, txs)
        for recon in reconciliations:
            root.append(recon)
        root.append(case_block)

    submission = etree.tostring(root)
    logger.debug("submitting: %s" % submission)

    submit_time = root.find(".//%s" % _("timeStart", META_XMLNS)).text
    spoof_submission(get_submit_url(domain), submission, headers={"HTTP_X_SUBMIT_TIME": submit_time})
예제 #17
0
def get_number_of_cases_by_filters(domain, owner_id, case_type,
                                   status=None, date_range=None):
    """
    Get number of cases in a domain filtered by a number of different fields:

    domain: required, non-null
    owner_id: required, non-null
    case_type: optional, no filter applied if null
    status: optional, no filter applied if null
    date_range: optional (start, end) tuple, no filter applied if null

    returns number of matching cases

    """
    from casexml.apps.case.models import CommCareCase
    couch_key = [domain, status or {}, case_type or {}, owner_id]

    start_date, end_date = date_range or (None, None)
    start_date_key = [start_date.isoformat()] if start_date else []
    end_date_key = [end_date.isoformat()] if end_date else [{}]

    results = CommCareCase.view(
        'case/by_date_modified_owner',
        reduce=True,
        startkey=couch_key + start_date_key,
        endkey=couch_key + end_date_key,
    ).one()
    return results['value'] if results else 0
예제 #18
0
 def _get_cases(self):
     case_ids = get_case_ids_in_domain(self.domain)
     return CommCareCase.view(
         '_all_docs',
         keys=case_ids,
         include_docs=True,
     )
예제 #19
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError('Usage: %s\n%s' % (self.args, self.help))

        domain = args[0]
        view_name = 'hqcase/all_cases'
        key = [domain, {}, {}]
        case_ids = CommCareCase.view(view_name,
            startkey=key,
            endkey=key + [{}],
            reduce=False,
            include_docs=False,
            wrapper=lambda r: r['id']
        )

        print 'loading %s cases in %s' % (len(case_ids), domain)
        def stream_cases(all_case_ids):
            for case_ids in chunked(all_case_ids, 1000):
                for case in wrapped_docs(CommCareCase, keys=case_ids):
                # for case in CommCareCase.view('_all_docs', keys=case_ids, include_docs=True):
                    yield case

        count = 0
        for c in stream_cases(case_ids):
            count += 1
        print 'read %s cases' % count
    def handle(self, *args, **options):
        key = make_form_couch_key("hsph")
        test_forms = XFormInstance.view('reports_forms/all_forms',
            reduce=False,
            startkey=key,
            endkey=key+["2012-11-07"],
            include_docs=True,
        ).all()
        test_cases = CommCareCase.view('reports/case_activity',
            reduce=False,
            startkey=["","hsph"],
            endkey=["","hsph","2012-11-07"],
            include_docs=True,
        ).all()

        print "\nDELETING TEST HSPH FORMS"
        for form in test_forms:
            if form.domain == "hsph":
                sys.stdout.write(".")
                sys.stdout.flush()
                form.delete()

        print "\n\nDELETING TEST HSPH CASES"
        for case in test_cases:
            if case.domain == "hsph":
                sys.stdout.write(".")
                sys.stdout.flush()
                case.delete()
        print "\n"
예제 #21
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError('Usage: %s\n%s' % (self.args, self.help))

        domain = args[0]
        view_name = 'hqcase/all_cases'
        key = [domain, {}, {}]
        case_ids = CommCareCase.view(view_name,
                                     startkey=key,
                                     endkey=key + [{}],
                                     reduce=False,
                                     include_docs=False,
                                     wrapper=lambda r: r['id'])

        print 'loading %s cases in %s' % (len(case_ids), domain)

        def stream_cases(all_case_ids):
            for case_ids in chunked(all_case_ids, 1000):
                for case in wrapped_docs(CommCareCase, keys=case_ids):
                    # for case in CommCareCase.view('_all_docs', keys=case_ids, include_docs=True):
                    yield case

        count = 0
        for c in stream_cases(case_ids):
            count += 1
        print 'read %s cases' % count
예제 #22
0
def open_cases_json(request, domain):
    delete_ids = json.loads(request.GET.get("delete_ids", "false"))

    cases = CommCareCase.view(
        "hqcase/open_cases", startkey=[domain], endkey=[domain, {}], reduce=False, include_docs=True
    )

    user_id_to_type_to_cases = defaultdict(lambda: defaultdict(list))
    for case in cases:
        case_json = deepcopy(case.to_json())
        user_id_to_type_to_cases[case.user_id][case.type].append(case_json)
        del case_json["domain"]

        if delete_ids:
            del case_json["_id"]
            del case_json["_rev"]
            del case_json["user_id"]
            #            del case_json['type']
            del case_json["doc_type"]
            case_json["actions"] = [action.action_type for action in case.actions]
            case_json["referrals"] = [referral.type for referral in case.referrals]

    usercases = [
        {
            "username": user_id_to_username(user_id),
            "cases": [{"type": type, "cases": cases} for (type, cases) in type_to_cases.items()],
        }
        for (user_id, type_to_cases) in user_id_to_type_to_cases.items()
    ]
    usercases.sort(key=lambda x: x["username"])
    return HttpResponse(json.dumps(usercases))
예제 #23
0
    def _testCornerCaseDatatypeBugs(self, value):
        self.assertEqual(
            0, len(CommCareCase.view("case/by_user", reduce=False).all()))

        def _test(custom_format_args):
            case_id = uuid.uuid4().hex
            format_args = {
                'case_id': case_id,
                'form_id': uuid.uuid4().hex,
                'user_id': uuid.uuid4().hex,
                'case_name': 'data corner cases',
                'case_type': 'datatype-check',
            }
            format_args.update(custom_format_args)
            for filename in [
                    'bugs_in_case_create_datatypes.xml',
                    'bugs_in_case_update_datatypes.xml'
            ]:
                file_path = os.path.join(os.path.dirname(__file__), "data",
                                         "bugs", filename)
                with open(file_path, "rb") as f:
                    xml_data = f.read()
                xml_data = xml_data.format(**format_args)
                form = post_xform_to_couch(xml_data)
                # before the bug was fixed this call failed
                process_cases(form)
                case = CommCareCase.get(case_id)
                self.assertEqual(format_args['user_id'], case.user_id)
                self.assertEqual(format_args['case_name'], case.name)
                self.assertEqual(format_args['case_type'], case.type)

        _test({'case_name': value})
        _test({'case_type': value})
        _test({'user_id': value})
예제 #24
0
def explode_cases(request, domain, template="hqcase/explode_cases.html"):
    if request.method == 'POST':
        user_id = request.POST['user_id']
        user = CommCareUser.get_by_user_id(user_id, domain)
        factor = request.POST.get('factor', '2')
        try:
            factor = int(factor)
        except ValueError:
            messages.error(request, 'factor must be an int; was: %s' % factor)
        else:
            keys = [[domain, owner_id, False]
                    for owner_id in user.get_owner_ids()]
            for case in CommCareCase.view('hqcase/by_owner',
                                          keys=keys,
                                          include_docs=True,
                                          reduce=False):
                # we'll be screwing with this guy, so make him unsaveable
                case.save = None
                for i in range(factor - 1):

                    case._id = uuid.uuid4().hex
                    case_block = get_case_xml(
                        case,
                        (const.CASE_ACTION_CREATE, const.CASE_ACTION_UPDATE),
                        version='2.0')
                    submit_case_blocks(case_block, domain)
            messages.success(
                request, "All of %s's cases were exploded by a factor of %d" %
                (user.raw_username, factor))
예제 #25
0
def get_case_ids_in_domain_by_owner(domain,
                                    owner_id=None,
                                    owner_id__in=None,
                                    closed=None):
    """
    get case_ids for open, closed, or all cases in a domain
    that belong to an owner_id or list of owner_ids

    domain: required
    owner_id: a single owner_id to filter on
    owner_id__in: a list of owner ids to filter on.
        A case matches if it belongs to any of them.
        You cannot specify both this and owner_id
    closed: True (only closed cases), False (only open cases), or None (all)
    returns a list of case_ids

    """
    assert not (owner_id__in and owner_id)
    assert closed in (True, False, None)
    if closed is None:
        closed_flags = [True, False]
    else:
        closed_flags = [closed]
    if owner_id:
        owner_id__in = [owner_id]
    return [
        res["id"] for res in CommCareCase.view(
            'cases_by_owner/view',
            keys=[[domain, owner_id, closed_flag] for owner_id in owner_id__in
                  for closed_flag in closed_flags],
            include_docs=False,
            reduce=False,
        )
    ]
예제 #26
0
    def testDuplicateCasePropertiesBug(self):
        """
        How do we do when submitting multiple values for the same property
        in an update block
        """
        self.assertEqual(
            0, len(CommCareCase.view("case/by_user", reduce=False).all()))
        file_path = os.path.join(os.path.dirname(__file__), "data", "bugs",
                                 "duplicate_case_properties.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()
        form = post_xform_to_couch(xml_data)
        # before the bug was fixed this call failed
        process_cases(form)
        case = CommCareCase.get(form.xpath("form/case/@case_id"))
        # make sure the property is there, but empty
        self.assertEqual("", case.foo)

        file_path = os.path.join(os.path.dirname(__file__), "data", "bugs",
                                 "duplicate_case_properties_2.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()
        form = post_xform_to_couch(xml_data)
        process_cases(form)
        case = CommCareCase.get(form.xpath("form/case/@case_id"))
        # make sure the property takes the last defined value
        self.assertEqual("2", case.bar)
예제 #27
0
 def cases(self):
     keys = [[self.domain, owner_id, False]
             for owner_id in self.all_owner_ids]
     return CommCareCase.view('hqcase/by_owner',
                              keys=keys,
                              include_docs=True,
                              reduce=False)
예제 #28
0
def _get_cases_by_domain_hq_user_id(domain, user_id, case_type, include_docs):
    return CommCareCase.view(
        'case_by_domain_hq_user_id_type/view',
        key=[domain, user_id, case_type],
        reduce=False,
        include_docs=include_docs
    ).all()
예제 #29
0
def open_cases_json(request, domain):
    delete_ids = json.loads(request.GET.get('delete_ids', 'false'))

    cases = CommCareCase.view('hqcase/open_cases', startkey=[domain], endkey=[domain, {}], reduce=False, include_docs=True)

    user_id_to_type_to_cases = defaultdict(lambda:defaultdict(list))
    for case in cases:
        case_json = deepcopy(case.to_json())
        user_id_to_type_to_cases[case.user_id][case.type].append(case_json)
        del case_json['domain']

        if delete_ids:
            del case_json['_id']
            del case_json['_rev']
            del case_json['user_id']
#            del case_json['type']
            del case_json['doc_type']
            case_json['actions'] = [action.action_type for action in case.actions]
            case_json['referrals'] = [referral.type for referral in case.referrals]

    usercases = [{
        "username": user_id_to_username(user_id),
        "cases": [{"type": type, "cases":cases} for (type, cases) in type_to_cases.items()]
    } for (user_id, type_to_cases) in user_id_to_type_to_cases.items()]
    usercases.sort(key=lambda x: x['username'])
    return HttpResponse(json.dumps(usercases))
예제 #30
0
    def update_indicators_for_case_type(self, case_type, domain):
        print "\n\n\nFetching %s cases in domain %s...." % (case_type, domain)
        key = ["all type", domain, case_type]
        relevant_indicators = CaseIndicatorDefinition.get_all(
            namespace=MVP.NAMESPACE,
            domain=domain,
            case_type=case_type
        )

        if relevant_indicators:
            all_cases = get_db().view("case/all_cases",
                reduce=True,
                startkey=key,
                endkey=key+[{}]
            ).first()
            num_cases = all_cases['value'] if all_cases else 0

            print "\nFound the following Case Indicator Definitions for Case Type %s in Domain %s" % (case_type, domain)
            print "--%s\n" % "\n--".join([i.slug for i in relevant_indicators])

            print "Found %d possible cases for update." % num_cases
            get_cases = lambda skip, limit: CommCareCase.view("case/all_cases",
                reduce=False,
                include_docs=True,
                startkey=key,
                endkey=key+[{}],
                skip=skip,
                limit=limit
            ).all()
            self._throttle_updates("Cases of type %s in %s" % (case_type, domain),
                                   relevant_indicators, num_cases, domain, get_cases)
예제 #31
0
def process(domain, instance):
    """process an incoming commtrack stock report instance"""
    config = CommtrackConfig.for_domain(domain)
    root = etree.fromstring(instance)
    user_id, transactions = unpack_transactions(root, config)
    transactions = list(normalize_transactions(transactions))

    def get_transactions(all_tx, type_filter):
        """get all the transactions of the relevant type (filtered by type_filter),
        grouped by product (returns a dict of 'product subcase id' => list of transactions),
        with each set of transactions sorted in the correct order for processing
        """
        return map_reduce(
            lambda tx: [(tx.case_id, )],
            lambda v: sorted(v, key=lambda tx: tx.priority_order
                             ),  # important!
            data=filter(type_filter, all_tx),
            include_docs=True)

    # split transactions by type and product
    stock_transactions = get_transactions(transactions,
                                          lambda tx: tx.category == 'stock')
    requisition_transactions = get_transactions(
        transactions, lambda tx: tx.category == 'requisition')

    case_ids = list(
        set(itertools.chain(*[tx.get_case_ids() for tx in transactions])))
    cases = dict((c._id, c) for c in CommCareCase.view(
        '_all_docs', keys=case_ids, include_docs=True))

    # TODO: code to auto generate / update requisitions from transactions if
    # project is configured for that.

    # TODO: when we start receiving commcare-submitted reports, we should be using a server time rather
    # than relying on timeStart (however timeStart is set to server time for reports received via sms)
    submit_time = root.find('.//%s' % _('timeStart', META_XMLNS)).text
    post_processed_transactions = list(transactions)
    for product_id, product_case in cases.iteritems():
        stock_txs = stock_transactions.get(product_id, [])
        if stock_txs:
            case_block, reconciliations = process_product_transactions(
                user_id, submit_time, product_case, stock_txs)
            root.append(case_block)
            post_processed_transactions.extend(reconciliations)

        req_txs = requisition_transactions.get(product_id, [])
        if req_txs and config.requisitions_enabled:
            req = RequisitionState.from_transactions(user_id, product_case,
                                                     req_txs)
            case_block = etree.fromstring(req.to_xml())
            root.append(case_block)
    replace_transactions(root, post_processed_transactions)

    submission = etree.tostring(root)
    logger.debug('submitting: %s' % submission)

    spoof_submission(get_submit_url(domain),
                     submission,
                     headers={'HTTP_X_SUBMIT_TIME': submit_time},
                     hqsubmission=False)
예제 #32
0
파일: api.py 프로젝트: mchampanis/core-hq
def get_owned_cases(domain, user_id, closed=False):
    """
    Get all cases in a domain owned by a particular user.
    """

    try:
        user = CouchUser.get_by_user_id(user_id, domain)
    except KeyError:
        user = None
    try:
        owner_ids = user.get_owner_ids()
    except AttributeError:
        owner_ids = [user_id]

    @list
    @inline
    def keys():
        for owner_id in owner_ids:
            if closed is None:
                yield [owner_id, True]
                yield [owner_id, False]
            else:
                yield [owner_id, closed]

    cases = CommCareCase.view('case/by_owner', keys=keys, include_docs=True, reduce=False)
    # demo_user cases!
    return [case.get_json() for case in cases if case.domain == domain]
예제 #33
0
    def rows(self):
        results = self.verbose_results[self.indicator.fluff_calculator.primary]
        numerators = self.verbose_results['numerator']

        def _reconcile(numerators, denominators):
            def _is_match(num, denom):
                return num['id'] == denom['id'] and num['key'][-1] == denom['key'][-1]

            num_copy = copy(numerators)
            for denom in denominators:
                denom['in_num'] = False
                for num in num_copy:
                    if _is_match(num, denom):
                        num_copy.remove(num)
                        denom['in_num'] = True
                        break
            if num_copy:
                logging.error('expected no indicators left in the numerator but found some')

        def _key(result):
            return (result['in_num'], result['key'][-1])

        _reconcile(numerators, results)
        results = sorted(results, key=_key)
        case_ids = set([res['id'] for res in results])
        cases = dict((c._id, c) for c in CommCareCase.view('_all_docs', keys=list(case_ids),
                                                           include_docs=True))

        return [
            self.indicator.as_row(cases[result['id']], self.fluff_results, fluff_row=result)
            for result in results
        ]
예제 #34
0
    def handle(self, *args, **options):
        domain, group_name = args
        group = Group.by_name(domain, name=group_name)
        owner_ids = get_all_owner_ids_from_group(group)
        pillow = CareBiharFluffPillow()
        db = CommCareCase.get_db()

        greenlets = []

        def process_case(case):
            pillow.change_transport(pillow.change_transform(case))


        for i, owner_id in enumerate(owner_ids):
            print '{0}/{1} owner_ids'.format(i, len(owner_ids))
            rows = CommCareCase.view(
                'hqcase/by_owner',
                startkey=[domain, owner_id],
                endkey=[domain, owner_id, {}],
                reduce=False,
            ).all()
            case_ids = [row['id'] for row in rows]
            print '{0} case_ids'.format(len(case_ids))
            for case in iter_docs(db, case_ids):
                g = gevent.Greenlet.spawn(process_case, case)
                greenlets.append(g)
        gevent.joinall(greenlets)
예제 #35
0
def get_cases_in_domain_by_external_id(domain, external_id):
    return CommCareCase.view(
        'cases_by_domain_external_id/view',
        key=[domain, external_id],
        reduce=False,
        include_docs=True,
    ).all()
예제 #36
0
def generate_case_export_payload(domain, include_closed, format, group, user_filter):
    """
    Returns a FileWrapper object, which only the file backend in django-soil supports

    """
    view_name = 'hqcase/all_cases' if include_closed else 'hqcase/open_cases'
    key = [domain, {}, {}]
    case_ids = CommCareCase.view(view_name,
        startkey=key,
        endkey=key + [{}],
        reduce=False,
        include_docs=False,
        wrapper=lambda r: r['id']
    )
    def stream_cases(all_case_ids):
        for case_ids in chunked(all_case_ids, 500):
            for case in CommCareCase.view('_all_docs', keys=case_ids, include_docs=True):
                yield case

    # todo deal with cached user dict here
    users = get_all_users_by_domain(domain, group=group, user_filter=user_filter)
    groups = Group.get_case_sharing_groups(domain)

    fd, path = tempfile.mkstemp()
    with os.fdopen(fd, 'wb') as file:
        workbook = WorkBook(file, format)
        export_cases_and_referrals(domain, stream_cases(case_ids), workbook, users=users, groups=groups)
        export_users(users, workbook)
        workbook.close()
    return FileWrapper(open(path))
예제 #37
0
def form_data(request, domain, instance_id):
    timezone = util.get_timezone(request.couch_user.user_id, domain)
    try:
        instance = XFormInstance.get(instance_id)
    except Exception:
        raise Http404()
    try:
        assert(domain == instance.domain)
    except AssertionError:
        raise Http404()
    cases = CommCareCase.view("case/by_xform_id", key=instance_id, reduce=False, include_docs=True).all()
    try:
        form_name = instance.get_form["@name"]
    except KeyError:
        form_name = "Untitled Form"
    is_archived = instance.doc_type == "XFormArchived"
    if is_archived:
        messages.info(request, _("This form is archived. To restore it, click 'Restore this form' at the bottom of the page."))
    return render(request, "reports/reportdata/form_data.html",
                              dict(domain=domain,
                                   instance=instance,
                                   cases=cases,
                                   timezone=timezone,
                                   slug=inspect.SubmitHistory.slug,
                                   is_archived=is_archived,
                                   form_data=dict(name=form_name,
                                                  modified=instance.received_on)))
예제 #38
0
def _get_cases(xforms):
    cases = []
    for case in CommCareCase.view('case/by_xform_id',
                                  keys=[xform.get_id for xform in xforms],
                                  reduce=False, include_docs=True).all():
        cases.append(case)
    return cases
예제 #39
0
def delete_all_data(request, domain, template="cleanup/delete_all_data.html"):
    if request.method == 'GET':
        return render(request, template, {
            'domain': domain
        })
    key = make_form_couch_key(domain)
    xforms = XFormInstance.view('reports_forms/all_forms',
        startkey=key,
        endkey=key+[{}],
        include_docs=True,
        reduce=False
    )
    cases = CommCareCase.view('case/by_date_modified',
        startkey=[domain, {}, {}],
        endkey=[domain, {}, {}, {}],
        include_docs=True,
        reduce=False
    )
    suffix = DELETED_SUFFIX
    deletion_id = random_hex()
    for thing_list in (xforms, cases):
        for thing in thing_list:
            thing.doc_type += suffix
            thing['-deletion_id'] = deletion_id
            thing.save()
    return HttpResponseRedirect(reverse('homepage'))
예제 #40
0
def _get_cases_by_domain_hq_user_id(domain, user_id, case_type, include_docs):
    return CommCareCase.view(
        'case_by_domain_hq_user_id_type/view',
        key=[domain, user_id, case_type],
        reduce=False,
        include_docs=include_docs
    ).all()
예제 #41
0
    def rows(self):
        results = self.verbose_results[self.indicator.fluff_calculator.primary]
        numerators = self.verbose_results['numerator']
        def _reconcile(numerators, denominators):
            def _is_match(num, denom):
                return num['id'] == denom['id'] and num['key'][-1] == denom['key'][-1]

            num_copy = copy(numerators)
            for denom in denominators:
                denom['in_num'] = False
                for num in num_copy:
                    if _is_match(num, denom):
                        num_copy.remove(num)
                        denom['in_num'] = True
                        break
            if num_copy:
                logging.error('expected no indicators left in the numerator but found some')


        def _key(result):
            return (result['in_num'], result['key'][-1])

        _reconcile(numerators, results)
        results = sorted(results, key=_key)
        case_ids = set([res['id'] for res in results])
        cases = dict((c._id, c) for c in CommCareCase.view('_all_docs', keys=list(case_ids),
                                                           include_docs=True))

        return [
            self.indicator.as_row(cases[result['id']], self.fluff_results, fluff_row=result)
            for result in results
        ]
예제 #42
0
 def testAttachInCreate(self):
     self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all()))
     
     file_path = os.path.join(os.path.dirname(__file__), "data", "attachments", "create_with_attach.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     
     attach_name = "fruity.jpg"
     attachment_path = os.path.join(os.path.dirname(__file__), "data", "attachments", attach_name)
     with open(attachment_path, "rb") as attachment:
         uf = UploadedFile(attachment, attach_name)
         form = post_xform_to_couch(xml_data, {attach_name: uf})
         self.assertEqual(1, len(form.attachments))
         fileback = form.fetch_attachment(attach_name)
         # rewind the pointer before comparing
         attachment.seek(0) 
         self.assertEqual(hashlib.md5(fileback).hexdigest(), 
                          hashlib.md5(attachment.read()).hexdigest())
         
     
     process_cases(sender="testharness", xform=form)
     case = CommCareCase.get(form.xpath("form/case/case_id"))
     self.assertEqual(1, len(case.attachments))
     self.assertEqual(form.get_id, case.attachments[0][0])
     self.assertEqual(attach_name, case.attachments[0][1])
 def _get_cases(self):
     case_ids = get_case_ids_in_domain(self.domain)
     return CommCareCase.view(
         '_all_docs',
         keys=case_ids,
         include_docs=True,
     )
예제 #44
0
def product_subcases(supply_point):
    """given a supply point, return all the sub-cases for each product stocked at that supply point
    actually returns a mapping: product doc id => sub-case id
    ACTUALLY returns a dict that will create non-existent product sub-cases on demand
    """
    product_subcase_uuids = [ix.referenced_id for ix in supply_point.reverse_indices if ix.identifier == const.PARENT_CASE_REF]
    product_subcases = CommCareCase.view('_all_docs', keys=product_subcase_uuids, include_docs=True)
    product_subcase_mapping = dict((subcase.dynamic_properties().get('product'), subcase._id) for subcase in product_subcases)

    def create_product_subcase(product_uuid):
        return make_supply_point_product(supply_point, product_uuid)._id

    class DefaultDict(dict):
        """similar to collections.defaultdict(), but factory function has access
        to 'key'
        """
        def __init__(self, factory, *args, **kwargs):
            super(DefaultDict, self).__init__(*args, **kwargs)
            self.factory = factory

        def __getitem__(self, key):
            if key in self:
                val = self.get(key)
            else:
                val = self.factory(key)
                self[key] = val
            return val

    return DefaultDict(create_product_subcase, product_subcase_mapping)
예제 #45
0
파일: views.py 프로젝트: atinus/commcare-hq
def explode_cases(request, domain, template="hqcase/explode_cases.html"):
    if request.method == 'POST':
        user_id = request.POST['user_id']
        user = CommCareUser.get_by_user_id(user_id, domain)
        factor = request.POST.get('factor', '2')
        try:
            factor = int(factor)
        except ValueError:
            messages.error(request, 'factor must be an int; was: %s' % factor)
        else:
            keys = [[domain, owner_id, False] for owner_id in user.get_owner_ids()]
            for case in CommCareCase.view('hqcase/by_owner',
                keys=keys,
                include_docs=True,
                reduce=False
            ):
                for i in range(factor - 1):
                    new_case_id = uuid.uuid4().hex
                    case_block, attachments = make_creating_casexml(case, new_case_id)
                    submit_case_blocks(case_block, domain, attachments=attachments)

            messages.success(request, "All of %s's cases were exploded by a factor of %d" % (user.raw_username, factor))

    return render(request, template, {
        'domain': domain,
        'users': CommCareUser.by_domain(domain),
    })
예제 #46
0
 def get_case(self, external_id):
     case = CommCareCase.view("hqcase/by_domain_external_id",
         key=[self.domain, external_id],
         include_docs=True,
         reduce=False,
     ).one()
     return case
예제 #47
0
파일: views.py 프로젝트: mchampanis/core-hq
def download_cases(request, domain):
    include_closed = json.loads(request.GET.get('include_closed', 'false'))
    format = Format.from_format(request.GET.get('format') or Format.XLS_2007)

    view_name = 'hqcase/all_cases' if include_closed else 'hqcase/open_cases'

    key = [domain, {}, {}]
    cases = CommCareCase.view(view_name, startkey=key, endkey=key + [{}], reduce=False, include_docs=True)
#    group, users = util.get_group_params(domain, **json_request(request.GET))
    group = request.GET.get('group', None)
    user_filter, _ = FilterUsersField.get_user_filter(request)
    # todo deal with cached user dict here
    users = get_all_users_by_domain(domain, group=group, user_filter=user_filter)
    groups = Group.get_case_sharing_groups(domain)
    
#    if not group:
#        users.extend(CommCareUser.by_domain(domain, is_active=False))

    workbook = WorkBook()
    export_cases_and_referrals(cases, workbook, users=users, groups=groups)
    export_users(users, workbook)
    response = HttpResponse(workbook.format(format.slug))
    response['Content-Type'] = "%s" % format.mimetype
    response['Content-Disposition'] = "attachment; filename={domain}_data.{ext}".format(domain=domain, ext=format.extension)
    return response
예제 #48
0
def get_cases_in_domain_by_external_id(domain, external_id):
    return CommCareCase.view(
        'cases_by_domain_external_id/view',
        key=[domain, external_id],
        reduce=False,
        include_docs=True,
    ).all()
예제 #49
0
def get_case_ids_in_domain_by_owner(domain, owner_id=None, owner_id__in=None,
                                    closed=None):
    """
    get case_ids for open, closed, or all cases in a domain
    that belong to an owner_id or list of owner_ids

    domain: required
    owner_id: a single owner_id to filter on
    owner_id__in: a list of owner ids to filter on.
        A case matches if it belongs to any of them.
        You cannot specify both this and owner_id
    closed: True (only closed cases), False (only open cases), or None (all)
    returns a list of case_ids

    """
    assert not (owner_id__in and owner_id)
    assert closed in (True, False, None)
    if closed is None:
        closed_flags = [True, False]
    else:
        closed_flags = [closed]
    if owner_id:
        owner_id__in = [owner_id]
    return [res["id"] for res in CommCareCase.view(
        'cases_by_owner/view',
        keys=[[domain, owner_id, closed_flag]
              for owner_id in owner_id__in
              for closed_flag in closed_flags],
        include_docs=False,
        reduce=False,
    )]
예제 #50
0
    def query(stale="ok", **kwargs):
        subs = [dict(
            userID      = r['key'][1],
            username    = r['key'][2],
            deviceID    = r['key'][3],
            submissions = r['value']['count'],
            start       = r['value']['start'].split('T')[0],
            end         = r['value']['end'  ].split('T')[0]
        ) for r in get_db().view('cleanup/case_submissions',
             startkey=[domain],
             endkey=[domain, {}],
             group=True,
#             stale=stale
        )]
        subs.sort(key=lambda sub: (sub['userID'], sub['end']))

        # Try and help identify lost devices
        latest_start = defaultdict(lambda: None)
        for sub in subs:
            latest_start[sub['userID']] = max(sub['start'], latest_start[sub['userID']])
        for sub in subs:
            if sub['end'] < latest_start[sub['userID']]:
                sub['old'] = True
            else:
                sub['old'] = False


        # show the number of cases made by these xforms
#        for sub in subs:
#            cases = _get_cases(_get_submissions(domain, [sub]))
#            sub['cases'] = len([None for case in cases if not case.closed])

        open_cases = CommCareCase.view('hqcase/open_cases', startkey=[domain], endkey=[domain, {}], reduce=False, include_docs=True).all()
        xform_ids = [case.xform_ids[0] for case in open_cases]
예제 #51
0
def get_case_by_domain_hq_user_id(domain, user_id, include_docs=False):
    """
    Get the 'user case' for user_id. User cases are part of the call center feature.
    """
    return CommCareCase.view('hqcase/by_domain_hq_user_id',
                             key=[domain, user_id],
                             reduce=False,
                             include_docs=include_docs).one()
예제 #52
0
def get_one_case_in_domain_by_external_id(domain, external_id):
    return CommCareCase.view(
        'hqcase/by_domain_external_id',
        key=[domain, external_id],
        reduce=False,
        include_docs=True,
        # limit for efficiency, 2 instead of 1 so it raises if multiple found
        limit=2,
    ).one()
예제 #53
0
def run():
    print "starting out"
    pact_cases = CommCareCase.view('case/by_owner_lite', key=[PACT_HP_GROUP_ID, True],
                                   include_docs=True, reduce=False).all()

    for c in pact_cases:
        print "#### Case %s" % c._id
        for action in c.actions:
            if getattr(action, 'server_date', None) is None:
                print "\taction is none!"
                print "\t%s" % simplejson.dumps(action.to_json(), indent=4)
예제 #54
0
파일: utils.py 프로젝트: ekush/commcare-hq
def get_callcenter_case_mapping(domain, user_ids):
    """
    Get the mapping from user_id to 'user case id' for each user in user_ids.
    """
    keys = [[domain, user_id] for user_id in user_ids]
    rows = CommCareCase.view('hqcase/by_domain_hq_user_id',
                             keys=keys,
                             reduce=False,
                             include_docs=False)

    return {r['key'][1]: r['id'] for r in rows}
예제 #55
0
def get_reverse_indexed_cases(domain, case_ids, relationship=None):
    """
    Gets all reverse indexed cases of a case (including child cases and extensions).
    """
    from casexml.apps.case.models import CommCareCase
    return CommCareCase.view(
        'case_indices/related',
        keys=_get_keys_for_reverse_index_view(domain, case_ids, relationship),
        reduce=False,
        include_docs=True,
    )
예제 #56
0
파일: utils.py 프로젝트: ekush/commcare-hq
def get_case_by_domain_hq_user_id(domain, user_id, case_type):
    """
    Get the 'user case' for user_id. User cases are part of the call center feature.
    """
    cases = CommCareCase.view('hqcase/by_domain_hq_user_id',
                              key=[domain, user_id],
                              reduce=False,
                              include_docs=True).all()

    for case in cases:
        if case.type == case_type:
            return case
 def testCasesInRepeats(self):
     self.assertEqual(
         0, len(CommCareCase.view("case/by_user", reduce=False).all()))
     file_path = os.path.join(os.path.dirname(__file__), "data",
                              "multicase", "case_in_repeats.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     form = post_xform_to_couch(xml_data)
     process_cases(form)
     cases = self._get_cases()
     self.assertEqual(3, len(cases))
     self._check_ids(form, cases)