コード例 #1
0
ファイル: releases.py プロジェクト: twymer/commcare-hq
def save_copy(request, domain, app_id):
    """
    Saves a copy of the app to a new doc.
    See ApplicationBase.save_copy

    """
    track_built_app_on_hubspot.delay(request.couch_user)
    comment = request.POST.get('comment')
    app = get_app(domain, app_id)
    try:
        errors = app.validate_app()
    except ModuleIdMissingException:
        # For apps (mainly Exchange apps) that lost unique_id attributes on Module
        app.ensure_module_unique_ids(should_save=True)
        errors = app.validate_app()

    if not errors:
        try:
            user_id = request.couch_user.get_id
            timer = datadog_bucket_timer('commcare.app_build.new_release',
                                         tags=[],
                                         timing_buckets=(1, 10, 30, 60, 120,
                                                         240))
            with timer:
                copy = make_app_build(app, comment, user_id)
            CouchUser.get(user_id).set_has_built_app()
        except BuildConflictException:
            return JsonResponse(
                {
                    'error':
                    _("There is already a version build in progress. Please wait."
                      )
                },
                status=400)
        finally:
            # To make a RemoteApp always available for building
            if app.is_remote_app():
                app.save(increment_version=True)

        _track_build_for_app_preview(domain, request.couch_user, app_id,
                                     'User created a build')

    else:
        copy = None
    copy = copy and SavedAppBuild.wrap(copy.to_json()).releases_list_json(
        get_timezone_for_user(request.couch_user, domain))
    lang, langs = get_langs(request, app)

    return json_response({
        "saved_app":
        copy,
        "error_html":
        render_to_string(
            "app_manager/partials/build_errors.html", {
                'app': get_app(domain, app_id),
                'build_errors': errors,
                'domain': domain,
                'langs': langs,
            }),
    })
コード例 #2
0
ファイル: releases.py プロジェクト: kkrampa/commcare-hq
def save_copy(request, domain, app_id):
    """
    Saves a copy of the app to a new doc.
    See VersionedDoc.save_copy

    """
    track_built_app_on_hubspot_v2.delay(request.couch_user)
    comment = request.POST.get('comment')
    app = get_app(domain, app_id)
    try:
        errors = app.validate_app()
    except ModuleIdMissingException:
        # For apps (mainly Exchange apps) that lost unique_id attributes on Module
        app.ensure_module_unique_ids(should_save=True)
        errors = app.validate_app()

    if not errors:
        try:
            user_id = request.couch_user.get_id
            timer = datadog_bucket_timer('commcare.app_build.new_release', tags=[],
                                         timing_buckets=(1, 10, 30, 60, 120, 240))
            with timer:
                copy = app.make_build(
                    comment=comment,
                    user_id=user_id,
                )
                copy.save(increment_version=False)
            CouchUser.get(user_id).set_has_built_app()
        finally:
            # To make a RemoteApp always available for building
            if app.is_remote_app():
                app.save(increment_version=True)

        _track_build_for_app_preview(domain, request.couch_user, app_id, 'User created a build')

    else:
        copy = None
    copy = copy and SavedAppBuild.wrap(copy.to_json()).releases_list_json(
        get_timezone_for_user(request.couch_user, domain)
    )
    lang, langs = get_langs(request, app)
    if copy:
        # Set if build is supported for Java Phones
        j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels()
        copy['j2me_enabled'] = copy['menu_item_label'] in j2me_enabled_configs

    return json_response({
        "saved_app": copy,
        "error_html": render_to_string("app_manager/partials/build_errors.html", {
            'request': request,
            'app': get_app(domain, app_id),
            'build_errors': errors,
            'domain': domain,
            'langs': langs,
            'lang': lang
        }),
    })
コード例 #3
0
def save_copy(request, domain, app_id):
    """
    Saves a copy of the app to a new doc.
    See VersionedDoc.save_copy

    """
    track_built_app_on_hubspot.delay(request.couch_user)
    comment = request.POST.get('comment')
    app = get_app(domain, app_id)
    try:
        errors = app.validate_app()
    except ModuleIdMissingException:
        # For apps (mainly Exchange apps) that lost unique_id attributes on Module
        app.ensure_module_unique_ids(should_save=True)
        errors = app.validate_app()

    if not errors:
        try:
            user_id = request.couch_user.get_id
            copy = app.make_build(
                comment=comment,
                user_id=user_id,
                previous_version=app.get_latest_app(released_only=False))
            copy.save(increment_version=False)
            CouchUser.get(user_id).set_has_built_app()
        finally:
            # To make a RemoteApp always available for building
            if app.is_remote_app():
                app.save(increment_version=True)

        _track_build_for_app_preview(domain, request.couch_user, app_id,
                                     'User created a build')

    else:
        copy = None
    copy = copy and SavedAppBuild.wrap(copy.to_json()).to_saved_build_json(
        get_timezone_for_user(request.couch_user, domain))
    lang, langs = get_langs(request, app)
    if copy:
        # Set if build is supported for Java Phones
        j2me_enabled_configs = CommCareBuildConfig.j2me_enabled_config_labels()
        copy['j2me_enabled'] = copy['menu_item_label'] in j2me_enabled_configs

    return json_response({
        "saved_app":
        copy,
        "error_html":
        render_to_string(
            "app_manager/partials/build_errors.html", {
                'request': request,
                'app': get_app(domain, app_id),
                'build_errors': errors,
                'domain': domain,
                'langs': langs,
                'lang': lang
            }),
    })
コード例 #4
0
ファイル: releases.py プロジェクト: soitun/commcare-hq
def save_copy(request, domain, app_id):
    """
    Saves a copy of the app to a new doc.
    """
    track_built_app_on_hubspot.delay(request.couch_user.get_id)
    comment = request.POST.get('comment')
    app = get_app(domain, app_id)
    try:
        user_id = request.couch_user.get_id
        with report_build_time(domain, app._id, 'new_release'):
            copy = make_app_build(app, comment, user_id)
        CouchUser.get(user_id).set_has_built_app()
    except AppValidationError as e:
        lang, langs = get_langs(request, app)
        return JsonResponse({
            "saved_app":
            None,
            "error_html":
            render_to_string(
                "app_manager/partials/build_errors.html", {
                    'app': get_app(domain, app_id),
                    'build_errors': e.errors,
                    'domain': domain,
                    'langs': langs,
                    'toggles': toggles_enabled_for_request(request),
                }),
        })
    except BuildConflictException:
        return JsonResponse(
            {
                'error':
                _("There is already a version build in progress. Please wait.")
            },
            status=400)
    except XFormValidationFailed:
        return JsonResponse({'error': _("Unable to validate forms.")},
                            status=400)
    finally:
        # To make a RemoteApp always available for building
        if app.is_remote_app():
            app.save(increment_version=True)

    _track_build_for_app_preview(domain, request.couch_user, app_id,
                                 'User created a build')

    copy_json = copy and SavedAppBuild.wrap(copy.to_json()).releases_list_json(
        get_timezone_for_user(request.couch_user, domain))

    return JsonResponse({
        "saved_app": copy_json,
        "error_html": "",
    })
コード例 #5
0
ファイル: generic.py プロジェクト: tsinkala/core-hq
    def __setstate__(self, state):
        """
            For unpickling a pickled report.
        """
        logging = get_task_logger(__name__) # logging lis likely to happen within celery.
        self.domain = state.get('domain')
        self.context = state.get('context', {})

        class FakeHttpRequest(object):
            GET = {}
            META = {}
            couch_user = None
            datespan = None

        request_data = state.get('request')
        request = FakeHttpRequest()
        request.GET = request_data.get('GET', {})
        request.META = request_data.get('META', {})
        request.datespan = request_data.get('datespan')

        try:
            couch_user = CouchUser.get(request_data.get('couch_user'))
            request.couch_user = couch_user
        except Exception as e:
            logging.error("Could not unpickle couch_user from request for report %s. Error: %s" %
                            (self.name, e))
        self.request = request
        self._caching = True
        self.request_params = state.get('request_params')
        self._update_initial_context()
コード例 #6
0
ファイル: views.py プロジェクト: kkrampa/commcare-hq
def heartbeat(request, domain, app_build_id):
    """
    An endpoint for CommCare mobile to get latest CommCare APK and app version
        info. (Should serve from cache as it's going to be busy view)

    'app_build_id' (that comes from URL) can be id of any version of the app
    'app_id' (urlparam) is usually id of an app that is not a copy
        mobile simply needs it to be resent back in the JSON, and doesn't
        need any validation on it. This is pulled from @uniqueid from profile.xml
    """
    app_id = request.GET.get('app_id', '')

    info = {"app_id": app_id}
    try:
        # mobile will send brief_app_id
        info.update(LatestAppInfo(app_id, domain).get_info())
    except (Http404, AssertionError):
        # If it's not a valid 'brief' app id, find it by talking to couch
        notify_exception(request, 'Received an invalid heartbeat request')
        app = get_app_cached(domain, app_build_id)
        brief_app_id = app.master_id
        info.update(LatestAppInfo(brief_app_id, domain).get_info())

    else:
        if settings.SERVER_ENVIRONMENT not in settings.ICDS_ENVS:
            # disable on icds for now since couch still not happy
            couch_user = request.couch_user
            try:
                update_user_reporting_data(app_build_id, app_id, couch_user, request)
            except ResourceConflict:
                # https://sentry.io/dimagi/commcarehq/issues/521967014/
                couch_user = CouchUser.get(couch_user.user_id)
                update_user_reporting_data(app_build_id, app_id, couch_user, request)

    return JsonResponse(info)
コード例 #7
0
ファイル: delete_cases.py プロジェクト: dimagi/commcare-hq
    def handle(self, user, **options):
        try:
            self.user = CouchUser.get_by_username(user)
            if not self.user:
                self.user = CouchUser.get(user)
        except ResourceNotFound:
            print("Could not find user {}".format(user))
            return

        if not isinstance(self.user, CommCareUser):
            print ("Sorry, the user you specify has to be a mobile worker. "
                   "This changed when delete_cases was refactored to use "
                   "cases_by_owner/view instead of case/by_owner. "
                   "The new view needs an explicit domain, "
                   "and I didn't implement that for WebUsers who can belong "
                   "to multiple domains, but usually do not own cases.")
            exit(1)

        self.domain = self.user.domain

        if should_use_sql_backend(self.domain):
            raise CommandError('This command only works for couch-based domains.')

        if not options.get('no_prompt'):
            msg = "Delete all cases owned by {}? (y/n)\n".format(
                self.user.username,
            )
            if not input(msg) == 'y':
                print("cancelling")
                return

        self.delete_all()
        print("Cases successfully deleted, you monster!")
コード例 #8
0
ファイル: requisitions.py プロジェクト: tsinkala/core-hq
    def from_transactions(cls, user_id, product_stock_case, transactions):
        assert transactions, "can't make a requisition state from an empty transaciton list"

        def _to_fields(transaction):
            # TODO support other types
            if transaction.action_config.action_type == RequisitionActions.REQUEST:
                return {
                    'create':           True,
                    'amount_requested': transaction.value,
                }
            else:
                raise ValueError('only requests are currently supported')

        kwargs = {}
        for tx in transactions:
            fields = _to_fields(tx)
            for field in fields:
                assert field not in kwargs, 'transaction updates should be disjoint but found %s twice' % field
            kwargs.update(fields)

        username = CouchUser.get(user_id).username
        return cls(
            domain=product_stock_case.domain,
            id=uuid.uuid4().hex, # TODO: support non-create case
            user_id=user_id,
            username=username,
            product_stock_case_id=product_stock_case._id,
            **kwargs
        )
コード例 #9
0
    def __setstate__(self, state):
        """
            For unpickling a pickled report.
        """
        logging = get_task_logger(
            __name__)  # logging lis likely to happen within celery.
        self.domain = state.get('domain')
        self.context = state.get('context', {})

        class FakeHttpRequest(object):
            GET = {}
            META = {}
            couch_user = None
            datespan = None

        request_data = state.get('request')
        request = FakeHttpRequest()
        request.GET = request_data.get('GET', {})
        request.META = request_data.get('META', {})
        request.datespan = request_data.get('datespan')

        try:
            couch_user = CouchUser.get(request_data.get('couch_user'))
            request.couch_user = couch_user
        except Exception as e:
            logging.error(
                "Could not unpickle couch_user from request for report %s. Error: %s"
                % (self.name, e))
        self.request = request
        self._caching = True
        self.request_params = state.get('request_params')
        self._update_initial_context()
コード例 #10
0
ファイル: delete_cases.py プロジェクト: ansarbek/commcare-hq
    def handle(self, *args, **options):
        if not len(args):
            print "Usage: ./manage.py delete_cases <user>"
            return
        try:
            self.user = CouchUser.get_by_username(args[0])
            if not self.user:
                self.user = CouchUser.get(args[0])
        except ResourceNotFound:
            print "Could not find user {}".format(args[0])
            return

        if not isinstance(self.user, CommCareUser):
            print ("Sorry, the user you specify has to be a mobile worker. "
                   "This changed when delete_cases was refactored to use "
                   "cases_by_owner/view instead of case/by_owner. "
                   "The new view needs an explicit domain, "
                   "and I didn't implement that for WebUsers who can belong "
                   "to multiple domains, but usually do not own cases.")
            exit(1)

        self.domain = self.user.domain

        if not options.get('no_prompt'):
            msg = "Delete all cases owned by {}? (y/n)\n".format(
                self.user.username,
            )
            if not raw_input(msg) == 'y':
                print "cancelling"
                return

        self.delete_all()
        print "Cases successfully deleted, you monster!"
コード例 #11
0
    def handle(self, user, **options):
        try:
            self.user = CouchUser.get_by_username(user)
            if not self.user:
                self.user = CouchUser.get(user)
        except ResourceNotFound:
            print("Could not find user {}".format(user))
            return

        if not isinstance(self.user, CommCareUser):
            print("Sorry, the user you specify has to be a mobile worker. "
                  "This changed when delete_cases was refactored to use "
                  "cases_by_owner/view instead of case/by_owner. "
                  "The new view needs an explicit domain, "
                  "and I didn't implement that for WebUsers who can belong "
                  "to multiple domains, but usually do not own cases.")
            exit(1)

        self.domain = self.user.domain

        if should_use_sql_backend(self.domain):
            raise CommandError(
                'This command only works for couch-based domains.')

        if not options.get('no_prompt'):
            msg = "Delete all cases owned by {}? (y/n)\n".format(
                self.user.username, )
            if not raw_input(msg) == 'y':
                print("cancelling")
                return

        self.delete_all()
        print("Cases successfully deleted, you monster!")
コード例 #12
0
def users_for_phone(phone):
    """
    Get users attached to a phone number
    """
    view_results = get_db().view("sms/phones_to_domains", key=phone)
    user_ids = set([row["id"] for row in view_results])
    return [CouchUser.get(id) for id in user_ids]
コード例 #13
0
def users_for_phone(phone):
    """
    Get users attached to a phone number
    """
    view_results = get_db().view("sms/phones_to_domains", key=phone)
    user_ids = set([row["id"] for row in view_results])
    return [CouchUser.get(id) for id in user_ids]
コード例 #14
0
ファイル: delete_cases.py プロジェクト: aristide/commcare-hq
    def handle(self, *args, **options):
        self.last_submitter = options.get('last_submitter', False)
        if not len(args):
            print "Usage: ./manage.py delete_cases <user>"
            return
        try:
            self.user = CouchUser.get_by_username(args[0])
            if not self.user:
                self.user = CouchUser.get(args[0])
        except ResourceNotFound:
            print "Could not find user {}".format(args[0])
            return

        if not options.get('no_prompt'):
            msg = "Delete all {} cases {} by {}? (y/n)\n".format(
                self.get_case_count(),
                "submitted" if self.last_submitter else "owned",
                self.user.username,
            )
            if not raw_input(msg) == 'y':
                print "cancelling"
                return

        self.delete_all()
        print "Cases successfully deleted, you monster!"
コード例 #15
0
def update_user_reporting_data(app_build_id, app_id, build_profile_id,
                               couch_user, request):
    def _safe_int(val):
        try:
            return int(val)
        except:
            pass

    app_version = _safe_int(request.GET.get('app_version', ''))
    device_id = request.GET.get('device_id', '')
    last_sync_time = request.GET.get('last_sync_time', '')
    num_unsent_forms = _safe_int(request.GET.get('num_unsent_forms', ''))
    num_quarantined_forms = _safe_int(
        request.GET.get('num_quarantined_forms', ''))
    commcare_version = request.GET.get('cc_version', '')
    # if mobile cannot determine app version it sends -1
    if app_version == -1:
        app_version = None
    try:
        last_sync = adjust_text_to_datetime(last_sync_time)
    except iso8601.ParseError:
        try:
            last_sync = string_to_utc_datetime(last_sync_time)
        except (ValueError, OverflowError):
            last_sync = None

    if settings.USER_REPORTING_METADATA_BATCH_ENABLED:
        UserReportingMetadataStaging.add_heartbeat(
            request.domain, couch_user._id, app_id, app_build_id, last_sync,
            device_id, app_version, num_unsent_forms, num_quarantined_forms,
            commcare_version, build_profile_id)
    else:
        record = UserReportingMetadataStaging(
            domain=request.domain,
            user_id=couch_user._id,
            app_id=app_id,
            build_id=app_build_id,
            sync_date=last_sync,
            device_id=device_id,
            app_version=app_version,
            num_unsent_forms=num_unsent_forms,
            num_quarantined_forms=num_quarantined_forms,
            commcare_version=commcare_version,
            build_profile_id=build_profile_id,
            last_heartbeat=datetime.utcnow(),
            modified_on=datetime.utcnow())
        try:
            record.process_record(couch_user)
        except ResourceConflict:
            # https://sentry.io/dimagi/commcarehq/issues/521967014/
            couch_user = CouchUser.get(couch_user.user_id)
            record.process_record(couch_user)
コード例 #16
0
def get_user_type(user_id):
    if user_id == SYSTEM_USER_ID:
        # Every form with user_id == system also has username == system.
        # But there are some forms where username == system but the user_id is different.
        # Any chance those should be included?
        return SYSTEM_USER_TYPE
    elif user_id == DEMO_USER_ID:
        return DEMO_USER_TYPE
    elif user_id == COMMTRACK_USERNAME:
        return COMMCARE_SUPPLY_USER_TYPE
    else:
        try:
            user = CouchUser.get(user_id)
            if user.is_web_user():
                return WEB_USER_TYPE
            elif user.is_commcare_user():
                return MOBILE_USER_TYPE
        except:
            pass
    return UNKNOWN_USER_TYPE
コード例 #17
0
ファイル: utils.py プロジェクト: tstalka/commcare-hq
def get_user_type(user_id):
    if user_id == SYSTEM_USER_ID:
        # Every form with user_id == system also has username == system.
        # But there are some forms where username == system but the user_id is different.
        # Any chance those should be included?
        return SYSTEM_USER_TYPE
    elif user_id == DEMO_USER_ID:
        return DEMO_USER_TYPE
    elif user_id == COMMTRACK_USERNAME:
        return COMMCARE_SUPPLY_USER_TYPE
    elif user_id:
        try:
            user = CouchUser.get(user_id)
            if user.is_web_user():
                return WEB_USER_TYPE
            elif user.is_commcare_user():
                return MOBILE_USER_TYPE
        except (ResourceNotFound, WrappingAttributeError):
            pass
    return UNKNOWN_USER_TYPE
コード例 #18
0
def heartbeat(request, domain, app_build_id):
    """
    An endpoint for CommCare mobile to get latest CommCare APK and app version
        info. (Should serve from cache as it's going to be busy view)

    'app_build_id' (that comes from URL) can be id of any version of the app
    'app_id' (urlparam) is usually id of an app that is not a copy
        mobile simply needs it to be resent back in the JSON, and doesn't
        need any validation on it. This is pulled from @uniqueid from profile.xml
    """
    app_id = request.GET.get('app_id', '')

    info = {"app_id": app_id}
    try:
        # mobile will send brief_app_id
        info.update(LatestAppInfo(app_id, domain).get_info())
    except (Http404, AssertionError):
        # If it's not a valid 'brief' app id, find it by talking to couch
        notify_exception(request, 'Received an invalid heartbeat request')
        app = get_app_cached(domain, app_build_id)
        brief_app_id = app.master_id
        info.update(LatestAppInfo(brief_app_id, domain).get_info())

    else:
        if settings.SERVER_ENVIRONMENT not in settings.ICDS_ENVS:
            # disable on icds for now since couch still not happy
            couch_user = request.couch_user
            try:
                update_user_reporting_data(app_build_id, app_id, couch_user,
                                           request)
            except ResourceConflict:
                # https://sentry.io/dimagi/commcarehq/issues/521967014/
                couch_user = CouchUser.get(couch_user.user_id)
                update_user_reporting_data(app_build_id, app_id, couch_user,
                                           request)

    if _should_force_log_submission(request):
        info['force_logs'] = True
    return JsonResponse(info)
コード例 #19
0
ファイル: delete_cases.py プロジェクト: ekush/commcare-hq
    def handle(self, *args, **options):
        if not len(args):
            print "Usage: ./manage.py delete_cases <user>"
            return
        try:
            self.user = CouchUser.get_by_username(args[0])
            if not self.user:
                self.user = CouchUser.get(args[0])
        except ResourceNotFound:
            print "Could not find user {}".format(args[0])
            return

        if not isinstance(self.user, CommCareUser):
            print(
                "Sorry, the user you specify has to be a mobile worker. "
                "This changed when delete_cases was refactored to use "
                "hqcase/by_owner instead of case/by_owner. "
                "The new view needs an explicit domain, "
                "and I didn't implement that for WebUsers who can belong "
                "to multiple domains, but usually do not own cases.")
            exit(1)

        self.domain = self.user.domain

        if not options.get('no_prompt'):
            msg = "Delete all {} cases {} by {}? (y/n)\n".format(
                self.get_case_count(),
                "owned",
                self.user.username,
            )
            if not raw_input(msg) == 'y':
                print "cancelling"
                return

        self.delete_all()
        print "Cases successfully deleted, you monster!"
コード例 #20
0
ファイル: tasks.py プロジェクト: mchampanis/core-hq
def _run_reports(reps):
    for rep in reps:
        for user_id in rep.user_ids:
            user = CouchUser.get(user_id)
            send_report.delay(rep, user.to_json())
コード例 #21
0
 def get_user(self, user_id):
     return CouchUser.get(user_id)
コード例 #22
0
 else:
     target_date = EMPTY_FIELD
 interaction = {
     'url': '',
     'name': visit['visit_name'],
     'target_date': target_date,
     'received_date': EMPTY_FIELD,
     'completed_by': EMPTY_FIELD,
     'scheduled_date': EMPTY_FIELD
 }
 for key, action in enumerate(case['actions']):
     if visit['xmlns'] == action['xform_xmlns']:
         interaction['received_date'] = action['date'].strftime(
             INTERACTION_OUTPUT_DATE_FORMAT)
         try:
             user = CouchUser.get(action['user_id'])
             interaction['completed_by'] = user.raw_username
         except ResourceNotFound:
             interaction['completed_by'] = EMPTY_FIELD
         del case['actions'][key]
         break
 if visit['show_button']:
     interaction['url'] = get_form_url(cm_app_dict,
                                       latest_cm_build,
                                       visit['module_idx'],
                                       visit['xmlns'])
 if 'scheduled_source' in visit and case.get_case_property(
         visit['scheduled_source']):
     interaction['scheduled_date'] = (case.get_case_property(
         visit['scheduled_source'])).strftime(
             INTERACTION_OUTPUT_DATE_FORMAT)
コード例 #23
0
    def from_transactions(cls, user_id, product_stock_case, transactions):
        assert transactions, "can't make a requisition state from an empty transaction list"

        def _to_fields(transaction):
            ret = {
                'requisition_status':
                RequisitionStatus.by_action_type(
                    transaction.action_config.action_type)
            }
            if transaction.action_config.action_type == RequisitionActions.REQUEST:
                ret.update({
                    'create': True,
                    'owner_id': get_owner_id(product_stock_case) or user_id,
                    'amount_requested': transaction.value,
                    'product_id': product_stock_case.product,
                    'requested_by': user_id,
                    'requested_on': datetime.utcnow(),
                })
            elif transaction.action_config.action_type == RequisitionActions.APPROVAL:
                ret.update({
                    'amount_approved': transaction.value,
                    'approved_by': user_id,
                    'approved_on': datetime.utcnow(),
                })
            elif transaction.action_config.action_type == RequisitionActions.PACK:
                ret.update({
                    'amount_packed': transaction.value,
                    'packed_by': user_id,
                    'packed_on': datetime.utcnow(),
                })
            elif transaction.action_config.action_type == RequisitionActions.RECEIPTS:
                ret.update({
                    'amount_received': transaction.value,
                    'received_by': user_id,
                    'received_on': datetime.utcnow(),
                    'close': True,
                })
            else:
                raise ValueError("the type %s isn't yet supported." %
                                 transaction.action_config.action_type)
            return ret

        def _get_case_id(transactions):
            req_case_id = None
            for tx in transactions:
                if tx.requisition_case_id:
                    if req_case_id:
                        assert tx.requisition_case_id == req_case_id, 'tried to update multiple cases with one set of transactions'
                    req_case_id = tx.requisition_case_id
            return req_case_id or uuid.uuid4().hex

        kwargs = {}
        for tx in transactions:
            fields = _to_fields(tx)
            for field in fields:
                assert field not in kwargs, 'transaction updates should be disjoint but found %s twice' % field
            kwargs.update(fields)

        username = CouchUser.get(user_id).username

        return cls(domain=product_stock_case.domain,
                   id=_get_case_id(transactions),
                   user_id=user_id,
                   username=username,
                   product_stock_case=product_stock_case,
                   **kwargs)
コード例 #24
0
    def from_transactions(cls, user_id, product_stock_case, transactions):
        assert transactions, "can't make a requisition state from an empty transaction list"

        def _to_fields(transaction):
            ret = {'requisition_status': RequisitionStatus.by_action_type(transaction.action_config.action_type)}
            if transaction.action_config.action_type == RequisitionActions.REQUEST:
                ret.update({
                    'create': True,
                    'owner_id': get_owner_id(product_stock_case) or user_id,
                    'amount_requested': transaction.value,
                    'product_id': product_stock_case.product,
                    'requested_by': user_id,
                    'requested_on': datetime.utcnow(),
                })
            elif transaction.action_config.action_type == RequisitionActions.APPROVAL:
                ret.update({
                    'amount_approved': transaction.value,
                    'approved_by': user_id,
                    'approved_on': datetime.utcnow(),
                })
            elif transaction.action_config.action_type == RequisitionActions.PACK:
                ret.update({
                    'amount_packed': transaction.value,
                    'packed_by': user_id,
                    'packed_on': datetime.utcnow(),
                })
            elif transaction.action_config.action_type == RequisitionActions.RECEIPTS:
                ret.update({
                    'amount_received': transaction.value,
                    'received_by': user_id,
                    'received_on': datetime.utcnow(),
                    'close': True,
                })
            else:
                raise ValueError("the type %s isn't yet supported." % transaction.action_config.action_type)
            return ret

        def _get_case_id(transactions):
            req_case_id = None
            for tx in transactions:
                if tx.requisition_case_id:
                    if req_case_id:
                        assert tx.requisition_case_id == req_case_id, 'tried to update multiple cases with one set of transactions'
                    req_case_id = tx.requisition_case_id
            return req_case_id or uuid.uuid4().hex

        kwargs = {}
        for tx in transactions:
            fields = _to_fields(tx)
            for field in fields:
                assert field not in kwargs, 'transaction updates should be disjoint but found %s twice' % field
            kwargs.update(fields)

        username = CouchUser.get(user_id).username

        return cls(
            domain=product_stock_case.domain,
            id=_get_case_id(transactions),
            user_id=user_id,
            username=username,
            product_stock_case=product_stock_case,
            **kwargs
        )
コード例 #25
0
    def report_context(self):
        ret = {}

        try:
            case = self.get_case()
            has_error = False
        except ResourceNotFound:

            has_error = True
            case = None
        if case is None:
            self.report_template_path = "patient_error.html"
            if has_error:
                ret['error_message'] = "Patient not found"
            else:
                ret['error_message'] = "No patient selected"
            return ret


        def get_form_url(app_dict, app_build_id, module_idx, form, case_id=None):
            try:
                module = app_dict['modules'][module_idx]
                form_idx = [ix for (ix, f) in enumerate(module['forms']) if f['xmlns'] == form][0]
            except IndexError:
                form_idx = None

            return html.escape(get_cloudcare_form_url(domain=self.domain,
                                                      app_build_id=app_build_id,
                                                      module_id=module_idx,
                                                      form_id=form_idx,
                                                      case_id=case_id) + '/enter/')

        try:
            cm_app_dict = get_cloudcare_app(case['domain'], SUCCEED_CM_APPNAME)
            latest_cm_build = get_app_build(cm_app_dict)
            pm_app_dict = get_cloudcare_app(case['domain'], SUCCEED_PM_APPNAME)
            latest_pm_build = get_app_build(pm_app_dict)
            chw_app_dict = get_cloudcare_app(case['domain'], SUCCEED_CHW_APPNAME)
            latest_chw_build = get_app_build(pm_app_dict)
        except ResourceNotFound as ex:
            self.report_template_path = "patient_error.html"
            ret['error_message'] = ex.message
            return ret

        ret['patient'] = case
        ret['root_url'] = '?patient_id=%s' % case['_id']
        ret['view_mode'] = self.view_mode
        ret['patient_status_access'] = self.patient_status_access
        ret['submission_user_access'] = self.submission_user_access

        if self.view_mode == 'info':
            self.report_template_path = "patient_info.html"
            patient_info = PatientInfoDisplay(case)

            #  check user role:
            user = self.request.couch_user
            if is_pm_or_pi(user):
                ret['edit_patient_info_url'] = get_form_url(pm_app_dict, latest_pm_build, PM_APP_PM_MODULE, PM_PM2, case['_id'])
            elif is_cm(user):
                ret['edit_patient_info_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_PD_MODULE, PM2, case['_id'])
            elif is_chw(user):
                ret['edit_patient_info_url'] = get_form_url(chw_app_dict, latest_chw_build, CHW_APP_PD_MODULE, PM2, case['_id'])

            if is_pm_or_pi(user):
                ret['upcoming_appointments_url'] = get_form_url(pm_app_dict, latest_pm_build, PM_APP_PM_MODULE, PM_PM2, case['_id'])
            elif is_cm(user):
                ret['upcoming_appointments_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_PD_MODULE, PM2, case['_id'])
            elif is_chw(user):
                ret['upcoming_appointments_url'] = get_form_url(chw_app_dict, latest_chw_build, CHW_APP_MA_MODULE, AP2, case['_id'])

            ret['general_information'] = patient_info.general_information
            ret['contact_information'] = patient_info.contact_information
            ret['most_recent_lab_exams'] = patient_info.most_recent_lab_exams
            ret['allergies'] = patient_info.allergies

        elif self.view_mode == 'submissions':
            if self.submission_user_access:
                tabular_context = super(PatientInfoReport, self).report_context
                tabular_context.update(ret)
                self.report_template_path = "patient_submissions.html"
                tabular_context['patient_id'] = self.request_params['patient_id']

                return tabular_context
            else:
                self.report_template_path = "patient_error.html"
                ret['error_message'] = "Cannot access report(incorrect user role)"
                return ret
        elif self.view_mode == 'interactions':
            self.report_template_path = "patient_interactions.html"
            ret['problem_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_PD_MODULE, PD1, case['_id'])
            ret['huddle_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_HUD_MODULE, HUD2, case['_id'])
            ret['cm_phone_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_CM_MODULE, CM6, case['_id'])
            ret['chw_phone_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_CHW_MODULE, CHW3, case['_id'])
            ret['cm_visits_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_APPOINTMENTS_MODULE, AP2, case['_id'])

            ret['anti_thrombotic_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_MEDICATIONS_MODULE, PD2AM, case['_id'])
            ret['blood_pressure_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_MEDICATIONS_MODULE, PD2BPM, case['_id'])
            ret['cholesterol_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_MEDICATIONS_MODULE, PD2CHM, case['_id'])
            ret['depression_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_MEDICATIONS_MODULE, PD2DIABM, case['_id'])
            ret['diabetes_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_MEDICATIONS_MODULE, PD2DEPM, case['_id'])
            ret['smoking_cessation_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_MEDICATIONS_MODULE, PD2SCM, case['_id'])
            ret['other_meds_url'] = get_form_url(cm_app_dict, latest_cm_build, CM_APP_MEDICATIONS_MODULE, PD2OM, case['_id'])

            ret['interaction_table'] = []
            for visit_key, visit in enumerate(VISIT_SCHEDULE):
                if case["randomization_date"]:
                    target_date = (case["randomization_date"] + timedelta(days=visit['days'])).strftime(OUTPUT_DATE_FORMAT)
                else:
                    target_date = EMPTY_FIELD
                interaction = {
                    'url': '',
                    'name': visit['visit_name'],
                    'target_date': target_date,
                    'received_date': EMPTY_FIELD,
                    'completed_by': EMPTY_FIELD,
                    'scheduled_date': EMPTY_FIELD
                }
                for key, action in enumerate(case['actions']):
                    if visit['xmlns'] == action['xform_xmlns']:
                        interaction['received_date'] = action['date'].strftime(INTERACTION_OUTPUT_DATE_FORMAT)
                        try:
                            user = CouchUser.get(action['user_id'])
                            interaction['completed_by'] = user.raw_username
                        except ResourceNotFound:
                            interaction['completed_by'] = EMPTY_FIELD
                        del case['actions'][key]
                        break
                if visit['show_button']:
                    interaction['url'] = get_form_url(cm_app_dict, latest_cm_build, visit['module_idx'], visit['xmlns'], case['_id'])
                if 'scheduled_source' in visit and case.get_case_property(visit['scheduled_source']):
                    interaction['scheduled_date'] = format_date(case.get_case_property(visit['scheduled_source']), INTERACTION_OUTPUT_DATE_FORMAT)

                ret['interaction_table'].append(interaction)

                medication = []
                for med_prop in MEDICATION_DETAILS:
                    medication.append(getattr(case, med_prop, EMPTY_FIELD))
                ret['medication_table'] = medication

        elif self.view_mode == 'plan':
            self.report_template_path = "patient_plan.html"
        elif self.view_mode == 'status':
            if self.patient_status_access:
                self.report_template_path = "patient_status.html"
                ret['disenroll_patient_url'] = get_form_url(pm_app_dict, latest_pm_build, PM_APP_PM_MODULE, PM3)
                ret['change_patient_data_url'] = get_form_url(pm_app_dict, latest_pm_build, PM_APP_PM_MODULE, PM4)
            else:
                self.report_template_path = "patient_error.html"
                ret['error_message'] = "Only PMs can disenrollment participants"
                return ret
        else:
            raise Http404
        return ret
コード例 #26
0
 def get_user(self, user_id):
     return CouchUser.get(user_id)