Esempio n. 1
0
def wf_send_msg(users, msg_type, event=None, ext_ctx=None):
    if not users:
        return

    users = set(users)
    if event:  # ignore operator
        if event.user in users:
            users = users.remove(event.user)

    for send_msg in settings.WF_SEND_MSG_FUNCS:
        as_callable(send_msg)(users, msg_type, event, ext_ctx)
class ExecuteBackToTransitionView(ExecuteTransitionView):
    form_classes = {
        'form': as_callable(settings.BACK_TO_ACTIVITY_FORM)
    }

    def has_permission(self, request, instance, task, transition):
        # TODO ...
        return True

    def get_form_kwargs(self, form_class_key, form_class):
        """
        Returns the keyword arguments for instantiating the form.
        """
        kwargs = super().get_form_kwargs(form_class_key, form_class)
        kwargs['process_instance'] = self.process_instance
        return kwargs

    def get_init_transition(self, process_instance, request):
        return process_instance.get_back_to_transition()

    def get_transition_before_execute(self, cleaned_data):
        back_to_node = cleaned_data.get('back_to_node')
        transition = self.transition
        transition.output_node = Node.objects.get(pk=back_to_node)
        return transition
Esempio n. 3
0
class AddAssigneeView(ExecuteTransitionView):
    form_classes = {'form': as_callable(settings.ADD_ASSIGNEE_FORM)}

    def get_form_kwargs(self, form_class_key, form_class):
        kwargs = super().get_form_kwargs(form_class_key, form_class)
        kwargs['instance'] = self.process_instance
        return kwargs

    def get_init_transition(self, process_instance, request):
        return process_instance.get_add_assignee_transition()

    def do_transition(self, cleaned_data):
        request = self.request
        transition = self.get_transition_before_execute(cleaned_data)
        comment = cleaned_data.get('comment')
        attachments = cleaned_data.get('attachments')
        user = request.user
        instance = self.process_instance
        assignees = cleaned_data.get('assignees', [])
        for assignee in assignees:
            instance.create_task(assignee, is_joint=True)
        msg = 'Add assignee %s.' % ', '.join(
            [GET_USER_DISPLAY_NAME_FUNC(e) for e in assignees])
        messages.info(request, msg)
        comment = msg + '\n' + comment
        event = create_event(instance,
                             transition,
                             comment=comment,
                             user=user,
                             old_node=instance.cur_node,
                             new_node=instance.cur_node)
        event.attachments.add(*attachments)
        wf_send_msg(assignees, 'new_workitem', event)
class BatchExecuteTransitionView(FormView):
    template_name = 'lbworkflow/batch_transition_form.html'
    form_class = as_callable(settings.BATCH_WORK_FLOW_FORM)

    def get_success_url(self):
        return reverse("wf_todo")

    def get_transition_name(self):
        return 'Agree'

    def get_context_data(self, **kwargs):
        kwargs['task_list'] = self.task_list
        kwargs['transition_name'] = self.get_transition_name()
        return super(BatchExecuteTransitionView,
                     self).get_context_data(**kwargs)

    def get_transition(self, process_instance):
        pass

    def add_processed_message(self, process_instance, act_descn='Processed'):
        add_processed_message(self.request, process_instance, act_descn)

    def post(self, request, *args, **kwargs):
        if not request.POST.get('do_submit'):
            return self.get(request, *args, **kwargs)
        return super(BatchExecuteTransitionView,
                     self).post(request, *args, **kwargs)

    def form_valid(self, form):
        user = self.request.user
        cleaned_data = form.cleaned_data
        for task in self.task_list:
            if task.user != user:
                # TODO message for ignore
                continue
            instance = task.instance
            transition = self.get_transition(task.instance)
            comment = cleaned_data.get('comment')
            attachments = cleaned_data.get('attachments')
            TransitionExecutor(user, instance, task, transition, comment,
                               attachments).execute()
            self.add_processed_message(instance)
        return HttpResponseRedirect(self.get_success_url())

    def get_task_list(self, request):
        task_pk_list = request.POST.getlist('wi')
        task_pk_list = [e for e in task_pk_list if e]
        task_list = Task.objects.filter(status='in progress',
                                        pk__in=task_pk_list)
        return task_list

    def dispatch(self, request, *args, **kwargs):
        self.task_list = self.get_task_list(request)
        return super(BatchExecuteTransitionView,
                     self).dispatch(request, *args, **kwargs)
class BatchExecuteTransitionView(FormView):
    template_name = "lbworkflow/batch_transition_form.html"
    form_class = as_callable(settings.BATCH_WORK_FLOW_FORM)
    success_url = reverse_lazy("wf_todo")

    def get_context_data(self, **kwargs):
        kwargs["task_list"] = self.task_list
        kwargs["transition_name"] = self.get_transition_name()
        return super().get_context_data(**kwargs)

    def get_transition_name(self):
        return "Agree"

    def get_transition(self, process_instance):
        pass

    def add_processed_message(self, process_instance, act_descn="Processed"):
        add_processed_message(self.request, process_instance, act_descn)

    def post(self, request, *args, **kwargs):
        if not request.POST.get("do_submit"):
            return self.get(request, *args, **kwargs)
        return super().post(request, *args, **kwargs)

    def form_valid(self, form):
        user = self.request.user
        cleaned_data = form.cleaned_data
        for task in self.task_list:
            if task.user != user:
                # TODO message for ignore
                continue
            instance = task.instance
            transition = self.get_transition(task.instance)
            comment = cleaned_data.get("comment")
            attachments = cleaned_data.get("attachments")
            TransitionExecutor(
                user, instance, task, transition, comment, attachments
            ).execute()
            self.add_processed_message(instance)
        return super().form_valid(form)

    def get_task_list(self, request):
        task_pk_list = request.POST.getlist("wi")
        task_pk_list = [e for e in task_pk_list if e]
        task_list = Task.objects.filter(
            status="in progress", pk__in=task_pk_list
        )
        return task_list

    def dispatch(self, request, *args, **kwargs):
        self.task_list = self.get_task_list(request)
        return super().dispatch(request, *args, **kwargs)
class ExecuteTransitionView(TemplateResponseMixin, FormsView):
    """
    request.GET:
        ts_id: transition pk
        wi_id: work item pk
        pid: process instance pk (not used)
    """
    form_classes = {'form': as_callable(settings.WORK_FLOW_FORM)}

    def get_success_url(self):
        return reverse("wf_todo")

    def get_template_names(self):
        try:
            return super(ExecuteTransitionView, self).get_template_names()
        except ImproperlyConfigured:
            base_tmpl = 'lbworkflow/do_transition_form.html'
            _meta = self.object._meta
            app_label = _meta.app_label
            object_name = _meta.object_name.lower()
            return [
                "%s/%s/%s" % (
                    app_label,
                    object_name,
                    base_tmpl,
                ),
                "%s/%s" % (
                    app_label,
                    base_tmpl,
                ), base_tmpl
            ]

    def get_init_transition(self, process_instance, request):
        ts_id = request.GET.get('ts_id')
        return Transition.objects.get(pk=ts_id)

    def get_task(self, request):
        # TODO admin may don't have task, need auto create a work item for admin
        wi_id = request.GET.get('wi_id')
        user = request.user
        return get_or_none(Task, Q(user=user) | Q(agent_user=user), id=wi_id)

    def init_process_data(self, request):
        task = self.get_task(request)
        if not task:
            self.raise_no_permission_exception()
        instance = task.instance

        self.transition = self.get_init_transition(instance, request)
        self.task = task
        self.process_instance = instance
        self.object = instance.content_object

    def raise_no_permission_exception(self, instance=None):
        from django.template import Context, Template
        t = Template("""
            <!DOCTYPE HTML>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title></title>
            </head>
            <body>
                No permission to perform this action
                {% if instance %}
                    <br/>
                    <a href="{% url 'wf_detail' instance.pk %}"> View this process </a>
                {% endif %}
            </body>
            </html>
            """)
        http_response = HttpResponse(t.render(Context({"instance": instance})),
                                     content_type='text/html',
                                     status=403)
        raise HttpResponseException(http_response)

    def has_permission(self, request, instance, task, transition):
        node_is_ok = (transition.input_node == instance.cur_node
                      and task.node == instance.cur_node
                      and task.status == 'in progress')
        user_is_ok = (request.user in [task.user, task.agent_user]
                      or instance.is_wf_admin(request.user))
        is_ok = node_is_ok and user_is_ok
        return is_ok

    def check_permission(self, request):
        """ If no permission raise HttpResponseException """
        if not self.has_permission(request, self.process_instance, self.task,
                                   self.transition):
            self.raise_no_permission_exception(self.process_instance)

    def get_transition_before_execute(self, cleaned_data):
        return self.transition

    def do_transition(self, cleaned_data):
        comment = cleaned_data.get('comment')
        attachments = cleaned_data.get('attachments')

        user = self.request.user
        instance = self.process_instance
        transition = self.get_transition_before_execute(cleaned_data)

        TransitionExecutor(user, instance, self.task, transition, comment,
                           attachments).execute()

    def add_processed_message(self, process_instance, act_descn='Processed'):
        add_processed_message(self.request, process_instance, act_descn)

    def save_form(self, form):
        return form.save()

    def forms_valid(self, **forms):
        form = forms.pop('form')
        if isinstance(form, ModelForm):
            wf_obj = self.save_form(form)
            # update cache for wf_obj
            self.object = wf_obj
            self.process_instance = wf_obj.pinstance
        for other_form in forms:
            self.save_form(other_form)
        self.do_transition(form.cleaned_data)
        self.add_processed_message(self.process_instance)
        return HttpResponseRedirect(self.get_success_url())

    def get_context_data(self, **kwargs):
        kwargs = super(ExecuteTransitionView, self).get_context_data(**kwargs)
        kwargs['task'] = self.task
        kwargs['transition'] = self.transition
        kwargs.update(user_wf_info_as_dict(self.object, self.request.user))
        return kwargs

    def dispatch(self, request, *args, **kwargs):
        self.request = request
        try:
            self.init_process_data(request)
            self.check_permission(request)
            return super(ExecuteTransitionView,
                         self).dispatch(request, *args, **kwargs)
        except HttpResponseException as error:
            return error.http_response
Esempio n. 7
0
 def handle(self, *args, **options):
     func = options['func']
     func = as_callable(func)
     func()
Esempio n. 8
0
 def get_permit_query_param(self, user, q_param):
     # override this function to add addition permit
     get_permit_query_param = as_callable(PROCESS_INSTANCE_GET_PERMIT_QUERY_PARAM_FUNC)
     return get_permit_query_param(user, q_param)
class ExecuteTransitionView(TemplateResponseMixin, FormsView):
    """
    request.GET:
        ts_id: transition pk
        wi_id: work item pk
        pid: process instance pk (not used)
    """

    form_classes = {"form": as_callable(settings.WORK_FLOW_FORM)}
    success_url = reverse_lazy("wf_todo")

    def get_template_names(self):
        try:
            return super().get_template_names()
        except ImproperlyConfigured:
            base_tmpl = "lbworkflow/do_transition_form.html"
            _meta = self.object._meta
            app_label = _meta.app_label
            object_name = _meta.object_name.lower()
            return [
                "%s/%s/%s"
                % (
                    app_label,
                    object_name,
                    base_tmpl,
                ),
                "%s/%s"
                % (
                    app_label,
                    base_tmpl,
                ),
                base_tmpl,
            ]

    def get_init_transition(self, process_instance, request):
        ts_id = request.GET.get("ts_id")
        return Transition.objects.get(pk=ts_id)

    def get_task(self, request):
        # TODO admin may don't have task, need auto create a work item for admin
        wi_id = request.GET.get("wi_id")
        user = request.user
        return get_or_none(Task, Q(user=user) | Q(agent_user=user), id=wi_id)

    def init_process_data(self, request):
        task = self.get_task(request)
        if not task:
            self.raise_no_permission_exception()
        instance = task.instance

        self.transition = self.get_init_transition(instance, request)
        self.task = task
        self.process_instance = instance
        self.object = instance.content_object

    def raise_no_permission_exception(self, instance=None):
        raise PermissionDenied()

    def has_permission(self, request, instance, task, transition):
        node_is_ok = (
            transition.input_node == instance.cur_node
            and task.node == instance.cur_node
            and task.status == "in progress"
        )
        user_is_ok = (
            request.user
            in [
                task.user,
                task.agent_user,
            ]
            or instance.is_wf_admin(request.user)
        )
        is_ok = node_is_ok and user_is_ok
        return is_ok

    def check_permission(self, request):
        """If no permission raise HttpResponseException"""
        if not self.has_permission(
            request, self.process_instance, self.task, self.transition
        ):
            self.raise_no_permission_exception(self.process_instance)

    def get_transition_before_execute(self, cleaned_data):
        return self.transition

    def do_transition(self, cleaned_data):
        comment = cleaned_data.get("comment")
        attachments = cleaned_data.get("attachments")

        user = self.request.user
        instance = self.process_instance
        transition = self.get_transition_before_execute(cleaned_data)

        TransitionExecutor(
            user, instance, self.task, transition, comment, attachments
        ).execute()

    def add_processed_message(self, process_instance, act_descn="Processed"):
        add_processed_message(self.request, process_instance, act_descn)

    def save_form(self, form):
        return form.save()

    def forms_valid(self, **forms):
        form = forms.pop("form")
        if isinstance(form, ModelForm):
            wf_obj = self.save_form(form)
            # update cache for wf_obj
            self.object = wf_obj
            self.process_instance = wf_obj.pinstance
        for other_form in forms:
            self.save_form(other_form)
        self.do_transition(form.cleaned_data)
        self.add_processed_message(self.process_instance)
        return super().forms_valid(**forms)

    def get_context_data(self, **kwargs):
        kwargs = super().get_context_data(**kwargs)
        kwargs["task"] = self.task
        kwargs["transition"] = self.transition
        kwargs.update(user_wf_info_as_dict(self.object, self.request.user))
        return kwargs

    def dispatch(self, request, *args, **kwargs):
        self.request = request
        try:
            self.init_process_data(request)
            self.check_permission(request)
            return super().dispatch(request, *args, **kwargs)
        except HttpResponseException as error:
            return error.http_response
class BatchExecuteTransitionView(FormView):
    # template_name = 'lbworkflow/batch_transition_form.html'
    template_name = 'myworkflow/mywf_batch_agree.html'
    form_class = as_callable(settings.BATCH_WORK_FLOW_FORM)


    def get_success_url(self):
        return reverse("wf_todo")

    def get_transition_name(self):
        return 'Agree'

    def get_context_data(self, **kwargs):
        kwargs['task_list'] = self.task_list
        kwargs['transition_name'] = self.get_transition_name()
        return super().get_context_data(**kwargs)

    def get_transition(self, process_instance):
        # print('2222')
        pass

    def add_processed_message(self, process_instance, act_descn='Processed'):
        add_processed_message(self.request, process_instance, act_descn)

    def post(self, request, *args, **kwargs):
        if not request.POST.get('do_submit'):
            return self.get(request, *args, **kwargs)
        return super().post(request, *args, **kwargs)

    def form_valid(self, form):
        user = self.request.user
        cleaned_data = form.cleaned_data
        for task in self.task_list:
            if task.user != user:
                # TODO message for ignore
                continue
            instance = task.instance
            # 获取lbworkflow_processinstance的summary字段内容
            # print(instance.content_object)
            # 定期策划01
            # print(task.instance)
            # print(222222222222222222)
            # 52
            transition = self.get_transition(task.instance)
            comment = cleaned_data.get('comment')
            attachments = cleaned_data.get('attachments')
            # print('11',transition)
            # 11 Regularworkplan - Agree
            # print(transition.output_node)
            # 二级审批

            TransitionExecutor(
                user, instance, task, transition, comment, attachments
            ).execute()

            # res_a = ProcessInstance.objects.filter(cur_node=task.node_id)
            res_e = Event.objects.filter(task=task.id)
            # res.instance_id
            res_task = Task.objects.filter(id=task.id)
            res_pi = ProcessInstance.objects.filter(id=res_task[0].instance.id)
            # print(res_e[0].instance)
            # print(task.user)
            for res in res_e:
            # print(res_e[0].instance,res_e[0].user,res_e[0].old_node,res_e[0].task,res_e[0].comment)
            # print("611111111111")
            # print(comment)
            # res = TaskHistory.objects.all()
            # print(res)
                # print(111111111111111111111111)
                TaskHistory.objects.create(node_name=task.node,approve_name=user,created_name=res_pi[0].id,approve_type=res.act_type,content=res.comment,process_id=int(res.instance_id),created_time=task.created_on)

            self.add_processed_message(instance)
        return HttpResponseRedirect(self.get_success_url())

    def get_task_list(self, request):
        task_pk_list = request.POST.getlist('wi')
        task_pk_list = [e for e in task_pk_list if e]
        task_list = Task.objects.filter(status='in progress', pk__in=task_pk_list)
        return task_list

    def dispatch(self, request, *args, **kwargs):
        self.task_list = self.get_task_list(request)
        return super().dispatch(request, *args, **kwargs)
Esempio n. 11
0
from django.shortcuts import get_object_or_404
from django.shortcuts import redirect
from django.shortcuts import render
from django.urls import reverse
from lbutils import as_callable

from lbworkflow import settings
from lbworkflow.models import Process
from lbworkflow.models import ProcessCategory
from lbworkflow.models import ProcessInstance

from .helper import import_wf_views
from .helper import user_wf_info_as_dict
from systemsettings.views import menu_data

can_edit_wf = as_callable(settings.CAN_EDIT_WF_FUNC)
can_submit_wf = as_callable(settings.CAN_SUBMIT_WF_FUNC)
can_view_wf = as_callable(settings.CAN_VIEW_WF_FUNC)


def new(request, wf_code):  # 创建新的工单,wf_code 为models名称
    views = import_wf_views(wf_code)
    process = Process.objects.get(code=wf_code)
    if not can_submit_wf(process, request.user):
        raise PermissionDenied
    return views.new(request, wf_code=wf_code)


def show_list(request, wf_code):
    views = import_wf_views(wf_code)
    return views.show_list(request, wf_code=wf_code)
def load_wf_data(app, wf_code=""):
    if wf_code:
        func = "%s.wfdata.load_%s" % (app, wf_code)
    else:
        func = "%s.wfdata.load_data" % app
    as_callable(func)()
Esempio n. 13
0
def safe_eval(source, globals, *args, **kwargs):
    globals['Q'] = Q
    for s in settings.EVAL_FUNCS:
        globals[s[0]] = as_callable(s[1])
    source = source.replace('import', '')
    return eval(source, globals, *args, **kwargs)