Beispiel #1
0
def get_stock_actions(xform):
    if is_device_report(xform):
        return _empty_actions()

    stock_report_helpers = list(unpack_commtrack(xform))
    transaction_helpers = [
        transaction_helper
        for stock_report_helper in stock_report_helpers
        for transaction_helper in stock_report_helper.transactions
    ]
    if not transaction_helpers:
        return _empty_actions()

    # list of cases that had stock reports in the form
    case_ids = list(set(transaction_helper.case_id
                        for transaction_helper in transaction_helpers))

    user_id = xform.form['meta']['userID']
    submit_time = xform['received_on']
    case_action_intents = []

    for case_id in case_ids:
        if is_deprecation(xform):
            case_action_intents.append(CaseActionIntent(
                case_id=case_id, form_id=xform.orig_id, is_deprecation=True, action=None
            ))
        else:
            case_action = CommCareCaseAction.from_parsed_action(
                submit_time, user_id, xform, AbstractAction(CASE_ACTION_COMMTRACK)
            )
            case_action_intents.append(CaseActionIntent(
                case_id=case_id, form_id=xform._id, is_deprecation=False, action=case_action
            ))

    return StockFormActions(stock_report_helpers, case_action_intents)
Beispiel #2
0
def get_stock_actions(xform):
    """
    Pulls out the ledger blocks and case action intents from a form and returns them
    in a StockFormActions object.

    The stock_report_helpers are StockReportHelper objects, which are basically parsed commtrack actions.
    They should only affect ledger data.

    The case_action_intents are the actions that should be applied to the case, and should not contain
    any ledger data. These are just marker actions that can be used in looking up a case's forms or
    in rebuilding it.
    """
    if is_device_report(xform):
        return _empty_actions()

    stock_report_helpers = list(get_all_stock_report_helpers_from_form(xform))
    transaction_helpers = [
        transaction_helper for stock_report_helper in stock_report_helpers
        for transaction_helper in stock_report_helper.transactions
    ]
    if not transaction_helpers:
        return _empty_actions()

    case_ids = {
        transaction_helper.case_id
        for transaction_helper in transaction_helpers
    }
    case_action_intents = get_ledger_case_action_intents(xform, case_ids)
    return StockFormActions(stock_report_helpers, case_action_intents)
Beispiel #3
0
def get_stock_actions(xform):
    """
    Pulls out the ledger blocks and case action intents from a form and returns them
    in a StockFormActions object.

    The stock_report_helpers are StockReportHelper objects, which are basically parsed commtrack actions.
    They should only affect ledger data.

    The case_action_intents are the actions that should be applied to the case, and should not contain
    any ledger data. These are just marker actions that can be used in looking up a case's forms or
    in rebuilding it.
    """
    if is_device_report(xform):
        return _empty_actions()

    stock_report_helpers = list(_get_all_stock_report_helpers_from_form(xform))
    transaction_helpers = [
        transaction_helper
        for stock_report_helper in stock_report_helpers
        for transaction_helper in stock_report_helper.transactions
    ]
    if not transaction_helpers:
        return _empty_actions()

    case_action_intents = _get_case_action_intents(xform, transaction_helpers)
    return StockFormActions(stock_report_helpers, case_action_intents)
Beispiel #4
0
def get_stock_actions(xform):
    if is_device_report(xform):
        return [], []

    stock_report_helpers = list(unpack_commtrack(xform))
    transaction_helpers = [
        transaction_helper
        for stock_report_helper in stock_report_helpers
        for transaction_helper in stock_report_helper.transactions
    ]
    if not transaction_helpers:
        return [], []

    # list of cases that had stock reports in the form
    case_ids = list(set(transaction_helper.case_id
                        for transaction_helper in transaction_helpers))

    user_id = xform.form['meta']['userID']
    submit_time = xform['received_on']
    case_actions = []
    for case_id in case_ids:
        case_action = CommCareCaseAction.from_parsed_action(
            submit_time, user_id, xform, AbstractAction(CASE_ACTION_COMMTRACK)
        )
        case_actions.append((case_id, case_action))

    return stock_report_helpers, case_actions
Beispiel #5
0
def process_stock(xform, case_db=None):
    """
    process the commtrack xml constructs in an incoming submission
    """
    case_db = case_db or CaseDbCache()
    assert isinstance(case_db, CaseDbCache)
    if is_device_report(xform):
        return []

    domain = xform.domain

    config = CommtrackConfig.for_domain(domain)

    # these are the raw stock report objects from the xml
    stock_reports = list(unpack_commtrack(xform, config))
    # flattened transaction list spanning all stock reports in the form
    transactions = [t for r in stock_reports for t in r.transactions]
    # omitted: normalize_transactions (used for bulk requisitions?)

    if not transactions:
        return []

    # transactions grouped by case/product id
    grouped_tx = map_reduce(lambda tx: [((tx.case_id, tx.product_id),)],
                            lambda v: sorted(v, key=lambda tx: tx.timestamp),
                            data=transactions,
                            include_docs=True)

    case_ids = list(set(k[0] for k in grouped_tx))
    # list of cases that had stock reports in the form
    # there is no need to wrap them by case type
    relevant_cases = [case_db.get(case_id) for case_id in case_ids]

    user_id = xform.form['meta']['userID']
    submit_time = xform['received_on']

    # touch every case for proper ota restore logic syncing to be preserved
    for case in relevant_cases:
        case_action = CommCareCaseAction.from_parsed_action(
            submit_time, user_id, xform, AbstractAction(CASE_ACTION_COMMTRACK)
        )
        # hack: clear the sync log id so this modification always counts
        # since consumption data could change server-side
        case_action.sync_log_id = ''
        case.actions.append(case_action)
        case_db.mark_changed(case)

    # also purge the sync token cache for the same reason
    if relevant_cases and xform.get_sync_token():
        xform.get_sync_token().invalidate_cached_payloads()

    # create the django models
    for report in stock_reports:
        report.create_models(domain)

    # TODO make this a signal
    from corehq.apps.commtrack.signals import send_notifications, raise_events
    send_notifications(xform, relevant_cases)
    raise_events(xform, relevant_cases)
    return relevant_cases
Beispiel #6
0
def create_repeat_records(repeater_cls, payload):
    domain = payload.domain
    if domain:
        repeaters = repeater_cls.by_domain(domain)
        for repeater in repeaters:
            if not (getattr(repeater, 'exclude_device_reports', False)
                    and is_device_report(payload)):
                repeater.register(payload)
def process_stock(xform):
    """
    process the commtrack xml constructs in an incoming submission
    """
    if is_device_report(xform):
        return

    domain = xform.domain

    config = CommtrackConfig.for_domain(domain)

    # these are the raw stock report objects from the xml
    stock_reports = list(unpack_commtrack(xform, config))
    # flattened transaction list spanning all stock reports in the form
    transactions = [t for r in stock_reports for t in r.transactions]
    # omitted: normalize_transactions (used for bulk requisitions?)

    if not transactions:
        return

    # transactions grouped by case/product id
    grouped_tx = map_reduce(lambda tx: [((tx.case_id, tx.product_id),)],
                            lambda v: sorted(v, key=lambda tx: tx.timestamp),
                            data=transactions,
                            include_docs=True)

    # list of cases that had stock reports in the form, properly wrapped by case type
    try:
        relevant_cases = [wrap_commtrack_case(result['doc']) for result in
                          CommCareCase.get_db().view('_all_docs',
                                                     keys=list(set(k[0] for k in grouped_tx)),
                                                     include_docs=True)]
    except KeyError:
        raise Exception("Cannot find case matching supplied entity id")

    user_id = xform.form['meta']['userID']
    submit_time = xform['received_on']

    # touch every case for proper ota restore logic syncing to be preserved
    for case in relevant_cases:
        case_action = CommCareCaseAction.from_parsed_action(
            submit_time, user_id, xform, AbstractAction(CASE_ACTION_COMMTRACK)
        )
        # hack: clear the sync log id so this modification always counts
        # since consumption data could change server-side
        case_action.sync_log_id = ''
        case.actions.append(case_action)
        case.save()

    # create the django models
    for report in stock_reports:
        report.create_models()

    # TODO make this a signal
    from corehq.apps.commtrack.signals import send_notifications, raise_events
    send_notifications(xform, relevant_cases)
    raise_events(xform, relevant_cases)
Beispiel #8
0
def process_stock(xform, case_db=None):
    """
    process the commtrack xml constructs in an incoming submission
    """
    case_db = case_db or CaseDbCache()
    assert isinstance(case_db, CaseDbCache)
    if is_device_report(xform):
        return StockProcessingResult(xform)

    stock_report_helpers = list(unpack_commtrack(xform))
    transaction_helpers = [
        transaction_helper
        for stock_report_helper in stock_report_helpers
        for transaction_helper in stock_report_helper.transactions
    ]

    # omitted: normalize_transactions (used for bulk requisitions?)

    if not transaction_helpers:
        return StockProcessingResult(xform)

    # validate product ids
    if any(transaction_helper.product_id in ('', None)
            for transaction_helper in transaction_helpers):
        raise MissingProductId(
            _('Product IDs must be set for all ledger updates!'))

    # list of cases that had stock reports in the form
    # there is no need to wrap them by case type
    case_ids = list(set(transaction_helper.case_id
                        for transaction_helper in transaction_helpers))
    relevant_cases = [case_db.get(case_id) for case_id in case_ids]

    user_id = xform.form['meta']['userID']
    submit_time = xform['received_on']

    # touch every case for proper ota restore logic syncing to be preserved
    for case_id, case in zip(case_ids, relevant_cases):
        if case is None:
            raise IllegalCaseId(
                _('Ledger transaction references invalid Case ID "{}"')
                .format(case_id))

        case_action = CommCareCaseAction.from_parsed_action(
            submit_time, user_id, xform, AbstractAction(CASE_ACTION_COMMTRACK)
        )
        # hack: clear the sync log id so this modification always counts
        # since consumption data could change server-side
        case_action.sync_log_id = ''
        case.actions.append(case_action)
        case_db.mark_changed(case)

    return StockProcessingResult(
        xform=xform,
        relevant_cases=relevant_cases,
        stock_report_helpers=stock_report_helpers,
    )
Beispiel #9
0
 def form_ok(form_json):
     try:
         # require new-style meta/userID (reject Meta/chw_id)
         if form_json['meta']['userID'] == 'demo_user':
             return True
     except (KeyError, ValueError):
         pass
     if is_device_report(form_json):
         return True
     return False
Beispiel #10
0
def process_stock(xform, case_db=None):
    """
    process the commtrack xml constructs in an incoming submission
    """
    case_db = case_db or CaseDbCache()
    assert isinstance(case_db, CaseDbCache)
    if is_device_report(xform):
        return StockProcessingResult(xform)

    # these are the raw stock report objects from the xml
    stock_reports = list(unpack_commtrack(xform))
    # flattened transaction list spanning all stock reports in the form
    transactions = [t for r in stock_reports for t in r.transactions]
    # omitted: normalize_transactions (used for bulk requisitions?)

    if not transactions:
        return StockProcessingResult(xform)

    # validate product ids
    is_empty = lambda product_id: product_id is None or product_id == ''
    if any([is_empty(tx.product_id) for tx in transactions]):
        raise MissingProductId(
            _('Product IDs must be set for all ledger updates!'))
    # transactions grouped by case/product id
    grouped_tx = map_reduce(lambda tx: [((tx.case_id, tx.product_id),)],
                            lambda v: sorted(v, key=lambda tx: tx.timestamp),
                            data=transactions,
                            include_docs=True)

    case_ids = list(set(k[0] for k in grouped_tx))
    # list of cases that had stock reports in the form
    # there is no need to wrap them by case type
    relevant_cases = [case_db.get(case_id) for case_id in case_ids]

    user_id = xform.form['meta']['userID']
    submit_time = xform['received_on']

    # touch every case for proper ota restore logic syncing to be preserved
    for case in relevant_cases:
        case_action = CommCareCaseAction.from_parsed_action(
            submit_time, user_id, xform, AbstractAction(CASE_ACTION_COMMTRACK)
        )
        # hack: clear the sync log id so this modification always counts
        # since consumption data could change server-side
        case_action.sync_log_id = ''
        case.actions.append(case_action)
        case_db.mark_changed(case)

    return StockProcessingResult(
        xform=xform,
        relevant_cases=relevant_cases,
        stock_report_helpers=stock_reports,
    )
Beispiel #11
0
 def form_ok(form_json):
     return (from_demo_user(form_json) or is_device_report(form_json))
Beispiel #12
0
 def python_filter(self, change):
     # designed to exactly mimic the behavior of couchforms/filters/xforms.js
     doc = change.document
     return doc.get('doc_type', None) in all_known_formlike_doc_types() and not is_device_report(doc)
Beispiel #13
0
 def form_ok(form_json):
     return (from_demo_user(form_json) or is_device_report(form_json))
def default_form_filter(form, filter):
    # hack: all the other filters we use completely break on device logs
    # which don't have standard meta blocks, so just always force them
    # to be accepted, since the only time they are relevant is when they're
    # explicitly wanted
    return is_device_report(form) or filter(form)
Beispiel #15
0
def default_form_filter(form, filter):
    # hack: all the other filters we use completely break on device logs
    # which don't have standard meta blocks, so just always force them
    # to be accepted, since the only time they are relevant is when they're
    # explicitly wanted
    return is_device_report(form) or filter(form)
Beispiel #16
0
 def form_ok(form_json):
     return (from_demo_user(form_json) or is_device_report(form_json)
             or request.GET.get('submit_mode') == DEMO_SUBMIT_MODE)