def set_all_tasks(my, sobject, process, status): tasks = Task.get_by_sobject(sobject, process=process) title = status.replace("-", " ") title = title.replace("_", " ") title = Common.get_display_title(title) for task in tasks: task.set_value("status", title) task.commit()
def _test_approval(my): # create a dummy sobject sobject = SearchType.create("unittest/person") pipeline_xml = ''' <pipeline> <process type="action" name="a"/> <process type="approval" name="b"/> <process type="action" name="c"/> <connect from="a" to="b"/> <connect from="b" to="c"/> </pipeline> ''' pipeline, processes = my.get_pipeline(pipeline_xml) sobject.set_value("pipeline_code", pipeline.get_code()) sobject.commit() # ensure there are not tasks tasks = Task.get_by_sobject(sobject, process="b") my.assertEquals(0, len(tasks)) # Run the pipeline process = "a" output = { "pipeline": pipeline, "sobject": sobject, "process": process } Trigger.call(my, "process|pending", output) # ensure there are not tasks tasks = Task.get_by_sobject(sobject, process="b") my.assertEquals(1, len(tasks)) task = tasks[0] my.assertEquals("b", task.get("process")) # approve the task task.set_value("status", "approved") task.commit() my.assertEquals( "complete", sobject.get_value("b")) my.assertEquals( "complete", sobject.get_value("c"))
def _test_approval(my): # create a dummy sobject sobject = SearchType.create("unittest/person") pipeline_xml = ''' <pipeline> <process type="action" name="a"/> <process type="approval" name="b"/> <process type="action" name="c"/> <connect from="a" to="b"/> <connect from="b" to="c"/> </pipeline> ''' pipeline, processes = my.get_pipeline(pipeline_xml) sobject.set_value("pipeline_code", pipeline.get_code()) sobject.commit() # ensure there are not tasks tasks = Task.get_by_sobject(sobject, process="b") my.assertEquals(0, len(tasks)) # Run the pipeline process = "a" output = { "pipeline": pipeline, "sobject": sobject, "process": process } Trigger.call(my, "process|pending", output) # ensure there are not tasks tasks = Task.get_by_sobject(sobject, process="b") my.assertEquals(1, len(tasks)) task = tasks[0] my.assertEquals("b", task.get("process")) # approve the task task.set_value("status", "approved") task.commit() my.assertEquals( "complete", sobject.get_value("b")) my.assertEquals( "complete", sobject.get_value("c"))
def get_to(my): recipients = super(TaskStatusEmailHandler, my).get_to() sobj = my.sobject # it could be the parent of task: if not isinstance(sobj, Task): tasks = Task.get_by_sobject(sobj) else: tasks = [sobj] for task in tasks: assigned = my._get_login(task.get_assigned()) if assigned: recipients.add(assigned) supe = my._get_login(task.get_supervisor()) if supe: recipients.add(supe) return recipients
def get_to(my): recipients = super(TaskStatusEmailHandler, my).get_to() sobj = my.sobject # it could be the parent of task: if not isinstance(sobj, Task): tasks = Task.get_by_sobject(sobj) else: tasks = [sobj] for task in tasks: assigned = my._get_login(task.get_assigned()) if assigned: recipients.add(assigned) supe = my._get_login(task.get_supervisor()) if supe: recipients.add(supe) return recipients
def handle_sobject(my, sobject, command): # the sobject here is a task if not my.check(sobject): return # the parent is the asset or shot parent = sobject.get_parent() print "Check finished" tasks = Task.get_by_sobject(parent, "compositing") # about to commit task_ids = [] for task in tasks: if task.get_value("status") != "Pending": task.set_value("status", "Pending") task.commit() task_ids.append(task.get_id()) print "Changed task status to [Pending] for task id %s'" % str(task_ids)
def handle_sobject(my, sobject, command): # the sobject here is a task if not my.check(sobject): return # the parent is the asset or shot parent = sobject.get_parent() print "Check finished" tasks = Task.get_by_sobject(parent, 'compositing') # about to commit task_ids = [] for task in tasks: if task.get_value('status') != 'Pending': task.set_value('status','Pending') task.commit() task_ids.append(task.get_id()) print "Changed task status to [Pending] for task id %s'" %str(task_ids)
def handle_sobject(self, sobject, command): # the sobject here is a task if not self.check(sobject): return # the parent is the asset or shot parent = sobject.get_parent() print "Check finished" tasks = Task.get_by_sobject(parent, 'compositing') # about to commit task_ids = [] for task in tasks: if task.get_value('status') != 'Pending': task.set_value('status','Pending') task.commit() task_ids.append(task.get_id()) print "Changed task status to [Pending] for task id %s'" %str(task_ids)
def get_display(my): web = WebContainer.get_web() task = my.get_current_sobject() id = task.get_id() if task.is_insert(): return HtmlElement.i("Dependency on insert not supported yet.") # get the sobject sobject = task.get_parent() if not sobject: return "No parent" tmp_tasks = Task.get_by_sobject(sobject) tasks = [] for tmp_task in tmp_tasks: # skip the task self if tmp_task.get_id() == id: continue # prevent direct circular dependencies if tmp_task.get_value("depend_id") == id: continue tasks.append(tmp_task) ids = [x.get_id() for x in tasks] labels = [] for task in tasks: process = task.get_value("process") description = task.get_value("description") if len(description) > 30: description = description[0:30]+"..." label = "%s - %s" % (process, description) labels.append(label) my.set_option("empty", "true") my.set_option("labels", labels) my.set_option("values", ids) return super(TaskParentInputWdg,my).get_display()
def get_display(self): web = WebContainer.get_web() task = self.get_current_sobject() id = task.get_id() if task.is_insert(): return HtmlElement.i("Dependency on insert not supported yet.") # get the sobject sobject = task.get_parent() if not sobject: return "No parent" tmp_tasks = Task.get_by_sobject(sobject) tasks = [] for tmp_task in tmp_tasks: # skip the task self if tmp_task.get_id() == id: continue # prevent direct circular dependencies if tmp_task.get_value("depend_id") == id: continue tasks.append(tmp_task) ids = [x.get_id() for x in tasks] labels = [] for task in tasks: process = task.get_value("process") description = task.get_value("description") if len(description) > 30: description = description[0:30]+"..." label = "%s - %s" % (process, description) labels.append(label) self.set_option("empty", "true") self.set_option("labels", labels) self.set_option("values", ids) return super(TaskParentInputWdg,self).get_display()
def delete(my, log=True): '''This is for undo''' # TODO: the should probably be clearer!!!! if log == False: super(Asset,my).delete(log) return # An asset can only be deleted if only icon snapshots exist snapshots = Snapshot.get_by_sobject(my) only_icons = True for snapshot in snapshots: context = snapshot.get_value("context") if context != my.get_icon_context(): only_icons = False if not only_icons: raise TacticException("Cannot delete because snapshots exist") # only delete if not tasks have been assigned tasks = Task.get_by_sobject(my) has_assigned = False for task in tasks: assigned = task.get_value("assigned") if assigned != "" and assigned != "None": has_assigned = True if has_assigned: raise TacticException("Cannot delete because tasks have been assigned") # delete tasks and icons for snapshot in snapshots: snapshot.delete() for task in tasks: task.delete() my.description = "Deleted '%s', search_type '%s'" % (my.get_code(), my.get_search_type) super(Asset,my).delete(log)
def delete(my, log=True): '''This is for undo''' # TODO: the should probably be clearer!!!! if log == False: super(Shot, my).delete(log) return # An asset can only be deleted if only icon snapshots exist snapshots = Snapshot.get_by_sobject(my) only_icons = True for snapshot in snapshots: context = snapshot.get_value("context") if context != my.get_icon_context(): only_icons = False if not only_icons: raise TacticException("Cannot delete because snapshots exist") # only delete if not tasks have been assigned tasks = Task.get_by_sobject(my) has_assigned = False for task in tasks: assigned = task.get_value("assigned") if assigned != "" and assigned != "None": has_assigned = True if has_assigned: raise TacticException( "Cannot delete because tasks have been assigned") # delete tasks and icons for snapshot in snapshots: snapshot.delete() for task in tasks: task.delete() my.description = "Deleted '%s', search_type '%s'" % ( my.get_code(), my.get_search_type) super(Shot, my).delete(log)
def get_display(my): args = WebContainer.get_web().get_form_args() # get the args in the URL search_type = args['search_type'] search_id = args['search_id'] sobject = Search.get_by_search_key("%s|%s" % (search_type, search_id)) widget = DivWdg() widget.add_style("width: 95%") widget.add_style("margin-left: 20px") table = TableWdg("sthpw/task", "layout_right") from pyasm.biz import Task tasks = Task.get_by_sobject(sobject) table.set_sobjects(tasks) table.set_show_property(False) widget.add(table) return widget
def get_display(my): args = WebContainer.get_web().get_form_args() # get the args in the URL search_type = args['search_type'] search_id = args['search_id'] sobject = Search.get_by_search_key("%s|%s" % (search_type,search_id) ) widget = DivWdg() widget.add_style("width: 95%") widget.add_style("margin-left: 20px") table = TableWdg("sthpw/task", "layout_right") from pyasm.biz import Task tasks = Task.get_by_sobject(sobject) table.set_sobjects(tasks) table.set_show_property(False) widget.add(table) return widget
def handle_pending(my): my.log_message(my.sobject, my.process, "pending") search = Search("config/process") search.add_filter("process", my.process) search.add_filter("pipeline_code", my.pipeline.get_code()) process_sobj = search.get_sobject() workflow = process_sobj.get_json_value("workflow") if workflow: assigned = workflow.get("assigned") else: assigned = None # check to see if the tasks exist and if they don't then create one tasks = Task.get_by_sobject(my.sobject, process=my.process) if not tasks: tasks = Task.add_initial_tasks(my.sobject, processes=[my.process], assigned=assigned) else: my.set_all_tasks(my.sobject, my.process, "pending") Trigger.call(my, "process|action", my.input)
def execute(my): # set all task to pending pipeline = my.input.get("pipeline") process = my.input.get("process") sobject = my.input.get("sobject") process_obj = pipeline.get_process(process) node_type = process_obj.get_type() #print "pending: ", process, node_type my.run_callback(pipeline, process, "pending") if node_type not in ["node", "manual"]: my.set_all_tasks(sobject, process, "pending") if node_type in ["action", "condition"]: Trigger.call(my, "process|action", output=my.input) elif node_type in ["approval"]: # check to see if the tasks exist and if they don't then create one tasks = Task.get_by_sobject(sobject, process=process) if not tasks: tasks = Task.add_initial_tasks(sobject, processes=[process]) else: my.set_all_tasks(sobject, process, "pending") elif node_type in ["hierarchy"]: search = Search("config/process") search.add_filter("pipeline_code", pipeline.get_code()) search.add_filter("process", process) process_sobj = search.get_sobject() process_code = process_sobj.get_code() search = Search("sthpw/pipeline") search.add_filter("parent_process", process_code) subpipeline = search.get_sobject() if not subpipeline: return child_processes = subpipeline.get_processes() #child_pipeline = process_obj.get_child_pipeline() #child_processes = child_pipeline.get_processes() if child_processes: first_process = child_processes[0] first_name = first_process.get_name() input = { 'pipeline': subpipeline, 'sobject': sobject, 'process': first_process.get_name(), } event = "process|pending" Trigger.call(my, event, input)
def get_pipeline_wdg(my, pipeline_code): div = DivWdg() title = DivWdg() title.add_gradient("background", "background3", 0) title.add_style("height: 20px") title.add_style("font-weight: bold") title.add_style("padding: 4px") title.add_border() title.add("Pipeline") div.add(title) kwargs = { 'width': 800, 'height': 300, 'pipeline': pipeline_code, 'scale': 0.7, } pipeline = TaskDetailPipelineWdg(**kwargs) div.add(pipeline) load_div = DivWdg() div.add(load_div) # This is only for tasks!!!! enabled_tasks = set() from pyasm.biz import Task process = '' if my.parent: tasks = Task.get_by_sobject(my.parent) if my.sobject.has_value("process"): process = my.sobject.get_value("process") else: tasks = Task.get_by_sobject(my.sobject) for task in tasks: enabled_tasks.add(task.get_value("process")) enabled_tasks = list(enabled_tasks) load_div.add_behavior( { 'type': 'load', 'process': process, 'enabled_tasks': enabled_tasks, 'pipeline': pipeline_code, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_pipeline_wrapper"); spt.pipeline.init_cbk(top); var nodes = spt.pipeline.get_nodes_by_group(bvr.pipeline); for (var i = 0; i < nodes.length; i++) { var has_task = false; var node = nodes[i]; var node_name = spt.pipeline.get_node_name(node); for (var j = 0; j < bvr.enabled_tasks.length; j++) { if (node_name == bvr.enabled_tasks[j]) { has_task = true; break; } } if (!has_task && node) { spt.pipeline.disable_node(node); } } spt.pipeline.unselect_all_nodes(); var node = spt.pipeline.get_node_by_name(bvr.process); //process and node name could be different if (node) { node.setStyle("font-weight", "bold"); spt.pipeline.select_node(node); //spt.pipeline.center_node(node); } spt.pipeline.fit_to_canvas(bvr.pipeline); ''' } ) #div.add_style("padding: 10px") div.add_border() return div
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(" [%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
def get_pipeline_wdg(my, pipeline_code): div = DivWdg() title = DivWdg() title.add_color("background", "background3", -5) title.add_style("height: 20px") title.add_style("font-weight: bold") title.add_style("padding: 4px") title.add_border() title.add("Pipeline") div.add(title) kwargs = { 'width': 1280, 'height': 500, 'pipeline': pipeline_code, 'scale': 0.7, 'is_editable': False, } pipeline = TaskDetailPipelineWdg(**kwargs) div.add(pipeline) load_div = DivWdg() div.add(load_div) # This is only for tasks!!!! enabled_tasks = set() from pyasm.biz import Task process = '' if my.parent: tasks = Task.get_by_sobject(my.parent) if my.sobject.has_value("process"): process = my.sobject.get_value("process") else: tasks = Task.get_by_sobject(my.sobject) for task in tasks: enabled_tasks.add(task.get_value("process")) enabled_tasks = list(enabled_tasks) load_div.add_behavior({ 'type': 'load', 'process': process, 'enabled_tasks': enabled_tasks, 'search_key': my.sobject.get_search_key(), 'pipeline': pipeline_code, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_pipeline_wrapper"); spt.pipeline.init_cbk(top); var nodes = spt.pipeline.get_nodes_by_group(bvr.pipeline); for (var i = 0; i < nodes.length; i++) { var has_task = false; var node = nodes[i]; var node_name = spt.pipeline.get_node_name(node); for (var j = 0; j < bvr.enabled_tasks.length; j++) { if (node_name == bvr.enabled_tasks[j]) { has_task = true; break; } } if (!has_task && node) { spt.pipeline.disable_node(node); } } spt.pipeline.unselect_all_nodes(); var node = spt.pipeline.get_node_by_name(bvr.process); //process and node name could be different if (node) { node.setStyle("font-weight", "bold"); spt.pipeline.select_node(node); //spt.pipeline.center_node(node); } spt.pipeline.set_status_color(bvr.search_key); var top = spt.pipeline.top; var text = top.getElement(".spt_pipeline_editor_current2"); spt.pipeline.load_triggers(); spt.pipeline.fit_to_canvas(bvr.pipeline); var server = TacticServerStub.get(); var pipeline = server.get_by_code("sthpw/pipeline", bvr.pipeline); var html = "<span class='hand spt_pipeline_link' spt_pipeline_code='"+pipeline.code+"'>"+pipeline.name+"</span>"; text.innerHTML = html; ''' }) #div.add_style("padding: 10px") div.add_border() return div
def execute(my): trigger_sobj = my.get_trigger_sobj() data = trigger_sobj.get_value("data") data = jsonloads(data) print "trigger data: ", data, type(data) data_list = data if isinstance(data, dict): data_list = [data] src_task = my.get_caller() for data in data_list: # get the src task caller dst_task = None # it could be the FileCheckin Command if not isinstance(src_task, SObject): input = my.get_input() snapshot = input.get('snapshot') if not snapshot: continue if isinstance(snapshot, dict): snapshot = SearchKey.get_by_search_key(snapshot.get('__search_key__')) src_process = data.get('src_process') src_task = Search.eval("@SOBJECT(parent.sthpw/task['process','%s'])"%src_process,\ sobjects=snapshot, single=True) if not src_task: continue # make sure the caller process is the same as the source process if src_task.get_value("process") != data.get("src_process"): continue #conditionx = "@GET(.status) != 'Approved'" #result = Search.eval(conditionx, src_task) #print "result: ", result # make sure that the appropriate status was set src_status = data.get("src_status") if src_status and src_task.get_value("status") != src_status: continue dst_process = data.get("dst_process") dst_status = data.get("dst_status") sobject = src_task.get_parent() tasks = Task.get_by_sobject(sobject) updated_tasks = [] use_parent = data.get("use_parent") if use_parent in [True,'true']: parent = sobject.get_parent() parent_tasks = Task.get_by_sobject(parent, dst_process) condition = data.get("condition") if not condition: condition = "all" if condition == "all": condition_met = True for task in tasks: if src_task.get_value("status") != src_status: condition_met = False elif condition == "any": condition_met = False for task in tasks: if task.get_value("status") == src_status: condition_met = True break if condition_met: for task in parent_tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) else: for task in tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) for task in updated_tasks: if task.get_value("process") == dst_process: task.set_value("status", dst_status) task.commit() """
def get_pipeline_wdg(my, pipeline_code): div = DivWdg() title = DivWdg() title.add_gradient("background", "background3", 0) title.add_style("height: 20px") title.add_style("font-weight: bold") title.add_style("padding: 4px") title.add_border() title.add("Pipeline") div.add(title) kwargs = { 'width': 800, 'height': 300, 'pipeline': pipeline_code, 'scale': 0.7, } pipeline = TaskDetailPipelineWdg(**kwargs) div.add(pipeline) load_div = DivWdg() div.add(load_div) # This is only for tasks!!!! enabled_tasks = set() from pyasm.biz import Task process = '' if my.parent: tasks = Task.get_by_sobject(my.parent) if my.sobject.has_value("process"): process = my.sobject.get_value("process") else: tasks = Task.get_by_sobject(my.sobject) for task in tasks: enabled_tasks.add(task.get_value("process")) enabled_tasks = list(enabled_tasks) load_div.add_behavior({ 'type': 'load', 'process': process, 'enabled_tasks': enabled_tasks, 'pipeline': pipeline_code, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_pipeline_wrapper"); spt.pipeline.init_cbk(top); var nodes = spt.pipeline.get_nodes_by_group(bvr.pipeline); for (var i = 0; i < nodes.length; i++) { var has_task = false; var node = nodes[i]; var node_name = spt.pipeline.get_node_name(node); for (var j = 0; j < bvr.enabled_tasks.length; j++) { if (node_name == bvr.enabled_tasks[j]) { has_task = true; break; } } if (!has_task && node) { spt.pipeline.disable_node(node); } } spt.pipeline.unselect_all_nodes(); var node = spt.pipeline.get_node_by_name(bvr.process); //process and node name could be different if (node) { node.setStyle("font-weight", "bold"); spt.pipeline.select_node(node); //spt.pipeline.center_node(node); } spt.pipeline.fit_to_canvas(bvr.pipeline); ''' }) #div.add_style("padding: 10px") div.add_border() return div
def execute(my): trigger_sobj = my.get_trigger_sobj() data = trigger_sobj.get_value("data") data = jsonloads(data) print "trigger data: ", data, type(data) data_list = data if isinstance(data, dict): data_list = [data] src_task = my.get_caller() for data in data_list: # get the src task caller dst_task = None # it could be the FileCheckin Command if not isinstance(src_task, SObject): input = my.get_input() snapshot = input.get('snapshot') if not snapshot: continue if isinstance(snapshot, dict): snapshot = SearchKey.get_by_search_key( snapshot.get('__search_key__')) src_process = data.get('src_process') src_task = Search.eval("@SOBJECT(parent.sthpw/task['process','%s'])"%src_process,\ sobjects=snapshot, single=True) if not src_task: continue # make sure the caller process is the same as the source process if src_task.get_value("process") != data.get("src_process"): continue #conditionx = "@GET(.status) != 'Approved'" #result = Search.eval(conditionx, src_task) #print "result: ", result # make sure that the appropriate status was set src_status = data.get("src_status") if src_status and src_task.get_value("status") != src_status: continue dst_process = data.get("dst_process") dst_status = data.get("dst_status") sobject = src_task.get_parent() tasks = Task.get_by_sobject(sobject) updated_tasks = [] use_parent = data.get("use_parent") if use_parent in [True, 'true']: parent = sobject.get_parent() parent_tasks = Task.get_by_sobject(parent, dst_process) condition = data.get("condition") if not condition: condition = "all" if condition == "all": condition_met = True for task in tasks: if src_task.get_value("status") != src_status: condition_met = False elif condition == "any": condition_met = False for task in tasks: if task.get_value("status") == src_status: condition_met = True break if condition_met: for task in parent_tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) else: for task in tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) for task in updated_tasks: if task.get_value("process") == dst_process: task.set_value("status", dst_status) task.commit() """
def execute(self): trigger_sobj = self.get_trigger_sobj() data = trigger_sobj.get_value("data") data = jsonloads(data) data_list = data if isinstance(data, dict): data_list = [data] src_task = self.get_caller() for data in data_list: # get the src task caller dst_task = None # it could be the FileCheckin Command if not isinstance(src_task, SObject): input = self.get_input() snapshot = input.get('snapshot') if not snapshot: continue if isinstance(snapshot, dict): snapshot = SearchKey.get_by_search_key( snapshot.get('__search_key__')) src_process = data.get('src_process') src_task = Search.eval("@SOBJECT(parent.sthpw/task['process','%s'])"%src_process,\ sobjects=snapshot, single=True) if not src_task: continue # make sure the caller process is the same as the source process if src_task.get_value("process") != data.get("src_process"): continue #conditionx = "@GET(.status) != 'Approved'" #result = Search.eval(conditionx, src_task) #print "result: ", result # make sure that the appropriate status was set src_status = data.get("src_status") if src_status and src_task.get_value("status") != src_status: continue # Execute script if necessary script_path = trigger_sobj.get_value("script_path") if script_path: cmd = PythonTrigger(script_path=script_path) cmd.set_input(self.input) cmd.set_output(self.input) cmd.execute() continue # Execute trigger if necessary class_path = data.get("class_path") if class_path: trigger = Common.create_from_class_path(class_path) trigger.set_input(self.input) trigger.set_output(self.input) trigger.execute() continue # If no script was execute,then assume other task # statuses should be updated. dst_process = data.get("dst_process") dst_status = data.get("dst_status") sobject = src_task.get_parent() tasks = Task.get_by_sobject(sobject) updated_tasks = [] use_parent = data.get("use_parent") if use_parent in [True, 'true']: parent = sobject.get_parent() parent_tasks = Task.get_by_sobject(parent, dst_process) condition = data.get("condition") if not condition: condition = "all" if condition == "all": condition_met = True for task in tasks: if src_task.get_value("status") != src_status: condition_met = False elif condition == "any": condition_met = False for task in tasks: if task.get_value("status") == src_status: condition_met = True break if condition_met: for task in parent_tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) else: for task in tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) for task in updated_tasks: if task.get_value("process") == dst_process: task.set_value("status", dst_status) task.commit() """
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(" [%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
def execute(self): trigger_sobj = self.get_trigger_sobj() data = trigger_sobj.get_value("data") data = jsonloads(data) data_list = data if isinstance(data, dict): data_list = [data] src_task = self.get_caller() for data in data_list: # get the src task caller dst_task = None # it could be the FileCheckin Command if not isinstance(src_task, SObject): input = self.get_input() snapshot = input.get('snapshot') if not snapshot: continue if isinstance(snapshot, dict): snapshot = SearchKey.get_by_search_key(snapshot.get('__search_key__')) src_process = data.get('src_process') src_task = Search.eval("@SOBJECT(parent.sthpw/task['process','%s'])"%src_process,\ sobjects=snapshot, single=True) if not src_task: continue # make sure the caller process is the same as the source process if src_task.get_value("process") != data.get("src_process"): continue #conditionx = "@GET(.status) != 'Approved'" #result = Search.eval(conditionx, src_task) #print "result: ", result # make sure that the appropriate status was set src_status = data.get("src_status") if src_status and src_task.get_value("status") != src_status: continue # Execute script if necessary script_path = trigger_sobj.get_value("script_path") if script_path: cmd = PythonTrigger(script_path=script_path) cmd.set_input(self.input) cmd.set_output(self.input) cmd.execute() continue # Execute trigger if necessary class_path = data.get("class_path") if class_path: trigger = Common.create_from_class_path(class_path) trigger.set_input(self.input) trigger.set_output(self.input) trigger.execute() continue # If no script was execute,then assume other task # statuses should be updated. dst_process = data.get("dst_process") dst_status = data.get("dst_status") sobject = src_task.get_parent() tasks = Task.get_by_sobject(sobject) updated_tasks = [] use_parent = data.get("use_parent") if use_parent in [True,'true']: parent = sobject.get_parent() parent_tasks = Task.get_by_sobject(parent, dst_process) condition = data.get("condition") if not condition: condition = "all" if condition == "all": condition_met = True for task in tasks: if src_task.get_value("status") != src_status: condition_met = False elif condition == "any": condition_met = False for task in tasks: if task.get_value("status") == src_status: condition_met = True break if condition_met: for task in parent_tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) else: for task in tasks: if task.get_value("process") == dst_process: updated_tasks.append(task) for task in updated_tasks: if task.get_value("process") == dst_process: task.set_value("status", dst_status) task.commit() """