コード例 #1
0
 def handle_td(my, td):
     super(LoginTableElementWdg, my).handle_td(td)
     task = my.get_current_sobject()
     if task:
         search_type = task.get_value('search_type')
         search_id = task.get_value('search_id')
         
         if not search_type or not search_id:
             return
         
         search_key = SearchKey.build_search_key(search_type, search_id, column='id')
         
         from pyasm.common import SObjectSecurityException
         try:
             parent = Search.get_by_search_key(search_key)
             pipeline = Pipeline.get_by_sobject(parent)
            
             if pipeline:
                 attrs = pipeline.get_process_attrs(task.get_value('process'))
             
                 td.add_attr('spt_pipeline_code', attrs.get('%s_login_group'%my.get_name()))
         except SObjectSecurityException, e:
             pass
         except SearchException, e:
             if e.__str__().find('not registered') != -1:
                 pass
             elif e.__str__().find('does not exist for database') != -1:
                 pass    
             elif e.__str__().find('Cannot find project') != -1:
                 pass
             else:
                 raise
コード例 #2
0
ファイル: dataflow_test.py プロジェクト: zieglerm/TACTIC
    def get_input_state(self, sobject, process):

        pipeline = Pipeline.get_by_sobject(sobject)

        # use the first input process
        input_processes = pipeline.get_input_processes(process)
        if not input_processes:
            return {}

        # get the first process for now
        p = input_processes[0]

        process_name = p.get_name()

        key = self.get_state_key(sobject, process_name)

        from tactic_client_lib import TacticServerStub
        server = TacticServerStub.get()

        from pyasm.common import jsonloads
        message = server.get_message(key)
        message = message.get("message")
        if not message:
            state = {}
        else:
            state = jsonloads(message)

        return state
コード例 #3
0
    def execute(my):

        key = "enable_workflow_engine"
        from prod_setting import ProdSetting
        setting = ProdSetting.get_value_by_key(key)
        if setting not in [True, 'true']:
            return


        # find the node in the pipeline
        task = my.get_caller()
        sobject = task.get_parent()
        if not sobject:
            return

        pipeline = None

        process_code = task.get_value("process_code", no_exception=True)
        if process_code:
            process_sobj = Search.get_by_code("config/process", process_code)
            if process_sobj:
                pipeline_code = process_sobj.get_value("pipeline_code")
                pipeline = Pipeline.get_by_code("sthpw/pipeline", pipeline_code) 

        if not pipeline:
            pipeline = Pipeline.get_by_sobject(sobject)






        if not pipeline:
            return

        process_name = task.get_value("process")
        status = task.get_value("status")

        process = pipeline.get_process(process_name)
        if not process:
            # we don't have enough info here
            return

        node_type = process.get_type()
        process_name = process.get_name()

        event = "process|%s" % status.lower()
        output = {
            'sobject': sobject,
            'pipeline': pipeline,
            'process': process_name,
        }
        Trigger.call(task, event, output=output)
コード例 #4
0
ファイル: task_wdg.py プロジェクト: mwx1993/TACTIC
    def preprocess(my):
        if my.sobjects:
            try:
                search = Search(Task)
                search_ids = [x.get_id() for x in my.sobjects]
                search.add_filters("search_id", search_ids)
                search_type = my.sobjects[0].get_search_type()
                search.add_filter("search_type", search_type)

                # go thru children of main search
                search = my.alter_task_search(search, prefix='children')
                # go thru Local Search
                search = my.alter_task_search(
                    search,
                    prefix='main_body',
                    prefix_namespace=my.__class__.__name__)

                sobj = my.sobjects[0]
                pipeline = Pipeline.get_by_sobject(sobj)
                if pipeline:
                    process_names = pipeline.get_process_names(True)
                    search.add_enum_order_by("process", process_names)
                else:
                    search.add_order_by("process")

                search.add_order_by("id")
                tasks = search.get_sobjects()
                # create a data structure
                for task in tasks:
                    search_type = task.get_value("search_type")
                    search_id = task.get_value("search_id")
                    search_key = "%s|%s" % (search_type, search_id)

                    sobject_tasks = my.data.get(search_key)
                    if not sobject_tasks:
                        sobject_tasks = []
                        my.data[search_key] = sobject_tasks
                    sobject_tasks.append(task)
            except:
                from tactic.ui.app import SearchWdg
                parent_search_type = get_search_type()
                SearchWdg.clear_search_data(parent_search_type)
                raise
コード例 #5
0
ファイル: web_init.py プロジェクト: southpawtech/TACTIC-DEV
    def execute(my):
        from pyasm.biz import Task, Pipeline


        src_task = my.get_caller()
        process = src_task.get_value("process")
        status = src_task.get_value("status")

        pipeline_code = src_task.get_value("pipeline_code")
        if pipeline_code == "approval":
            tasks = src_task.get_output_tasks()

            if status == "Revise":
                pass

        else:
            tasks = src_task.get_output_tasks(type="approval")


        # for approval, the task must be completed
        completion = src_task.get_completion()
        if completion != 100:
            return


        if not tasks:
            # autocreate ??
            parent = src_task.get_parent()
            pipeline = Pipeline.get_by_sobject(parent)
            if not pipeline:
                return
            processes = pipeline.get_output_processes(process, type="approval")
            if not processes:
                return

            if processes:
                print "Missing task: ", processes


        # set those approvals to "Pending"
        for task in tasks:
            task.set_value("status", "Pending")
            task.commit()
コード例 #6
0
ファイル: task_wdg.py プロジェクト: 0-T-0/TACTIC
    def preprocess(my):
        if my.sobjects:
            try:
                search = Search(Task) 
                search_ids = [x.get_id() for x in my.sobjects]
                search.add_filters("search_id", search_ids)
                search_type = my.sobjects[0].get_search_type()
                search.add_filter("search_type", search_type)
                
                # go thru children of main search
                search = my.alter_task_search(search, prefix='children')
                # go thru Local Search
                search = my.alter_task_search(search, prefix='main_body', prefix_namespace=my.__class__.__name__)

                sobj = my.sobjects[0]
                pipeline = Pipeline.get_by_sobject(sobj) 
                if pipeline:
                    process_names = pipeline.get_process_names(True)
                    search.add_enum_order_by("process", process_names)
                else:
                    search.add_order_by("process")

                search.add_order_by("id")
                tasks = search.get_sobjects()
                # create a data structure
                for task in tasks:
                    search_type = task.get_value("search_type")
                    search_id = task.get_value("search_id")
                    search_key = "%s|%s" % (search_type, search_id)

                    sobject_tasks = my.data.get(search_key)
                    if not sobject_tasks:
                        sobject_tasks = []
                        my.data[search_key] = sobject_tasks
                    sobject_tasks.append(task)
            except:
                from tactic.ui.app import SearchWdg
                parent_search_type = get_search_type()
                SearchWdg.clear_search_data(parent_search_type)
                raise
コード例 #7
0
    def execute(my):

        web = WebContainer.get_web()
        value = web.get_form_value('value')
        if my.search_key == None or value == None or my.attr_name == None:
            raise CommandExitException()


        sobject = Search.get_by_search_key(my.search_key)
        old_value = sobject.get_value(my.attr_name)
        sobject.set_value(my.attr_name, value)
        sobject.commit()

        # setting target attributes if sobject is a task
        if sobject.get_search_type_obj().get_base_key() == Task.SEARCH_TYPE:
            task = sobject

            # FIXME: not sure what this if for???
            my.users = [task.get_value("assigned")]

            process_name = task.get_value('process')


            task_description = task.get_value("description")

            my.parent = task.get_parent()
            # it should be task, notification will get the parent in the 
            # email trigger logic
            my.sobject = task
            code = my.parent.get_code()
            name = my.parent.get_name()
            my.info['parent_centric'] = True
            my.description = "%s set to '%s' for %s (%s), task: %s, %s" % (\
                my.attr_name.capitalize(), value, code, name, process_name, task_description)


            # set the states of the command
            pipeline = Pipeline.get_by_sobject(my.parent)
            process = pipeline.get_process(process_name)
            completion = task.get_completion()

            if pipeline and process:
                my.set_process(process_name)
                my.set_pipeline_code( pipeline.get_code() )
                if completion == 100:
                    my.set_event_name("task/approved")
                else:
                    my.set_event_name("task/change")
                    


        else:
            my.sobject = sobject
            code = my.sobject.get_code()

            my.description = "%s set to '%s' for %s" % (\
                my.attr_name.capitalize(), value, code)

            process_name = "None"
            my.info['parent_centric'] = False

        my.sobjects.append(my.sobject)
       
        # set the information about this command
        my.info['to'] = value
        my.info['process'] = process_name
コード例 #8
0
ファイル: parallel_status.py プロジェクト: zieglerm/TACTIC
    def get_display(self):
        self.task_per_process_dict = {}

        # get the sobject and relevent parameters
        sobject = self.get_current_sobject()
        search_type = sobject.get_search_type()

        if self.pipeline_code:
            pipeline = Pipeline.get_by_code(self.pipeline_code)
        else:
            pipeline = Pipeline.get_by_sobject(sobject, allow_default=True)

        if not pipeline:
            # while default is auto-generated, an empty pipeline code will trigger this
            Environment.add_warning('missing pipeline code', \
                "Pipeline code is empty for [%s]" %sobject.get_code())
            return
        if self.include_sub_task_value:
            self.recurse = True

        processes = pipeline.get_processes(recurse=self.recurse)
        # filter out process names
        if self.process_names != None:
            filtered_processes = []
            for process in processes:
                if process.get_name() in self.process_names:
                    filtered_processes.append(process)

            processes = filtered_processes

        # draw the proceses
        top = DivWdg()

        action = DivWdg()
        action.add_style("float: right")

        top.add(action)

        table = Table()
        table.add_style("font-size: 11px")
        top.add(table)

        #if self.max_count:
        #    percent_width = float(len(processes)) / float(self.max_count+1) * 100
        #else:
        #    percent_width = 100

        # we want them more squeezed together when in abbr mode
        if self.label_select_value != 'abbr':
            percent_width = 100
            table.add_style("width: %d%%" % percent_width)
        tr = table.add_row()

        for process in processes:
            completion_wdg = self.get_completion(sobject, process,\
                len(processes))
            if not completion_wdg:
                continue
            td = table.add_cell(completion_wdg)
            td.add_style('border-width: 0px')

        tr = table.add_row(css='underline')
        tr.add_color("color", "color")

        label_format = self.get_option("label_format")
        if not label_format:
            label_format = self.label_select_value

        tup_list = self._get_labels(processes,
                                    label_format,
                                    show_sub_pipeline=self.is_ajax())
        style = ''
        for i, tup in enumerate(tup_list):
            name, process = tup
            span = SpanWdg()
            child_pipeline = process.get_child_pipeline()
            if child_pipeline:

                title = SpanWdg()
                title.add("[%s]" % name)
                title.add_style("margin-left: -5px")

                swap = SwapDisplayWdg.get_triangle_wdg()
                content_id = '%s_%s' % (sobject.get_search_key(),
                                        child_pipeline.get_id())
                content_id = self.generate_unique_id(content_id)
                content = DivWdg(id=content_id)

                SwapDisplayWdg.create_swap_title(title, swap, content)

                dyn_load = AjaxLoader(display_id=content_id)

                args_dict = {'search_type': sobject.get_search_type()}
                args_dict['search_id'] = sobject.get_id()
                args_dict['pipeline_skey'] = child_pipeline.get_search_key()
                dyn_load.set_load_method('_get_child_wdg')
                dyn_load.set_load_class('pyasm.widget.ParallelStatusWdg',
                                        load_args=args_dict)
                dyn_load.add_element_name('cal_sub_task')
                on_script = dyn_load.get_on_script(load_once=True)

                swap.add_action_script(on_script,
                                       "set_display_off('%s')" % content_id)

                script = "if ($(%s).getStyle('display')=='none') {%s}" \
                    %(swap.swap1_id, on_script)
                title.add_event('onclick', script)

                span.add(swap)
                span.add(title)
                span.add(HtmlElement.br())
                span.add(HtmlElement.br())

                span.add(content)

            else:
                span.add(name)
                if self.task_per_process_dict.get(process) == 0:
                    span.add_class('unused')

            if label_format == 'small' or label_format == 'abbr':
                span.add_class('smaller')
            if not label_format == "none":
                table.add_cell(span)

        return top
コード例 #9
0
    def handle_instance(my,
                        table,
                        instance,
                        asset,
                        node_name='',
                        publish=True,
                        allow_ref_checkin=False):

        # handle the case where asset is not defined
        if not asset:
            table.add_row()
            table.add_blank_cell()
            table.add_blank_cell()

            # FIXME: Maya specific
            parts = instance.split(":")
            instance_name = parts[0]
            asset_code = parts[1]

            if instance_name == asset_code:
                table.add_cell(instance_name)
            else:
                table.add_cell(instance)
            td = table.add_cell()
            td.add("< %s node >" % my.session.get_node_type(instance_name))
            table.add_blank_cell()
            return

        # get the pipeline for this asset and handlers for the pipeline
        process_name = my.process_select.get_value()
        handler_hidden = my.get_handler_input(asset, process_name)
        pipeline = Pipeline.get_by_sobject(asset)

        # TEST: switch this to using node name instead, if provided
        if node_name:
            instance_node = my.session.get_node(node_name)
        else:
            instance_node = my.session.get_node(instance)

        if instance_node is None:
            return
        if Xml.get_attribute(instance_node, "reference") == "true":
            is_ref = True
        else:
            is_ref = False

        namespace = Xml.get_attribute(instance_node, "namespace")
        if not namespace:
            namespace = instance

        asset_code = asset.get_code()
        is_set = False
        if asset.get_value('asset_type',
                           no_exception=True) in ['set', 'section']:
            is_set = True

        tr = table.add_row()

        if is_set:
            tr.add_class("group")

        if publish and (allow_ref_checkin or not is_ref):
            checkbox = CheckboxWdg("asset_instances")
            if is_set:
                checkbox = CheckboxWdg("set_instances")

            checkbox.set_option("value", "%s|%s|%s" % \
                        (namespace, asset_code, instance) )
            checkbox.set_persist_on_submit()

            td = table.add_cell(checkbox)

        else:
            td = table.add_blank_cell()

        # only one will be added even if there are multiple
        if handler_hidden:
            td.add(handler_hidden)

        # add the thumbnail
        thumb = ThumbWdg()
        thumb.set_name("images")
        thumb.set_sobject(asset)
        thumb.set_icon_size(60)
        table.add_cell(thumb)

        info_wdg = Widget()
        info_wdg.add(HtmlElement.b(instance))

        if not node_name:
            node_name = '%s - %s' % (asset_code, asset.get_name())
        info_div = DivWdg(node_name)
        info_div.add_style('font-size: 0.8em')
        info_wdg.add(info_div)
        info_div.add(HtmlElement.br(2))
        if pipeline:
            info_div.add(pipeline.get_code())
        table.add_cell(info_wdg)

        #  by default can't checkin references
        if not allow_ref_checkin and is_ref:
            #icon = IconWdg("error", IconWdg.ERROR)
            #td = table.add_cell(icon)
            td = table.add_cell()
            td.add(HtmlElement.b("Ref. instance"))
            '''
            import_button = ProdIconButtonWdg('import')
            import_button.add_event('onclick', "import_instance('%s')"  %instance)
            td.add(import_button)
            '''
            table.add_cell(my.get_save_wdg(my.current_sobject))

        elif publish:
            textarea = TextAreaWdg()
            textarea.set_persist_on_submit()
            textarea.set_name("%s_description" % instance)
            textarea.set_attr("cols", "35")
            textarea.set_attr("rows", "2")
            table.add_cell(textarea)
            table.add_cell(my.get_save_wdg(my.current_sobject))
        else:
            table.add_blank_cell()
            table.add_blank_cell()
コード例 #10
0
    def handle_instance(my, table, instance, asset, node_name='', publish=True, allow_ref_checkin=False):

        # handle the case where asset is not defined
        if not asset:
            table.add_row()
            table.add_blank_cell()
            table.add_blank_cell()

            # FIXME: Maya specific
            parts = instance.split(":")
            instance_name = parts[0]
            asset_code = parts[1]

            
            if instance_name == asset_code:
                table.add_cell(instance_name)
            else:
                table.add_cell(instance)
            td = table.add_cell()
            td.add("< %s node >" % my.session.get_node_type(instance_name))
            table.add_blank_cell()
            return 

        # get the pipeline for this asset and handlers for the pipeline
        process_name = my.process_select.get_value() 
        handler_hidden = my.get_handler_input(asset, process_name)
        pipeline = Pipeline.get_by_sobject(asset) 
        



        # TEST: switch this to using node name instead, if provided
        if node_name:
            instance_node = my.session.get_node(node_name)
        else:
            instance_node = my.session.get_node(instance)

        if instance_node is None:
            return
        if Xml.get_attribute(instance_node,"reference") == "true":
            is_ref = True
        else:
            is_ref = False

        namespace = Xml.get_attribute(instance_node, "namespace")
        if not namespace:
            namespace = instance

        asset_code = asset.get_code()
        is_set = False
        if asset.get_value('asset_type', no_exception=True) in ['set','section']:
            is_set = True
            
        tr = table.add_row()
        
        if is_set:
            tr.add_class("group")

        if publish and (allow_ref_checkin or not is_ref):
            checkbox = CheckboxWdg("asset_instances")
            if is_set:
                checkbox = CheckboxWdg("set_instances")
               
            checkbox.set_option("value", "%s|%s|%s" % \
                        (namespace, asset_code, instance) )
            checkbox.set_persist_on_submit()

            td = table.add_cell(checkbox)
            
        else:
            td = table.add_blank_cell()

        # only one will be added even if there are multiple
        if handler_hidden:
            td.add(handler_hidden)

        # add the thumbnail
        thumb = ThumbWdg()
        thumb.set_name("images")
        thumb.set_sobject(asset)
        thumb.set_icon_size(60)
        table.add_cell(thumb)


        info_wdg = Widget()
        info_wdg.add(HtmlElement.b(instance))

        if not node_name:
            node_name = '%s - %s' %(asset_code, asset.get_name()) 
        info_div = DivWdg(node_name)
        info_div.add_style('font-size: 0.8em')
        info_wdg.add(info_div)
        info_div.add(HtmlElement.br(2))
        if pipeline:
            info_div.add(pipeline.get_code())
        table.add_cell(info_wdg)

        #  by default can't checkin references
        if not allow_ref_checkin and is_ref:
            #icon = IconWdg("error", IconWdg.ERROR)
            #td = table.add_cell(icon)
            td = table.add_cell()
            td.add(HtmlElement.b("Ref. instance"))
            '''
            import_button = ProdIconButtonWdg('import')
            import_button.add_event('onclick', "import_instance('%s')"  %instance)
            td.add(import_button)
            '''
            table.add_cell(my.get_save_wdg(my.current_sobject) )

        elif publish:
            textarea = TextAreaWdg()
            textarea.set_persist_on_submit()
            textarea.set_name("%s_description" % instance)
            textarea.set_attr("cols", "35")
            textarea.set_attr("rows", "2")
            table.add_cell(textarea)
            table.add_cell(my.get_save_wdg(my.current_sobject) )
        else:
            table.add_blank_cell()
            table.add_blank_cell()
コード例 #11
0
ファイル: task_wdg.py プロジェクト: 0-T-0/TACTIC
    def get_display(my):

        web = WebContainer.get_web()
        
        # this needs to be a BaseInputWdg since UserFilterWdg is hideable
        user_filter = FilterSelectWdg("user_filter")
        user_filter = user_filter.get_values()
     
        #login = Environment.get_security().get_login()
        #user = login.get_value("login")

        if my.is_refresh:
            widget = Widget()
            my.init_cgi()
        else:
            my.sobject = my.get_current_sobject()
            widget = DivWdg(id="task_elem_%s"% my.sobject.get_id())
            widget.add_class('spt_task_panel')
            try:
                my.set_as_panel(widget)
            except:
                pass
       
        #TODO: remove this
        my.init_setup(widget)
        #my.set_ajax_top(widget)
        
        table = Table(css="minimal")
        table.add_style("width: 100%")

        # get all of the tasks related to this sobject
        search_type = my.sobject.get_search_type()
        search_id = my.sobject.get_id()
        if my.data:
            tasks = my.data.get("%s|%s" % (search_type,search_id) )
        else:
            tasks = Task.get_by_sobject(my.sobject)
            my.data[my.sobject.get_search_key()] = tasks
        if not tasks:
            tasks = []


        task_statuses_filter = web.get_form_values("task_status")
        show_sub_tasks = False
        if not task_statuses_filter:
            # NOTE: Not sure if this is correct!!
            # have to do this because it is impossible to tell if a checkbox
            # is empty or not there.  This is used for pages that do not have
            # tasks_status checkboxes
            show_all_tasks = True
        else:
            cb = FilterCheckboxWdg('show_all_tasks') 
            show_all_tasks = cb.is_checked(False)

            sub_cb = FilterCheckboxWdg('show_sub_tasks') 
            show_sub_tasks = sub_cb.is_checked(False)
        # trim down the process list
        """
        if not show_sub_tasks:
            process_list = [x for x in process_list if "/" not in x]
        """
        pipeline = Pipeline.get_by_sobject(my.sobject)

        # retrieve the pipeline   
        if not pipeline:
            td = table.add_cell("<br/><i>No pipeline</i>")
            td.add_style("text-align: center")
            return table

        # store completion per process first in a dict
        # reset it first
        my.process_completion_dict = {}
        for task in tasks:
            task_process = task.get_value("process")
            status_attr = task.get_attr('status')
            percent = status_attr.get_percent_completion()
            
            my.store_completion(task_process, percent)

        security = WebContainer.get_security()
        me = Environment.get_user_name()

        

        for task in tasks:
            has_valid_status = True
            task_pipeline = task.get_pipeline()
            task_statuses = task_pipeline.get_process_names()
            task_process = task.get_value("process")

            # Commenting this out.  It is not very meaningful in 2.5 ...
            # we need a better mechanism.  The end result of this code
            # is that "admin" never sees any tasks
            #if security.check_access("public_wdg", "SObjectTaskTableElement|unassigned", "deny", is_match=True):
            #    assignee = task.get_value("assigned")
            #    if assignee != me:
            #        continue


            if not show_all_tasks:
                """
                if process_list and task_process not in process_list:
                    continue
                """
                # skip sub tasks
                if not show_sub_tasks and '/' in task_process:
                    continue

                task_status = task.get_value("status")
                if task_status not in task_statuses:
                    has_valid_status = False

                if has_valid_status  and task_status \
                        and task_status not in task_statuses_filter:
                    continue
                # the first one shouldn't be empty
                if user_filter and user_filter[0] and task.get_value("assigned") not in  user_filter:
                    continue
                
            table.add_row()

            
            #link = "%s/Maya/?text_filter=%s&load_asset_process=%s" % (web.get_site_context_url().to_string(), my.sobject.get_code(), task_process)
            #icon = IconButtonWdg("Open Loader", IconWdg.LOAD, False)
            #table.add_cell( HtmlElement.href(icon, link, target='maya') )

            td = table.add_cell(css='no_wrap')

            description = task.get_value("description")
            expand = ExpandableTextWdg()
            expand.set_max_length(50)
            expand.set_value(description)
            assigned = task.get_value("assigned").strip()

            status_wdg = SimpleStatusWdg()
            status_wdg.set_sobject(task)
            status_wdg.set_name("status")
            # refresh myself on execution of SimpleStatusCmd
            #post_scripts = my.get_refresh_script(show_progress=False)
            post_scripts = '''var panel = bvr.src_el.getParent('.spt_task_panel');
                              var search_top = spt.get_cousin(bvr.src_el, '.spt_view_panel','.spt_search');
                              var search_val = spt.dg_table.get_search_values(search_top);
                              var values = spt.api.Utility.get_input_values(panel);
                              values['json'] = search_val;
                              spt.panel.refresh(panel, values);'''
            status_wdg.set_post_ajax_script(post_scripts)
    
            if assigned:
                user_info = UserExtraInfoWdg(assigned).get_buffer_display()
            else:
                user_info = HtmlElement.i(" unassigned").get_buffer_display()

            info_span = SpanWdg()
            
            info_span.add(TaskExtraInfoWdg(task))
            info_span.add("- ")
            
            info_span.add("&nbsp;[%s]" % user_info)


            if UserAssignWdg.has_access() and my.get_option('supe')=='true':
                my._add_user_assign_wdg(task, info_span, widget) 

            td.add( info_span )

            #--------------

            my.calendar_bar.set_sobject(task)
            # set always recalculate since each task is set individually
            my.calendar_bar.set_always_recal(True)

            #---------------

            td.add_color('color','color')
            td.add(HtmlElement.br())
            if description:
                td.add(expand)
                td.add(HtmlElement.br())
            td.add(status_wdg)

            if my.last_process_finished(pipeline, task_process): 
                dot = IconWdg(icon=IconWdg.DOT_GREEN)
                dot.add_tip("All dependent processs complete")
                dot.add_style('float','left')
                dot.add_style('display','block')
                td.add(dot)
            else:
                dot = IconWdg(icon=IconWdg.DOT_RED)
                dot.add_tip("Dependent process in progress")
                dot.add_style('float','left')
                dot.add_style('display','block')
                td.add(dot)

            
            
            date_display = None
            if my.get_option('simple_date') == 'true':
                start_wdg = DateWdg()
                start_wdg.set_option("pattern", "%b %d")
                start_wdg.set_name('bid_start_date')
                start_wdg.set_sobject(task)
                end_wdg = DateWdg()
                end_wdg.set_name('bid_end_date')
                end_wdg.set_option("pattern", "%b %d")
                end_wdg.set_sobject(task)
                date_display = '%s - %s' %(start_wdg.get_buffer_display(), \
                    end_wdg.get_buffer_display())
            else:
                my.calendar_bar.set_sobject(task)
                # set always recalculate since each task is set individuallly
                my.calendar_bar.set_always_recal(True)

                my.calendar_bar.set_option("width", "40")
                my.calendar_bar.set_option("bid_edit", my.get_option('bid_edit'))
                date_display = my.calendar_bar.get_buffer_display()
            
            #td = table.add_cell(date_display, css='smaller')
            td.add(FloatDivWdg(date_display, float='right', css='smaller')) 
                
            #td.set_style("width: 120; padding-left: 15px")

            # This uses the parallel status widget to display status of
            # dependent tasks
            dependent_processes = pipeline.get_input_contexts(task_process)


            from parallel_status import ParallelStatusWdg
            dep_status_div = DivWdg()
            dep_status_div.add_style("padding-right: 10px")
            dep_status_wdg = ParallelStatusWdg()
            dep_status_wdg.set_process_names(dependent_processes)
            dep_status_wdg.set_label_format("abbr")
            dep_status_wdg.set_sobject(my.sobject)
            
            #dep_status_wdg.preprocess()
            dep_status_wdg.set_data(my.data)
            dep_status_div.add(dep_status_wdg)
            td.add(dep_status_div)
            #td.add_style("border-style: solid")
            #td.add_style("border-bottom: 1px")
            #td.add_style("border-color: #999")
            td.add_style("padding: 3px 0 3px 0")

        
        widget.add(table)
       
        return widget
コード例 #12
0
ファイル: parallel_status.py プロジェクト: 0-T-0/TACTIC
    def get_display(my):
        my.task_per_process_dict = {}
        
        # get the sobject and relevent parameters
        sobject = my.get_current_sobject()
        search_type = sobject.get_search_type()

        if my.pipeline_code:
            pipeline = Pipeline.get_by_code(my.pipeline_code)
        else:
            pipeline = Pipeline.get_by_sobject(sobject, allow_default=True)

        if not pipeline:
            # while default is auto-generated, an empty pipeline code will trigger this
            Environment.add_warning('missing pipeline code', \
                "Pipeline code is empty for [%s]" %sobject.get_code())
            return
        if my.include_sub_task_value:
            my.recurse = True

        processes = pipeline.get_processes(recurse=my.recurse)
        # filter out process names
        if my.process_names != None:
            filtered_processes = []
            for process in processes:
                if process.get_name() in my.process_names:
                    filtered_processes.append(process)

            processes = filtered_processes 


        # draw the proceses
        top = DivWdg()


        action = DivWdg()
        action.add_style("float: right")

        top.add(action)



        table = Table()
        table.add_style("font-size: 11px")
        top.add(table)

        #if my.max_count:
        #    percent_width = float(len(processes)) / float(my.max_count+1) * 100
        #else:
        #    percent_width = 100

        # we want them more squeezed together when in abbr mode
        if my.label_select_value != 'abbr':
            percent_width = 100
            table.add_style("width: %d%%" % percent_width)
        tr = table.add_row()
        
        for process in processes:
            completion_wdg = my.get_completion(sobject, process,\
                len(processes))
            if not completion_wdg:
                continue
            td = table.add_cell( completion_wdg )
            td.add_style('border-width: 0px')


        
        tr = table.add_row(css='underline')
        tr.add_color("color", "color")
        
        label_format = my.get_option("label_format")
        if not label_format:
            label_format =  my.label_select_value
       

        tup_list = my._get_labels(processes, label_format, show_sub_pipeline=my.is_ajax()) 
        style = ''
        for i, tup in enumerate(tup_list):
            name, process = tup
            span = SpanWdg()    
            child_pipeline = process.get_child_pipeline()
            if child_pipeline:
                
                title = SpanWdg()
                title.add("[%s]" % name)
                title.add_style("margin-left: -5px")

                swap = SwapDisplayWdg.get_triangle_wdg()
                content_id =  '%s_%s' %(sobject.get_search_key(), child_pipeline.get_id())
                content_id = my.generate_unique_id(content_id)
                content = DivWdg(id=content_id)

                SwapDisplayWdg.create_swap_title(title, swap, content)

                dyn_load = AjaxLoader(display_id=content_id)

                args_dict = {'search_type': sobject.get_search_type()}
                args_dict['search_id'] = sobject.get_id()
                args_dict['pipeline_skey'] = child_pipeline.get_search_key()
                dyn_load.set_load_method('_get_child_wdg')
                dyn_load.set_load_class('pyasm.widget.ParallelStatusWdg', load_args=args_dict)
                dyn_load.add_element_name('cal_sub_task')
                on_script = dyn_load.get_on_script(load_once=True)

                swap.add_action_script(on_script, "set_display_off('%s')" %content_id)

                script = "if ($(%s).getStyle('display')=='none') {%s}" \
                    %(swap.swap1_id, on_script)
                title.add_event('onclick', script)
                

                span.add(swap)
                span.add(title)
                span.add(HtmlElement.br())
                span.add(HtmlElement.br())
              
                span.add(content)

            else:
                span.add(name)
                if my.task_per_process_dict.get(process) == 0:
                    span.add_class('unused')

            if label_format == 'small' or label_format == 'abbr':
                span.add_class('smaller')
            if not label_format == "none":
                table.add_cell(span)


        return top
コード例 #13
0
    def get_info_wdg(my):

        widget = Widget()

        table = Table()
        table.set_class("minimal")
        table.add_style("font-size: 0.8em")

        context_option = my.kwargs.get('context')
        context_expr_option = my.kwargs.get('context_expr')

        pipeline_option = my.kwargs.get('pipeline') in ['true', True, 'True']
        setting_option = my.kwargs.get('setting')
        context_name = "%s|context" % my.get_input_name()
        text = None
        span1 = SpanWdg("Context", id='context_mode')
        span2 = SpanWdg("Context<br/>/Subcontext", id='subcontext_mode')
        span2.add_style('display', 'none')
        table.add_cell(span1)
        table.add_data(span2)
        if context_expr_option or context_option or setting_option:
            # add swap display for subcontext only if there is setting or context option
            swap = SwapDisplayWdg()
            table.add_data(SpanWdg(swap, css='small'))
            swap.set_display_widgets(StringWdg('[+]'), StringWdg('[-]'))
            subcontext_name = "%s|subcontext" % my.get_input_name()
            subcontext = SpanWdg('/ ', css='small')
            subcontext.add(TextWdg(subcontext_name))
            subcontext.add_style('display', 'none')
            subcontext.set_id(subcontext_name)
            on_script = "set_display_on('%s');swap_display('subcontext_mode','context_mode')" % subcontext_name
            off_script = "set_display_off('%s');get_elements('%s').set_value(''); "\
                "swap_display('context_mode','subcontext_mode')"%(subcontext_name, subcontext_name)
            swap.add_action_script(on_script, off_script)
            text = SelectWdg(context_name)
            if my.sobjects:
                text.set_sobject(my.sobjects[0])
            if context_expr_option:
                text.set_option('values_expr', context_expr_option)
            elif context_option:
                text.set_option('values', context_option)
            elif setting_option:
                text.set_option('setting', setting_option)

            td = table.add_cell(text)

            table.add_data(subcontext)

        elif pipeline_option:
            from pyasm.biz import Pipeline
            sobject = my.sobjects[0]
            pipeline = Pipeline.get_by_sobject(sobject)
            context_names = []
            process_names = pipeline.get_process_names(recurse=True)
            for process in process_names:
                context_names.append(pipeline.get_output_contexts(process))
            text = SelectWdg(context_name)
            text.set_option('values', process_names)
            table.add_cell(text)

        else:
            text = TextWdg(context_name)
            table.add_cell(text)
            hint = HintWdg('If not specified, the default is [publish]')
            table.add_data(hint)

        revision_cb = CheckboxWdg('%s|is_revision' %my.get_input_name(),\
            label='is revision', css='med')
        table.add_data(revision_cb)
        table.add_row()
        table.add_cell("Comment")
        textarea = TextAreaWdg("%s|description" % my.get_input_name())
        table.add_cell(textarea)
        widget.add(table)

        return widget
コード例 #14
0
    def get_info_wdg(my):

        widget = Widget()

        table = Table()
        table.set_class("minimal")
        table.add_style("font-size: 0.8em")

        context_option = my.kwargs.get('context')
        context_expr_option = my.kwargs.get('context_expr')
        
        pipeline_option = my.kwargs.get('pipeline') in ['true', True, 'True']
        setting_option = my.kwargs.get('setting')
        context_name = "%s|context" % my.get_input_name()
        text = None 
        span1 = SpanWdg("Context", id='context_mode')
        span2 = SpanWdg("Context<br/>/Subcontext", id='subcontext_mode')
        span2.add_style('display','none')
        table.add_cell(span1)
        table.add_data(span2)
        if context_expr_option or context_option or setting_option:
            # add swap display for subcontext only if there is setting or context option
            swap = SwapDisplayWdg()
            table.add_data(SpanWdg(swap, css='small'))
            swap.set_display_widgets(StringWdg('[+]'), StringWdg('[-]'))
            subcontext_name = "%s|subcontext" % my.get_input_name()
            subcontext = SpanWdg('/ ', css='small')
            subcontext.add(TextWdg(subcontext_name))
            subcontext.add_style('display','none')
            subcontext.set_id(subcontext_name)
            on_script = "set_display_on('%s');swap_display('subcontext_mode','context_mode')"%subcontext_name
            off_script = "set_display_off('%s');get_elements('%s').set_value(''); "\
                "swap_display('context_mode','subcontext_mode')"%(subcontext_name, subcontext_name)
            swap.add_action_script(on_script, off_script)
            text = SelectWdg(context_name)
            if my.sobjects:
                text.set_sobject(my.sobjects[0])
            if context_expr_option:
                text.set_option('values_expr', context_expr_option)
            elif context_option:
                text.set_option('values', context_option)
            elif setting_option:
                text.set_option('setting', setting_option)
                    

            td = table.add_cell(text)
            
            table.add_data(subcontext)
            
        elif pipeline_option:
            from pyasm.biz import Pipeline
            sobject = my.sobjects[0]
            pipeline = Pipeline.get_by_sobject(sobject)
            context_names = []
            process_names = pipeline.get_process_names(recurse=True)
            for process in process_names:
                context_names.append(pipeline.get_output_contexts(process))
            text = SelectWdg(context_name)
            text.set_option('values', process_names)
            table.add_cell(text)
            
        else:
            text = TextWdg(context_name)
            table.add_cell(text)
            hint = HintWdg('If not specified, the default is [publish]')
            table.add_data(hint)
      
        revision_cb = CheckboxWdg('%s|is_revision' %my.get_input_name(),\
            label='is revision', css='med')
        table.add_data(revision_cb)
        table.add_row()
        table.add_cell("Comment")
        textarea = TextAreaWdg("%s|description"% my.get_input_name())
        table.add_cell(textarea)
        widget.add(table)

        return widget
コード例 #15
0
ファイル: workflow.py プロジェクト: jayvdb/TACTIC
    def handle_action(my):
        my.log_message(my.sobject, my.process, "in_prgress")
        my.set_all_tasks(my.sobject, my.process, "in_progress")
        my.run_callback(my.pipeline, my.process, "action")


        pipeline = my.input.get("pipeline")
        process = my.input.get("process")
        sobject = my.input.get("sobject")

        process_obj = pipeline.get_process(process)
        related_search_type = process_obj.get_attribute("search_type")
        related_status = process_obj.get_attribute("status")
        related_process = process_obj.get_attribute("process")
        related_scope = process_obj.get_attribute("scope")

        # get the node's triggers
        if not related_search_type:
            search = Search("config/process")        
            search.add_filter("process", process)
            search.add_filter("pipeline_code", pipeline.get_code())
            process_sobj = search.get_sobject()

            workflow = process_sobj.get_json_value("workflow")
            related_search_type = workflow.get("search_type")
            related_proces = workflow.get("proces")
            related_status = workflow.get("status")
            related_scope = workflow.get("scope")



        if not related_search_type:
            print "WARNING: no related search_type found"
            return


        if not related_process:
            print "WARNING: no related process found"
            return



        if related_search_type.startswith("@"):
            expression = related_search_type
        else:
            expression = "@SOBJECT(%s)" % related_search_type

        if related_scope == "global":
            related_sobjects = Search.eval(expression)
        else:
            related_sobjects = Search.eval(expression, sobjects=[sobject])


        if not related_sobjects:
            event = "process|complete"
            Trigger.call(my, event, my.input)
            return



        # log a message storing these related sobjects
        message = {}
        for related_sobject in related_sobjects:
            related_search_key = related_sobject.get_search_key()

            message[related_search_key] = False


        message = jsondumps(message)
        search_key = sobject.get_search_key()
        key = "%s|%s|dependent" % (sobject.get_search_key(), process)

        from tactic_client_lib import TacticServerStub
        server = TacticServerStub.get()
        server.log_message(key, message)



        for related_sobject in related_sobjects:

            # TEST: do this to grab from cache
            # This is for unittests which don't necessarily commit changes
            related_sobject = Search.get_by_search_key(related_sobject.get_search_key())

            complete = True
            num_complete = 0


            # look at the message
            key = "%s|%s|dependent" % (related_sobject.get_search_key(), related_process)
            message_sobj = Search.get_by_code("sthpw/message", key)
            if message_sobj:
                message = message_sobj.get_json_value("message")

                message[search_key] = True
                message_sobj.set_json_value("message", message)
                message_sobj.commit()

                # test for completeness
                for name, value in message.items():
                    if value == False:
                        complete = False
                    else:
                        num_complete += 1
            else:
                # TODO:
                # This means that the receiving related sobject has not cached
                print ("WARNING: No dependencies cached [%s]" % related_process)
                return
                #raise Exception("No dependendies casched")


            # FIXME: this should be handled by "multiple inputs"

            if complete:
                related_pipeline = Pipeline.get_by_sobject(related_sobject)
                if not related_process:
                    # get the first one
                    related_processes = related_pipeline.get_processes()
                    related_process = related_processes[0]

                if related_status == "in_progress":
                    event = "process|action"
                else:
                    event = "process|%s" % related_status

                input = {
                    'sobject': related_sobject,
                    'pipeline': related_pipeline,
                    'process': related_process
                }

                Trigger.call(my, event, input)



        event = "process|complete"
        Trigger.call(my, event, my.input)
コード例 #16
0
ファイル: workflow.py プロジェクト: jayvdb/TACTIC
    def execute(my):

        """
        key = "enable_workflow_engine"
        from prod_setting import ProdSetting
        setting = ProdSetting.get_value_by_key(key)
        if setting not in [True, 'true']:
            return
        """


        # find the node in the pipeline
        task = my.get_caller()
        sobject = task.get_parent()
        if not sobject:
            return

        pipeline = None

        process_code = task.get_value("process_code", no_exception=True)
        if process_code:
            process_sobj = Search.get_by_code("config/process", process_code)
            if process_sobj:
                pipeline_code = process_sobj.get_value("pipeline_code")
                pipeline = Pipeline.get_by_code("sthpw/pipeline", pipeline_code) 

        if not pipeline:
            pipeline = Pipeline.get_by_sobject(sobject)

        if not pipeline:
            return


        if pipeline.get_value("use_workflow", no_exception=True) in [False, "false"]:
            return



        process_name = task.get_value("process")
        status = task.get_value("status")

        if status.lower() in PREDEFINED:
            status = status.lower()

        # handle the approve case (which really means complete)
        if status == "approved":
            status = "complete"

        process = pipeline.get_process(process_name)
        if not process:
            # we don't have enough info here
            return

        node_type = process.get_type()
        process_name = process.get_name()


        if status in PREDEFINED:
            event = "process|%s" % status
        else:
            event = "process|custom"

        output = {
            'sobject': sobject,
            'pipeline': pipeline,
            'process': process_name,
            'status': status
        }
        Trigger.call(task, event, output=output)
コード例 #17
0
    def get_display(self):

        web = WebContainer.get_web()
        
        # this needs to be a BaseInputWdg since UserFilterWdg is hideable
        user_filter = FilterSelectWdg("user_filter")
        user_filter = user_filter.get_values()
     
        #login = Environment.get_security().get_login()
        #user = login.get_value("login")

        if self.is_refresh:
            widget = Widget()
            self.init_cgi()
        else:
            self.sobject = self.get_current_sobject()
            widget = DivWdg(id="task_elem_%s"% self.sobject.get_id())
            widget.add_class('spt_task_panel')
            try:
                self.set_as_panel(widget)
            except:
                pass
       
        #TODO: remove this
        self.init_setup(widget)
        #self.set_ajax_top(widget)
        
        table = Table(css="minimal")
        table.add_style("width: 100%")

        # get all of the tasks related to this sobject
        search_type = self.sobject.get_search_type()
        search_id = self.sobject.get_id()
        if self.data:
            tasks = self.data.get("%s|%s" % (search_type,search_id) )
        else:
            tasks = Task.get_by_sobject(self.sobject)
            self.data[self.sobject.get_search_key()] = tasks
        if not tasks:
            tasks = []


        task_statuses_filter = web.get_form_values("task_status")
        show_sub_tasks = False
        if not task_statuses_filter:
            # NOTE: Not sure if this is correct!!
            # have to do this because it is impossible to tell if a checkbox
            # is empty or not there.  This is used for pages that do not have
            # tasks_status checkboxes
            show_all_tasks = True
        else:
            cb = FilterCheckboxWdg('show_all_tasks') 
            show_all_tasks = cb.is_checked(False)

            sub_cb = FilterCheckboxWdg('show_sub_tasks') 
            show_sub_tasks = sub_cb.is_checked(False)
        # trim down the process list
        """
        if not show_sub_tasks:
            process_list = [x for x in process_list if "/" not in x]
        """
        pipeline = Pipeline.get_by_sobject(self.sobject)

        # retrieve the pipeline   
        if not pipeline:
            td = table.add_cell("<br/><i>No pipeline</i>")
            td.add_style("text-align: center")
            return table

        # store completion per process first in a dict
        # reset it first
        self.process_completion_dict = {}
        for task in tasks:
            task_process = task.get_value("process")
            status_attr = task.get_attr('status')
            percent = status_attr.get_percent_completion()
            
            self.store_completion(task_process, percent)

        security = WebContainer.get_security()
        me = Environment.get_user_name()

        

        for task in tasks:
            has_valid_status = True
            task_pipeline = task.get_pipeline()
            task_statuses = task_pipeline.get_process_names()
            task_process = task.get_value("process")

            # Commenting this out.  It is not very meaningful in 2.5 ...
            # we need a better mechanism.  The end result of this code
            # is that "admin" never sees any tasks
            #if security.check_access("public_wdg", "SObjectTaskTableElement|unassigned", "deny", is_match=True):
            #    assignee = task.get_value("assigned")
            #    if assignee != me:
            #        continue


            if not show_all_tasks:
                """
                if process_list and task_process not in process_list:
                    continue
                """
                # skip sub tasks
                if not show_sub_tasks and '/' in task_process:
                    continue

                task_status = task.get_value("status")
                if task_status not in task_statuses:
                    has_valid_status = False

                if has_valid_status  and task_status \
                        and task_status not in task_statuses_filter:
                    continue
                # the first one shouldn't be empty
                if user_filter and user_filter[0] and task.get_value("assigned") not in  user_filter:
                    continue
                
            table.add_row()

            
            #link = "%s/Maya/?text_filter=%s&load_asset_process=%s" % (web.get_site_context_url().to_string(), self.sobject.get_code(), task_process)
            #icon = IconButtonWdg("Open Loader", IconWdg.LOAD, False)
            #table.add_cell( HtmlElement.href(icon, link, target='maya') )

            td = table.add_cell(css='no_wrap')

            description = task.get_value("description")
            expand = ExpandableTextWdg()
            expand.set_max_length(50)
            expand.set_value(description)
            assigned = task.get_value("assigned").strip()

            status_wdg = SimpleStatusWdg()
            status_wdg.set_sobject(task)
            status_wdg.set_name("status")
            # refresh myself on execution of SimpleStatusCmd
            #post_scripts = self.get_refresh_script(show_progress=False)
            post_scripts = '''var panel = bvr.src_el.getParent('.spt_task_panel');
                              var search_top = spt.get_cousin(bvr.src_el, '.spt_view_panel','.spt_search');
                              var search_val = spt.dg_table.get_search_values(search_top);
                              var values = spt.api.Utility.get_input_values(panel);
                              values['json'] = search_val;
                              spt.panel.refresh(panel, values);'''
            status_wdg.set_post_ajax_script(post_scripts)
    
            if assigned:
                user_info = UserExtraInfoWdg(assigned).get_buffer_display()
            else:
                user_info = HtmlElement.i(" unassigned").get_buffer_display()

            info_span = SpanWdg()
            
            info_span.add(TaskExtraInfoWdg(task))
            info_span.add("- ")
            
            info_span.add("&nbsp;[%s]" % user_info)


            if UserAssignWdg.has_access() and self.get_option('supe')=='true':
                self._add_user_assign_wdg(task, info_span, widget) 

            td.add( info_span )

            #--------------

            self.calendar_bar.set_sobject(task)
            # set always recalculate since each task is set individually
            self.calendar_bar.set_always_recal(True)

            #---------------

            td.add_color('color','color')
            td.add(HtmlElement.br())
            if description:
                td.add(expand)
                td.add(HtmlElement.br())
            td.add(status_wdg)

            if self.last_process_finished(pipeline, task_process): 
                dot = IconWdg(icon=IconWdg.DOT_GREEN)
                dot.add_tip("All dependent processs complete")
                dot.add_style('float','left')
                dot.add_style('display','block')
                td.add(dot)
            else:
                dot = IconWdg(icon=IconWdg.DOT_RED)
                dot.add_tip("Dependent process in progress")
                dot.add_style('float','left')
                dot.add_style('display','block')
                td.add(dot)

            
            
            date_display = None
            if self.get_option('simple_date') == 'true':
                start_wdg = DateWdg()
                start_wdg.set_option("pattern", "%b %d")
                start_wdg.set_name('bid_start_date')
                start_wdg.set_sobject(task)
                end_wdg = DateWdg()
                end_wdg.set_name('bid_end_date')
                end_wdg.set_option("pattern", "%b %d")
                end_wdg.set_sobject(task)
                date_display = '%s - %s' %(start_wdg.get_buffer_display(), \
                    end_wdg.get_buffer_display())
            else:
                self.calendar_bar.set_sobject(task)
                # set always recalculate since each task is set individuallly
                self.calendar_bar.set_always_recal(True)

                self.calendar_bar.set_option("width", "40")
                self.calendar_bar.set_option("bid_edit", self.get_option('bid_edit'))
                date_display = self.calendar_bar.get_buffer_display()
            
            #td = table.add_cell(date_display, css='smaller')
            td.add(FloatDivWdg(date_display, float='right', css='smaller')) 
                
            #td.set_style("width: 120; padding-left: 15px")

            # This uses the parallel status widget to display status of
            # dependent tasks
            dependent_processes = pipeline.get_input_contexts(task_process)


            from parallel_status import ParallelStatusWdg
            dep_status_div = DivWdg()
            dep_status_div.add_style("padding-right: 10px")
            dep_status_wdg = ParallelStatusWdg()
            dep_status_wdg.set_process_names(dependent_processes)
            dep_status_wdg.set_label_format("abbr")
            dep_status_wdg.set_sobject(self.sobject)
            
            #dep_status_wdg.preprocess()
            dep_status_wdg.set_data(self.data)
            dep_status_div.add(dep_status_wdg)
            td.add(dep_status_div)
            #td.add_style("border-style: solid")
            #td.add_style("border-bottom: 1px")
            #td.add_style("border-color: #999")
            td.add_style("padding: 3px 0 3px 0")

        
        widget.add(table)
       
        return widget