def used_columns(self) -> List[Column]: """Extend the used columns with those in the attachments. :return: List of column objects """ # Columns from base case column_list = super().used_columns() # Columns from {{ colname }} in text content for match in VAR_USE_RES[0].finditer(self.text_content): var_name = match.group('vname') column = self.workflow.columns.filter(name=var_name).first() if column: column_list.append(column) # Columns from {% ot_insert_report "c1" "c2" %} for match in VAR_USE_RES[2].finditer(self.text_content): column_list.extend([ col for col in self.workflow.columns.filter( name__in=shlex.split(match.group('args'))) ]) # Columns from the attachment for attachment in self.attachments.all(): column_list.extend([col for col in attachment.columns.all()]) attachment_formula = attachment.formula if attachment_formula: column_list.extend([ col for col in self.workflow.columns.filter( name__in=formula.get_variables(attachment_formula)) ]) return list(set(column_list))
def do_clone_condition( user, condition: models.Condition, new_action: models.Action = None, new_name: str = None, ) -> models.Condition: """Clone a condition. Function to clone a condition and change action and/or name :param user: User executing the operation :param condition: Condition to clone :param new_action: New action to point :param new_name: New name :return: New condition """ old_id = condition.id old_name = condition.name if new_name is None: new_name = condition.name if new_action is None: new_action = condition.action new_condition = models.Condition( name=new_name, description_text=condition.description_text, action=new_action, formula=copy.deepcopy(condition.formula), n_rows_selected=condition.n_rows_selected, is_filter=condition.is_filter) new_condition.save() try: # Update the many to many field. new_condition.columns.set( new_condition.action.workflow.columns.filter( name__in=formula.get_variables(new_condition.formula), )) except Exception as exc: new_condition.delete() raise exc condition.log(user, models.Log.CONDITION_CLONE, id_old=old_id, name_old=old_name) return new_condition
def create(self, validated_data, **kwargs) -> Optional[Condition]: """Create a new condition object based on the validated_data. :param validated_data: Validated data obtained by the parser :param kwargs: Additional arguments :return: Condition object """ condition_obj = None try: condition_obj = _create_condition( validated_data, self.context['action']) # Process columns if validated_data.get('columns'): # Load the columns pointing to the action (if any) columns = ColumnNameSerializer( data=validated_data.get('columns'), many=True, required=False, ) if columns.is_valid(): cnames = [cdata['name'] for cdata in columns.data] else: raise Exception(_('Incorrect column data')) else: cnames = get_variables(condition_obj.formula) # Set the condition values condition_obj.columns.set( self.context['action'].workflow.columns.filter( name__in=cnames), ) # If n_rows_selected is -1, reevaluate if condition_obj.n_rows_selected == -1: condition_obj.update_n_rows_selected() # Save condition object condition_obj.save() except Exception: if condition_obj and condition_obj.id: condition_obj.delete() raise return condition_obj
def save_condition_form( request: HttpRequest, form, action: models.Action, is_filter: Optional[bool] = False, ) -> JsonResponse: """Process the AJAX form POST to create and update conditions and filters. :param request: HTTP request :param form: Form being used to ask for the fields :param action: The action to which the condition is attached to :param is_filter: The condition is a filter :return: JSON response """ if is_filter and form.instance.id is None and action.get_filter(): # Should not happen. Go back to editing the action return JsonResponse({'html_redirect': ''}) is_new = form.instance.id is None # Update fields and save the condition condition = form.save(commit=False) condition.formula_text = None condition.action = action condition.is_filter = is_filter condition.save() condition.columns.set( action.workflow.columns.filter(name__in=formula.get_variables( condition.formula), )) # If the request has the 'action_content' field, update the action action_content = request.POST.get('action_content') if action_content: action.set_text_content(action_content) _propagate_changes(condition, form.changed_data, form.old_name, is_new) # Store the type of event to log if is_new: log_type = models.Log.CONDITION_CREATE else: log_type = models.Log.CONDITION_UPDATE condition.log(request.user, log_type) return JsonResponse({'html_redirect': ''})
def do_clone_condition( condition: Condition, new_action: Action = None, new_name: str = None, ) -> Condition: """Clone a condition. Function to clone a condition and change action and/or name :param condition: Condition to clone :param new_action: New action to point :param new_name: New name :return: New condition """ if new_name is None: new_name = condition.name if new_action is None: new_action = condition.action new_condition = Condition( name=new_name, description_text=condition.description_text, action=new_action, formula=copy.deepcopy(condition.formula), n_rows_selected=condition.n_rows_selected, is_filter=condition.is_filter ) new_condition.save() try: # Update the many to many field. new_condition.columns.set(new_condition.action.workflow.columns.filter( name__in=get_variables(new_condition.formula), )) except Exception as exc: new_condition.delete() raise exc return new_condition
def save_condition_form( request: HttpRequest, form, template_name: str, action: Action, is_filter: Optional[bool] = False, ) -> JsonResponse: """ Process the AJAX form to create and update conditions and filters. :param request: HTTP request :param form: Form being used to ask for the fields :param template_name: Template being used to render the form :param action: The action to which the condition is attached to :param is_filter: The condition is a filter :return: JSON response """ if request.method == 'POST' and form.is_valid(): if not form.has_changed(): return JsonResponse({'html_redirect': None}) if is_filter and form.instance.id is None and action.get_filter(): # Should not happen. Go back to editing the action return JsonResponse({'html_redirect': ''}) is_new = form.instance.id is None # Update fields and save the condition condition = form.save(commit=False) condition.formula_text = None condition.action = action condition.is_filter = is_filter condition.save() condition.columns.set(action.workflow.columns.filter( name__in=get_variables(condition.formula), )) # If the request has the 'action_content' field, update the action action_content = request.POST.get('action_content') if action_content: action.set_text_content(action_content) propagate_changes(condition, form.changed_data, form.old_name, is_new) # Store the type of event to log if is_new: log_type = Log.CONDITION_CREATE else: log_type = Log.CONDITION_UPDATE condition.log(request.user, log_type) return JsonResponse({'html_redirect': ''}) # GET request or invalid form return JsonResponse({ 'html_form': render_to_string( template_name, { 'form': form, 'action_id': action.id, 'condition': form.instance}, request=request), })