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)
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)
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)
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
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
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)
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, )
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
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, )
def form_ok(form_json): return (from_demo_user(form_json) or is_device_report(form_json))
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)
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)
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)