def _test_commit(my): from pyasm.biz import Project database_type = Project.get_by_code("unittest").get_database_type() if database_type == "MySQL": print print "WARNING: !!!!!!!" print "_test_commit is disabled" print "WARNING: !!!!!!!" print return person_s = Search('unittest/person') person_s.add_filter('name_first', 'pete') person = person_s.get_sobject() from pyasm.biz import Note Note.create(person, "3 slashes \\\\\\", context="unittest_commit", process="unittest_commit") search = Search('sthpw/note') search.add_filter('process', 'unittest_commit') search.set_limit(1) note = search.get_sobject() my.assertEquals(note.get_value('note'), "3 slashes \\\\\\")
def add_publish_note(my): # DISABLING because this is too overbearing. There are way # too many notes created return description = my.snapshot.get_value("description") process = my.snapshot.get_value("process") context = my.snapshot.get_value("context") version = my.snapshot.get_value("version") from pyasm.biz import Note if description: description = "Check-in [v%0.3d]: %s" % (version, description) Note.create(my.sobject, description, context=context, process=process)
def add_publish_note(self): # DISABLING because this is too overbearing. There are way # too many notes created return description = self.snapshot.get_value("description") process = self.snapshot.get_value("process") context = self.snapshot.get_value("context") version = self.snapshot.get_value("version") from pyasm.biz import Note if description: description = "Check-in [v%0.3d]: %s" % (version, description) Note.create(self.sobject, description, context=context, process=process)
def _test_commit(self): from pyasm.biz import Project database_type = Project.get_by_code("unittest").get_database_type() if database_type == "MySQL": print print "WARNING: !!!!!!!" print "_test_commit is disabled" print "WARNING: !!!!!!!" print return person_s = Search('unittest/person') person_s.add_filter('name_first','pete') person = person_s.get_sobject() from pyasm.biz import Note Note.create(person, "3 slashes \\\\\\", context="unittest_commit", process="unittest_commit") search = Search('sthpw/note') search.add_filter('process','unittest_commit') search.set_limit(1) note = search.get_sobject() self.assertEquals(note.get_value('note'), "3 slashes \\\\\\")
def main(server=None, input=None): """ The main function of the custom script. The entire script was copied and pasted into the body of the try statement in order to add some error handling. It's all legacy code, so edit with caution. :param server: the TacticServerStub object :param input: a dict with data like like search_key, search_type, sobject, and update_data :return: None """ if not input: input = {} try: # CUSTOM_SCRIPT00019 # # Created by Matthew Misenhimer # def make_timestamp(): #Makes a Timestamp for postgres import datetime now = datetime.datetime.now() return now.strftime("%Y-%m-%d %H:%M:%S") def are_no_hackpipes_preceding(sob, ignore_code): #Checks to see if there are any manually inserted/non-pipeline Projects or Work Orders that lead in to the sob that are not completed yet #If there are incompleted hackpipe work orders or projs that precede the sob, then this will return false. #Ignore code is usually the code of the task just completed. We don't care about looking at it's status in determining this. boolio = True matcher = '' #This is the type of sob (PROJ or WORK_ORDER) that we care about looking at if 'PROJ' in sob.get('code'): matcher = 'PROJ' elif 'WORK_ORDER' in sob.get('code'): matcher = 'WORK_ORDER' pre_hacks_expr = "@SOBJECT(twog/hackpipe_out['out_to','%s'])" % sob.get('code') #See what hackpipes lead in to this sob pre_hacks = server.eval(pre_hacks_expr) for ph in pre_hacks: if matcher in ph.get('lookup_code') and ignore_code not in ph.get('lookup_code'): #If it's the type we care about and it isn't the main sob ph_task = server.eval("@SOBJECT(sthpw/task['lookup_code','%s'])" % ph.get('lookup_code')) if ph_task: ph_task = ph_task[0] if ph_task.get('status') != 'Completed': #If it hasn't been completed, then there is an incomplete hackpipe preceding sob, so return false boolio = False return boolio def block_manual_status_adjust_for_inactive_hackup(sob, task): #This was created because people used to be able to change the status of inactive work orders #I think this is prevented in other ways now, but I am keeping it in just in case it is still needed. from pyasm.common import TacticException good = True if sob.get('creation_type') == 'hackup': if task.get('active') not in [True,'true','t',1,'1']: raise TacticException('This needs to be active in order to change the status') return good from pyasm.common import TacticException, Environment # input and server are assumed variables # define some contants here #print "\n\nIN KICKOFF" COMPLETE = 'Completed' READY = 'Ready' PENDING = 'Pending' sobj = input.get('sobject') this_process = sobj.get('process') this_lookup = sobj.get('lookup_code') sk = input.get('search_key') task_code = sobj.get('code') update_data = input.get('update_data') #These are the new values prev_data = {} old_status = '' if 'prev_data' in input.keys(): prev_data = input.get('prev_data') #These are the old values if 'status' in prev_data.keys(): old_status = prev_data.get('status') new_status = update_data.get('status') login = Environment.get_login() user_name = login.get_login() assigned_login_group = sobj.get('assigned_login_group') parent_obj = None title = None order = None if 'PROJ' in this_lookup: parent_obj = server.eval("@SOBJECT(twog/proj['code','%s'])" % this_lookup)[0] #Parent Obj is the Proj attached to the task proj = parent_obj title = server.eval("@SOBJECT(twog/title['code','%s'])" % parent_obj.get('title_code'))[0] order = server.eval("@SOBJECT(twog/order['code','%s'])" % title.get('order_code'))[0] elif 'WORK_ORDER' in this_lookup: parent_obj = server.eval("@SOBJECT(twog/work_order['code','%s'])" % this_lookup)[0] #Parent Obj is the Work Order attached to the task work_order = parent_obj proj = server.eval("@SOBJECT(twog/proj['code','%s'])" % work_order.get('proj_code'))[0] title = server.eval("@SOBJECT(twog/proj['code','%s'].twog/title)" % parent_obj.get('proj_code'))[0] order = server.eval("@SOBJECT(twog/order['code','%s'])" % title.get('order_code'))[0] if 'PROJ' in this_lookup and title.get('priority_triggers') != 'No': #If the new status for this Proj is ready, then grab the priority attached to he proj and give it to the Title #This is to control priority order per department if new_status == 'Ready': server.update(title.get('__search_key__'), {'priority': parent_obj.get('priority')}, triggers=False) elif 'WORK_ORDER' in this_lookup: t_wo_completed = title.get('wo_completed') #This is for the completion ratio on title o_wo_completed = order.get('wo_completed') #This is for the completion ratio on order if new_status == COMPLETE: title_str = title.get('title') #This is for a potential alert/exception if title.get('episode') not in [None,'']: title_str = '%s: %s' % (title_str, title.get('episode')) #Block QC and Edel from completing their work orders if the TRT or TRT w/Textless are not filled in if 'qc' in assigned_login_group or 'edeliveries' in assigned_login_group: total_program_runtime = title.get('total_program_runtime') total_runtime_w_textless = title.get('total_runtime_w_textless') say_str = '' say_str2 = '' if total_program_runtime in [None,''] or total_runtime_w_textless in [None,'']: if total_program_runtime in [None,'']: say_str = 'Total Program Runtime has' if total_runtime_w_textless in [None,'']: if say_str == '': say_str = 'Total Runtime With Textless has' else: say_str = '%s and Total Runtime With Textless have' % (say_str[:-4]) say_str2 = "%s (%s)'s %s not been filled. You must enter this data before trying to complete this work order." % (title_str, title.get('code'), say_str) if 'qc' in assigned_login_group: if total_program_runtime in [None,''] or total_runtime_w_textless in [None,'']: raise TacticException(say_str2) else: #They were filled in, so finish completing the task and send a note from pyasm.biz import Note from pyasm.search import Search title_obj2 = Search.get_by_search_key(title.get('__search_key__')) #This is the type of object required for Note creation note_text = '%s (%s) has been Passed and Completed by %s in QC' % (sobj.get('process'), this_lookup, user_name) note = Note.create(title_obj2, note_text, context='QC Completed', process='QC Completed') elif 'edeliveries' in assigned_login_group and (total_program_runtime in [None,''] or total_runtime_w_textless in [None,'']): raise TacticException(say_str2) #This section is turned off due to logistical problems with it. #It intended to block machine room, edit, and compression from completing a work order unless the pulled_blacks had been filled out. #if 'machine_room' in assigned_login_group or 'edit' in assigned_login_group or 'compression' in assigned_login_group: # pulled_blacks = title.get('pulled_blacks') # if pulled_blacks in [None,'','0']: # raise TacticException("%s (%s)'s pulled_blacks has not been filled, or is still '0'." % (title_str, title.get('code'))) t_wo_completed = t_wo_completed + 1 o_wo_completed = o_wo_completed + 1 #Update the completion ratios attached, since there were no blocking exceptions server.update(title.get('__search_key__'), {'wo_completed': t_wo_completed}) server.update(order.get('__search_key__'), {'wo_completed': o_wo_completed}) elif old_status == COMPLETE: t_wo_completed = t_wo_completed - 1 o_wo_completed = o_wo_completed - 1 #Reduce the completion ratio, since it was completed but has now been taken off that status server.update(title.get('__search_key__'), {'wo_completed': t_wo_completed}) server.update(order.get('__search_key__'), {'wo_completed': o_wo_completed}) #Still doing this, but don't know if it's neccessary anymore mmkay = block_manual_status_adjust_for_inactive_hackup(parent_obj, sobj) if new_status == COMPLETE and 'PROJ' not in this_lookup: #Make sure they have set the assigned person to the work order. if sobj.get('assigned') in [None,'']: task_assigned_expr = "@GET(sthpw/task['code','%s'].assigned)" % sobj.get('code') #MTM: Do I need to retrieve the task again, or can I just use the sobj's "assigned"? task_assigned = server.eval(task_assigned_expr) if task_assigned: task_assigned = task_assigned[0] if task_assigned in [None,'']: raise TacticException('Before completing a work order, someone must be assigned to it.') #Make sure they have added work hours. If not, error out. whs_expr = "@SOBJECT(sthpw/work_hour['task_code','%s'])" % task_code whs = server.eval(whs_expr) sum = 0 for wh in whs: straight_time = wh.get('straight_time') if straight_time in [None,'']: straight_time = 0 else: straight_time = float(straight_time) sum = float(sum) + straight_time sum = str(sum) if sum in ['0','',0,0.0]: raise TacticException('You need to save the hours you worked on this before you can set the status to "Completed".') now_timestamp = make_timestamp() #Since there have been no blocking exceptions, record the status change server.insert('twog/status_log', {'login': user_name, 'timestamp': now_timestamp, 'from_status': old_status, 'status': new_status, 'task_code': task_code, 'lookup_code': this_lookup, 'order_code': sobj.get('order_code'), 'title_code': sobj.get('title_code'), 'process': this_process}) if new_status == COMPLETE: #Record the completion date on the work order, and take it off the BigBoard import datetime now = datetime.datetime.now() timestamp_str = '%s-%s-%s %s:%s:%s' % (now.year, now.month, now.day, now.hour, now.minute, now.second) updict = {'actual_end_date': timestamp_str} if 'WORK_ORDER' in this_lookup: updict['bigboard'] = False server.update(sk, updict) elif new_status not in ['Pending','Ready','Completed'] and 'WORK_ORDER' in this_lookup: server.update(server.build_search_key('sthpw/task', proj.get('task_code')), {'status': new_status}) #NEW if 'PROJ' in sobj.get('lookup_code'): #MTM: This annoying section is for passing Proj's their task's status. #I don't know if this is needed at all anymore. Will have to check other triggers and reports. #The "tripwire" stuff was just to keep it from infinitely passing statuses from proj to task, task to proj do_it = True if 'tripwire' in update_data.keys(): if update_data.get('tripwire') == 'No Send Back': #? do_it = False server.update(input.get('search_key'), {'tripwire': ''}, triggers=False) #Empty the tripwire and do nothing server.update(proj.get('__search_key__'), {'tripwire': '', 'status': sobj.get('status')}, triggers=False) #? if do_it: if proj: server.update(proj.get('__search_key__'), {'status': new_status}) if title.get('priority_triggers') != 'No': #Update Title Priority for On Hold Status, or having that status removed -- BEGIN if sobj.get('status') in ['On_Hold','On Hold']: title_priority = title.get('priority') server.update(title.get('__search_key__'), {'saved_priority': title_priority, 'priority': 200}, triggers=False) else: if old_status in ['On_Hold','On Hold']: saved_priority = title.get('saved_priority') server.update(title.get('__search_key__'), {'priority': saved_priority}, triggers=False) #Update Title Priority for On Hold Status, or having that status removed -- END #Update Title Priority for Client Response Status, or having that status removed -- BEGIN if sobj.get('status') == 'Client Response': title_priority = title.get('priority') crc = title.get('client_response_count') crc_num = 0 if crc not in [None,'']: crc_num = int(crc) crc_num = crc_num + 1 server.update(title.get('__search_key__'), {'saved_priority': title_priority, 'priority': 300, 'client_response_count': crc_num}, triggers=False) else: if old_status == 'Client Response': saved_priority = title.get('saved_priority') crc = title.get('client_response_count') crc_num = 0 if crc not in [None,'']: crc_num = int(crc) if crc_num > 0: crc_num = crc_num - 1 server.update(title.get('__search_key__'), {'priority': saved_priority, 'client_response_count': crc_num}, triggers=False) #Update Title Priority for Client Response Status, or having that status removed -- END if sobj.get('status') in ['In_Progress','In Progress','DR In_Progress','DR In Progress', 'Amberfin01_In_Progress', 'Amberfin01 In Progress', 'Amberfin02_In_Progress', 'Amberfin02 In Progress','BATON In_Progress','BATON In Progress','Export In_Progress','Export In Progress','Buddy Check In_Progress','Buddy Check In Progress','Need Buddy Check','Completed'] and old_status not in ['In_Progress','DR In_Progress','DR In Progress','Amberfin01_In_Progress','Amberfin01 In Progress', 'Amberfin02_In_Progress','Amberfin02 In Progress','BATON In_Progress','BATON In Progress','Export In_Progress','Export In Progress','Buddy Check In_Progress','Buddy Check In Progress','Need Buddy Check','In Progress']: #Update the actual start date if they just set the status to 'In Progress' if sobj.get('actual_start_date') in ['',None]: now_timestamp = make_timestamp() server.update(sk, {'actual_start_date': now_timestamp}) if sobj.get('status') in ['Ready','In_Progress','In Progress'] and 'WORK_ORDER' in sobj.get('lookup_code'): if title.get('client_status') != 'In Production': server.update(title.get('__search_key__'), {'client_status': 'In Production', 'status': 'In Production'}) elif sobj.get('status') in ['Rejected','Fix Needed'] and 'WORK_ORDER' in sobj.get('lookup_code'): from pyasm.biz import Note from pyasm.search import Search server.insert('twog/production_error', {'error_type': sobj.get('status'), 'process': sobj.get('process'), 'work_order_code': sobj.get('lookup_code'), 'title': title.get('title'), 'episode': title.get('episode'), 'title_code': title.get('code'), 'order_code': order.get('code'), 'order_name': order.get('name'), 'po_number': order.get('po_number'), 'proj_code': proj.get('code'), 'scheduler_login': sobj.get('creator_login'), 'operator_login': user_name, 'login': user_name}) if sobj.get('status') == 'Rejected': server.update(title.get('__search_key__'), {'client_status': 'QC Rejected'}) if title.get('priority_triggers') != 'No': server.update(title.get('__search_key__'), {'priority': 90}, triggers=False) title_obj2 = Search.get_by_search_key(title.get('__search_key__')) #This is the type of object required for Note creation note_text = '%s (%s) has been Rejected, as marked by %s' % (sobj.get('process'), this_lookup, user_name) note = Note.create(title_obj2, note_text, context='QC Rejected', process='QC Rejected') if sobj.get('status') == COMPLETE and title.get('status_triggers') != 'No': # Now we need to set the next task(s) statuses to 'Ready' parent = server.get_parent(sk) # Get all process information from the pipeline regarding processes linked to this process in the normal pipeline info = server.get_pipeline_processes_info(parent.get('__search_key__'), related_process=this_process) input_processes = info.get('input_processes') output_processes = info.get('output_processes') # this combines all other input_processes and this process # including this_process in case this process has more than 1 task ready = False if input_processes: input_processes.append(this_process) ready = True input_tasks = server.query('sthpw/task', filters = [('search_type', sobj.get('search_type')), ('search_id', sobj.get('search_id')), ('process', input_processes), ('title_code',sobj.get('title_code'))]) for task in input_tasks: if task.get('status') != COMPLETE: ready = False else: ready = True #Now we need to check the manually entered work orders and projs #This section may be replaced with the are_no_hackpipes_preceding function, but for the sake of stability, I won't do it until I test it again hack_outs_expr = "@SOBJECT(twog/hackpipe_out['out_to','%s'])" % sobj.get('lookup_code') hack_outs = server.eval(hack_outs_expr) stype = '' stype_st = '' if 'PROJ' in sobj.get('lookup_code'): stype = 'PROJ' stype_st = 'twog/proj' elif 'WORK_ORDER' in sobj.get('lookup_code'): stype = 'WORK_ORDER' stype_st = 'twog/work_order' for ho in hack_outs: lookup_code = ho.get('lookup_code') if stype in lookup_code: hacktasks = server.eval("@SOBJECT(sthpw/task['lookup_code','%s'])" % lookup_code) for hacktask in hacktasks: if hacktask.get('status') != COMPLETE: ready = False # make the next process ready if ready == True: output_tasks = server.query('sthpw/task', filters = [('search_type', sobj.get('search_type')), ('search_id', sobj.get('search_id')), ('process', output_processes), ('title_code',sobj.get('title_code'))]) update_data = {} for task in output_tasks: if task.get('lookup_code') not in [None,'']: if task.get('status') == 'Pending': #Need to make sure other tasks leading into this one (an output task for the triggered task) are also complete - both ways, with pipeline and hackpipe - before allowing this status update out_info = server.get_pipeline_processes_info(parent.get('__search_key__'), related_process=task.get('process')) input_to_out = out_info.get('input_processes') if this_process in input_to_out: prc_idx = input_to_out.index(this_process) input_to_out.pop(prc_idx) ready2 = False if input_to_out: #input_to_out.append(task.get('process')) ts_st = '' if 'PROJ' in task.get('lookup_code'): ts_st = 'twog/proj' elif 'WORK_ORDER' in task.get('lookup_code'): ts_st = 'twog/work_order' tsob = server.eval("@SOBJECT(%s['code','%s'])" % (ts_st, task.get('lookup_code')))[0] ready2 = are_no_hackpipes_preceding(tsob, sobj.get('lookup_code')) into_out_tasks = server.query('sthpw/task', filters = [('search_type', task.get('search_type')), ('search_id', task.get('search_id')), ('process', input_to_out)]) for iotask in into_out_tasks: # If preceding tasks have not yet been set to 'Completed', do not change the next task's status if iotask.get('status') != COMPLETE: ready2 = False else: ready2 = True hacks_expr = "@SOBJECT(twog/hackpipe_out['out_to','%s'])" % task.get('lookup_code') hacks = server.eval(hacks_expr) for hack in hacks: lu_code = hack.get('lookup_code') hacktasks = server.eval("@SOBJECT(sthpw/task['lookup_code','%s'])" % lu_code) for hacktask in hacktasks: if hacktask.get('status') != COMPLETE: ready2 = False if ready2 == True: update_data[task.get('__search_key__')] = { 'status': READY } if 'PROJ' in task.get('lookup_code'): get_proj_expr = "@SOBJECT(twog/proj['code','%s'])" % task.get('lookup_code') proj = server.eval(get_proj_expr)[0] # FIND ALL NON HACK WOS wos = server.eval("@SOBJECT(twog/work_order['proj_code','%s'])" % proj.get('code')) for wo in wos: if wo.get('creation_type') not in ['hackpipe','hackup']: this_processer = wo.get('process') info2 = server.get_pipeline_processes_info(proj.get('__search_key__'), related_process=this_processer) input_processes2 = info2.get('input_processes') okayed = are_no_hackpipes_preceding(wo, sobj.get('lookup_code')) len_proc = 0 if input_processes2 not in ['',{},[],None]: len_proc = len(input_processes2) if len_proc < 1 and okayed: task2 = server.eval("@SOBJECT(sthpw/task['code','%s'])" % wo.get('task_code')) if task2: task2 = task2[0] if task2.get('status') == 'Pending': server.update(task2.get('__search_key__'), {'status': READY}) #? # FIND ALL HACK WOS HERE......... hack_dudes = server.eval("@SOBJECT(twog/hackpipe_out['lookup_code','%s'])" % proj.get('code')) for ho in hack_dudes: ready3 = True out_to = ho.get('out_to') label = '' if 'PROJ' in out_to: label = 'twog/proj' elif 'WORK_ORDER' in out_to: label = 'twog/work_order' sob_guy = server.eval("@SOBJECT(%s['code','%s'])" % (label, out_to)) for sobby in sob_guy: ready3 = are_no_hackpipes_preceding(sobby, sobj.get('lookup_code')) if ready3: htask = server.eval("@SOBJECT(sthpw/task['lookup_code','%s'])" % out_to) if htask: htask = htask[0] if htask.get('status') == 'Pending': server.update(htask.get('__search_key__'), {'status': READY}) hackers = server.eval("@SOBJECT(twog/hackpipe_out['lookup_code','%s'])" % sobj.get('lookup_code')) for hack in hackers: if stype in hack.get('out_to'): out_to = hack.get('out_to') out_sob = server.eval("@SOBJECT(%s['code','%s'])" % (stype_st, out_to)) if out_sob: out_sob = out_sob[0] ready4 = are_no_hackpipes_preceding(out_sob, sobj.get('lookup_code')) if ready4: tasker = server.eval("@SOBJECT(sthpw/task['code','%s'])" % out_sob.get('task_code')) if tasker: tasker = tasker[0] if tasker.get('status') == 'Pending': server.update(tasker.get('__search_key__'), {'status': READY}) if stype == 'PROJ': # Need to do the same thing here, looking at pipeline and hackpipe hack_wos = server.eval("@SOBJECT(twog/hackpipe_out['lookup_code','%s'])" % out_to) for hos in hack_wos: if 'PROJ' not in hos.get('out_to'): ho_wo = server.eval("@SOBJECT(twog/work_order['code','%s'])" % hos.get('out_to')) if ho_wo: ho_wo = ho_wo[0] ready5 = are_no_hackpipes_preceding(ho_wo, out_sob.get('code')) if ready5: ho_wo_task_sk = server.build_search_key('sthpw/task', ho_wo.get('task_code')) #7/10/2014 --- WAIT. WTF. THERE IS NO STATUS ON WOS, JUST THE TASK..... MTMMTMMTM!!! if ho_wo.get('status') == 'Pending': server.update(ho_wo_task_sk, {'status': READY}) # NEED TO LOOK AT PROJ PIPELINE NOW proj_sk = server.build_search_key('twog/proj', out_to) pipe_wos = server.eval("@SOBJECT(twog/work_order['proj_code','%s'])" % out_to) for pwos in pipe_wos: if pwos.get('creation_type') not in ['hackpipe','hackup']: info2 = server.get_pipeline_processes_info(proj_sk, related_process=pwos.get('process')) if 'input_processes' in info2.keys(): input_processes2 = info2.get('input_processes') whack_says = are_no_hackpipes_preceding(pwos, out_to) # If there are no input processes, it must be a work order that should also be set to ready - as long as hackpipe says it's ok len_proc2 = 0 if input_processes2 not in ['',{},[],None]: len_proc2 = len(input_processes2) if len_proc2 < 1 and whack_says: wtask_code = pwos.get('task_code') # Get the task sobject associated with this work order wtask = server.eval("@SOBJECT(sthpw/task['code','%s'])" % wtask_code) if wtask: wtask = wtask[0] # If the task's status has not been touched yet ('Pending') and active is set to true, update the status with 'Ready' if wtask.get('status') == 'Pending': wdata = {} wdata['status'] = 'Ready' if wtask.get('status') == 'Pending': server.update(wtask.get('__search_key__'), wdata) # # HERE NEED TO FIND ANY OTHER TASKS THIS GOES 'OUT_TO' and make sure they don't also depend on another task's status (if so, make sure it is completed) # # this is optional, for simplicity, turn off triggers for these updates if update_data != {} and title.get('priority_triggers') != 'No': #make title priority the proj priority, if proj is becoming "Ready" for tkey in update_data.keys(): record = update_data.get(tkey) tkcode = tkey.split('code=')[1] if 'status' in record.keys(): if record.get('status') == 'Ready': ttt = server.eval("@GET(sthpw/task['code','%s'].lookup_code)" % tkcode)[0] if 'PROJ' in ttt: pjj = server.eval("@SOBJECT(twog/proj['code','%s'])" % ttt)[0] proj_title_code = pjj.get('title_code') proj_prio = pjj.get('priority') server.update(server.build_search_key('twog/title',proj_title_code), {'priority': proj_prio}, triggers=False) server.update_multiple(update_data, triggers=False) #? Should triggers=False? # Now see if all wos under proj or all projs under title are completed. If so, make their parent's status completed all_wos_completed = False all_wos_pending = False prj = None if new_status in [COMPLETE,PENDING]: if 'WORK_ORDER' in this_lookup: wo = server.eval("@SOBJECT(twog/work_order['code','%s'])" % sobj.get('lookup_code')) wo = wo[0] other_wotasks_expr = "@SOBJECT(twog/proj['code','%s'].twog/work_order.WT:sthpw/task)" % wo.get('proj_code') other_wo_tasks = server.eval(other_wotasks_expr) all_wos_completed = True all_wos_pending = True if new_status == PENDING: all_wos_completed = False else: all_wos_pending = False for owt in other_wo_tasks: if owt.get('lookup_code') != wo.get('code'): if owt.get('status') != COMPLETE: all_wos_completed = False if owt.get('status') != PENDING: all_wos_pending = False prj = server.eval("@SOBJECT(twog/proj['code','%s'])" % wo.get('proj_code')) if len(prj) > 0: prj = prj[0] else: prj = None if (all_wos_completed or all_wos_pending) and prj not in [None,'']: if title.get('status_triggers') != 'No' or all_wos_pending == True: prj_task = server.eval("@SOBJECT(sthpw/task['lookup_code','%s'])" % prj.get('code')) if prj_task: prj_task = prj_task[0] server.update(prj_task.get('__search_key__'), {'status': new_status}) elif 'PROJ' in this_lookup: prj = server.eval("@SOBJECT(twog/proj['code','%s'])" % this_lookup) if prj: prj = prj[0] else: prj = None all_projs_completed = True all_projs_pending = True all_titles_completed = False all_titles_pending = False if prj not in [None,'']: title_proj_tasks = server.eval("@SOBJECT(twog/title['code','%s'].twog/proj.PT:sthpw/task)" % prj.get('title_code')) for tpt in title_proj_tasks: if tpt.get('status') != COMPLETE: all_projs_completed = False if tpt.get('status') != PENDING: all_projs_pending = False title_updated = False if all_projs_completed: title_sk = server.build_search_key('twog/title', prj.get('title_code')) if title.get('priority_triggers') != 'No' and title.get('status_triggers') != 'No': server.update(title_sk, {'status': COMPLETE, 'bigboard': False, 'priority': 5000}) titles_completed = order.get('titles_completed') title_codes_completed = order.get('title_codes_completed') if title.get('code') not in title_codes_completed: if titles_completed in [None,'']: titles_completed = 0 else: titles_completed = int(titles_completed) titles_completed = titles_completed + 1 if title_codes_completed == '': title_codes_completed = title.get('code') else: title_codes_completed = '%s,%s' % (title_codes_completed, title.get('code')) server.update(order.get('__search_key__'), {'titles_completed': titles_completed, 'title_codes_completed': title_codes_completed}) title_updated = True all_titles_completed = True title = server.eval("@SOBJECT(twog/title['code','%s'])" % prj.get('title_code')) if title and title_updated: title = title[0] other_titles = server.eval("@SOBJECT(twog/order['code','%s'].twog/title)" % title.get('order_code')) for ot in other_titles: if title.get('code') != ot.get('code'): if ot.get('status') != COMPLETE: all_titles_completed = False else: all_titles_completed = False if all_projs_pending: title_sk = server.build_search_key('twog/title', prj.get('title_code')) if title.get('priority_triggers') != 'No' and title.get('status_triggers') != 'No': server.update(title_sk, {'status': '', 'bigboard': False}) title_codes_completed = order.get('title_codes_completed') if title.get('code') in title_codes_completed: title_codes_completed = title_codes_completed.replace(',%s' % title.get('code'),'').replace('%s,' % title.get('code'),'').replace('%s' % title.get('code'),'') titles_completed = order.get('titles_completed') if titles_completed in [None,'']: titles_completed = 0 else: titles_completed = int(titles_completed) - 1 server.update(order.get('__search_key__'), {'titles_completed': titles_completed, 'title_codes_completed': title_codes_completed}) title_updated = True all_titles_pending = True title = server.eval("@SOBJECT(twog/title['code','%s'])" % prj.get('title_code')) if title and title_updated: title = title[0] other_titles = server.eval("@SOBJECT(twog/order['code','%s'].twog/title)" % title.get('order_code')) for ot in other_titles: if title.get('code') != ot.get('code'): if ot.get('status') != '': all_titles_pending = False else: all_titles_pending = False if all_titles_pending: server.update(server.build_search_key('twog/order', title.get('order_code')), {'needs_completion_review': False}) if all_titles_completed: server.update(server.build_search_key('twog/order', title.get('order_code')), {'needs_completion_review': True}) #print "LEAVING KICKOFF" except AttributeError as e: traceback.print_exc() print str(e) + '\nMost likely the server object does not exist.' raise e except KeyError as e: traceback.print_exc() print str(e) + '\nMost likely the input dictionary does not exist.' raise e except Exception as e: traceback.print_exc() print str(e) raise e
def get_message(my): search_type_obj = my.parent.get_search_type_obj() title = search_type_obj.get_title() subject = my.get_subject() notification_message = my.notification.get_value("message") message = "%s %s Note Entry" % (title, my.parent.get_name()) if notification_message: message = "%s (%s)" %(message, notification_message) submit_desc = '' from pyasm.prod.biz import Submission if isinstance(my.parent, Submission): update_info = [''] # add more info about the file and bin snapshot = Snapshot.get_latest_by_sobject(my.parent, "publish") xpath = "snapshot/file[@type='main']" xml = snapshot.get_xml_value('snapshot') file = None if xml.get_node(xpath) is not None: file = my._get_file_obj(snapshot) else: snapshots = snapshot.get_all_ref_snapshots() snapshot_file_objects = [] if snapshots: snapshot = snapshots[0] file = my._get_file_obj(snapshot, type=None) if file: file_name = file.get_file_name() web_path = file.get_web_path() from pyasm.web import WebContainer host = WebContainer.get_web().get_base_url() update_info.append('Browse: %s %s%s' %( file_name, host.to_string(), web_path)) bins = my.parent.get_bins() bin_labels = [ bin.get_label() for bin in bins] update_info.append('Bin: %s' %', '.join(bin_labels)) update_info.append('Artist: %s' %my.parent.get_value('artist')) update_info.append('Description: %s' %my.parent.get_value('description')) # get notes search = Note.get_search_by_sobjects([my.parent]) if search: search.add_order_by("context") search.add_order_by("timestamp desc") notes = search.get_sobjects() last_context = None note_list = [] for i, note in enumerate(notes): context = note.get_value('context') # explicit compare to None if last_context == None or context != last_context: note_list.append( "[ %s ] " % context ) last_context = context #child_notes = my.notes_dict.get(note.get_id()) # draw note item date = Date(db=note.get_value('timestamp')) note_list.append('(%s) %s'%(date.get_display_time(), note.get_value("note"))) update_info.append('Notes: \n %s' % '\n'.join(note_list)) submit_desc = '\n'.join(update_info) update_desc = my.sobject.get_update_description() command_desc = my.command.get_description() message = '%s\n\nReport from transaction:\n%s\n\n%s\n%s' \ % (message, update_desc, command_desc, submit_desc) return message
def get_message(my): search_type_obj = my.parent.get_search_type_obj() title = search_type_obj.get_title() subject = my.get_subject() notification_message = my.notification.get_value("message") message = "%s %s Note Entry" % (title, my.parent.get_name()) if notification_message: message = "%s (%s)" % (message, notification_message) submit_desc = '' from pyasm.prod.biz import Submission if isinstance(my.parent, Submission): update_info = [''] # add more info about the file and bin snapshot = Snapshot.get_latest_by_sobject(my.parent, "publish") xpath = "snapshot/file[@type='main']" xml = snapshot.get_xml_value('snapshot') file = None if xml.get_node(xpath) is not None: file = my._get_file_obj(snapshot) else: snapshots = snapshot.get_all_ref_snapshots() snapshot_file_objects = [] if snapshots: snapshot = snapshots[0] file = my._get_file_obj(snapshot, type=None) if file: file_name = file.get_file_name() web_path = file.get_web_path() from pyasm.web import WebContainer host = WebContainer.get_web().get_base_url() update_info.append('Browse: %s %s%s' % (file_name, host.to_string(), web_path)) bins = my.parent.get_bins() bin_labels = [bin.get_label() for bin in bins] update_info.append('Bin: %s' % ', '.join(bin_labels)) update_info.append('Artist: %s' % my.parent.get_value('artist')) update_info.append('Description: %s' % my.parent.get_value('description')) # get notes search = Note.get_search_by_sobjects([my.parent]) if search: search.add_order_by("context") search.add_order_by("timestamp desc") notes = search.get_sobjects() last_context = None note_list = [] for i, note in enumerate(notes): context = note.get_value('context') # explicit compare to None if last_context == None or context != last_context: note_list.append("[ %s ] " % context) last_context = context #child_notes = my.notes_dict.get(note.get_id()) # draw note item date = Date(db=note.get_value('timestamp')) note_list.append( '(%s) %s' % (date.get_display_time(), note.get_value("note"))) update_info.append('Notes: \n %s' % '\n'.join(note_list)) submit_desc = '\n'.join(update_info) update_desc = my.sobject.get_update_description() command_desc = my.command.get_description() message = '%s\n\nReport from transaction:\n%s\n\n%s\n%s' \ % (message, update_desc, command_desc, submit_desc) return message
def main(server=None, input=None): """ The main function of the custom script. The entire script was copied and pasted into the body of the try statement in order to add some error handling. It's all legacy code, so edit with caution. :param server: the TacticServerStub object :param input: a dict with data like like search_key, search_type, sobject, and update_data :return: None """ if not input: input = {} try: # CUSTOM_SCRIPT00091 # # Created by Matthew Misenhimer # def no_incompletes_preceding(new_sob, initial_sob_code): comes_from = new_sob.get('comes_from').split('|^|') for c in comes_from: if initial_sob_code not in c: task_code = c.split(',')[1] task_code = task_code.replace(']', '').replace('[', '') task_status = server.eval("@GET(sthpw/task['code','{0}'].status)".format(task_code))[0] if task_status != 'Completed': return False return True from pyasm.common import TacticException, Environment # input and server are assumed variables # define some constants here COMPLETE = 'Completed' READY = 'Ready' PENDING = 'Pending' sobj = input.get('sobject') # This next statement will basically skip the entire script if the task is a task assigned to onboarding, # asking them to create a workflow/pipeline. Ideally I would disable this entire script, since it's an # incoherent mess, but I can't do that without messing up a bunch of other things. Once the Order/Title/Task # logic has all been updated, then this script can be removed entirely, but until then, this will have to do. if 'Make a Workflow for' in sobj.get('process'): return this_process = sobj.get('process') this_lookup = sobj.get('lookup_code') sk = input.get('search_key') task_code = sobj.get('code') # These are the new values update_data = input.get('update_data') old_status = '' if 'prev_data' in input: # These are the old values prev_data = input.get('prev_data') old_status = prev_data.get('status', '') new_status = update_data.get('status') login = Environment.get_login() user_name = login.get_login() assigned_login_group = sobj.get('assigned_login_group') proj = None title = None order = None if 'PROJ' in this_lookup: # Parent Obj is the Proj attached to the task parent_obj = server.eval("@SOBJECT(twog/proj['code','{0}'])".format(this_lookup))[0] proj = parent_obj title = server.eval("@SOBJECT(twog/title['code','{0}'])".format(parent_obj.get('title_code')))[0] order = server.eval("@SOBJECT(twog/order['code','{0}'])".format(title.get('order_code')))[0] elif 'WORK_ORDER' in this_lookup: # Parent Obj is the Work Order attached to the task parent_obj = server.eval("@SOBJECT(twog/work_order['code','{0}'])".format(this_lookup))[0] work_order = parent_obj proj = server.eval("@SOBJECT(twog/proj['code','{0}'])".format(work_order.get('proj_code')))[0] title = server.eval("@SOBJECT(twog/title['code','{0}'])".format(proj.get('title_code')))[0] order = server.eval("@SOBJECT(twog/order['code','{0}'])".format(title.get('order_code')))[0] if 'PROJ' in this_lookup and title.get('priority_triggers') != 'No': pass elif 'WORK_ORDER' in this_lookup: if new_status == COMPLETE: # Make sure they have set the assigned person to the work order. if sobj.get('assigned') in [None, '']: raise TacticException('Before completing a work order, someone must be assigned to it.') # Make sure they have added work hours. If not, error out. total_time = server.eval("@SUM(sthpw/work_hour['task_code','{0}'].straight_time)".format(task_code)) if total_time < 0.001: # account for floating point inaccuracy raise TacticException('You need to save the hours you worked on this before you can set the status to "Completed".') # This is for the completion ratio on title t_wo_completed = title.get('wo_completed') # This is for the completion ratio on order o_wo_completed = order.get('wo_completed') if new_status == COMPLETE: # This is for a potential alert/exception title_str = title.get('title') if title.get('episode') not in [None, '']: title_str = '{0}: {1}'.format(title_str, title.get('episode')) # Block QC and Edel from completing their work orders if the TRT or TRT w/Textless are not filled in if 'qc' in assigned_login_group or 'edeliveries' in assigned_login_group: total_program_runtime = title.get('total_program_runtime') total_runtime_w_textless = title.get('total_runtime_w_textless') invalid_runtime = total_program_runtime in [None, ''] or total_runtime_w_textless in [None, ''] say_str = '' say_str2 = '' if invalid_runtime: if total_program_runtime in [None, '']: say_str = 'Total Program Runtime has' if total_runtime_w_textless in [None, '']: if say_str == '': say_str = 'Total Runtime With Textless has' else: say_str = '%s and Total Runtime With Textless have' % (say_str[:-4]) say_str2 = "%s (%s)'s %s not been filled. You must enter this data before trying to complete this work order." % (title_str, title.get('code'), say_str) if 'qc' in assigned_login_group: if invalid_runtime: raise TacticException(say_str2) else: # They were filled in, so finish completing the task and send a note from pyasm.biz import Note from pyasm.search import Search # This is the type of object required for Note creation title_obj2 = Search.get_by_search_key(title.get('__search_key__')) note_text = '%s (%s) has been Passed and Completed by %s in QC' % (sobj.get('process'), this_lookup, user_name) note = Note.create(title_obj2, note_text, context='QC Completed', process='QC Completed') elif 'edeliveries' in assigned_login_group and invalid_runtime: raise TacticException(say_str2) t_wo_completed += 1 o_wo_completed += 1 # Update the completion ratios attached, since there were no blocking exceptions server.update(title.get('__search_key__'), {'wo_completed': t_wo_completed}) server.update(order.get('__search_key__'), {'wo_completed': o_wo_completed}) elif old_status == COMPLETE: t_wo_completed -= 1 o_wo_completed -= 1 # Reduce the completion ratio, since it was completed but has now been taken off that status server.update(title.get('__search_key__'), {'wo_completed': t_wo_completed}) server.update(order.get('__search_key__'), {'wo_completed': o_wo_completed}) now_timestamp = make_timestamp() # Since there have been no blocking exceptions, record the status change stat_log_dict = {'login': user_name, 'timestamp': now_timestamp, 'from_status': old_status, 'status': new_status, 'task_code': task_code, 'lookup_code': this_lookup, 'order_code': sobj.get('order_code'), 'title_code': sobj.get('title_code'), 'process': this_process} server.insert('twog/status_log', stat_log_dict) if new_status == COMPLETE: # Record the completion date on the work order, and take it off the BigBoard updict = {'actual_end_date': make_timestamp()} do_indie = False if 'WORK_ORDER' in this_lookup: updict['bigboard'] = False if sobj.get('indie_bigboard') in [True, 'true', 't', 'T', 1]: updict['indie_bigboard'] = False do_indie = True server.update(sk, updict) if do_indie: indies = server.eval("@SOBJECT(twog/indie_bigboard['task_code','{0}'])".format(task_code)) for indie in indies: indie_dict = {'indie_bigboard': False} if indie.get('removal_login') in [None, '']: indie_dict['removal_login'] = user_name if indie.get('removal_login') in [None, '']: indie_dict['removal_timestamp'] = now_timestamp server.update(indie.get('__search_key__'), indie_dict) elif new_status not in ['Pending', 'Ready', 'Completed'] and 'WORK_ORDER' in this_lookup: server.update(server.build_search_key('sthpw/task', proj.get('task_code')), {'status': new_status}) if 'PROJ' in sobj.get('lookup_code'): # MTM: This annoying section is for passing Proj's their task's status. # I don't know if this is needed at all anymore. Will have to check other triggers and reports. # The "tripwire" stuff was just to keep it from infinitely passing statuses from proj to task, task to proj do_it = True if update_data.get('tripwire', '') == 'No Send Back': do_it = False # Empty the tripwire and do nothing server.update(input.get('search_key'), {'tripwire': ''}, triggers=False) server.update(proj.get('__search_key__'), {'tripwire': '', 'status': sobj.get('status')}, triggers=False) if do_it and proj: server.update(proj.get('__search_key__'), {'status': new_status}) if title.get('priority_triggers') != 'No': # Update Title Priority for On Hold Status, or having that status removed -- BEGIN if sobj.get('status') in ['On_Hold', 'On Hold']: title_priority = title.get('priority') server.update(title.get('__search_key__'), {'saved_priority': title_priority, 'priority': 200}, triggers=False) elif old_status in ['On_Hold', 'On Hold']: saved_priority = title.get('saved_priority') server.update(title.get('__search_key__'), {'priority': saved_priority}, triggers=False) # Update Title Priority for On Hold Status, or having that status removed -- END # Update Title Priority for Client Response Status, or having that status removed -- BEGIN if sobj.get('status') == 'Client Response': title_priority = title.get('priority') crc = title.get('client_response_count') crc_num = 0 if crc not in [None, '']: crc_num = int(crc) crc_num += 1 title_update_data = {'saved_priority': title_priority, 'priority': 300, 'client_response_count': crc_num} server.update(title.get('__search_key__'), title_update_data, triggers=False) elif old_status == 'Client Response': saved_priority = title.get('saved_priority') crc = title.get('client_response_count') crc_num = 0 if crc not in [None, '']: crc_num = int(crc) if crc_num > 0: crc_num -= 1 title_update_data = {'priority': saved_priority, 'client_response_count': crc_num} server.update(title.get('__search_key__'), title_update_data, triggers=False) # Update Title Priority for Client Response Status, or having that status removed -- END statuses = ['In_Progress', 'In Progress', 'DR In_Progress', 'DR In Progress', 'Amberfin01_In_Progress', 'Amberfin01 In Progress', 'Amberfin02_In_Progress', 'Amberfin02 In Progress', 'BATON In_Progress', 'BATON In Progress', 'Export In_Progress', 'Export In Progress', 'Buddy Check In_Progress', 'Buddy Check In Progress', 'Need Buddy Check', 'In Review'] if sobj.get('status') in statuses + ['Completed'] and old_status not in statuses: # Update the actual start date if they just set the status to 'In Progress' if sobj.get('actual_start_date') in ['', None]: now_timestamp = make_timestamp() server.update(sk, {'actual_start_date': now_timestamp, 'flag_future_changes': True}) if sobj.get('status') in ['Ready', 'In_Progress', 'In Progress', 'In Review'] and 'WORK_ORDER' in sobj.get('lookup_code'): if title.get('client_status') != 'In Production': server.update(title.get('__search_key__'), {'client_status': 'In Production', 'status': 'In Production'}) elif sobj.get('status') in ['Rejected', 'Fix Needed'] and 'WORK_ORDER' in sobj.get('lookup_code'): from pyasm.biz import Note from pyasm.search import Search prod_error = {'error_type': sobj.get('status'), 'process': sobj.get('process'), 'work_order_code': sobj.get('lookup_code'), 'title': title.get('title'), 'episode': title.get('episode'), 'title_code': title.get('code'), 'order_code': order.get('code'), 'order_name': order.get('name'), 'po_number': order.get('po_number'), 'proj_code': proj.get('code'), 'scheduler_login': sobj.get('creator_login'), 'operator_login': user_name, 'login': user_name} server.insert('twog/production_error', prod_error, triggers=False) if sobj.get('status') == 'Rejected': server.update(title.get('__search_key__'), {'client_status': 'QC Rejected'}) if title.get('priority_triggers') != 'No': server.update(title.get('__search_key__'), {'priority': 90}, triggers=False) status_triggers = proj.get('status_triggers') if status_triggers in [None, '']: status_triggers = title.get('status_triggers') if sobj.get('status') == COMPLETE and status_triggers != 'No': # Now we need to set the next task(s) statuses to 'Ready' goes_to = sobj.get('goes_to').split('|^|') for gt in goes_to: if ',' not in gt: continue next_task_code = gt.split(',')[1].replace('[', '').replace(']', '') nt_expr = "@SOBJECT(sthpw/task['code','{0}'])".format(next_task_code) next_task = server.eval(nt_expr) if next_task: next_task = next_task[0] if next_task.get('status') != 'Pending': continue if no_incompletes_preceding(next_task, task_code): server.update(next_task.get('__search_key__'), {'status': READY}) if 'PROJ' not in next_task.get('lookup_code'): continue oip = next_task.get('order_in_pipe') if oip in [None, '', 0]: oip = 1 else: oip = int(oip) smallest_wo = (oip * 1000) + 10 nwt_expr = "@GET(twog/work_order['proj_code','{0}']['order_in_pipe','<=','{1}'].WT:sthpw/task['status','Pending']['@ORDER_BY','order_in_pipe desc'].__search_key__)" task_search_keys = server.eval(nwt_expr.format(next_task.get('lookup_code'), smallest_wo)) task_update_data = dict.fromkeys(task_search_keys, {'status': READY}) server.update_multiple(task_update_data, triggers=False) # Now see if all wos under proj or all projs under title are completed. # If so, make their parent's status completed prj = None if new_status not in [COMPLETE, PENDING]: return if 'WORK_ORDER' in this_lookup: wo = server.eval("@SOBJECT(twog/work_order['code','{0}'])".format(sobj.get('lookup_code'))) wo = wo[0] other_wotasks_expr = "@SOBJECT(twog/proj['code','{0}'].twog/work_order.WT:sthpw/task)".format(wo.get('proj_code')) other_wo_tasks = server.eval(other_wotasks_expr) all_wos_completed = True all_wos_pending = True if new_status == PENDING: all_wos_completed = False elif new_status == COMPLETE: all_wos_pending = False un_indie = False if sobj.get('indie_bigboard') in [True, 'true', 't', 'T', 1]: un_indie = True for owt in other_wo_tasks: if owt.get('lookup_code') != wo.get('code'): if owt.get('status') != COMPLETE: all_wos_completed = False if owt.get('status') != PENDING: all_wos_pending = False if owt.get('indie_bigboard') in [True, 'true', 't', 'T', 1] and (owt.get('assigned_login_group') == sobj.get('assigned_login_group')): un_indie = False # HERE NEED TO DETERMINE WHICH DEPT THIS WAS FOR AND SEE IF ANY OTHER WOs # IN THE SAME DEPT ARE STILL INDIE. IF NOT, THEN TAKE THE DEPT NAME OUT OF # active_dept_priorities ON THE TITLE if un_indie: that_dept = sobj.get('assigned_login_group').replace(' supervisor', '') adps = title.get('active_dept_priorities') adps = adps.replace(',%s' % that_dept, '').replace('%s,' % that_dept, '').replace(that_dept, '') indie_data = {'active_dept_priorities': adps} prio_name = '%s_priority' % that_dept.replace(' ', '_') indie_data[prio_name] = title.get('priority') server.update(title.get('__search_key__'), indie_data) prj = server.eval("@SOBJECT(twog/proj['code','{0}'])".format(wo.get('proj_code'))) prj = prj[0] if prj else None if (all_wos_completed or all_wos_pending) and prj not in [None, '']: prj_task = server.eval("@SOBJECT(sthpw/task['lookup_code','{0}'])".format(prj.get('code'))) if prj_task: server.update(prj_task[0].get('__search_key__'), {'status': new_status}) elif 'PROJ' in this_lookup: prj = server.eval("@SOBJECT(twog/proj['code','{0}'])".format(this_lookup)) prj = prj[0] if prj else None all_projs_completed = True all_projs_pending = True all_titles_completed = False all_titles_pending = False if prj in [None, '']: return title_proj_tasks = server.eval("@SOBJECT(twog/title['code','{0}'].twog/proj.PT:sthpw/task)".format(prj.get('title_code'))) for tpt in title_proj_tasks: if tpt.get('status') != COMPLETE: all_projs_completed = False if tpt.get('status') != PENDING: all_projs_pending = False title_updated = False if all_projs_completed: title_sk = server.build_search_key('twog/title', prj.get('title_code')) server.update(title_sk, {'status': COMPLETE, 'client_status': COMPLETE, 'bigboard': False, 'priority': 5000}) titles_completed = order.get('titles_completed') title_codes_completed = order.get('title_codes_completed') if title.get('code') not in title_codes_completed: if titles_completed in [None, '']: titles_completed = 0 else: titles_completed = int(titles_completed) titles_completed += 1 if title_codes_completed == '': title_codes_completed = title.get('code') else: title_codes_completed = '%s,%s' % (title_codes_completed, title.get('code')) server.update(order.get('__search_key__'), {'titles_completed': titles_completed, 'title_codes_completed': title_codes_completed}) title_updated = True all_titles_completed = True title = server.eval("@SOBJECT(twog/title['code','{0}'])".format(prj.get('title_code'))) if title and title_updated: title = title[0] other_titles = server.eval("@SOBJECT(twog/order['code','{0}'].twog/title)".format(title.get('order_code'))) for ot in other_titles: if title.get('code') != ot.get('code') and ot.get('status') != COMPLETE: all_titles_completed = False break else: all_titles_completed = False if all_projs_pending: title_sk = server.build_search_key('twog/title', prj.get('title_code')) if title.get('priority_triggers') != 'No' and title.get('status_triggers') != 'No': server.update(title_sk, {'status': '', 'bigboard': False}) title_codes_completed = order.get('title_codes_completed') if title.get('code') in title_codes_completed: title_codes_completed = title_codes_completed.replace(',%s' % title.get('code'), '').replace('%s,' % title.get('code'), '').replace('%s' % title.get('code'), '') titles_completed = order.get('titles_completed') if titles_completed in [None, '']: titles_completed = 0 else: titles_completed = int(titles_completed) - 1 server.update(order.get('__search_key__'), {'titles_completed': titles_completed, 'title_codes_completed': title_codes_completed}) title_updated = True all_titles_pending = True title = server.eval("@SOBJECT(twog/title['code','{0}'])".format(prj.get('title_code'))) if title and title_updated: title = title[0] other_titles = server.eval("@SOBJECT(twog/order['code','{0}'].twog/title)".format(title.get('order_code'))) for ot in other_titles: if title.get('code') != ot.get('code') and ot.get('status') != '': all_titles_pending = False break else: all_titles_pending = False if all_titles_pending: server.update(server.build_search_key('twog/order', title.get('order_code')), {'needs_completion_review': False}) if all_titles_completed: server.update(server.build_search_key('twog/order', title.get('order_code')), {'needs_completion_review': True}) except AttributeError as e: traceback.print_exc() print str(e) + '\nMost likely the server object does not exist.' raise e except KeyError as e: traceback.print_exc() print str(e) + '\nMost likely the input dictionary does not exist.' raise e except Exception as e: traceback.print_exc() print str(e) raise e
def main(server=None, input=None): """ The main function of the custom script. The entire script was copied and pasted into the body of the try statement in order to add some error handling. It's all legacy code, so edit with caution. :param server: the TacticServerStub object :param input: a dict with data like like search_key, search_type, sobject, and update_data :return: None """ if not input: input = {} try: # CUSTOM_SCRIPT00101 def make_timestamp(): from pyasm.common import SPTDate #Makes a Timestamp for postgres import datetime now = SPTDate.convert_to_local(datetime.datetime.now()) return now sobject = input.get('sobject') update_data = input.get('update_data') sk = sobject.get('__search_key__') if 'is_external_rejection' in update_data.keys(): from pyasm.biz import Note from pyasm.search import Search title_name = sobject.get('title') if sobject.get('episode') not in [None,'']: title_name = '%s: %s' % (title_name, sobject.get('episode')) title_obj = Search.get_by_search_key(sk) #Need this kind of object to make the note we'll be sending is_external_rejection = update_data.get('is_external_rejection') if is_external_rejection == 'true': non_rejected_titles = server.eval("@SOBJECT(twog/title['bigboard','True']['is_external_rejection','false']['status','!=','Completed']['@ORDER_BY','priority asc'])") smaller = .05 if len(non_rejected_titles) > 0: smallest_prio = non_rejected_titles[0].get('priority') smaller = float(float(smallest_prio)/2) el_timeo = make_timestamp() #Set priority to something smaller than all non-externally-rejected titles on the bigboard #Set due date and deliver by date to today's date #Set bigboard to true and put all WOs on bigboard server.update(sk, {'priority': smaller, 'bigboard': True, 'due_date': el_timeo, 'expected_delivery_date': el_timeo}) all_tasks = server.eval("@SOBJECT(sthpw/task['title_code','%s'])" % sobject.get('code')) for task in all_tasks: server.update(task.get('__search_key__'), {'bigboard': True}, triggers=False) #Now make the note note = "%s (%s) was rejected externally.\nThis title has been put on the bigboard and it's due & expected delivery dates have been set to today.\nPlease do all you can to get this title back out to the client by the end of the day.\n\nReason provided for External Rejection: %s\n\nOrder Code = %s\nTitle Code = %s" % (title_name, sobject.get('code'), sobject.get('external_rejection_reason'), sobject.get('order_code'), sobject.get('code')) note2 = Note.create(title_obj, note, context='Received External Rejection', process='Received External Rejection') sources_str = '' source_links = server.eval("@SOBJECT(twog/title_origin['title_code','%s'])" % title_obj.get_code()) for s in source_links: source = server.eval("@SOBJECT(twog/source['code','%s'])" % s.get('source_code')) if source: source = source[0] source_fn = source.get('title') if source.get('episode') not in [None,'']: source_fn = '%s: %s' % (source_fn, source.get('episode')) if sources_str == '': sources_str = '%s (%s) Barcode: %s' % (source.get('code'), source_fn, source.get('barcode')) else: sources_str = '%s\n%s (%s) Barcode: %s' % (sources_str, source.get('code'), source_fn, source.get('barcode')) server.insert('twog/external_rejection', {'order_code': title_obj.get_value('order_code'), 'order_name': title_obj.get_value('order_name'), 'status': 'Open', 'reported_issue': sobject.get('external_rejection_reason'), 'title_code': title_obj.get_code(), 'scheduler_reason': sobject.get('external_rejection_reason'), 'title': title_obj.get_value('title'), 'episode': title_obj.get_value('episode'), 'po_number': title_obj.get('po_number'), 'email_list': '', 'sources': sources_str}) else: #DO THE OPPOSITE AS ABOVE saved_priority = sobject.get('saved_priority') server.update(sk, {'bigboard': False, 'priority': saved_priority}) note = "%s (%s) had been marked as rejected externally, but this may have been in error. It is no longer marked as rejected externally.\nThis title has been removed from the bigboard, but it's due & expected delivery dates may still be set to today's date (might need to be addressed).\nOrder Code = %s\nTitle Code = %s" % (title_name, sobject.get('code'), sobject.get('order_code'), sobject.get('code')) note2 = Note.create(title_obj, note, context='External Rejection Mark Removed', process='External Rejection Mark Removed') except AttributeError as e: traceback.print_exc() print str(e) + '\nMost likely the server object does not exist.' raise e except KeyError as e: traceback.print_exc() print str(e) + '\nMost likely the input dictionary does not exist.' raise e except Exception as e: traceback.print_exc() print str(e) raise e
def main(server=None, input=None): """ The main function of the custom script. The entire script was copied and pasted into the body of the try statement in order to add some error handling. It's all legacy code, so edit with caution. :param server: the TacticServerStub object :param input: a dict with data like like search_key, search_type, sobject, and update_data :return: None """ if not input: input = {} try: # CUSTOM_SCRIPT00078 from pyasm.common import Environment from pyasm.biz import Note from pyasm.search import Search import common_tools.utils as ctu login = Environment.get_login() user_name = login.get_login() delim = '#Xs*' all_ccs = '[email protected]%[email protected]' % delim #This is for production_error operator_description update sobject = input.get('sobject') operator_description = sobject.get('operator_description') title_code = sobject.get('title_code') wo_code = sobject.get('work_order_code') title_id_pre = title_code.split('TITLE')[1] found_non_zero = False title_id = '' note = '' for ch in title_id_pre: if ch != '0': found_non_zero = True if ch == '0' and found_non_zero or (ch != '0'): title_id = '%s%s' % (title_id, ch) wo_code = sobject.get('work_order_code') expr = "@SOBJECT(sthpw/note['search_id','%s']['search_type','~','twog/title']['process','QC Rejected']['@ORDER_BY','timestamp desc'])" % (title_id) last_note = server.eval(expr) if last_note: last_note = last_note[0] # Now just need to update it with the operator description, wo code and title note = last_note.get('note') note = '%s\n%s' % (note, operator_description) server.update(last_note.get('__search_key__'), {'note': note}, triggers=False) wo_obj2 = Search.get_by_search_key(server.build_search_key('twog/work_order',wo_code)) #This is the type of object required for Note creation note2 = Note.create(wo_obj2, note, context='QC Rejected', process='QC Rejected') wo = server.eval("@SOBJECT(twog/work_order['code','%s'])" % wo_code)[0] proj = server.eval("@SOBJECT(twog/proj['code','%s'])" % wo.get('proj_code'))[0] title = server.eval("@SOBJECT(twog/title['code','%s'])" % proj.get('title_code'))[0] order = server.eval("@SOBJECT(twog/order['code','%s'])" % title.get('order_code'))[0] scheduler_name = order.get('login') scheduler = server.eval("@SOBJECT(sthpw/login['login','%s']['location','internal'])" % scheduler_name) if scheduler: scheduler = scheduler[0] all_ccs = '%s%s%s' % (all_ccs, delim, scheduler.get('email')) group = '' process = '' client_name = '' po_number = order.get('po_number') order_name = order.get('name') title_name = title.get('title') episode = title.get('episode') if wo: group = wo.get('work_group') process = wo.get('process') client_name = wo.get('client_name') error_type = sobject.get('error_type') rejection_cause = sobject.get('rejection_cause') time_spent = sobject.get('time_spent') client_description = sobject.get('client_description') client_description = client_description.replace('\t',' ') client_description = client_description.replace('\n','<br/>') client_description = client_description.replace(' ', ' ') operator_description = operator_description.replace('\t',' ') operator_description = operator_description.replace('\n','<br/>') operator_description = operator_description.replace(' ', ' ') action_taken = sobject.get('action_taken') order_builder_url = ctu.get_order_builder_url(order.get('code'), server) href = '<a href="{0}">{1}</a>' order_hyperlink = href.format(order_builder_url, order_name) title_row = '' proj_row = '' if title: full_title = title.get('title') if title.get('episode') not in [None,'']: full_title = '%s: %s' % (full_title, title.get('episode')) title_row = "<tr><td align='left' style='color: #06C; font-size: 16px;'>Title: <strong>%s</strong> | Title Code: <strong>%s</strong></td></tr>" % (full_title, title.get('code')) if proj: proj_row = "<tr><td align='left' style='color: #06C; font-size: 16px;'>Project: <strong>%s</strong> | Project Code: <strong>%s</strong></td></tr>" % (proj.get('process'), proj.get('code')) template_path = '/opt/spt/custom/formatted_emailer/error_msg.html' filled_in_path = '/var/www/html/formatted_emails/error_msg_%s.html' % wo_code template = open(template_path, 'r') filled = '' for line in template: line = line.replace('[WORK_ORDER_CODE]', wo_code) line = line.replace('[TITLE_CODE]', title.get('code')) line = line.replace('[PROJ_CODE]', proj.get('code')) line = line.replace('[TITLE_ROW]', title_row) line = line.replace('[PROJ_ROW]', proj_row) line = line.replace('[ORDER_CODE]', order.get('code')) line = line.replace('[LOGIN]', user_name) line = line.replace('[GROUP]', group) line = line.replace('[PROCESS]', process) line = line.replace('[CLIENT_NAME]', client_name) line = line.replace('[PO_NUMBER]', po_number) line = line.replace('[ORDER_NAME]', order_hyperlink) line = line.replace('[TITLE]', title_name) line = line.replace('[EPISODE]', episode) line = line.replace('[ERROR_TYPE]', error_type) line = line.replace('[REJECTION_CAUSE]', rejection_cause) line = line.replace('[TIME_SPENT]', time_spent) line = line.replace('[CLIENT_DESCRIPTION]', client_description) line = line.replace('[OPERATOR_DESCRIPTION]', operator_description) line = line.replace('[ACTION_TAKEN]', action_taken) filled = '%s%s' % (filled, line) template.close() filler = open(filled_in_path, 'w') filler.write(filled) filler.close() server.insert('twog/bundled_message', {'filled_in_path': filled_in_path, 'message': 'New Error', 'from_email': '*****@*****.**', 'to_email': '*****@*****.**', 'from_name': 'Tech Alert', 'subject': 'Error: %s, %s, %s: %s' % (wo_code, po_number, title_name, episode), 'all_ccs': all_ccs, 'object_code': wo_code}) except AttributeError as e: traceback.print_exc() print str(e) + '\nMost likely the server object does not exist.' raise e except KeyError as e: traceback.print_exc() print str(e) + '\nMost likely the input dictionary does not exist.' raise e except Exception as e: traceback.print_exc() print str(e) raise e
def main(server=None, input=None): """ The main function of the custom script. The entire script was copied and pasted into the body of the try statement in order to add some error handling. It's all legacy code, so edit with caution. :param server: the TacticServerStub object :param input: a dict with data like like search_key, search_type, sobject, and update_data :return: None """ if not input: input = {} try: # CUSTOM_SCRIPT00091 # # Created by Matthew Misenhimer # def make_timestamp(): from pyasm.common import SPTDate #Makes a Timestamp for postgres import datetime now = SPTDate.convert_to_local(datetime.datetime.now()) return now def no_incompletes_preceding(new_sob, initial_sob_code): comes_from = new_sob.get('comes_from').split('|^|') ret_val = True for c in comes_from: if initial_sob_code not in c: task_code = c.split(',')[1] task_code = task_code.replace(']','').replace('[','') task_status = server.eval("@GET(sthpw/task['code','%s'].status)" % task_code)[0] if task_status != 'Completed': ret_val = False return ret_val return ret_val from pyasm.common import TacticException, Environment # input and server are assumed variables # define some contants here #print "\n\nIN KICKOFF input = %s" % input COMPLETE = 'Completed' READY = 'Ready' PENDING = 'Pending' sobj = input.get('sobject') this_process = sobj.get('process') this_lookup = sobj.get('lookup_code') sk = input.get('search_key') task_code = sobj.get('code') update_data = input.get('update_data') #These are the new values #print "UPDATE DATA = %s" % update_data prev_data = {} old_status = '' if 'prev_data' in input.keys(): prev_data = input.get('prev_data') #These are the old values if 'status' in prev_data.keys(): old_status = prev_data.get('status') new_status = update_data.get('status') login = Environment.get_login() user_name = login.get_login() assigned_login_group = sobj.get('assigned_login_group') #print "STATUS = %s, ALG = %s" % (new_status, assigned_login_group) parent_obj = None proj = None title = None order = None if 'PROJ' in this_lookup: parent_obj = server.eval("@SOBJECT(twog/proj['code','%s'])" % this_lookup)[0] #Parent Obj is the Proj attached to the task proj = parent_obj title = server.eval("@SOBJECT(twog/title['code','%s'])" % parent_obj.get('title_code'))[0] order = server.eval("@SOBJECT(twog/order['code','%s'])" % title.get('order_code'))[0] elif 'WORK_ORDER' in this_lookup: parent_obj = server.eval("@SOBJECT(twog/work_order['code','%s'])" % this_lookup)[0] #Parent Obj is the Work Order attached to the task work_order = parent_obj proj = server.eval("@SOBJECT(twog/proj['code','%s'])" % work_order.get('proj_code'))[0] title = server.eval("@SOBJECT(twog/title['code','%s'])" % proj.get('title_code'))[0] order = server.eval("@SOBJECT(twog/order['code','%s'])" % title.get('order_code'))[0] #print "PARENT = %s" % parent_obj #print "TITLE = %s" % title #print "ORDER = %s" % order if 'PROJ' in this_lookup and title.get('priority_triggers') != 'No': #TURNING THIS OFF FOR NOW, PER NEW SOLUTIONS AND CONVERSATION WITH SCHEDULERS #If the new status for this Proj is ready, then grab the priority attached to he proj and give it to the Title #This is to control priority order per department #if new_status == 'Ready': # server.update(title.get('__search_key__'), {'priority': parent_obj.get('priority')}, triggers=False) nothing = 1 elif 'WORK_ORDER' in this_lookup: #TURNING THIS OFF FOR NOW, PER NEW SOLUTIONS AND CONVERSATION WITH SCHEDULERS #status_triggers = proj.get('status_triggers') #if status_triggers in [None,'']: # status_triggers = title.get('status_triggers') #if status_triggers == 'No' and status_triggers == 'Yes' and new_status == READY: # pprio = 0 # if proj.get('priority') not in [None,'']: # pprio = proj.get('priority') # server.update(title.get('__search_key__'), {'priority': pprio}, triggers=False) nothing = 1 if new_status == COMPLETE: #print "NEW STATUS COMPLETE 1" #Make sure they have set the assigned person to the work order. if sobj.get('assigned') in [None,'']: raise TacticException('Before completing a work order, someone must be assigned to it.') #Make sure they have added work hours. If not, error out. whs_expr = "@SOBJECT(sthpw/work_hour['task_code','%s'])" % task_code whs = server.eval(whs_expr) sum = 0 for wh in whs: straight_time = wh.get('straight_time') if straight_time in [None,'']: straight_time = 0 else: straight_time = float(straight_time) sum = float(sum) + straight_time sum = str(sum) if sum in ['0','',0,0.0]: raise TacticException('You need to save the hours you worked on this before you can set the status to "Completed".') #print "SUM = %s" % sum t_wo_completed = title.get('wo_completed') #This is for the completion ratio on title o_wo_completed = order.get('wo_completed') #This is for the completion ratio on order if new_status == COMPLETE: #print "NEW STATUS COMPLETE 2" title_str = title.get('title') #This is for a potential alert/exception if title.get('episode') not in [None,'']: title_str = '%s: %s' % (title_str, title.get('episode')) #Block QC and Edel from completing their work orders if the TRT or TRT w/Textless are not filled in if 'qc' in assigned_login_group or 'edeliveries' in assigned_login_group: total_program_runtime = title.get('total_program_runtime') total_runtime_w_textless = title.get('total_runtime_w_textless') say_str = '' say_str2 = '' if total_program_runtime in [None,''] or total_runtime_w_textless in [None,'']: if total_program_runtime in [None,'']: say_str = 'Total Program Runtime has' if total_runtime_w_textless in [None,'']: if say_str == '': say_str = 'Total Runtime With Textless has' else: say_str = '%s and Total Runtime With Textless have' % (say_str[:-4]) say_str2 = "%s (%s)'s %s not been filled. You must enter this data before trying to complete this work order." % (title_str, title.get('code'), say_str) if 'qc' in assigned_login_group: if total_program_runtime in [None,''] or total_runtime_w_textless in [None,'']: raise TacticException(say_str2) else: #They were filled in, so finish completing the task and send a note from pyasm.biz import Note from pyasm.search import Search title_obj2 = Search.get_by_search_key(title.get('__search_key__')) #This is the type of object required for Note creation note_text = '%s (%s) has been Passed and Completed by %s in QC' % (sobj.get('process'), this_lookup, user_name) note = Note.create(title_obj2, note_text, context='QC Completed', process='QC Completed') elif 'edeliveries' in assigned_login_group and (total_program_runtime in [None,''] or total_runtime_w_textless in [None,'']): raise TacticException(say_str2) #This section is turned off due to logistical problems with it. #It intended to block machine room, edit, and compression from completing a work order unless the pulled_blacks had been filled out. #if 'machine_room' in assigned_login_group or 'edit' in assigned_login_group or 'compression' in assigned_login_group: # pulled_blacks = title.get('pulled_blacks') # if pulled_blacks in [None,'','0']: # raise TacticException("%s (%s)'s pulled_blacks has not been filled, or is still '0'." % (title_str, title.get('code'))) t_wo_completed = t_wo_completed + 1 o_wo_completed = o_wo_completed + 1 #print "T WO COMPLETED = %s" % t_wo_completed #print "O WO COMPLETED = %s" % o_wo_completed #Update the completion ratios attached, since there were no blocking exceptions server.update(title.get('__search_key__'), {'wo_completed': t_wo_completed}) server.update(order.get('__search_key__'), {'wo_completed': o_wo_completed}) elif old_status == COMPLETE: t_wo_completed = t_wo_completed - 1 o_wo_completed = o_wo_completed - 1 #Reduce the completion ratio, since it was completed but has now been taken off that status server.update(title.get('__search_key__'), {'wo_completed': t_wo_completed}) server.update(order.get('__search_key__'), {'wo_completed': o_wo_completed}) now_timestamp = make_timestamp() #Since there have been no blocking exceptions, record the status change stat_log_dict = {'login': user_name, 'timestamp': now_timestamp, 'from_status': old_status, 'status': new_status, 'task_code': task_code, 'lookup_code': this_lookup, 'order_code': sobj.get('order_code'), 'title_code': sobj.get('title_code'), 'process': this_process} #print "GOING TO INSERT INTO STATUS LOG = %s" % stat_log_dict server.insert('twog/status_log', stat_log_dict) if new_status == COMPLETE: #print "NEW STATUS COMPLETE 3" #Record the completion date on the work order, and take it off the BigBoard updict = {'actual_end_date': make_timestamp()} do_indie = False if 'WORK_ORDER' in this_lookup: updict['bigboard'] = False if sobj.get('indie_bigboard') in [True,'true','t','T',1]: updict['indie_bigboard'] = False do_indie = True #print "REMOVING BIGBOARD..." server.update(sk, updict) if do_indie: indies = server.eval("@SOBJECT(twog/indie_bigboard['task_code','%s'])" % task_code) for indie in indies: indie_dict = {'indie_bigboard': False} if indie.get('removal_login') in [None,'']: indie_dict['removal_login'] = user_name if indie.get('removal_login') in [None,'']: indie_dict['removal_timestamp'] = now_timestamp server.update(indie.get('__search_key__'), indie_dict) elif new_status not in ['Pending','Ready','Completed'] and 'WORK_ORDER' in this_lookup: server.update(server.build_search_key('sthpw/task', proj.get('task_code')), {'status': new_status}) #NEW if 'PROJ' in sobj.get('lookup_code'): #MTM: This annoying section is for passing Proj's their task's status. #I don't know if this is needed at all anymore. Will have to check other triggers and reports. #The "tripwire" stuff was just to keep it from infinitely passing statuses from proj to task, task to proj do_it = True if 'tripwire' in update_data.keys(): if update_data.get('tripwire') == 'No Send Back': #? do_it = False server.update(input.get('search_key'), {'tripwire': ''}, triggers=False) #Empty the tripwire and do nothing server.update(proj.get('__search_key__'), {'tripwire': '', 'status': sobj.get('status')}, triggers=False) #? if do_it: if proj: server.update(proj.get('__search_key__'), {'status': new_status}) if title.get('priority_triggers') != 'No': #print "IN TITLE PRIORITY TRIGGERS ON" #Update Title Priority for On Hold Status, or having that status removed -- BEGIN if sobj.get('status') in ['On_Hold','On Hold']: title_priority = title.get('priority') server.update(title.get('__search_key__'), {'saved_priority': title_priority, 'priority': 200}, triggers=False) else: if old_status in ['On_Hold','On Hold']: saved_priority = title.get('saved_priority') server.update(title.get('__search_key__'), {'priority': saved_priority}, triggers=False) #Update Title Priority for On Hold Status, or having that status removed -- END #Update Title Priority for Client Response Status, or having that status removed -- BEGIN if sobj.get('status') == 'Client Response': title_priority = title.get('priority') crc = title.get('client_response_count') crc_num = 0 if crc not in [None,'']: crc_num = int(crc) crc_num = crc_num + 1 server.update(title.get('__search_key__'), {'saved_priority': title_priority, 'priority': 300, 'client_response_count': crc_num}, triggers=False) else: if old_status == 'Client Response': saved_priority = title.get('saved_priority') crc = title.get('client_response_count') crc_num = 0 if crc not in [None,'']: crc_num = int(crc) if crc_num > 0: crc_num = crc_num - 1 server.update(title.get('__search_key__'), {'priority': saved_priority, 'client_response_count': crc_num}, triggers=False) #Update Title Priority for Client Response Status, or having that status removed -- END #print "HERE 0" if sobj.get('status') in ['In_Progress','In Progress','DR In_Progress','DR In Progress', 'Amberfin01_In_Progress','Amberfin01 In Progress', 'Amberfin02_In_Progress','Amberfin02 In Progress','BATON In_Progress','BATON In Progress','Export In_Progress','Export In Progress','Buddy Check In_Progress','Buddy Check In Progress','Need Buddy Check','Completed','In Review'] and old_status not in ['In_Progress','DR In_Progress','DR In Progress','Amberfin01_In_Progress','Amberfin01 In Progress', 'Amberfin02_In_Progress','Amberfin02 In Progress', 'BATON In_Progress','BATON In Progress','Export In_Progress','Export In Progress','Buddy Check In_Progress','Buddy Check In Progress','Need Buddy Check','In Progress','In Review']: #Update the actual start date if they just set the status to 'In Progress' if sobj.get('actual_start_date') in ['',None]: now_timestamp = make_timestamp() server.update(sk, {'actual_start_date': now_timestamp, 'flag_future_changes': True}) if sobj.get('status') in ['Ready','In_Progress','In Progress','In Review'] and 'WORK_ORDER' in sobj.get('lookup_code'): if title.get('client_status') != 'In Production': server.update(title.get('__search_key__'), {'client_status': 'In Production', 'status': 'In Production'}) elif sobj.get('status') in ['Rejected','Fix Needed'] and 'WORK_ORDER' in sobj.get('lookup_code'): from pyasm.biz import Note from pyasm.search import Search server.insert('twog/production_error', {'error_type': sobj.get('status'), 'process': sobj.get('process'), 'work_order_code': sobj.get('lookup_code'), 'title': title.get('title'), 'episode': title.get('episode'), 'title_code': title.get('code'), 'order_code': order.get('code'), 'order_name': order.get('name'), 'po_number': order.get('po_number'), 'proj_code': proj.get('code'), 'scheduler_login': sobj.get('creator_login'), 'operator_login': user_name, 'login': user_name}, triggers=False) if sobj.get('status') == 'Rejected': server.update(title.get('__search_key__'), {'client_status': 'QC Rejected'}) if title.get('priority_triggers') != 'No': server.update(title.get('__search_key__'), {'priority': 90}, triggers=False) #title_obj2 = Search.get_by_search_key(title.get('__search_key__')) #This is the type of object required for Note creation #note_text = '%s (%s) has been Rejected, as marked by %s' % (sobj.get('process'), this_lookup, user_name) #note = Note.create(title_obj2, note_text, context='QC Rejected', process='QC Rejected', triggers=False) status_triggers = proj.get('status_triggers') if status_triggers in [None,'']: status_triggers = title.get('status_triggers') if sobj.get('status') == COMPLETE and status_triggers != 'No': # Now we need to set the next task(s) statuses to 'Ready' ready = True # Took out the checks to this WO's input WOs # make the next processes ready #print "STATUS TRIGGERS ON, STATUS = COMPLETE" if ready == True: goes_to = sobj.get('goes_to').split('|^|') #print "GOES TO = %s" % goes_to for gt in goes_to: next_task_code = '' next_task_code_split = gt.split(',') if len(next_task_code_split) > 1: next_task_code = next_task_code_split[1] next_task_code = next_task_code.replace('[','').replace(']','') nt_expr = "@SOBJECT(sthpw/task['code','%s'])" % next_task_code next_task = server.eval(nt_expr) #print "NEXT TASK = %s" % next_task if next_task: next_task = next_task[0] if next_task.get('status') == 'Pending': if no_incompletes_preceding(next_task, task_code): server.update(next_task.get('__search_key__'), {'status': READY}) if 'PROJ' in next_task.get('lookup_code'): oip = next_task.get('order_in_pipe') if oip in [None,'',0]: oip = 1 else: oip = int(oip) smallest_wo = (oip * 1000) + 10 nwt_expr = "@SOBJECT(twog/work_order['proj_code','%s']['order_in_pipe','<=','%s'].WT:sthpw/task['status','Pending']['@ORDER_BY','order_in_pipe desc'])" % (next_task.get('lookup_code'), smallest_wo) next_wo_tasks = server.eval(nwt_expr) for nwo in next_wo_tasks: #print "MAKING %s READY" % nwo.get('__search_key__') server.update(nwo.get('__search_key__'), {'status': READY}, triggers=False) # Now see if all wos under proj or all projs under title are completed. If so, make their parent's status completed all_wos_completed = False all_wos_pending = False prj = None if new_status in [COMPLETE,PENDING]: if 'WORK_ORDER' in this_lookup: #print "WORK ORDER IN LOOKUP" wo = server.eval("@SOBJECT(twog/work_order['code','%s'])" % sobj.get('lookup_code')) wo = wo[0] other_wotasks_expr = "@SOBJECT(twog/proj['code','%s'].twog/work_order.WT:sthpw/task)" % wo.get('proj_code') other_wo_tasks = server.eval(other_wotasks_expr) all_wos_completed = True all_wos_pending = True if new_status == PENDING: all_wos_completed = False elif new_status == COMPLETE: all_wos_pending = False un_indie = False if sobj.get('indie_bigboard') in [True,'true','t','T',1]: un_indie = True for owt in other_wo_tasks: if owt.get('lookup_code') != wo.get('code'): if owt.get('status') != COMPLETE: all_wos_completed = False if owt.get('status') != PENDING: all_wos_pending = False if owt.get('indie_bigboard') in [True,'true','t','T',1] and (owt.get('assigned_login_group') == sobj.get('assigned_login_group')): un_indie = False #HERE NEED TO DETERMINE WHICH DEPT THIS WAS FOR AND SEE IF ANY OTHER WOs #IN THE SAME DEPT ARE STILL INDIE. IF NOT, THEN TAKE THE DEPT NAME OUT OF #active_dept_priorities ON THE TITLE if un_indie: that_dept = sobj.get('assigned_login_group').replace(' supervisor','') adps = title.get('active_dept_priorities') adps = adps.replace(',%s' % that_dept, '').replace('%s,' % that_dept, '').replace(that_dept,'') indie_data = {} indie_data['active_dept_priorities'] = adps prio_name = '%s_priority' % that_dept.replace(' ','_') indie_data[prio_name] = title.get('priority') server.update(title.get('__search_key__'), indie_data) prj = server.eval("@SOBJECT(twog/proj['code','%s'])" % wo.get('proj_code')) if len(prj) > 0: prj = prj[0] else: prj = None if (all_wos_completed or all_wos_pending) and prj not in [None,'']: prj_task = server.eval("@SOBJECT(sthpw/task['lookup_code','%s'])" % prj.get('code')) if prj_task: prj_task = prj_task[0] server.update(prj_task.get('__search_key__'), {'status': new_status}) #print "END OF WO IN LOOKUP" elif 'PROJ' in this_lookup: prj = server.eval("@SOBJECT(twog/proj['code','%s'])" % this_lookup) if prj: prj = prj[0] else: prj = None all_projs_completed = True all_projs_pending = True all_titles_completed = False all_titles_pending = False #print "HERE 1" if prj not in [None,'']: title_proj_tasks = server.eval("@SOBJECT(twog/title['code','%s'].twog/proj.PT:sthpw/task)" % prj.get('title_code')) for tpt in title_proj_tasks: if tpt.get('status') != COMPLETE: all_projs_completed = False if tpt.get('status') != PENDING: all_projs_pending = False title_updated = False if all_projs_completed: title_sk = server.build_search_key('twog/title', prj.get('title_code')) if 1: server.update(title_sk, {'status': COMPLETE, 'client_status': COMPLETE, 'bigboard': False, 'priority': 5000}) titles_completed = order.get('titles_completed') title_codes_completed = order.get('title_codes_completed') if title.get('code') not in title_codes_completed: if titles_completed in [None,'']: titles_completed = 0 else: titles_completed = int(titles_completed) titles_completed = titles_completed + 1 if title_codes_completed == '': title_codes_completed = title.get('code') else: title_codes_completed = '%s,%s' % (title_codes_completed, title.get('code')) server.update(order.get('__search_key__'), {'titles_completed': titles_completed, 'title_codes_completed': title_codes_completed}) title_updated = True all_titles_completed = True title = server.eval("@SOBJECT(twog/title['code','%s'])" % prj.get('title_code')) if title and title_updated: title = title[0] other_titles = server.eval("@SOBJECT(twog/order['code','%s'].twog/title)" % title.get('order_code')) for ot in other_titles: if title.get('code') != ot.get('code'): if ot.get('status') != COMPLETE: all_titles_completed = False else: all_titles_completed = False #print "HERE 2" if all_projs_pending: title_sk = server.build_search_key('twog/title', prj.get('title_code')) if title.get('priority_triggers') != 'No' and title.get('status_triggers') != 'No': server.update(title_sk, {'status': '', 'bigboard': False}) title_codes_completed = order.get('title_codes_completed') if title.get('code') in title_codes_completed: title_codes_completed = title_codes_completed.replace(',%s' % title.get('code'),'').replace('%s,' % title.get('code'),'').replace('%s' % title.get('code'),'') titles_completed = order.get('titles_completed') if titles_completed in [None,'']: titles_completed = 0 else: titles_completed = int(titles_completed) - 1 server.update(order.get('__search_key__'), {'titles_completed': titles_completed, 'title_codes_completed': title_codes_completed}) title_updated = True all_titles_pending = True title = server.eval("@SOBJECT(twog/title['code','%s'])" % prj.get('title_code')) if title and title_updated: title = title[0] other_titles = server.eval("@SOBJECT(twog/order['code','%s'].twog/title)" % title.get('order_code')) for ot in other_titles: if title.get('code') != ot.get('code'): if ot.get('status') != '': all_titles_pending = False else: all_titles_pending = False #print "HERE 3" if all_titles_pending: server.update(server.build_search_key('twog/order', title.get('order_code')), {'needs_completion_review': False}) if all_titles_completed: server.update(server.build_search_key('twog/order', title.get('order_code')), {'needs_completion_review': True}) #print "LEAVING KICKOFF" except AttributeError as e: traceback.print_exc() print str(e) + '\nMost likely the server object does not exist.' raise e except KeyError as e: traceback.print_exc() print str(e) + '\nMost likely the input dictionary does not exist.' raise e except Exception as e: traceback.print_exc() print str(e) raise e