def convert_value(self, col_type, value): if col_type == 'timecode': timecode = TimeCode(timecode=value) value = timecode.get_frames() elif col_type in ["time", "timestamp"]: from pyasm.common import SPTDate if not value: value = "" elif not SPTDate.has_timezone(value): timezone = PrefSetting.get_value_by_key('timezone') if timezone: value = SPTDate.add_timezone(value, timezone) else: value = SPTDate.add_local_timezone(value) elif col_type in ["float", "integer"]: if isinstance(value, basestring): value = value.replace(",", "") if value.startswith("$"): value = value.lstrip("$") try: if not value: value = None elif col_type == "float": value = float(value) else: value = int(value) except: raise UserException("[%s] must a number." % value) return value
def get_display(self): sobject = self.get_current_sobject() name = self.get_name() value = self.get_value() if sobject: data_type = SearchType.get_column_type(sobject.get_search_type(), name) else: data_type = 'text' if data_type in ["timestamp", "time"] or self.name == "timestamp": if value == 'now': value = '' elif value: date = parser.parse(value) # we want to match what's in the db which is server local timezone if not SPTDate.has_timezone(value): value = SPTDate.convert_to_local(value) #value = SPTDate.add_gmt_timezone(date) value = str(value) else: value = '' return value
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_SCRIPT00046 #print "UPDATE TASK SORT ESSENTIALS" from pyasm.common import SPTDate update_data = input.get('update_data') sobject = input.get('sobject') if 'twog/title' in sobject.get('search_type'): server.update(input.get('search_key'), {'tripwire': ''}, triggers=False) proj_sk = server.build_search_key('twog/proj', sobject.get('lookup_code')) proj_data = {} task_data = {} if 'bid_end_date' in update_data: proj_data['due_date'] = SPTDate.convert_to_local(update_data.get('bid_end_date')) task_data['bid_end_date'] = proj_data['due_date'] if proj_data != {}: server.update(proj_sk, proj_data, triggers=False) wos = server.eval("@SOBJECT(twog/work_order['proj_code','%s'])" % sobject.get('lookup_code')) for wo in wos: server.update(wo.get('__search_key__'), proj_data, triggers=False) if wo.get('task_code') not in [None,'']: task = server.eval("@SOBJECT(sthpw/task['code','%s'])" % wo.get('task_code')) if len(task) > 0: task = task[0] task_data['tripwire'] = '' server.update(task.get('__search_key__'), task_data, triggers=False) elif 'twog/proj' in sobject.get('search_type'): wo_sk = server.build_search_key('twog/work_order', sobject.get('lookup_code')) wo_data = {} if 'bid_end_date' in update_data: wo_data['due_date'] = SPTDate.convert_to_local(update_data.get('bid_end_date')) if wo_data != {}: server.update(wo_sk, wo_data, triggers=False) #print "LEAVING UPDATE TASK SORT ESSENTIALS" 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 convert_value(my, col_type, value): if col_type == 'timecode': timecode = TimeCode(timecode=value) value = timecode.get_frames() elif col_type in ["time", "timestamp"]: from pyasm.common import SPTDate if not SPTDate.has_timezone(value): value = SPTDate.add_local_timezone(value) elif col_type in ["float", "integer"]: if isinstance(value, basestring): value = value.replace(",", "") return value
def get_timezone_value(self, value): '''given a datetime value, try to convert to timezone specified in the widget. If not specified, use the My Preferences time zone''' timezone = self.get_option('timezone') if not timezone: timezone = PrefSetting.get_value_by_key('timezone') if timezone in ["local", '']: value = SPTDate.convert_to_local(value) else: value = SPTDate.convert_to_timezone(value, timezone) return value
def get_timezone_value(my, value): '''given a datetime value, try to convert to timezone specified in the widget. If not specified, use the My Preferences time zone''' timezone = my.get_option('timezone') if not timezone: timezone = PrefSetting.get_value_by_key('timezone') if timezone in ["local", '']: value = SPTDate.convert_to_local(value) else: value = SPTDate.convert_to_timezone(value, timezone) return value
def get_display(my): top = DivWdg() value = my.get_value() widget_type = my.get_option("type") if widget_type in ['integer', 'float', 'timecode', 'currency']: top.add_style("float: right") my.justify = "right" elif widget_type in ['date','time']: name = my.get_name() if value and not SObject.is_day_column(name): value = SPTDate.convert_to_local(value) value = str(value) else: top.add_style("float: left") my.justify = "left" top.add_style("padding-right: 3px") top.add_style("min-height: 15px") format = my.get_option('format') value = my.get_format_value( value, format ) top.add(value) return top
def accesshandler(request): cookies = Cookie.get_cookies(request) # if login ticket cookie does not exist, then deny if not cookies.has_key('login_ticket'): # just refuse access return apache.HTTP_FORBIDDEN ticket = cookies['login_ticket'].value if not ticket: return apache.HTTP_FORBIDDEN server = TacticServerStub.get(protocol='local') expr = "@SOBJECT(sthpw/ticket['ticket','%s'])" % ticket sobject = server.eval(expr, single=True) now = SPTDate.now() expiry = sobject.get("expiry") if expiry and expiry < str(now): return apache.HTTP_FORBIDDEN request.add_common_vars() path = str(request.subprocess_env['REQUEST_URI']) if path == None: return apache.HTTP_FORBIDDEN # FIXME: find some mechanism which is more acceptable ... like /icons #if path.find("_icon_") != -1: # return apache.OK return apache.OK
def test_time(): from pyasm.search import SearchType sobj = SearchType.create('sthpw/note') sobj.set_value('process', 'TEST') sobj.set_value('note', '123') sobj.commit() sobj.set_value('note', 'new note') sobj.commit() # check change_timestamp change_t = Search.eval( "@SOBJECT(sthpw/change_timestamp['search_type','sthpw/note']['search_code','%s'])" % sobj.get_code(), single=True) if change_t: change_t_timestamp = change_t.get('timestamp') change_t_timestamp = parser.parse(change_t_timestamp) from pyasm.common import SPTDate now = SPTDate.now() diff = now - change_t_timestamp # should be roughly the same minute, not hours apart print "Change timestamp diff is ", diff.seconds
def init_data(my): sobject = my.get_current_sobject() value = sobject.get_value(my.due_date_col) if not value: my.mode = "" return status = sobject.get_value("status") due_date = parser.parse(value) # get today's date from pyasm.common import SPTDate today = SPTDate.start_of_today() # get the difference delta = due_date - today diff = delta.days if diff < 0: if status.lower() in ["approved", "complete", "done"]: mode = "done" else: mode = "critical" elif diff >= 0 and diff < 1: mode = "today" else: mode = "due" my.mode = mode my.diff = diff
def fix_date(date): # This is needed due to the way Tactic deals with dates (using timezone info), post v4.0 return_date = '' date_obj = SPTDate.convert_to_local(date) if date_obj not in [None, '']: return_date = date_obj.strftime("%Y-%m-%d %H:%M") return return_date
def _test_time(self): ''' test timezone related behavior''' sobject = SearchType.create('sthpw/task') sobject.set_value('project_code', 'unittest') sobject.set_value('bid_start_date', '2014-11-11 05:00:00') time = sobject.get_value('bid_start_date') self.assertEquals(time, '2014-11-11 05:00:00') sobject.commit() time = sobject.get_value('bid_start_date') self.assertEquals(time, '2014-11-11 05:00:00') from pyasm.search import DbContainer sql = DbContainer.get('sthpw') db_value = sql.do_query( 'SELECT bid_start_date from task where id = %s' % sobject.get_id()) # 2014-11-11 00:00:00 is actually written to the database self.assertEquals(db_value[0][0].strftime('%Y-%m-%d %H:%M:%S %Z'), '2014-11-11 00:00:00 ') # an sType specified without a project but with an id could be a common human error # but it should handle that fine obj1 = Search.eval( '@SOBJECT(unittest/person?project=unittest["id", "%s"])' % sobject.get_id(), single=True) obj2 = Search.eval('@SOBJECT(unittest/person?id=2["id", "%s"])' % sobject.get_id(), single=True) obj3 = Search.eval('@SOBJECT(sthpw/task?id=2["id", "%s"])' % sobject.get_id(), single=True) task = Search.eval('@SOBJECT(sthpw/task["id", "%s"])' % sobject.get_id(), single=True) # EST and GMT diff is 5 hours self.assertEquals(task.get_value('bid_start_date'), '2014-11-11 05:00:00') # test NOW() auto conversion sobj = SearchType.create('sthpw/note') sobj.set_value('process', 'TEST') sobj.set_value('note', '123') self.assertEquals(sobj.get_value('timestamp'), "") sobj.commit() # this is local commited time converted back to GMT committed_time = sobj.get_value('timestamp') from dateutil import parser committed_time = parser.parse(committed_time) from pyasm.common import SPTDate now = SPTDate.now() diff = now - committed_time # should be roughly the same minute, not hours apart self.assertEquals(diff.seconds < 60, True)
def make_timestamp(): from pyasm.common import SPTDate # Makes a Timestamp for postgres import datetime now = SPTDate.convert_to_local(datetime.datetime.now()) now = datetime.datetime.now() return now
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_SCRIPT00049 #print "IN SET REVENUE MONTH" from pyasm.common import SPTDate update_data = input.get('update_data') if 'due_date' in update_data.keys(): if update_data.get('due_date') not in [None,'']: sobj = input.get('sobject') sk = input.get('search_key') if sobj.get('expected_delivery_date') in [None,''] and input.get('is_insert'): server.update(sk, {'expected_revenue_month': SPTDate.convert_to_local(update_data.get('due_date')), 'expected_delivery_date': SPTDate.convert_to_local(update_data.get('due_date'))}) elif not input.get('is_insert'): do_it = True if 'expected_delivery_date' in update_data.keys(): if update_data.get('expected_delivery_date') not in [None,'']: do_it = False if do_it: server.update(sk, {'expected_revenue_month': SPTDate.convert_to_local(update_data.get('due_date')), 'expected_delivery_date': SPTDate.convert_to_local(update_data.get('due_date'))}) #print "LEAVING SET REVENUE MONTH" 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_display(my): sobject = my.get_current_sobject() column = my.kwargs.get('column') if column: name = column else: name = my.get_name() value = my.get_value(name=name) if sobject: data_type = SearchType.get_column_type(sobject.get_search_type(), name) else: data_type = 'text' if type(value) in types.StringTypes: wiki = WikiUtil() value = wiki.convert(value) if name == 'id' and value == -1: value = '' elif data_type == "timestamp" or name == "timestamp": if value == 'now': value = '' elif value: # This date is assumed to be GMT date = parser.parse(value) # convert to local if not SObject.is_day_column(name): date = SPTDate.convert_to_local(date) try: encoding = locale.getlocale()[1] value = date.strftime("%b %d, %Y - %H:%M").decode(encoding) except: value = date.strftime("%b %d, %Y - %H:%M") else: value = '' else: if isinstance(value, Widget): return value elif not isinstance(value, basestring): try: value + 1 except TypeError: value = str(value) else: value_wdg = DivWdg() value_wdg.add_style("float: right") value_wdg.add_style("padding-right: 3px") value_wdg.add(str(value)) return value_wdg return value
def get_display(my): sobject = my.get_current_sobject() column = my.kwargs.get('column') if column: name = column else: name = my.get_name() value = my.get_value(name=name) if sobject: data_type = SearchType.get_column_type(sobject.get_search_type(), name) else: data_type = 'text' if type(value) in types.StringTypes: wiki = WikiUtil() value = wiki.convert(value) if name == 'id' and value == -1: value = '' elif data_type == "timestamp" or name == "timestamp": if value == 'now': value = '' elif value: # This date is assumed to be GMT date = parser.parse(value) # convert to local if not SObject.is_day_column(name): date = SPTDate.convert_to_local(date) try: encoding = locale.getlocale()[1] value = date.strftime("%b %d, %Y - %H:%M").decode(encoding) except: value = date.strftime("%b %d, %Y - %H:%M") else: value = '' else: if isinstance(value, Widget): return value elif not isinstance(value, basestring): try: value + 1 except TypeError: value = str(value) else: value_wdg = DivWdg() value_wdg.add_style("float: right") value_wdg.add_style("padding-right: 3px") value_wdg.add( str(value) ) return value_wdg return value
def fix_date(date): #This is needed due to the way Tactic deals with dates (using timezone info), post v4.0 from pyasm.common import SPTDate date_obj = SPTDate.convert_to_local(date) #return_date = '' #date_obj = SPTDate.convert_to_timezone(date, 'EDT') #print "DATE OBJ = %s" % date_obj #if date_obj not in [None,'']: # return_date = date_obj.strftime("%Y-%m-%d %H:%M:%S") #return return_date return date_obj
def get_display(my): sobject = my.get_current_sobject() name = my.get_name() value = my.get_value() if sobject: data_type = SearchType.get_column_type(sobject.get_search_type(), name) else: data_type = 'text' if data_type in ["timestamp","time"] or my.name == "timestamp": if value == 'now': value = '' elif value: date = parser.parse(value) # we want to match what's in the db which is server local timezone if not SPTDate.has_timezone(value): value = SPTDate.convert_to_local(value) #value = SPTDate.add_gmt_timezone(date) value = str(value) else: value = '' return value
def _test_time(my): ''' test timezone related behavior''' sobject = SearchType.create('sthpw/task') sobject.set_value('project_code','unittest') sobject.set_value('bid_start_date', '2014-11-11 05:00:00') time = sobject.get_value('bid_start_date') my.assertEquals(time, '2014-11-11 05:00:00') sobject.commit() time = sobject.get_value('bid_start_date') my.assertEquals(time, '2014-11-11 05:00:00') from pyasm.search import DbContainer sql = DbContainer.get('sthpw') db_value = sql.do_query('SELECT bid_start_date from task where id = %s'%sobject.get_id()) # 2014-11-11 00:00:00 is actually written to the database my.assertEquals(db_value[0][0].strftime('%Y-%m-%d %H:%M:%S %Z'), '2014-11-11 00:00:00 ') # an sType specified without a project but with an id could be a common human error # but it should handle that fine obj1 = Search.eval('@SOBJECT(unittest/person?project=unittest["id", "%s"])'%sobject.get_id(), single=True) obj2= Search.eval('@SOBJECT(unittest/person?id=2["id", "%s"])'%sobject.get_id(), single=True) obj3 = Search.eval('@SOBJECT(sthpw/task?id=2["id", "%s"])'%sobject.get_id(), single=True) task = Search.eval('@SOBJECT(sthpw/task["id", "%s"])'%sobject.get_id(), single=True) # EST and GMT diff is 5 hours my.assertEquals(task.get_value('bid_start_date'), '2014-11-11 05:00:00') # test NOW() auto conversion sobj = SearchType.create('sthpw/note') sobj.set_value('process','TEST') sobj.set_value('note','123') my.assertEquals(sobj.get_value('timestamp'), "") sobj.commit() # this is local commited time converted back to GMT committed_time = sobj.get_value('timestamp') from dateutil import parser committed_time = parser.parse(committed_time) from pyasm.common import SPTDate now = SPTDate.now() diff = now - committed_time # should be roughly the same minute, not hours apart my.assertEquals(diff.seconds < 60, True)
def get_text_value(my): value = my.get_value() widget_type = my.get_option("type") if widget_type in ['date','time']: name = my.get_name() if not SObject.is_day_column(name): value = SPTDate.convert_to_local(value) value = str(value) format = my.get_option('format') if format == 'Checkbox': value = str(value) else: value = my.get_format_value( value, format ) return value
def get_display(my): sobject = my.get_current_sobject() name = my.get_name() value = my.get_value() if sobject: data_type = SearchType.get_column_type(sobject.get_search_type(), name) else: data_type = 'text' if data_type == "timestamp" or my.name == "timestamp": if value == 'now': value = '' elif value: date = parser.parse(value) value = SPTDate.add_gmt_timezone(date) value = str(value) else: value = '' return value
def test_time(): from pyasm.search import SearchType sobj = SearchType.create('sthpw/note') sobj.set_value('process','TEST') sobj.set_value('note','123') sobj.commit() sobj.set_value('note', 'new note') sobj.commit() # check change_timestamp change_t = Search.eval("@SOBJECT(sthpw/change_timestamp['search_type','sthpw/note']['search_code','%s'])"%sobj.get_code(), single=True) if change_t: change_t_timestamp = change_t.get('timestamp') change_t_timestamp = parser.parse(change_t_timestamp) from pyasm.common import SPTDate now = SPTDate.now() diff = now - change_t_timestamp # should be roughly the same minute, not hours apart print "Change timestamp diff is ", diff.seconds
list=list, show_retired=my.show_retired) # FIXME: don't know how to do this any other way try: if not list: result = result.get_display_value() except AttributeError, e: pass if list and result: # turn non basestring into string encoded_result = [] for res in result: if isinstance(res, datetime.datetime): res = SPTDate.convert_to_local(res) res = str(res) elif not isinstance(res, basestring): res = unicode(res).encode('utf-8', 'ignore') encoded_result.append(res) result = ','.join(encoded_result) # FIXME: can we just do this?? # adding a tempoary value to this sobject ... dangerous because we # cannot commit this ... need a place for calculated values if result == None or result == []: result = '' if isinstance(result, datetime.datetime): result = SPTDate.convert_to_local(result) return result
def execute(my): start = time.time() from pyasm.common import SPTDate timestamp = SPTDate.now() timestamp = SPTDate.add_gmt_timezone(timestamp) timestamp = SPTDate.convert_to_local(timestamp) format = '%Y-%m-%d %H:%M:%S' timestamp = timestamp.strftime(format) updates = my.kwargs.get("updates") if isinstance(updates, basestring): updates = jsonloads(updates) last_timestamp = my.kwargs.get("last_timestamp") #assert last_timestamp if not last_timestamp: my.info = {"updates": {}, "timestamp": timestamp} return last_timestamp = parser.parse(last_timestamp) last_timestamp = SPTDate.add_gmt_timezone(last_timestamp) #last_timestamp = last_timestamp - timedelta(hours=24) #print "last: ", last_timestamp # get out all of the search_keys client_keys = set() for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key: client_keys.add(search_key) # find all of the search that have changed changed_keys = set() for check_type in ['sthpw/change_timestamp', 'sthpw/sobject_log']: search = Search(check_type) search.add_filter("timestamp", last_timestamp, op=">") search.add_filters("search_type", ["sthpw/sobject_log", "sthpw/status_log"], op="not in") #print search.get_statement() changed_sobjects = search.get_sobjects() for sobject in changed_sobjects: search_type = sobject.get_value("search_type") search_code = sobject.get_value("search_code") if search_type.startswith("sthpw/"): search_key = "%s?code=%s" % (search_type, search_code) else: search_key = "%s&code=%s" % (search_type, search_code) changed_keys.add(u'%s' % search_key) intersect_keys = client_keys.intersection(changed_keys) #for x in client_keys: # print x #print "---" #print "changed_keys: ", changed_keys #print "---" #print "intersect_keys: ", intersect_keys from pyasm.web import HtmlElement results = {} for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key and search_key not in intersect_keys: continue # evaluate any compare expressions compare = values.get("compare") if compare: search_key = values.get("search_key") if search_key: sobject = Search.get_by_search_key(search_key) else: sobject = None cmp_result = Search.eval(compare, sobject, single=True) if cmp_result == True: continue # some value to display value = "Loading ..." else: value = HtmlElement.eval_update(values) if value == None: continue results[id] = value my.info = {"updates": results, "timestamp": timestamp} #print "time: ", time.time() - start #print results return results
def execute(my): start = time.time() from pyasm.common import SPTDate timestamp = SPTDate.now() timestamp = SPTDate.add_gmt_timezone(timestamp) timestamp = SPTDate.convert_to_local(timestamp) format = '%Y-%m-%d %H:%M:%S' timestamp = timestamp.strftime(format) updates = my.kwargs.get("updates") if isinstance(updates, basestring): updates = jsonloads(updates) last_timestamp = my.kwargs.get("last_timestamp") #assert last_timestamp if not last_timestamp: my.info = { "updates": {}, "timestamp": timestamp } return last_timestamp = parser.parse(last_timestamp) last_timestamp = SPTDate.add_gmt_timezone(last_timestamp) #last_timestamp = last_timestamp - timedelta(hours=24) #print "last: ", last_timestamp # get out all of the search_keys client_keys = set() for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key: client_keys.add(search_key) # find all of the search that have changed changed_keys = set() for check_type in ['sthpw/change_timestamp', 'sthpw/sobject_log']: search = Search(check_type) search.add_filter("timestamp", last_timestamp, op=">") search.add_filters("search_type", ["sthpw/sobject_log", "sthpw/status_log"], op="not in") #print search.get_statement() changed_sobjects = search.get_sobjects() for sobject in changed_sobjects: search_type = sobject.get_value("search_type") search_code = sobject.get_value("search_code") if search_type.startswith("sthpw/"): search_key = "%s?code=%s" % (search_type, search_code) else: search_key = "%s&code=%s" % (search_type, search_code) changed_keys.add(u'%s'%search_key) intersect_keys = client_keys.intersection(changed_keys) #for x in client_keys: # print x #print "---" #print "changed_keys: ", changed_keys #print "---" #print "intersect_keys: ", intersect_keys from pyasm.web import HtmlElement results = {} for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key and search_key not in intersect_keys: continue # evaluate any compare expressions compare = values.get("compare") if compare: search_key = values.get("search_key") if search_key: sobject = Search.get_by_search_key(search_key) else: sobject = None cmp_result = Search.eval(compare, sobject, single=True) if cmp_result == True: continue # some randome value value = "Loading ..." else: value = HtmlElement.eval_update(values) if value == None: continue results[id] = value my.info = { "updates": results, "timestamp": timestamp } #print "time: ", time.time() - start #print results return results
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_SCRIPT00003 # Matthew Tyler Misenhimer # This is run when a task is added. Tasks are added when a pipeline is attached to a title or project. # This will take info from the task and create either a work order or proj # THIS IS ADD_WO_OR_PROJ # sobj is a task sobject from pyasm.common import Environment from pyasm.common import SPTDate sobj = input.get('sobject') # If it wasn't manually inserted, then it is a normally added task (from pipeline attachment) if 'Manually Inserted' in sobj.get('pipeline_code'): return sobj_sk = server.build_search_key('sthpw/task', sobj.get('code')) proj = None order = None is_master = False mr_title = None title_title = '' title_code = '' title_episode = '' title_territory = '' title_platform = '' title_id_number = '' client_name = '' login = Environment.get_login() user_name = login.get_login() #This sees if the sobject was being cloned or not. If so, then set the templ_me field to true cloning_expr = "@SOBJECT(twog/action_tracker['login','%s']['action','cloning'])" % (user_name) cloning = server.eval(cloning_expr) templ_me = False title_due_date = None if len(cloning) > 0: templ_me = True if 'twog/proj' in sobj.get('search_type'): prexpr = "@SOBJECT(twog/proj['id','%s'])" % sobj.get('search_id') proj = server.eval(prexpr)[0] killed_task = False if proj: mr_title_expr = "@SOBJECT(twog/title['code','%s'])" % proj.get('title_code') mr_title = server.eval(mr_title_expr) if mr_title: mr_title = mr_title[0] if mr_title: title_code = mr_title.get('code') title_title = mr_title.get('title') title_due_date = SPTDate.convert_to_local(mr_title.get('due_date')) title_episode = mr_title.get('episode') title_territory = mr_title.get('territory') title_platform = mr_title.get('platform') title_id_number = mr_title.get('title_id_number') client_code = mr_title.get('client_code') client_names = server.eval("@GET(twog/client['code','%s'].name)" % client_code) if len(client_names) > 0: client_name = client_names[0] if mr_title: order = server.eval("@SOBJECT(twog/order['code','%s'])" % mr_title.get('order_code'))[0] order_classification = order.get('classification') #If it is a master, kill the task so it won't show up in operator views if order_classification in ['master','Master']: is_master = True server.retire_sobject(sobj_sk) killed_task = True server.update(proj.get('__search_key__'), {'task_code': ''}) pipeline_code = proj.get('pipeline_code') spt_processes = server.eval("@SOBJECT(config/process['pipeline_code','%s']['process','%s'])"%(pipeline_code, sobj.get('process'))) # take the first one, we dont expect duplicates spt_process = spt_processes[0] # query if it exists work_order = server.query('twog/work_order', filters=[('process',sobj.get('process')), ('proj_code', proj.get('code')), ('description', spt_process.get('description')), ('parent_pipe', pipeline_code)]) if work_order: return # find work order template desc = spt_process.get('description') if not desc: desc = '' wot_expr = "@SOBJECT(twog/work_order_templ['process','%s']['parent_pipe','%s'])" % (sobj.get('process'), pipeline_code) work_order_template = server.eval(wot_expr) if work_order_template: work_order_template = work_order_template[0] instructions = '' estimated_work_hours = '' work_group = '' wo_templ_code = '' if work_order_template: instructions = work_order_template.get('instructions') work_group = work_order_template.get('work_group') estimated_work_hours = work_order_template.get('estimated_work_hours') wo_templ_code = work_order_template.get('code') wo_data = { 'process': sobj.get('process'), 'proj_code': proj.get('code'), 'description': spt_process.get('description'), 'client_code': proj.get('client_code'), 'instructions': instructions, 'parent_pipe': pipeline_code, 'work_group': work_group, 'estimated_work_hours': estimated_work_hours, 'order_name': order.get('name'), 'order_code': order.get('code'), 'title_code': proj.get('title_code'), 'po_number': order.get('po_number'), 'work_order_templ_code': wo_templ_code } if not is_master: wo_data['task_code'] = sobj.get('code') if title_title not in[None,'']: wo_data['title'] = title_title if title_due_date not in[None,'']: wo_data['due_date'] = title_due_date if title_episode not in [None,'']: wo_data['episode'] = title_episode if title_territory not in [None,'']: wo_data['territory'] = title_territory if title_platform not in [None,'']: wo_data['platform'] = title_platform if title_id_number not in [None,'']: wo_data['title_id_number'] = title_id_number # Create the work order wo_insert = server.insert('twog/work_order', wo_data) if templ_me: #If this is the going to be the standard/template for a work order in a pipeline, then we need to remember that this is the one to re-template if changed. server.update(wo_insert.get('__search_key__'), {'templ_me': templ_me}) if not killed_task: task_data = {} task_data['lookup_code'] = wo_insert.get('code') task_data['order_name'] = order.get('name') task_data['proj_code'] = proj.get('code') task_data['title_code'] = proj.get('title_code') task_data['order_code'] = order.get('code') if title_due_date: task_data['bid_end_date'] = title_due_date if user_name not in ['',None]: task_data['creator_login'] = user_name if work_order_template.get('assigned_login_group') not in ['',None]: task_data['assigned_login_group'] = work_order_template.get('assigned_login_group') if client_name not in ['',None]: task_data['client_name'] = client_name if title_title not in ['',None]: task_data['title'] = title_title if title_episode not in ['',None]: task_data['episode'] = title_episode if title_territory not in ['',None]: task_data['territory'] = title_territory if title_platform not in ['',None]: task_data['platform'] = title_platform if title_id_number not in ['',None]: task_data['title_id_number'] = title_id_number if order: if order.get('classification') in ['in_production','In Production']: task_data['active'] = True task_data['po_number'] = order.get('po_number') if work_group not in [None,'']: task_data['assigned_login_group'] = work_group #Make sure the wo and task have matching data task_update = server.update(sobj_sk, task_data) #Transfers are for deleted/retired work orders - if the same name is coming through from a different pipeline, switch out the info from the deleted one and give to new one #We may want to turn this off at some point... People may write over info they want, or carry over info they don't want transfer_expr = "@SOBJECT(twog/work_order_transfer['login','%s'])" % (user_name) transfers = server.eval(transfer_expr) #transfers = transfers[::-1] transfer = None for tran in transfers: if tran.get('used') == False: if wo_insert.get('process') == tran.get('process') and tran.get('used') == False: transfer = tran server.update(tran.get('__search_key__'), {'used': True}) break else: tr = server.eval("@SOBJECT(twog/work_order_transfer['code','%s'])" % tran.get('code')) if len(tr) > 0 and len(cloning) > 0: server.retire_sobject(tran.get('__search_key__')) if not transfer: # Attach the templated equipment_used's wot_eus_expr = "@SOBJECT(twog/equipment_used_templ['work_order_templ_code','%s'])" % wo_templ_code wot_eus = server.eval(wot_eus_expr) for eu in wot_eus: name = eu.get('name') equipment_code = eu.get('equipment_code') description = eu.get('description') expected_cost = eu.get('expected_cost') expected_duration = eu.get('expected_duration') expected_quantity = eu.get('expected_quantity') eq_templ_code = eu.get('code') units = eu.get('units') ins_data = {'name': name, 'work_order_code': wo_insert.get('code'), 'equipment_code': equipment_code, 'description': description, 'expected_cost': expected_cost, 'expected_duration': expected_duration, 'expected_quantity': expected_quantity, 'units': units} if eq_templ_code not in ['',None]: ins_data['equipment_used_templ_code'] = eq_templ_code server.insert('twog/equipment_used', ins_data) # Attach the templated prereqs wot_prereqs_expr = "@SOBJECT(twog/work_order_prereq_templ['work_order_templ_code','%s'])" % wo_templ_code wot_prereqs = server.eval(wot_prereqs_expr) for wp in wot_prereqs: prereq = wp.get('prereq') server.insert('twog/work_order_prereq', {'work_order_code': wo_insert.get('code'), 'prereq': prereq, 'from_title': False}) # Attach the templated work_order_intermediates # Don't create a new entry if the code had already been used all_other_wos_expr = "@SOBJECT(twog/work_order['proj_code','%s']['process','!=','%s'])" % (wo_insert.get('proj_code'), wo_insert.get('process')) all_other_wos = server.eval(all_other_wos_expr) all_other_interms = {} wods = [] for other in all_other_wos: other_reals_expr = "@SOBJECT(twog/work_order_intermediate['work_order_code','%s'])" % other.get('code') other_reals = server.eval(other_reals_expr) for otr in other_reals: intermediate_file_code = otr.get('intermediate_file_code') intermediate_file = server.eval("@SOBJECT(twog/intermediate_file['code','%s'])" % intermediate_file_code)[0] iftc = intermediate_file.get('intermediate_file_templ_code') if iftc not in [None,''] and iftc not in all_other_interms.keys(): all_other_interms[iftc] = [intermediate_file.get('code'), otr.get('code')] wods_expr = "@SOBJECT(twog/work_order_deliverables['work_order_code','%s'])" % other.get('code') wods.extend(server.eval(wods_expr)) #Intermediates aren't used at all by scheduling, we may want to get rid of these lines int_f_templ_codes_str = work_order_template.get('intermediate_file_templ_codes') int_f_templ_codes = work_order_template.get('intermediate_file_templ_codes').split(',') if int_f_templ_codes_str not in [None,'']: for tc in int_f_templ_codes: if tc not in all_other_interms.keys(): intm_templ = server.eval("@SOBJECT(twog/intermediate_file_templ['code','%s'])" % tc)[0] intm_title = intm_templ.get('title') intm_description = intm_templ.get('description') int_insert = server.insert('twog/intermediate_file', {'title': intm_title, 'description': intm_description, 'intermediate_file_templ_code': intm_templ.get('code')}) server.insert('twog/work_order_intermediate', {'work_order_code': wo_insert.get('code'), 'intermediate_file_code': int_insert.get('code')}) else: int_file_code = all_other_interms[tc] server.insert('twog/work_order_intermediate', {'work_order_code': wo_insert.get('code'), 'intermediate_file_code': int_file_code}) # Attach the templated deliverables all_delivs_expr = "@SOBJECT(twog/deliverable_templ['work_order_templ_code','%s'])" % wo_templ_code all_delivs = server.eval(all_delivs_expr) blacklisted_keys = ['code','id','login','timestamp','attn','name','deliver_to','keywords','s_status','pipeline_code','work_order_deliverables_code','work_order_templ_code','__search_key__','search_type'] for ad in all_delivs: new_deliv_data = {} for k in ad.keys(): if k not in blacklisted_keys: new_deliv_data[k] = ad.get(k) # NEED TO CREATE BARCODE HERE new_bc = 'XsXsXsXsX' repeat = True while repeat: last_bc_expr = "@SOBJECT(twog/barcode['name','The only entry'])" last_bc = server.eval(last_bc_expr)[0] last_num = int(last_bc.get('number')) new_num = last_num + 1 server.update(last_bc.get('__search_key__'), {'number': new_num}) new_bc = "2GV%s" % new_num bc_sources = server.eval("@SOBJECT(twog/source['barcode','%s'])" % new_bc) if len(bc_sources) < 2: repeat = False new_deliv_data['barcode'] = new_bc new_deliv_data['client_code'] = mr_title.get('client_code') new_deliv_data['source_for'] = '%s,%s,%s' % (mr_title.get('code'), proj.get('code'), wo_insert.get('code')) new_deliv = server.insert('twog/source', new_deliv_data) server.insert('twog/work_order_deliverables', {'attn': ad.get('attn'), 'name': ad.get('name'), 'deliver_to': ad.get('deliver_to'), 'deliverable_source_code': new_deliv.get('code'), 'title_code': mr_title.get('code'), 'work_order_code': wo_insert.get('code'), 'deliverable_templ_code': ad.get('code')}) # NEED TO ATTACH PASS-ALONG INTERMS HERE AS WELL AS PASS-ALONG DELIVS all_other_delivs = {} for wod in wods: wod_dtc = wod.get('deliverable_templ_code') if wod_dtc not in [None,''] and wod_dtc not in all_other_delivs.keys(): all_other_delivs[wod_dtc] = [wod.get('deliverable_source_code'), wod.get('code')] #People haven't been using the passin templs, we might want to remove these lines, if they'll never use them... passin_templs = server.eval("@SOBJECT(twog/work_order_passin_templ['work_order_templ_code','%s'])" % wo_templ_code) for passin_templ in passin_templs: int_templ_code = passin_templ.get('intermediate_file_templ_code') del_templ_code = passin_templ.get('deliverable_templ_code') if int_templ_code not in [None,''] and int_templ_code in all_other_interms.keys(): server.insert('twog/work_order_passin', {'work_order_code': wo_insert.get('code'), 'intermediate_file_code': all_other_interms[int_templ_code][0], 'work_order_intermediate_code': all_other_interms[int_templ_code][1], 'passin_templ_code': passin_templ.get('code')}) elif del_templ_code not in [None,''] and del_templ_code in all_other_delivs.keys(): server.insert('twog/work_order_passin', {'work_order_code': wo_insert.get('code'), 'deliverable_source_code': all_other_delivs[del_templ_code][0], 'work_order_deliverables_code': all_other_delivs[del_templ_code][1], 'passin_templ_code': passin_templ.get('code')}) else: transfer_wo = transfer.get('work_order_code') #transfer_wo = server.eval("@SOBJECT(twog/work_order_transfer['work_oder_code','%s'])" % sobj.get('transfer_wo'))[0] wo_upd = { 'description': transfer.get('description'), 'keywords': transfer.get('keywords'), 'instructions': transfer.get('instructions'), 'process': transfer.get('process'), 'client_code': transfer.get('client_code'), 'work_group': transfer.get('work_group'), 'templ_me': templ_me, 'estimated_work_hours': transfer.get('estimated_work_hours') } server.update(wo_insert.get('__search_key__'), wo_upd) all_eqs = server.eval("@GET(twog/equipment_used['work_order_code','%s'].__search_key__)" % transfer_wo) all_wods = server.eval("@GET(twog/work_order_deliverables['work_order_code','%s'].__search_key__)" % transfer_wo) all_wois = server.eval("@GET(twog/work_order_intermediate['work_order_code','%s'].__search_key__)" % transfer_wo) all_wops = server.eval("@GET(twog/work_order_passin['work_order_code','%s'].__search_key__)" % transfer_wo) all_woprs = server.eval("@GET(twog/work_order_prereq['work_order_code','%s'].__search_key__)" % transfer_wo) all_woss = server.eval("@GET(twog/work_order_sources['work_order_code','%s'].__search_key__)" % transfer_wo) # Attach these objects to the work order for equipment_sk in all_eqs: # equipment_used has update triggers, so I'm wary about doing an update_multiple server.update(equipment_sk, {'work_order_code': wo_insert.get('code')}) update_data = {} update_value = {'work_order_code': wo_insert.get('code')} update_data.update(dict.fromkeys(all_wods, update_value)) update_data.update(dict.fromkeys(all_wois, update_value)) update_data.update(dict.fromkeys(all_wops, update_value)) update_data.update(dict.fromkeys(all_woprs, update_value)) update_data.update(dict.fromkeys(all_woss, update_value)) server.update_multiple(update_data) tr = server.eval("@SOBJECT(twog/work_order_transfer['code','%s'])" % transfer.get('code')) if len(tr) > 0: server.retire_sobject(transfer.get('__search_key__')) if 'twog/title' in sobj.get('search_type'): #The resulting object will be a proj title = server.eval("@SOBJECT(twog/title['code','%s'])" % sobj.get('title_code'))[0] title_code = title.get('code') title_title = title.get('title') title_episode = title.get('episode') title_territory = title.get('territory') title_platform = title.get('platform') title_id_number = title.get('title_id_number') new_expr = "@SOBJECT(twog/order['code','%s'])" % title.get('order_code') order = server.eval(new_expr)[0] client_code = title.get('client_code') client_names = server.eval("@GET(twog/client['code','%s'].name)" % client_code) if len(client_names) > 0: client_name = client_names[0] pipeline_code = title.get('pipeline_code') pipe_for_expr = pipeline_code spt_processes = server.eval("@SOBJECT(config/process['pipeline_code','%s']['process','%s'])" % (pipeline_code, sobj.get('process'))) # take the first one, we dont expect duplicates spt_process = spt_processes[0] # query if it exists proj = server.query('twog/proj', filters=[('process',sobj.get('process')), ('title_code', title.get('code')), ('description', spt_process.get('description')),('parent_pipe',pipeline_code)]) if proj: return desc = spt_process.get('description') if not desc: desc = '' pj_expr = "@SOBJECT(twog/proj_templ['process','%s']['parent_pipe','%s'])" % (sobj.get('process'), pipeline_code) proj_template = server.eval(pj_expr) if proj_template: proj_template = proj_template[0] is_billable = True flat_pricing = False rate_card_price = 0 specs = '' projected_markup_pct = 0.0 projected_overhead_pct = 0.0 assign_pipe_code = '' proj_templ_code = '' if proj_template: proj_templ_code = proj_template.get('code') is_billable = proj_template.get('is_billable') flat_pricing = proj_template.get('flat_pricing') rate_card_price = proj_template.get('rate_card_price') specs = proj_template.get('specs') projected_markup_pct = proj_template.get('projected_markup_pct') projected_overhead_pct = proj_template.get('projected_overhead_pct') combo_expr = "@SOBJECT(twog/client_pipes['process_name','%s']['pipeline_code','%s'])" % (proj_template.get('process'), pipe_for_expr) combos = server.eval(combo_expr) if len(combos) > 0: assign_pipe_code = combos[0].get('pipe_to_assign') proj_ins_data = { 'process': sobj.get('process'), 'title_code': title.get('code'), 'description': spt_process.get('description'), 'task_code': sobj.get('code'), 'is_billable': is_billable, 'flat_pricing': flat_pricing, 'rate_card_price': rate_card_price, 'specs': specs, 'priority': 100, 'projected_markup_pct': projected_markup_pct, 'projected_overhead_pct': projected_overhead_pct, 'client_code': title.get('client_code'), 'pipeline_code': 'No Pipeline Assigned', 'parent_pipe': pipeline_code, 'order_name': order.get('name'), 'po_number': order.get('po_number'), 'status': sobj.get('status'), 'proj_templ_code': proj_templ_code, 'order_code': order.get('code') } if title_title not in [None,'']: proj_ins_data['title'] = title_title if title_due_date not in [None,'']: proj_ins_data['due_date'] = title_due_date if title_episode not in [None,'']: proj_ins_data['episode'] = title_episode if title_territory not in [None,'']: proj_ins_data['territory'] = title_territory if title_platform not in [None,'']: proj_ins_data['platform'] = title_platform if title_id_number not in [None,'']: proj_ins_data['title_id_number'] = title_id_number proj = server.insert('twog/proj', proj_ins_data) if templ_me: server.update(proj.get('__search_key__'), {'templ_me': templ_me}) killed_task = False if proj: mr_title2_expr = "@SOBJECT(twog/title['code','%s'])" % proj.get('title_code') mr_title = server.eval(mr_title2_expr)[0] if mr_title: order2_expr = "@SOBJECT(twog/order['code','%s'])" % mr_title.get('order_code') order = server.eval(order2_expr)[0] order_classification = order.get('classification') if order_classification in ['master','Master']: is_master = True server.retire_sobject(sobj_sk) killed_task = True server.update(proj.get('__search_key__'), {'task_code': ''}) if not killed_task: task_data = {} task_data['lookup_code'] = proj.get('code') task_data['proj_code'] = proj.get('code') task_data['order_name'] = order.get('name') task_data['po_number'] = order.get('po_number') task_data['order_code'] = order.get('code') task_data['title_code'] = proj.get('title_code') if title_due_date: task_data['bid_end_date'] = title_due_date if user_name not in ['',None]: task_data['creator_login'] = user_name if client_name not in ['',None]: task_data['client_name'] = client_name if title_title not in ['',None]: task_data['title'] = title_title if title_episode not in ['',None]: task_data['episode'] = title_episode if title_territory not in ['',None]: task_data['territory'] = title_territory if title_platform not in ['',None]: task_data['platform'] = title_platform if title_id_number not in ['',None]: task_data['title_id_number'] = title_id_number if order.get('classification') in ['in_production','In Production']: task_data['active'] = True server.update(sobj_sk, task_data) if assign_pipe_code not in [None,'']: server.update(proj.get('__search_key__'), {'pipeline_code': assign_pipe_code, 'priority': 100}) transfer_expr = "@SOBJECT(twog/proj_transfer['login','%s'])" % (user_name) transfers = server.eval(transfer_expr) transfer = None for tran in transfers: if tran.get('used') == False: if proj.get('process') == tran.get('process'): transfer = tran server.update(tran.get('__search_key__'), {'used': True}) break else: tr = server.eval("@SOBJECT(twog/proj_transfer['code','%s'])" % tran.get('code')) if len(tr) > 0 and len(cloning) > 0: server.retire_sobject(tran.get('__search_key__')) if transfer: transfer_proj = transfer.get('proj_code') proj_upd = { # Fill in fields here. Do a second update for the pipeline code 'actual_markup_pct': transfer.get('actual_markup_pct'), 'actual_overhead_pct': transfer.get('actual_overhead_pct'), 'adjusted_price': transfer.get('adjusted_price'), 'automated_estimate': transfer.get('automated_estimate'), 'bid_offer_price': transfer.get('bid_offer_price'), 'charged_amount': transfer.get('charged_amount'), 'client_status': transfer.get('client_status'), 'cost_margin': transfer.get('cost_margin'), 'flat_pricing': transfer.get('flat_pricing'), 'is_billable': transfer.get('is_billable'), 'pipeline_code': transfer.get('pipeline_code'), 'post_order_price': transfer.get('post_order_price'), 'projected_markup_pct': transfer.get('projected_markup_pct'), 'rate_card_price': transfer.get('rate_card_price'), 'specs': transfer.get('specs'), 'description': transfer.get('description'), 'keywords': transfer.get('keywords'), 'proj_templ_code': transfer.get('proj_templ_code'), 'title_code': transfer.get('title_code'), 'process': transfer.get('process'), 'client_code': transfer.get('client_code'), 'templ_me': templ_me, 'login': user_name } if transfer.get('completion_date') not in [None,'']: proj_upd['completion_date'] = SPTDate.convert_to_local(transfer.get('completion_date')) if transfer.get('start_date') not in [None,'']: proj_upd['start_date'] = SPTDate.convert_to_local(transfer.get('start_date')) if transfer.get('due_date') not in [None,'']: proj_upd['due_date'] = SPTDate.convert_to_local(transfer.get('due_date')) proj_again = server.update(proj.get('__search_key__'), proj_upd) tr = server.eval("@SOBJECT(twog/proj_transfer['code','%s'])" % transfer.get('code')) if len(tr) > 0: server.retire_sobject(transfer.get('__search_key__')) 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_SCRIPT00008 #THIS IS MAKE KIDS MATCH PIPE from pyasm.common import Environment from pyasm.common import SPTDate login = Environment.get_login() user_name = login.get_login() sk = input.get('search_key') st = sk.split('?')[0] st2 = '%s?project=twog' % st update_data = input.get('update_data') prev_data = input.get('prev_data') new_pipe = update_data.get('pipeline_code') old_pipe = prev_data.get('pipeline_code') sobb = input.get('sobject') order_code = sobb.get('order_code') pipe_create_method = sobb.get('pipe_create_method') the_order = server.eval("@SOBJECT(twog/order['code','%s'])" % order_code)[0] client_code = '' client_name = '' client = server.eval("@SOBJECT(twog/client['code','%s'])" % the_order.get('client_code')) client_hold_str = 'no problems' if client: client = client[0] client_code = client.get('code') client_name = client.get('name') client_hold = client.get('billing_status') if 'Do Not Ship' in client_hold: client_hold_str = 'noship' elif 'Do Not Book' in client_hold: client_hold_str = 'nobook' title_code = '' if st == 'twog/title': title_code = sobb.get('code') elif st == 'twog/proj': title_code = sobb.get('title_code') sob_code = sobb.get('code') sob_id = sobb.get('id') my_id = sob_id deps = {} saved_task_info = {} found = [] if new_pipe != old_pipe and st in ['twog/title','twog/proj']: if st == 'twog/proj': parent_expr = "@SOBJECT(twog/title['code','%s'])" % sobb.get('title_code') poss_parents = server.eval(parent_expr) if poss_parents: par = poss_parents[0] client_pipe_expr = "@SOBJECT(twog/client_pipes['pipeline_code','%s']['process_name','%s'])" % (par.get('pipeline_code'),sobb.get('process')) client_pipes = server.eval(client_pipe_expr) order = server.eval("@SOBJECT(twog/order['code','%s'])" % par.get('order_code'))[0] order_classification = order.get('classification') is_master = False if order_classification in ['master','Master']: is_master = True if is_master: if client_pipes: client_pipe = client_pipes[0] server.update(client_pipe.get('__search_key__'), {'pipe_to_assign': new_pipe}) else: server.insert('twog/client_pipes',{'pipeline_code': par.get('pipeline_code'), 'client_code': par.get('client_code'), 'process_name': sobb.get('process'), 'pipe_to_assign': new_pipe}) spt_processes_expr = "@SOBJECT(config/process['pipeline_code','%s'])" % (new_pipe) spt_processes = server.eval(spt_processes_expr) kids_expr = '' kids = [] if st == 'twog/title': kids_expr = "@SOBJECT(twog/proj['title_code','%s'])" % sob_code elif st == 'twog/proj': kids_expr = "@SOBJECT(twog/work_order['proj_code','%s'])" % sob_code kids = server.eval(kids_expr) if pipe_create_method != 'append': future_retires = {} for p in spt_processes: pr = p.get('process') for kid in kids: if p.get('process') == kid.get('process'): found.append(p.get('process')) deps_expr = '' if st == 'twog/title': deps_expr = "@SOBJECT(twog/work_order['proj_code','%s'])" % kid.get('code') dep_list = server.eval(deps_expr) for dep in dep_list: if p.get('process') not in deps.keys(): deps[p.get('process')] = [] deps[p.get('process')].append(dep) future_retires[pr] = kid.get('__search_key__') for kid in kids: if kid.get('process') not in future_retires.keys(): server.retire_sobject(kid.get('__search_key__')) tasks_expr = "@SOBJECT(sthpw/task['search_id','%s'])" % my_id tasks = server.eval(tasks_expr) for task in tasks: if task.get('process') in found: if task.get('process') not in saved_task_info.keys(): saved_task_info[task.get('process')] = task server.retire_sobject(task.get('__search_key__')) if task.get('process') in future_retires.keys(): server.retire_sobject(future_retires[task.get('process')]) if tasks == []: the_set = future_retires.keys() for prc in the_set: server.retire_sobject(future_retires[prc]) new_tasks = {} for p in spt_processes: mr_t = '' pr = p.get('process') if p.get('process') in saved_task_info.keys(): mr_t_data = { 'assigned': saved_task_info[pr].get('assigned'), 'description': saved_task_info[pr].get('description'), 'status': saved_task_info[pr].get('status'), 'discussion': saved_task_info[pr].get('discussion'), 'bid_duration': saved_task_info[pr].get('bid_duration'), 'search_type': saved_task_info[pr].get('search_type'), 'search_id': saved_task_info[pr].get('search_id'), 'timestamp': 'now()', 's_status': saved_task_info[pr].get('s_status'), 'process': saved_task_info[pr].get('process'), 'context': saved_task_info[pr].get('context'), 'milestone_code': saved_task_info[pr].get('milestone_code'), 'pipeline_code': new_pipe, 'parent_id': saved_task_info[pr].get('parent_id'), 'sort_order': saved_task_info[pr].get('sort_order'), 'depend_id': saved_task_info[pr].get('depend_id'), 'project_code': saved_task_info[pr].get('project_code'), 'supervisor': saved_task_info[pr].get('supervisor'), 'completion': saved_task_info[pr].get('completion'), 'client_code': client_code, 'client_name': client_name, 'client_hold': client_hold_str, 'order_code': the_order.get('code'), 'title_code': title_code, 'transfer_wo': saved_task_info[pr].get('lookup_code') } if saved_task_info[pr].get('bid_start_date') not in [None,'']: mr_t_data['bid_start_date'] = SPTDate.convert_to_local(saved_task_info[pr].get('bid_start_date')) if saved_task_info[pr].get('bid_end_date') not in [None,'']: mr_t_data['bid_end_date'] = SPTDate.convert_to_local(saved_task_info[pr].get('bid_end_date')) elif sobb.get('due_date') not in [None,'']: mr_t_data['bid_end_date'] = SPTDate.convert_to_local(sobb.get('due_date')) if saved_task_info[pr].get('actual_start_date') not in [None,'']: mr_t_data['actual_start_date'] = SPTDate.convert_to_local(saved_task_info[pr].get('actual_start_date')) if saved_task_info[pr].get('actual_end_date') not in [None,'']: mr_t_data['actual_end_date'] = SPTDate.convert_to_local(saved_task_info[pr].get('actual_end_date')) if the_order.get('classification') in ['in_production','In Production']: mr_t_data['active'] = True mr_t = server.insert('sthpw/task', mr_t_data) else: in_data = { 'description': p.get('description'), 'status': 'Pending', 'search_type': st2, 'search_id': my_id, 'timestamp': 'now()', 'process': pr, 'context': pr, 'client_code': client_code, 'client_name': client_name, 'client_hold': client_hold_str, 'order_code': the_order.get('code'), 'title_code': title_code, 'pipeline_code': new_pipe, 'project_code': 'twog' } if sobb.get('due_date') not in [None,'']: in_data['bid_end_date'] = SPTDate.convert_to_local(sobb.get('due_date')) if the_order.get('classification') in ['in_production','In Production']: in_data['active'] = True mr_t = server.insert('sthpw/task', in_data) new_tasks[p.get('process')] = mr_t.get('code') if st == 'twog/title': if pipe_create_method != 'append': for kid in kids: if kid.get('process') not in saved_task_info.keys(): kid['s_status'] = 'retired' server.retire_sobject(kid.get('__search_key__')) else: server.update(kid.get('__search_key__'), {'task_code': new_tasks[kid.get('process')]}) new_kids_expr = '' new_kids = [] new_kids_expr = "@SOBJECT(twog/proj['title_code','%s'])" % sob_code new_kids = server.eval(new_kids_expr) for nkid in new_kids: if nkid.get('process') in deps.keys(): for dep in deps[nkid.get('process')]: if st == 'twog/title': server.update(dep.get('__search_key__'), {'proj_code': nkid.get('code')}) title_prereq_expr = "@SOBJECT(twog/title_prereq['title_code','%s']['pipeline_code','%s'])" % (sob_code,old_pipe) title_prereqs = server.eval(title_prereq_expr) for tp in title_prereqs: server.retire_sobject(tp.get('__search_key__')) if new_pipe not in ['',None]: if new_pipe.find('NOTHINGXsXNOTHING') == -1: pipe_prereq_expr = "@SOBJECT(twog/pipeline_prereq['pipeline_code','%s'])" % new_pipe pipe_prereqs = server.eval(pipe_prereq_expr) for p in pipe_prereqs: server.insert('twog/title_prereq',{'title_code': sob_code, 'pipeline_code': new_pipe, 'prereq': p.get('prereq'), 'satisfied': False}) #Now do all Work Orders. Give them the same prereqs wos = server.eval("@SOBJECT(twog/title['code','%s'].twog/proj.twog/work_order)" % sob_code) for wo in wos: for p in pipe_prereqs: server.insert('twog/work_order_prereq', {'work_order_code': wo.get('code'), 'prereq': p.get('prereq'), 'satisfied': False, 'from_title': True}, triggers=False) if pipe_create_method != 'append': title_deliverable_expr = "@SOBJECT(twog/deliverable['title_code','%s'])" % (sob_code) title_deliverables = server.eval(title_deliverable_expr) for tp in title_deliverables: server.retire_sobject(tp.get('__search_key__')) if new_pipe not in ['',None]: pipe_deliverable_expr = "@SOBJECT(twog/deliverable_templ['pipeline_code','%s'])" % new_pipe pipe_deliverables = server.eval(pipe_deliverable_expr) for p in pipe_deliverables: p_keys = p.keys() p_data = {} p_data['title_code'] = sob_code for k in p_keys: if k not in ['code','id','__search_key__','search_key','search_type','login','notes','timestamp','s_status','pipeline_code']: p_data[k] = p[k] server.insert('twog/deliverable', p_data) server.update(sk, {'trigger_me': ''}) 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_format_value(self, value, format, format_option=None): '''format is required. format_option is optional where applicable like fps for timecode''' if value == '': return value if isinstance(value, datetime.datetime): value = str(value) elif not isinstance(value, basestring): value = str(value) if value.startswith("{") and value.endswith("}"): from pyasm.search import Search value = Search.eval(value) # ------------------------------------------------ # Integer if format == '-1234': if not value: # Case where value is '', 0, 0.0, -0.0 . value = 0 value = "%0.0f" % self.convert_to_float(value) elif format == '-1,234': if value == None: value = "" elif not value: value = 0 # Group the value into three numbers seperated by a comma. value = self.number_format(value, places=0) # ------------------------------------------------ # Float elif format == '-1234.12': if not value: value = 0 value = "%0.2f" % self.convert_to_float(value) elif format == '-1,234.12': # break the value up by 3s if not value: value = 0 elif isinstance(value, basestring): value = float(value) value = self.number_format(value, places=2) # ------------------------------------------------ # Percentage elif format == '-13%': if not value: value = 0 value = self.convert_to_float(value) * 100 value = "%0.0f" % self.convert_to_float(value) + "%" elif format == '-12.95%': if not value: value = 0 value = self.convert_to_float(value) * 100 value = "%0.2f" % self.convert_to_float(value) + "%" # ------------------------------------------------ # Currency elif format == '-$1,234': # break the value up by 3s if not value: value = 0 value = self.currency_format(value, grouping=True) value = value[0:-3] elif format == '-$1,234.00': if not value: value = 0 value = self.currency_format(value, grouping=True) elif format == '-$1,234.--': # break the value up by 3s if not value: value = 0 value = self.currency_format(value, grouping=True) value = value[0:-3] + ".--" elif format == '-$1,234.00 CAD': # break the value up by 3s if not value: value = 0 value = self.currency_format(value, grouping=True, monetary=True) elif format == '($1,234.00)': # break the value up by 3s if not value: value = "-" else: value = self.currency_format(value, grouping=True) if value.startswith("-"): value = "(%s)" % value.replace("-", "") # ------------------------------------------------ # Date elif format == '31/12/99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y") elif format == 'December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%B %d, %Y") elif format == '31/12/1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%Y") elif format == 'Dec 31, 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%b %d, %y") elif format == 'Dec 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%b %d, %Y") elif format == '31 Dec, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d %b, %Y") elif format == '31 December 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d %B %Y") elif format == 'Fri, Dec 31, 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a, %b %d, %y") elif format == 'Fri 31/Dec 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a %d/%b %y") elif format == 'Fri, December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a, %B %d, %Y") elif format == 'Friday, December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%A, %B %d, %Y") elif format == '12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%d") elif format == '99-12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%y-%m-%d") elif format == '1999-12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%Y-%m-%d") elif format == '12-31-1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%d-%Y") elif format == '12/99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%y") elif format == '31/Dec': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%b") elif format == 'December': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%B") elif format == '52': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%U") # ------------------------------------------------ # Time elif format == '13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%H:%M") elif format == '13:37:46': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%H:%M:%S") elif format == '01:37 PM': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%I:%M %p") elif format == '01:37:46 PM': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%I:%M:%S %p") elif format == '31/12/99 13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y %H:%M") elif format == '99/12/31 13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%y/%m/%d %H:%M") elif format == '1999/12/31 13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%Y/%m/%d %H:%M") elif format == 'YYYY/MM/DD HH:MM AM': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%Y/%m/%d %I:%M %p") elif format == '31/12/99 13:37:46': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y %H:%M:%S") elif format == 'DATETIME': if not value: value = '' else: value = parser.parse(value) from pyasm.biz import ProdSetting setting = ProdSetting.get_value_by_key('DATETIME') if not setting: setting = "%Y-%m-%d %H:%M" value = value.strftime(setting) elif format == 'DATE': if not value: value = '' else: value = parser.parse(value) from pyasm.biz import ProdSetting setting = ProdSetting.get_value_by_key('DATE') if not setting: setting = "%Y-%m-%d" value = value.strftime(setting) elif format == 'TIME_AGO': if not value: value = '' else: value = parser.parse(value) from pyasm.common import SPTDate value = SPTDate.get_time_ago(value) # ------------------------------------------------ # Scientific elif format == '-1.23E+03': if not value: value = '' else: try: value = "%.2e" % self.convert_to_float(value) except: value = "0.00" elif format == '-1.234E+03': if not value: value = '' else: try: value = "%.2e" % self.convert_to_float(value) except: value = "0.00" # ------------------------------------------------ # Boolean # false = 0, true = 1 elif format in ['True|False']: if value: value = 'True' else: value = 'False' elif format in ['true|false']: if value: value = 'true' else: value = 'false' # ------------------------------------------------ # Timecode elif format in ['MM:SS.FF','MM:SS:FF', 'MM:SS', 'HH:MM:SS.FF', 'HH:MM:SS:FF','HH:MM:SS']: #fps = self.get_option('fps') fps = format_option if not fps: fps = 24 else: fps = int(fps) timecode = TimeCode(frames=value, fps=fps) value = timecode.get_timecode(format) # ------------------------------------------------ # Dictionary elif format == "DICT": dict_as_str = "" dict_list = [] if not value: value = '' else: for key, value in sorted(value.iteritems()): dict_list.append("%s : %s" % (key, value)) dict_as_str = "<br />".join(dict_list) value = dict_as_str # ------------------------------------------------ # File Size elif format in ['KB']: value = float(value) ext = " B" if not value: value = 0 ext = "B" elif value > 1024**5/2: value = float(value)/1024**5 ext = "PB" elif value > 1024**4/2: value = float(value)/1024**4 ext = "TB" elif value > 1024**3/2: value = float(value)/1024**3 ext = "GB" elif value > 1024**2/2: value = float(value)/1024**2 ext = "MB" elif value > 1024/2: value = float(value)/1024 ext = "KB" else: value = int(value) return "%s B" % value value = self.currency_format(value, grouping=True) # HACK: remove $ and last decimal value = value[1:-1] value = "%s %s" % (value, ext) elif format in ['ROOT']: value, ext = os.path.splitext(value) elif format in ['EXT']: base, value = os.path.splitext(value) value = value.lstrip(".") elif format in ['BASENAME']: value = os.path.basename(value) elif format in ['DIRNAME']: value = os.path.dirname(value) return value
def get_format_value(self, value, format, format_option=None): '''format is required. format_option is optional where applicable like fps for timecode''' if value == '': return value if isinstance(value, datetime.datetime): value = str(value) elif not isinstance(value, basestring): value = str(value) if value.startswith("{") and value.endswith("}"): from pyasm.search import Search value = Search.eval(value) # ------------------------------------------------ # Integer if format == '-1234': if not value: # Case where value is '', 0, 0.0, -0.0 . value = 0 value = "%0.0f" % self.convert_to_float(value) elif format == '-1,234': if value == None: value = "" elif not value: value = 0 # Group the value into three numbers seperated by a comma. value = self.number_format(value, places=0) # ------------------------------------------------ # Float elif format == '-1234.12': if not value: value = 0 value = "%0.2f" % self.convert_to_float(value) elif format == '-1,234.12': # break the value up by 3s if not value: value = 0 elif isinstance(value, basestring): value = float(value) value = self.number_format(value, places=2) # ------------------------------------------------ # Percentage elif format == '-13%': if not value: value = 0 value = self.convert_to_float(value) * 100 value = "%0.0f" % self.convert_to_float(value) + "%" elif format == '-12.95%': if not value: value = 0 value = self.convert_to_float(value) * 100 value = "%0.2f" % self.convert_to_float(value) + "%" # ------------------------------------------------ # Currency elif format == '-$1,234': # break the value up by 3s if not value: value = 0 value = self.currency_format(value, grouping=True) value = value[0:-3] elif format == '-$1,234.00': if not value: value = 0 value = self.currency_format(value, grouping=True) elif format == '-$1,234.--': # break the value up by 3s if not value: value = 0 value = self.currency_format(value, grouping=True) value = value[0:-3] + ".--" elif format == '-$1,234.00 CAD': # break the value up by 3s if not value: value = 0 value = self.currency_format(value, grouping=True, monetary=True) elif format == '($1,234.00)': # break the value up by 3s if not value: value = "-" else: value = self.currency_format(value, grouping=True) if value.startswith("-"): value = "(%s)" % value.replace("-", "") # ------------------------------------------------ # Date elif format == '31/12/99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y") elif format == 'December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%B %d, %Y") elif format == '31/12/1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%Y") elif format == 'Dec 31, 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%b %d, %y") elif format == 'Dec 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%b %d, %Y") elif format == '31 Dec, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d %b, %Y") elif format == '31 December 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d %B %Y") elif format == 'Fri, Dec 31, 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a, %b %d, %y") elif format == 'Fri 31/Dec 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a %d/%b %y") elif format == 'Fri, December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a, %B %d, %Y") elif format == 'Friday, December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%A, %B %d, %Y") elif format == '12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%d") elif format == '99-12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%y-%m-%d") elif format == '1999-12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%Y-%m-%d") elif format == '12-31-1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%d-%Y") elif format == '12/99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%y") elif format == '31/Dec': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%b") elif format == 'December': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%B") elif format == '52': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%U") # ------------------------------------------------ # Time elif format == '13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%H:%M") elif format == '13:37:46': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%H:%M:%S") elif format == '01:37 PM': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%I:%M %p") elif format == '01:37:46 PM': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%I:%M:%S %p") elif format == '31/12/99 13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y %H:%M") elif format == '99/12/31 13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%y/%m/%d %H:%M") elif format == '1999/12/31 13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%Y/%m/%d %H:%M") elif format == 'YYYY/MM/DD HH:MM AM': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%Y/%m/%d %I:%M %p") elif format == '31/12/99 13:37:46': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y %H:%M:%S") elif format == 'DATETIME': if not value: value = '' else: value = parser.parse(value) from pyasm.biz import ProdSetting setting = ProdSetting.get_value_by_key('DATETIME') if not setting: setting = "%Y-%m-%d %H:%M" value = value.strftime(setting) elif format == 'DATE': if not value: value = '' else: value = parser.parse(value) from pyasm.biz import ProdSetting setting = ProdSetting.get_value_by_key('DATE') if not setting: setting = "%Y-%m-%d" value = value.strftime(setting) elif format == 'TIME_AGO': if not value: value = '' else: value = parser.parse(value) from pyasm.common import SPTDate value = SPTDate.get_time_ago(value) # ------------------------------------------------ # Scientific elif format == '-1.23E+03': if not value: value = '' else: try: value = "%.2e" % self.convert_to_float(value) except: value = "0.00" elif format == '-1.234E+03': if not value: value = '' else: try: value = "%.2e" % self.convert_to_float(value) except: value = "0.00" # ------------------------------------------------ # Boolean # false = 0, true = 1 elif format in ['True|False']: if value: value = 'True' else: value = 'False' elif format in ['true|false']: if value: value = 'true' else: value = 'false' # ------------------------------------------------ # Timecode elif format in [ 'MM:SS.FF', 'MM:SS:FF', 'MM:SS', 'HH:MM:SS.FF', 'HH:MM:SS:FF', 'HH:MM:SS' ]: #fps = self.get_option('fps') fps = format_option if not fps: fps = 24 else: fps = int(fps) timecode = TimeCode(frames=value, fps=fps) value = timecode.get_timecode(format) # ------------------------------------------------ # Dictionary elif format == "DICT": dict_as_str = "" dict_list = [] if not value: value = '' else: for key, value in sorted(value.iteritems()): dict_list.append("%s : %s" % (key, value)) dict_as_str = "<br />".join(dict_list) value = dict_as_str # ------------------------------------------------ # File Size elif format in ['KB']: value = float(value) ext = " B" if not value: value = 0 ext = "B" elif value > 1024**5 / 2: value = float(value) / 1024**5 ext = "PB" elif value > 1024**4 / 2: value = float(value) / 1024**4 ext = "TB" elif value > 1024**3 / 2: value = float(value) / 1024**3 ext = "GB" elif value > 1024**2 / 2: value = float(value) / 1024**2 ext = "MB" elif value > 1024 / 2: value = float(value) / 1024 ext = "KB" else: value = int(value) return "%s B" % value value = self.currency_format(value, grouping=True) # HACK: remove $ and last decimal value = value[1:-1] value = "%s %s" % (value, ext) elif format in ['ROOT']: value, ext = os.path.splitext(value) elif format in ['EXT']: base, value = os.path.splitext(value) value = value.lstrip(".") elif format in ['BASENAME']: value = os.path.basename(value) elif format in ['DIRNAME']: value = os.path.dirname(value) return value
def execute(my): start = time.time() from pyasm.common import SPTDate timestamp = SPTDate.now() timestamp = SPTDate.add_gmt_timezone(timestamp) timestamp = SPTDate.convert_to_local(timestamp) format = '%Y-%m-%d %H:%M:%S' timestamp = timestamp.strftime(format) updates = my.kwargs.get("updates") if isinstance(updates, basestring): updates = jsonloads(updates) last_timestamp = my.kwargs.get("last_timestamp") #assert last_timestamp if not last_timestamp: my.info = {"updates": {}, "timestamp": timestamp} return last_timestamp = parser.parse(last_timestamp) last_timestamp = SPTDate.add_gmt_timezone(last_timestamp) # give 2 seconds of extra room last_timestamp = last_timestamp - timedelta(seconds=2) # get out all of the search_keys client_keys = set() client_stypes = set() for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) # it could be a list search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key: if isinstance(search_key, list): search_key_set = set(search_key) else: search_key_set = set() search_key_set.add(search_key) client_keys.update(search_key_set) stype = values.get("search_type") if stype: client_stypes.add(stype) # find all of the search that have changed changed_keys = set() changed_types = set() for check_type in ['sthpw/change_timestamp', 'sthpw/sobject_log']: search = Search(check_type) search.add_filter("timestamp", last_timestamp, op=">") search.add_filters("search_type", ["sthpw/sobject_log", "sthpw/status_log"], op="not in") changed_sobjects = search.get_sobjects() for sobject in changed_sobjects: search_type = sobject.get_value("search_type") search_code = sobject.get_value("search_code") if search_type.startswith("sthpw/"): search_key = "%s?code=%s" % (search_type, search_code) else: search_key = "%s&code=%s" % (search_type, search_code) changed_keys.add(u'%s' % search_key) changed_types.add(search_type) intersect_keys = client_keys.intersection(changed_keys) from pyasm.web import HtmlElement results = {} for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) # handler can return a list of search_keys search_key = handler.get_search_key() else: search_key = values.get("search_key") stype = values.get("search_type") if search_key: if isinstance(search_key, list): search_key_set = set(search_key) else: search_key_set = set() search_key_set.add(search_key) # filter for search_type first if it exists # check if any search_key is contained in intersect_keys, skip if not if stype and stype in changed_types: if len(intersect_keys - search_key_set) == len(intersect_keys): continue elif len(intersect_keys - search_key_set) == len(intersect_keys): continue # evaluate any compare expressions compare = values.get("compare") if compare: search_key = values.get("search_key") if search_key: sobject = Search.get_by_search_key(search_key) else: sobject = None cmp_result = Search.eval(compare, sobject, single=True) if cmp_result == True: continue # some value to display value = "Loading ..." else: value = HtmlElement.eval_update(values) if value == None: continue results[id] = value my.info = {"updates": results, "timestamp": timestamp} #print "Dyn Cmd duration", time.time() - start return results
def get_format_value(my, value, format): if format not in ['Checkbox'] and value == '': return '' # ------------------------------------------------ # Integer if format == '-1234': if not value: # Case where value is '', 0, 0.0, -0.0 . value = 0 value = "%0.0f" % my.convert_to_float(value) elif format == '-1,234': if not value: value = 0 # Group the value into three numbers seperated by a comma. value = my.number_format(value, places=0) # ------------------------------------------------ # Float elif format == '-1234.12': if not value: value = 0 value = "%0.2f" % my.convert_to_float(value) elif format == '-1,234.12': # break the value up by 3s if not value: value = 0 value = my.number_format(value, places=2) # ------------------------------------------------ # Percentage elif format == '-13%': if not value: value = 0 value = my.convert_to_float(value) * 100 value = "%0.0f" % my.convert_to_float(value) + "%" elif format == '-12.95%': if not value: value = 0 value = my.convert_to_float(value) * 100 value = "%0.2f" % my.convert_to_float(value) + "%" # ------------------------------------------------ # Currency elif format == '-$1,234': # break the value up by 3s if not value: value = 0 value = my.currency_format(value, grouping=True) value = value[0:-3] elif format == '-$1,234.00': if not value: value = 0 value = my.currency_format(value, grouping=True) elif format == '-$1,234.--': # break the value up by 3s if not value: value = 0 value = my.currency_format(value, grouping=True) value = value[0:-3] + ".--" elif format == '-$1,234.00 CAD': # break the value up by 3s if not value: value = 0 value = my.currency_format(value, grouping=True, monetary=True) elif format == '($1,234.00)': # break the value up by 3s if not value or value == "0": value = " " else: value = my.currency_format(value, grouping=True) if value.startswith("-"): value = "<span style='color: #F00'>(%s)</span>" % value.replace("-", "") # ------------------------------------------------ # Date elif format == '31/12/99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y") elif format == 'December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%B %d, %Y") elif format == '31/12/1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%Y") elif format == 'Dec 31, 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%b %d, %y") elif format == 'Dec 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%b %d, %Y") elif format == '31 Dec, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d %b, %Y") elif format == '31 December 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d %B %Y") elif format == 'Fri, Dec 31, 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a, %b %d, %y") elif format == 'Fri 31/Dec 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a %d/%b %y") elif format == 'Fri, December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a, %B %d, %Y") elif format == 'Friday, December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%A, %B %d, %Y") elif format == '12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%d") elif format == '99-12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%y-%m-%d") elif format == '1999-12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%Y-%m-%d") elif format == '12-31-1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%d-%Y") elif format == '12/99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%y") elif format == '31/Dec': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%b") elif format == 'December': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%B") elif format == '52': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%U") # ------------------------------------------------ # Time elif format == '13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%H:%M") elif format == '13:37:46': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%H:%M:%S") elif format == '01:37 PM': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%I:%M %p") elif format == '01:37:46 PM': if not value: value = '' else: value = parser.parse(value) from pyasm.common import SPTDate timezone = my.get_option('timezone') if not timezone: pass elif timezone == "local": value = SPTDate.convert_to_local(value) else: value = SPTDate.convert_to_timezone(value, "EDT") value = value.strftime("%I:%M:%S %p") elif format == '31/12/99 13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y %H:%M") elif format == '31/12/99 13:37:46': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y %H:%M:%S") elif format == 'DATETIME': if not value: value = '' else: value = parser.parse(value) setting = ProdSetting.get_value_by_key('DATETIME') if not setting: setting = "%Y-%m-%d %H:%M" value = value.strftime(setting) elif format == 'DATE': if not value: value = '' else: value = parser.parse(value) setting = ProdSetting.get_value_by_key('DATE') if not setting: setting = "%Y-%m-%d" value = value.strftime(setting) # ------------------------------------------------ # Scientific elif format == '-1.23E+03': if not value: value = '' else: try: value = "%.2e" % my.convert_to_float(value) except: value = "0.00" elif format == '-1.234E+03': if not value: value = '' else: try: value = "%.2e" % my.convert_to_float(value) except: value = "0.00" # ------------------------------------------------ # Boolean # false = 0, true = 1 elif format in ['True|False']: if value: value = 'True' else: value = 'False' elif format in ['true|false']: if value: value = 'true' else: value = 'false' elif format == 'Checkbox': div = DivWdg() div.add_class("spt_boolean_top") from pyasm.widget import CheckboxWdg checkbox = CheckboxWdg(my.get_name()) checkbox.set_option("value", "true") if value: checkbox.set_checked() div.add(checkbox) div.add_class('spt_format_checkbox_%s' % my.get_name()) version = my.parent_wdg.get_layout_version() if version == "2": pass else: checkbox.add_behavior( { 'type': 'click_up', 'propagate_evt': True, 'cbjs_action': ''' var cached_data = {}; var value_wdg = bvr.src_el; var top_el = bvr.src_el.getParent(".spt_boolean_top"); spt.dg_table.edit.widget = top_el; var key_code = spt.kbd.special_keys_map.ENTER; spt.dg_table.inline_edit_cell_cbk( value_wdg, cached_data ); ''' } ) value = div # ------------------------------------------------ # Timecode elif format in ['MM:SS.FF','MM:SS:FF', 'MM:SS', 'HH:MM:SS.FF', 'HH:MM:SS:FF', 'HH:MM:SS']: fps = my.get_option('fps') if not fps: fps = 24 else: fps = int(fps) timecode = TimeCode(frames=value, fps=fps) value = timecode.get_timecode(format) # ------------------------------------------------ # Text formats elif format in ['wiki']: pass return value
def get_display(my): div = DivWdg() sobject = my.get_current_sobject() value = sobject.get_value("bid_end_date") if not value: return div status = sobject.get_value("status") due_date = parser.parse(value) # get today's date from pyasm.common import SPTDate today = SPTDate.start_of_today() # get the difference delta = due_date - today diff = delta.days if diff < 0: if status.lower() in ["approved", "complete", "done"]: mode = "done" else: mode = "critical" elif diff >= 0 and diff < 1: mode = "today" else: mode = "due" if mode == "critical": div.add_style("background: #F00") div.add_style("color: #FFF") msg = "%s Days" % (-diff) div.add_attr("title", msg) if diff == -1: div.add("Yesterday") else: div.add(msg) elif mode == "today": div.add_style("background: #00F") div.add_style("color: #FFF") div.add_attr("title", "Due today") div.add("Today") elif mode == "done": #div.add_style("background: #0F0") #div.add_style("color: #000") #div.add_attr("title", "Done") #div.add("Done") pass else: div.add_style("background: #FFF") div.add_style("color: #000") div.add_attr("title", "Due in %s days" % diff) if diff == 1: div.add("Tomorrow") else: div.add("%s Days" % diff) div.add_style("padding: 3px") div.add_style("text-align: center") div.add_style("margin: -3px") return div
# FIXME: don't know how to do this any other way try: if not list: result = result.get_display_value() except AttributeError, e: pass if list and result: # turn non basestring into string encoded_result = [] for res in result: if isinstance(res, datetime.datetime): res = SPTDate.convert_to_local(res) res = str(res) elif not isinstance(res, basestring): res = unicode(res).encode('utf-8','ignore') encoded_result.append(res) result = ','.join(encoded_result) # FIXME: can we just do this?? # adding a tempoary value to this sobject ... dangerous because we # cannot commit this ... need a place for calculated values if result == None or result == []: result = '' if isinstance(result, datetime.datetime): result = SPTDate.convert_to_local(result) return result
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_SCRIPT00020 def make_timestamp(): import datetime now = datetime.datetime.now() return now.strftime("%Y-%m-%d %H:%M:%S") def are_no_hackpipes_preceding(sob): boolio = True matcher = '' 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') pre_hacks = server.eval(pre_hacks_expr) for ph in pre_hacks: if matcher in ph.get('lookup_code'): 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': boolio = False return boolio def do_wo_loop(proj, active): # Get all work orders under the proj so we can determine # which one of them should be turned on (set to ready) wos = server.eval("@SOBJECT(twog/work_order['proj_code','%s'])" % proj.get('code')) updated_wo_count = 0 for wo in wos: if wo.get('creation_type') not in ['hackpipe', 'hackup']: # Get the process information surrounding this wo's process from the project's pipeline info2 = server.get_pipeline_processes_info(proj.get('__search_key__'), related_process=wo.get('process')) if 'input_processes' in info2.keys(): input_processes2 = info2.get('input_processes') # WHACKER whack_says = are_no_hackpipes_preceding(wo) # END WHACKER # If there are no input_processes, this must be one of the work orders to set to ready # (unless hackpipe says otherwise) if len(input_processes2) < 1 and whack_says: wtask_code = wo.get('task_code') # Get the task associated with the work order wtask = server.eval("@SOBJECT(sthpw/task['code','%s'])" % wtask_code) if wtask: wtask = wtask[0] wdata = {'active': active} # If the task has not been raised above 'Pending' yet, and if active should be true, # update the status to 'Ready' if wtask.get('status') == 'Pending' and active: wdata['status'] = 'Ready' server.update(wtask.get('__search_key__'), wdata, triggers=False) updated_wo_count += 1 # Get all the hack work orders stemming directly off of the proj hwos_expr = "@SOBJECT(twog/hackpipe_out['lookup_code','%s'])" % proj.get('code') hack_wos = server.eval(hwos_expr) for how in hack_wos: # If this is a work order, continue. If not, don't if 'WORK' in how.get('out_to'): wo = server.eval("@SOBJECT(twog/work_order['code','%s'])" % how.get('out_to')) if wo: wo = wo[0] wtask = server.eval("@SOBJECT(sthpw/task['code','%s'])" % wo.get('task_code')) if wtask: wtask = wtask[0] wdata = {'active': active} if wtask.get('status') == 'Pending' and active: wdata['status'] = 'Ready' server.update(wtask.get('__search_key__'), wdata, triggers=False) updated_wo_count += 1 if updated_wo_count == 0: wo_dict = {} for wo in wos: if wo.get('creation_type') not in ['hackpipe', 'hackup']: info = server.get_pipeline_processes_info(server.build_search_key('twog/proj', proj.get('code')), related_process=wo.get('process')) input_processes = info.get('input_processes') if wo.get('code') not in wo_dict.keys(): wo_dict[wo.get('code')] = 0 for in_p in input_processes: wo_alive_expr = "@SOBJECT(twog/work_order['proj_code','%s']['process','%s'])" % (proj.get('code'), in_p) wo_alive = server.eval(wo_alive_expr) wo_dict[wo.get('code')] += len(wo_alive) for pd in wo_dict.keys(): if wo_dict[pd] == 0: wtask = server.eval("@SOBJECT(sthpw/task['lookup_code','%s']['status','Pending'])" % pd) if wtask: wtask = wtask[0] server.update(wtask.get('__search_key__'), {'status': 'Ready'}, triggers=False) def loop_innerds(proj, hack, active): got_one = False # Get the object representing the proj's title parent = server.get_parent(proj.get('__search_key__')) # Get the pipeline information about which processes lead into and out of the proj process input_processes = [] if not hack: info = server.get_pipeline_processes_info(parent.get('__search_key__'), related_process=proj.get('process')) input_processes = info.get('input_processes') else: hack_rez = are_no_hackpipes_preceding(proj) if not hack_rez: input_processes.append("TRIPWIRE") # If there are no input processes for this, it must be one of the proj's that should be set to 'Ready' # (but we'll need to check hackpipe first) if input_processes is not None and len(input_processes) < 1: ptask_code = proj.get('task_code') # Get the actual task associated with the proj ptask = server.eval("@SOBJECT(sthpw/task['code','%s'])" % ptask_code) if ptask: ptask = ptask[0] # We'll be setting active to on or off anyway... pdata = {'active': active} # PHACKER phack_says = are_no_hackpipes_preceding(proj) # END PHACKER if ptask.get('status') == 'Pending' and active and phack_says: pdata['status'] = 'Ready' got_one = True server.update(ptask.get('__search_key__'), pdata, triggers=False) do_wo_loop(proj, active) return got_one from pyasm.common import TacticException from pyasm.common import SPTDate update_data = input.get('update_data') prev_data = input.get('prev_data') old_classification = prev_data.get('classification').replace(' ', '_').lower() classification = update_data.get('classification').replace(' ', '_').lower() sobject = input.get('sobject') sob_code = sobject.get('code') is_in_production = False errors_bool = False error_count = {} order_sk = '' titles = [] # Need to disallow going to 'completed' from anything other than 'in_production' if classification == 'completed' and old_classification != 'in_production': raise TacticException("You can only select 'Completed' if your order's current classification is 'in_production'.") elif classification == 'completed' and old_classification == 'in_production': server.update(input.get('search_key'), {'completion_date': SPTDate.convert_to_local(make_timestamp()), 'needs_completion_review': False}) # Need to force the order checker to check if going into in_production from anything other than 'completed' if classification == 'in_production': is_in_production = True wo_under = server.eval("@GET(twog/title['order_code','%s'].twog/proj.twog/work_order.code)" % sob_code) if len(wo_under) < 1: raise TacticException("You have to build your order before you can put it into production.") else: order_sk = server.build_search_key('twog/order', sob_code) titles = server.eval("@SOBJECT(twog/title['order_code','%s'])" % sob_code) work_order_count_update = {} total_order_wos = 0 total_order_completed = 0 for title in titles: title_code = title.get('code') tasks_total = server.eval("@COUNT(sthpw/task['title_code','%s']['lookup_code','~','WORK_ORDER'])" % title_code) tasks_completed = server.eval("@COUNT(sthpw/task['title_code','%s']['lookup_code','~','WORK_ORDER']['status','Completed'])" % title_code) if tasks_total in ['', None]: tasks_total = 0 if tasks_completed in ['', None]: tasks_completed = 0 work_order_data = {'wo_count': tasks_total, 'wo_completed': tasks_completed} work_order_count_update[title.get('__search_key__')] = work_order_data total_order_wos = total_order_wos + tasks_total total_order_completed = total_order_completed + tasks_completed work_order_count_update[order_sk] = {'wo_count': total_order_wos, 'wo_completed': total_order_completed} # I have no idea if triggers should be ignored on this update_multiple server.update_multiple(work_order_count_update) if old_classification != 'completed': from order_builder import OrderCheckerWdg ocw = OrderCheckerWdg(sk=input.get('search_key')) error_count = ocw.return_error_count_dict() if error_count['Critical'] > 0: errors_bool = True # GET ALL TITLE CODES ATTACHED THE THE SOBJ (The Order) title_codes = server.eval("@GET(twog/title['order_code','%s'].code)" % sob_code) if is_in_production and not errors_bool: for tcode in title_codes: # Get all projs attached to each title projs_expr = "@SOBJECT(twog/proj['title_code','%s'])" % tcode projs = server.eval(projs_expr) good_projs = 0 for project in projs: created_by_hack = project.get('creation_type') in ['hackpipe', 'hackup'] if loop_innerds(project, created_by_hack, is_in_production): good_projs += 1 if good_projs == 0: proj_dict = {} for project in projs: if project.get('creation_type') not in ['hackpipe', 'hackup']: info = server.get_pipeline_processes_info(server.build_search_key('twog/title', tcode), related_process=project.get('process')) input_processes = info.get('input_processes') if project.get('code') not in proj_dict.keys(): proj_dict[project.get('code')] = 0 for in_p in input_processes: proj_alive_expr = "@SOBJECT(twog/proj['title_code','%s']['process','%s'])" % (tcode, in_p) proj_alive = server.eval(proj_alive_expr) proj_dict[project.get('code')] += len(proj_alive) for pd in proj_dict.keys(): if proj_dict[pd] == 0: ptask = server.eval("@SOBJECT(sthpw/task['lookup_code','%s']['status','Pending'])" % pd) if ptask: ptask = ptask[0] server.update(ptask.get('__search_key__'), {'status': 'Ready'}, triggers=False) for project in projs: if project.get('code') == ptask.get('lookup_code'): do_wo_loop(project, is_in_production) if errors_bool: raise TacticException('You still have %s critical errors with your order. You may put this into production once you fix the errors.' % error_count['Critical']) else: # now make sure that all tasks under this order are set to active or off active task_search_keys = server.eval("@GET(sthpw/task['order_code','{0}'].__search_key__)".format(sob_code)) task_update_data = dict.fromkeys(task_search_keys, {'active': is_in_production}) server.update_multiple(task_update_data, triggers=False) if classification == 'in_production': from pyasm.common import Environment from cost_builder.cost_calculator import CostCalculator login = Environment.get_login() user = login.get_login() ccw = CostCalculator(order_code=sob_code, user=user) cost_arr = ccw.update_costs() # Update actual start dates for the order and titles datetime_now = SPTDate.convert_to_local(make_timestamp()) update_start_date_keys = [title.get('__search_key__') for title in titles] update_start_date_keys.insert(0, order_sk) update_start_date_data = dict.fromkeys(update_start_date_keys, {'actual_start_date': datetime_now}) # I have no idea if triggers should be ignored on this update_multiple server.update_multiple(update_start_date_data) 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 execute(my): from pyasm.common import SPTDate for ord_code in my.order_codes: order = my.server.eval("@SOBJECT(twog/order['code','%s'])" % ord_code)[0] new_title_count = 0 old_title_count = order.get('titles_total') if old_title_count in [None,'']: old_title_count = 0 else: old_title_count = int(old_title_count) titles = my.titles_str.split(',') exchange = {} #Need to fill in wo_count on title after you find all the work orders and tally them up o_wo_count = 0 for tsss in titles: times = tsss.split('[') t = times[0] repeats = int(times[1].replace(']','')) for dr_count in range(0,repeats): t_wo_count = 0 title = my.server.eval("@SOBJECT(twog/title['code','%s'])" % t) if len(title) > 0: title = title[0] tclient = my.server.eval("@SOBJECT(twog/client['code','%s'])" % title.get('client_code')) billing_str = 'no problems' client_name = '' client_code = '' if len(tclient) > 0: tclient = tclient[0] client_name = tclient.get('name') client_code = tclient.get('code') billing_status = tclient.get('billing_status') if 'Do Not Ship' in billing_status: billing_str = 'noship' elif 'Do Not Book' in billing_status: billing_str = 'nobook' tdict = my.clone_dict(title, {'order_code': ord_code, 'order_name': order.get('name'), 'login': my.user_name, 'po_number': order.get('po_number'), 'pulled_blacks': '', 'priority': 100, 'wo_completed': 0}, ['trigger_me', 'client_status', 'status', 'closed', 'actual_cost', 'trt_pricing', 'title_id_number', 'price', 'rejection_description', 'numeric_client_status', 'saved_priority', 'resets', 'bigboard', 'wo_count', 'file_size', 'status_triggers', 'priority_triggers']) tdict['no_charge'] = my.no_charge tdict['redo'] = my.redo if my.no_charge not in [False,'False','false','f',None] and my.redo not in [False,'False','false','f',None]: tdict['priority'] = .0001 tdict['audio_priority'] = .0001 tdict['compression_priority'] = .0001 tdict['edeliveries_priority'] = .0001 tdict['edit_priority'] = .0001 tdict['machine_room_priority'] = .0001 tdict['media_vault_priority'] = .0001 tdict['qc_priority'] = .0001 tdict['vault_priority'] = .0001 tdict['price'] = 0 tdict['expected_price'] = 0 tdict['bigboard'] = True elif my.copy_attributes: # Then copy the title priorities and bigboard stuff tdict['priority'] = title.get('priority') tdict['audio_priority'] = title.get('audio_priority') tdict['compression_priority'] = title.get('compression_priority') tdict['edeliveries_priority'] = title.get('edeliveries_priority') tdict['edit_priority'] = title.get('edit_priority') tdict['machine_room_priority'] = title.get('machine_room_priority') tdict['media_vault_priority'] = title.get('media_vault_priority') tdict['qc_priority'] = title.get('qc_priority') tdict['vault_priority'] = title.get('vault_priority') tdict['bigboard'] = title.get('bigboard') else: tdict['priority'] = 100 tdict['audio_priority'] = 100 tdict['compression_priority'] = 100 tdict['edeliveries_priority'] = 100 tdict['edit_priority'] = 100 tdict['machine_room_priority'] = 100 tdict['media_vault_priority'] = 100 tdict['qc_priority'] = 100 tdict['vault_priority'] = 100 tdict['bigboard'] = False if order.get('due_date') not in [None,'']: tdict['due_date'] = SPTDate.convert_to_local(order.get('due_date')) if order.get('start_date') not in [None,'']: tdict['start_date'] = SPTDate.convert_to_local(order.get('start_date')) if order.get('expected_revenue_month') not in [None,'']: tdict['expected_revenue_month'] = SPTDate.convert_to_local(order.get('expected_revenue_month')) if order.get('expected_delivery_date') not in [None,'']: tdict['expected_delivery_date'] = SPTDate.convert_to_local(order.get('expected_delivery_date')) tdict['is_external_rejection'] = 'false' new_title = my.server.insert('twog/title', tdict, triggers=False) new_title_count = new_title_count + 1 exchange[t] = new_title.get('code') projs = my.server.eval("@SOBJECT(twog/proj['title_code','%s'])" % t) for proj in projs: ptask = my.server.eval("@SOBJECT(sthpw/task['lookup_code','%s'])" % proj.get('code')) new_ptask = None if len(ptask) > 0: ptask = ptask[0] pt_dict = my.clone_dict(ptask, {'login': my.user_name, 'creator_login': my.user_name, 'order_code': ord_code, 'title_code': new_title.get('code'), 'po_number': order.get('po_number'), 'client_name': client_name, 'title_id_number': new_title.get('title_id_number'),'search_id': title.get('id'), 'title': new_title.get('title'), 'episode': new_title.get('episode'), 'status': 'Pending', 'po_number': order.get('po_number'), 'client_hold': billing_str, 'order_name': order.get('name')}, ['assigned','discussion','bid_duration','milestone_code','parent_id','sort_order','depend_id','supervisor','completion','lookup_code','active','proj_code','supervisor','actual_duration','tripwire','closed','transfer_wo']) new_ptask = my.server.insert('sthpw/task', pt_dict, triggers=False) pdict = my.clone_dict(proj, {'status': 'Pending', 'priority': 100, 'order_code': ord_code, 'order_name': order.get('name'), 'title_code': new_title.get('code'), 'parent_pipe': new_title.get('pipeline_code'), 'client_name': client_name, 'client_code': client_code, 'title': new_title.get('title'), 'episode': new_title.get('episode'), 'po_number': new_title.get('po_number'), 'title_id_number': new_title.get('title_id_number')}, ['cost_margin','client_status','bid_offer_price','automated_estimate','adjusted_price','charged_amount','is_billable','flat_pricing','projected_overhead_pct','actual_overhead_pct','projected_markup_pct','actual_markup_pct','trigger_me','templ_me','actual_cost','tripwire','post_order_price','price','actual_cost','closed','task_code']) if new_ptask: pdict['task_code'] = new_ptask.get('code') new_proj = my.server.insert('twog/proj', pdict, triggers=False) exchange[proj.get('code')] = new_proj.get('code') #Make sure to link the task and project together both ways - lookup_code, task_code & proj_code if new_ptask: my.server.update(new_ptask.get('__search_key__'), {'lookup_code': new_proj.get('code'), 'proj_code': new_proj.get('code')}, triggers=False) wos = my.server.eval("@SOBJECT(twog/work_order['proj_code','%s'])" % proj.get('code')) for wo in wos: wtask = my.server.eval("@SOBJECT(sthpw/task['lookup_code','%s'])" % wo.get('code')) new_wtask = None if len(wtask) > 0: wtask = wtask[0] wt_dict = my.clone_dict(wtask, {'login': my.user_name, 'creator_login': my.user_name, 'order_code': ord_code, 'title_code': new_title.get('code'), 'po_number': order.get('po_number'), 'client_name': client_name, 'proj_code': new_proj.get('code'), 'title_id_number': new_title.get('title_id_number'),'search_id': new_proj.get('id'), 'title': new_title.get('title'), 'episode': new_title.get('episode'), 'status': 'Pending', 'po_number': order.get('po_number'), 'client_hold': billing_str, 'order_name': order.get('name')}, ['assigned','discussion','bid_duration','milestone_code','parent_id','sort_order','depend_id','supervisor','completion','lookup_code','active','supervisor','actual_duration','tripwire','closed','transfer_wo']) if tdict['bigboard'] in [True,'true','t',1]: wt_dict['bigboard'] = True else: wt_dict['bigboard'] = False new_wtask = my.server.insert('sthpw/task', wt_dict, triggers=False) wo_dict = my.clone_dict(wo, {'order_code': ord_code, 'title_code': new_title.get('code'), 'proj_code': new_proj.get('code'), 'client_code': client_code, 'client_name': client_name, 'order_name': order.get('name'), 'title_id_number': new_title.get('title_id_number'), 'po_number': order.get('po_number')}, ['task_code','templ_me','closed','actual_cost','assigned','eq_info','status','priority']) if new_wtask: wo_dict['task_code'] = new_wtask.get('code') new_wo = my.server.insert('twog/work_order', wo_dict, triggers=False) t_wo_count = t_wo_count + 1 exchange[wo.get('code')] = new_wo.get('code') if new_wtask: my.server.update(new_wtask.get('__search_key__'), {'lookup_code': new_wo.get('code')}, triggers=False) #Make sure to link the task and work order together both ways eqs = my.server.eval("@SOBJECT(twog/equipment_used['work_order_code','%s'])" % wo.get('code')) eq_info = '' for eq in eqs: eq_dict = my.clone_dict(eq, {'work_order_code': new_wo.get('code'), 'client_code': client_code}, ['code','keywords','work_order_code','actual_cost','actual_duration','pipeline_code']) new_eq = my.server.insert('twog/equipment_used', eq_dict, triggers=False) if eq_info == '': eq_info = '%sX|X%sX|X%sX|X' % (new_eq.get('code'), new_eq.get('name'), new_eq.get('units').upper()) else: eq_info = '%sZ,Z%sX|X%sX|X%sX|X' % (eq_info, new_eq.get('code'), new_eq.get('name'), new_eq.get('units').upper()) #When done with eq, create the eq_info string to put on the work_order my.server.update(new_wo.get('__search_key__'), {'eq_info': eq_info}) my.server.update(new_title.get('__search_key__'), {'wo_count': t_wo_count}, triggers=False) o_wo_count = o_wo_count + t_wo_count now_title_count = old_title_count + new_title_count my.server.update(order.get('__search_key__'), {'wo_count': o_wo_count, 'titles_total': now_title_count}, triggers=False) #When done with WOS, create the wo hackups, if there are any #When done with Projs, create the proj hackups, if there are any exkeys = exchange.keys() long_str = '' for ecode in exkeys: if long_str == '': long_str = ecode else: long_str = '%s|%s' % (long_str, ecode) hackups = my.server.eval("@SOBJECT(twog/hackpipe_out['out_to','in','%s'])" % long_str) for h in hackups: lookup_code = h.get('lookup_code') out_to = h.get('out_to') new_lookup = '' new_out = '' if lookup_code in exkeys: new_lookup = exchange[lookup_code] if out_to in exkeys: new_out = exchange[out_to] if new_lookup != '' and new_out != '': my.server.insert('twog/hackpipe_out',{'lookup_code': new_lookup, 'out_to': new_out}) return ''
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_SCRIPT00044 def removekey(d, key): r = dict(d) del r[key] return r # This will act as a recursive trigger. if 'update_data' in input.keys(): from pyasm.common import SPTDate update_data = input.get('update_data') ukeys = update_data.keys() sobject = input.get('sobject') keep_going = True if 'tripwire' in ukeys: if update_data.get('tripwire') == 'No Send Back': keep_going = False task = server.eval("@SOBJECT(sthpw/task['code','%s'])" % sobject.get('task_code')) if task: task = task[0] server.update(task.get('__search_key__'), {'tripwire': ''}, triggers=False) server.update(input.get('search_key'), {'tripwire': ''}, triggers=False) if keep_going: prev_data = input.get('prev_data') sobject = input.get('sobject') search_type = input.get('search_type').split('?')[0] search_key = input.get('search_key') code = search_key.split('code=')[1] st_kids = {'twog/order': ['twog/title', 'order_code'], 'twog/title': ['twog/proj', 'title_code'], 'twog/proj': ['twog/work_order', 'proj_code']} kids_data = {} task_data = {} if 'po_number' in ukeys: kids_data['po_number'] = update_data.get('po_number') task_data['po_number'] = update_data.get('po_number') if 'name' in ukeys and search_type == 'twog/order': kids_data['order_name'] = update_data.get('name') if 'order_name' in ukeys: kids_data['order_name'] = update_data.get('order_name') task_data['order_name'] = update_data.get('order_name') if 'territory' in ukeys: kids_data['territory'] = update_data.get('territory') task_data['territory'] = update_data.get('territory') if 'title' in ukeys: kids_data['title'] = update_data.get('title') task_data['title'] = update_data.get('title') if 'episode' in ukeys: kids_data['episode'] = update_data.get('episode') task_data['episode'] = update_data.get('episode') if 'platform' in ukeys: kids_data['platform'] = update_data.get('platform') task_data['platform'] = update_data.get('platform') if 'title_id_number' in ukeys: kids_data['title_id_number'] = update_data.get('title_id_number') task_data['title_id_number'] = update_data.get('title_id_number') if 'login' in ukeys: kids_data['login'] = update_data.get('login') task_data['login'] = update_data.get('login') if 'client_code' in ukeys: cl_c = update_data.get('client_code') if cl_c not in [None,'']: kids_data['client_code'] = cl_c task_data['client_code'] = cl_c if 'client_name' in ukeys: cl_n = update_data.get('client_name') if cl_n not in [None,'']: kids_data['client_name'] = cl_n task_data['client_name'] = cl_n if 'status' in ukeys and search_type not in ['twog/order','twog/title']: task_data['status'] = update_data.get('status') if 'expected_delivery_date' in ukeys and search_type != 'twog/title': kids_data['expected_delivery_date'] = SPTDate.convert_to_local(update_data.get('expected_delivery_date')) if 'due_date' in ukeys: kids_data['due_date'] = SPTDate.convert_to_local(update_data.get('due_date')) if search_type in ['twog/proj','twog/work_order']: task_data['bid_end_date'] = kids_data['due_date'] if 'start_date' in ukeys: kids_data['start_date'] = SPTDate.convert_to_local(update_data.get('start_date')) if search_type in ['twog/proj','twog/work_order']: task_data['bid_start_date'] = kids_data['start_date'] if kids_data != {} and search_type != 'twog/work_order': kids_expr = "@SOBJECT(%s['%s','%s'])" % (st_kids[search_type][0], st_kids[search_type][1], code) kids = server.eval(kids_expr) for kid in kids: server.update(kid.get('__search_key__'), kids_data) if task_data != {} and search_type in ['twog/proj','twog/work_order']: task_code = sobject.get('task_code') if task_code not in [None,'']: task = server.eval("@SOBJECT(sthpw/task['code','%s'])" % task_code) if task: task = task[0] if 'status' in task_data.keys(): task_data['tripwire'] = 'No Send Back' server.update(task.get('__search_key__'), task_data) 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_SCRIPT00100 # Easy way to get the name of something you only have a code for def get_name(code, stype): name = "N/A" sob_name = server.eval("@GET(%s['code','%s'].name)" % (stype, code)) if sob_name: name = sob_name[0] return name def kill_nulls(poss_str): ret_str = "N/A" if poss_str not in [None, ""]: ret_str = str(poss_str) return ret_str def fix_note_chars(note): if isinstance(note, bool): note2 = "False" if note: note2 = "True" note = note2 else: import sys from json import dumps as jsondumps if note not in [None, ""]: if sys.stdout.encoding: note = note.decode(sys.stdout.encoding) note = jsondumps(note) note = note.replace("||t", " ") note = note.replace("\\\\t", " ") note = note.replace("\\\t", " ") note = note.replace("\\t", " ") note = note.replace("\t", " ") note = note.replace('\\"', '"') note = note.replace('"', '"') note = note.replace("||n", "<br/>") note = note.replace("\\\\n", "<br/>") note = note.replace("\\\n", "<br/>") note = note.replace("\\n", "<br/>") note = note.replace("\n", "<br/>") return note from pyasm.common import Environment from pyasm.common import SPTDate # print "IN SEND MOVEMENT PENDING EMAIL" login = Environment.get_login() user_name = login.get_login() sobject = input.get("sobject") spe = sobject.get("send_pending_email") if spe in [True, "True", "true", "t", "T", "1", 1]: name = sobject.get("name") code = sobject.get("code") waybill = sobject.get("waybill") outside_movement_contact = sobject.get("outside_movement_contact") expected_date = sobject.get("expected_date") if expected_date in [None, ""]: expected_date = "N/A" else: expected_date_obj = SPTDate.convert_to_local(expected_date) expected_date = expected_date_obj.strftime("%Y-%m-%d %H:%M:%S") shipper_name = get_name(sobject.get("shipper_code"), "twog/shipper") sending_company_name = get_name(sobject.get("sending_company_code"), "twog/company") receiving_company_name = get_name(sobject.get("receiving_company_code"), "twog/company") description = sobject.get("description") # Need these replacements to convert to html formatting description = description.replace("\t", " ") description = description.replace("\n", "<br/>") description = description.replace(" ", " ") description = fix_note_chars(description) delim = "#Xs*" all_ccs = "[email protected]%[email protected]%[email protected]" % (delim, delim) # This is the person that originally created the movement, want to add them to the email recipients creator_name = sobject.get("login") creator = server.eval("@SOBJECT(sthpw/login['login','%s']['location','internal'])" % creator_name) if creator: creator = creator[0] all_ccs = "%s%s%s" % (all_ccs, delim, creator.get("email")) # This is the person that just saved "send_pending_email" = True, want to add them to the email recipients requestor = server.eval("@SOBJECT(sthpw/login['login','%s']['location','internal'])" % user_name) requestor_full_name = "N/A" if requestor: requestor = requestor[0] requestor_full_name = "%s %s" % (requestor.get("first_name"), requestor.get("last_name")) all_ccs = "%s%s%s" % (all_ccs, delim, requestor.get("email")) # Create the list of sources with their locations client_names = {} sources = server.eval("@SOBJECT(twog/asset_to_movement['movement_code','%s'].twog/source)" % code) table = "<table>" for source in sources: client_code = source.get("client_code") client_name = "N/A" try: client_name = client_names[client_code] except: client_name = get_name(client_code, "twog/client") client_names[client_code] = client_name pass title = kill_nulls(source.get("title")) episode = kill_nulls(source.get("episode")) season = kill_nulls(source.get("season")) version = kill_nulls(source.get("version")) barcode = kill_nulls(source.get("barcode")) source_type = kill_nulls(source.get("source_type")) in_house = kill_nulls(source.get("in_house")) generation = kill_nulls(source.get("generation")) location = "N/A" last_location = server.eval( "@SOBJECT(twog/location_tracker['source_barcode','%s']['@ORDER_BY','timestamp desc'])" % barcode ) if last_location: last_location = last_location[len(last_location) - 1] location = last_location.get("location_name") table = ( '%s<tr><td nowrap="nowrap"><b>Barcode:</b> %s</td><td nowrap="nowrap"><b>Title:</b> %s <b>Episode:</b> %s <b>Season:</b> %s <b>Version:</b> %s</td><td><b>Type:</b> %s <b>Generation:</b> %s</td><td><b>Client:</b> %s</td><td><b>In House:</b> %s</td></tr><tr><td><b>Location:</b> %s</td></tr><tr><td>|</td></tr>' % ( table, barcode, title, episode, season, version, source_type, generation, client_name, in_house, location, ) ) table = "%s</table>" % table header_row = "<div id='pagesubTitle3'>Movement Pending: <strong>%s (%s)</strong></div>" % (name, code) template_path = "/opt/spt/custom/formatted_emailer/pending_movement.html" filled_in_path = "/var/www/html/formatted_emails/pending_movement_%s.html" % code template = open(template_path, "r") filled = "" for line in template: line = line.replace("[MOVEMENT_CODE]", code) line = line.replace("[MOVEMENT_NAME]", name) line = line.replace("[CREATOR_NAME]", creator_name) line = line.replace("[TITLE_ROW]", header_row) line = line.replace("[REQUESTOR_NAME]", user_name) line = line.replace("[OUTSIDE_MOVEMENT_CONTACT]", outside_movement_contact) line = line.replace("[EXPECTED_DATE]", expected_date) line = line.replace("[DESCRIPTION]", description) line = line.replace("[SHIPPER_NAME]", shipper_name) line = line.replace("[SENDING_COMPANY]", sending_company_name) line = line.replace("[RECEIVING_COMPANY]", receiving_company_name) line = line.replace("[SOURCES_TABLE]", table) 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": "Pending Movement (%s)" % code, "from_email": "*****@*****.**", "to_email": "*****@*****.**", "from_name": requestor_full_name, "subject": "Pending Movement: %s (%s) Issued by %s" % (name, code, requestor_full_name), "all_ccs": all_ccs, "object_code": code, }, ) # print "LEAVING SEND PENDING MOVEMENT EMAIL" 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_SCRIPT00007 ### NEED TO UPDATE COSTS ABOVE SOBJECT WITH THIS SCRIPT #print "IN RETIRE TREE NEW" def hackpipe_it(data): deld_code = data.get('code') peer_type = '' parent_type_code = '' parent_exists = True if 'PROJ' in deld_code: peer_type = 'proj' parent_type_code = 'title_code' exist_check = server.eval("@SOBJECT(twog/title['code','%s'])" % data.get('title_code')) if len(exist_check) < 1: parent_exists = False elif 'WORK_ORDER' in deld_code: peer_type = 'work_order' parent_type_code = 'proj_code' exist_check = server.eval("@SOBJECT(twog/proj['code','%s'])" % data.get('proj_code')) if len(exist_check) < 1: parent_exists = False deld_sk = server.build_search_key('twog/%s' % peer_type, deld_code) hack_as_out = server.eval("@SOBJECT(twog/hackpipe_out['out_to','%s'])" % deld_code) as_out = [] for hao in hack_as_out: as_out.append(hao.get('lookup_code')) server.delete_sobject(hao.get('__search_key__')) hack_as_lookup = server.eval("@SOBJECT(twog/hackpipe_out['lookup_code','%s'])" % deld_code) as_lookup = [] for hal in hack_as_lookup: as_lookup.append(hal.get('out_to')) server.delete_sobject(hal.get('__search_key__')) # DO I NEED TO BLOCK PROJs IT IS CONNECTED TO? SAME FOR TITLES IN PROJ HACKS... for ao in as_out: for al in as_lookup: server.insert('twog/hackpipe_out', {'lookup_code': ao, 'out_to': al}) if parent_exists: parent = server.get_parent(deld_sk) parent_sk = parent.get('__search_key__') parent_code = parent_sk.split('code=')[1] # 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=data.get('process')) input_processes = info.get('input_processes') real_inputs = {} real_input_keys = [] output_processes = info.get('output_processes') if output_processes and input_processes: real_outputs = {} real_out_keys = [] if len(input_processes) < 1: real_inputs['parent'] = parent_code real_input_keys.append('parent') for ip in input_processes: rez = server.eval("@SOBJECT(twog/%s['process','%s']['%s','%s'])" % (peer_type, ip, parent_type_code, parent_code)) if rez: real_inputs[ip] = rez[0].get('code') real_input_keys.append(ip) for op in output_processes: rez = server.eval("@SOBJECT(twog/%s['process','%s']['%s','%s'])" % (peer_type, op, parent_type_code, parent_code)) if rez: real_outputs[op] = rez[0].get('code') real_out_keys.append(op) for ri in real_input_keys: if ri not in as_out and ri not in as_lookup: for ro in real_out_keys: if ro not in as_out and ro not in as_lookup: server.insert('twog/hackpipe_out', {'lookup_code': real_inputs[ri], 'out_to': real_outputs[ro]}) def floatify(num_str): float_return = 0.0 if num_str not in [None,'']: float_return = float(num_str) return float_return import os, time from pyasm.common import Environment from pyasm.common import SPTDate login = Environment.get_login() user_name = login.get_login() data = input.get('data') my_actual = floatify(data.get('actual_cost')) my_expected = floatify(data.get('expected_cost')) code = data.get('code') inorder = ['twog/order','twog/title','twog/proj','twog/work_order'] fk = ['order_code','title_code','proj_code','work_order_code'] st = input.get('search_key').split('?')[0] idx = inorder.index(st) st_code = fk[idx] last_deletion_time = 0 new_time = int(round(time.time() * 1000)) do_hackpipe = True do_cost_reduction = True del_time_path = '/var/www/html/user_del_times/%s.time' % user_name if os.path.exists(del_time_path): f = open(del_time_path, 'r') for line in f: line = line.rstrip('\r\n') if line not in [None,'','\n']: last_deletion_time = int(line) f.close() os.system('rm -rf %s' % del_time_path) f = open(del_time_path, 'w') f.write(str(new_time)) f.close() if last_deletion_time == 0: last_deletion_time = new_time # The last_deletion_time will tell us whether or not we should do the hackpipe stuff. In a long deletion from a proj or title or order, we won't want to do the hackpipe stuff. if (new_time - last_deletion_time) < 5000: do_hackpipe = False do_cost_reduction = False if st != 'twog/work_order': if st == 'twog/proj': insert_data = { 'login': user_name, 'proj_code': data.get('code') } for j in data.keys(): if j in ['description','keywords','name','actual_markup_pct','actual_overhead_pct','adjusted_price','automated_estimate','bid_offer_price','charged_amount','client_status','cost_margin','flat_pricing','is_billable','pipeline_code','post_order_price','process','projected_markup_pct','rate_card_price','specs','title_code','client_code','proj_templ_code','proj_code','used','projected_overhead_pct','expected_cost','actual_cost','creation_type','title','order_name','priority','po_number','territory','episode','status','tripwire','title_id_number','platform','order_code']: if data[j] not in [None,'']: insert_data[j] = data[j] if data.get('completion_date'): insert_data['completion_date'] = SPTDate.convert_to_local(data.get('completion_date')) if data.get('due_date'): insert_data['due_date'] = SPTDate.convert_to_local(data.get('due_date')) if data.get('start_date'): insert_data['start_date'] = SPTDate.convert_to_local(data.get('start_date')) server.insert('twog/proj_transfer', insert_data) fk_st = inorder[idx + 1] expr = "@SOBJECT(%s['%s','%s'])" % (fk_st, st_code, code) sobs = server.eval(expr) for sob in sobs: if fk_st in ['twog/title', 'twog/proj','twog/work_order']: task_code = sob.get('task_code') expr = "@SOBJECT(sthpw/task['code','%s'])" % task_code task = server.eval(expr) if len(task) > 0: task = task[0] server.retire_sobject(task.get('__search_key__')) server.retire_sobject(sob.get('__search_key__')) if st == 'twog/proj': proj_task = server.eval("@SOBJECT(sthpw/task['code','%s'])" % data.get('task_code')) if proj_task: server.retire_sobject(proj_task[0].get('__search_key__')) if do_hackpipe and st == 'twog/proj': hackpipe_it(data) elif st == 'twog/work_order': insert_data = {'login': user_name, 'work_order_code': data.get('code')} for j in data.keys(): if j in ['description','keywords','name','work_order_code','work_order_templ_code','proj_code','instructions','process','client_code','work_group','estimated_work_hours','used','actual_cost','expected_cost','creation_type','po_number','order_name','due_date','title','episode','priority','territory','title_id_number','platform','eq_info','order_code','title_code']: if data[j] not in [None,'']: insert_data[j] = data[j] server.insert('twog/work_order_transfer', insert_data) task_code = data.get('task_code') expr = "@SOBJECT(sthpw/task['code','%s'])" % task_code task = server.eval(expr) if len(task) > 0: task = task[0] server.retire_sobject(task.get('__search_key__')) if do_hackpipe: hackpipe_it(data) # COST UPDATING if do_cost_reduction: if st == 'twog/title': order_code = data.get('order_code') the_order = server.eval("@SOBJECT(twog/order['code','%s'])" % order_code) if the_order: the_order = the_order[0] order_actual = floatify(the_order.get('actual_cost')) order_expected = floatify(the_order.get('expected_cost')) new_actual = order_actual - my_actual new_expected = order_expected - my_expected server.update(the_order.get('__search_key__'), {'actual_cost': new_actual, 'expected_cost': new_expected}) elif st == 'twog/proj': title_code = data.get('title_code') the_title = server.eval("@SOBJECT(twog/title['code','%s'])" % title_code) if the_title: the_title = the_title[0] title_actual = floatify(the_title.get('actual_cost')) title_expected = floatify(the_title.get('expected_cost')) new_title_actual = title_actual - my_actual new_title_expected = title_expected - my_expected server.update(the_title.get('__search_key__'), {'actual_cost': new_title_actual, 'expected_cost': new_title_expected}) the_order = server.eval("@SOBJECT(twog/order['code','%s'])" % the_title.get('order_code')) if the_order: the_order = the_order[0] order_actual = floatify(the_order.get('actual_cost')) order_expected = floatify(the_order.get('expected_cost')) new_order_actual = order_actual - my_actual new_order_expected = order_expected - my_expected server.update(the_order.get('__search_key__'), {'actual_cost': new_order_actual, 'expected_cost': new_order_expected}) elif st == 'twog/work_order': proj_code = data.get('proj_code') the_proj = server.eval("@SOBJECT(twog/proj['code','%s'])" % proj_code) if the_proj: the_proj = the_proj[0] proj_actual = floatify(the_proj.get('actual_cost')) proj_expected = floatify(the_proj.get('expected_cost')) new_proj_actual = proj_actual - my_actual new_proj_expected = proj_expected - my_expected server.update(the_proj.get('__search_key__'), {'actual_cost': new_proj_actual, 'expected_cost': new_proj_expected}) title_code = the_proj.get('title_code') the_title = server.eval("@SOBJECT(twog/title['code','%s'])" % title_code) if the_title: the_title = the_title[0] title_actual = floatify(the_title.get('actual_cost')) title_expected = floatify(the_title.get('expected_cost')) new_title_actual = title_actual - my_actual new_title_expected = title_expected - my_expected server.update(the_title.get('__search_key__'), {'actual_cost': new_title_actual, 'expected_cost': new_title_expected}) the_order = server.eval("@SOBJECT(twog/order['code','%s'])" % the_title.get('order_code')) if the_order: the_order = the_order[0] order_actual = floatify(the_order.get('actual_cost')) order_expected = floatify(the_order.get('expected_cost')) new_order_actual = order_actual - my_actual new_order_expected = order_expected - my_expected server.update(the_order.get('__search_key__'), {'actual_cost': new_order_actual, 'expected_cost': new_order_expected}) #print "LEAVING RETIRE TREE NEW" 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_format_value(my, value, format): if format not in ['Checkbox'] and value == '': return '' # ------------------------------------------------ # Integer if format == '-1234': if not value: # Case where value is '', 0, 0.0, -0.0 . value = 0 value = "%0.0f" % my.convert_to_float(value) elif format == '-1,234': if not value: value = 0 # Group the value into three numbers seperated by a comma. value = my.number_format(value, places=0) # ------------------------------------------------ # Float elif format == '-1234.12': if not value: value = 0 value = "%0.2f" % my.convert_to_float(value) elif format == '-1,234.12': # break the value up by 3s if not value: value = 0 value = my.number_format(value, places=2) # ------------------------------------------------ # Percentage elif format == '-13%': if not value: value = 0 value = my.convert_to_float(value) * 100 value = "%0.0f" % my.convert_to_float(value) + "%" elif format == '-12.95%': if not value: value = 0 value = my.convert_to_float(value) * 100 value = "%0.2f" % my.convert_to_float(value) + "%" # ------------------------------------------------ # Currency elif format == '-$1,234': # break the value up by 3s if not value: value = 0 value = my.currency_format(value, grouping=True) value = value[0:-3] elif format == '-$1,234.00': if not value: value = 0 value = my.currency_format(value, grouping=True) elif format == '-$1,234.--': # break the value up by 3s if not value: value = 0 value = my.currency_format(value, grouping=True) value = value[0:-3] + ".--" elif format == '-$1,234.00 CAD': # break the value up by 3s if not value: value = 0 value = my.currency_format(value, grouping=True, monetary=True) # ------------------------------------------------ # Date elif format == '31/12/99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y") elif format == 'December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%B %d, %Y") elif format == '31/12/1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%Y") elif format == 'Dec 31, 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%b %d, %y") elif format == 'Dec 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%b %d, %Y") elif format == '31 Dec, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d %b, %Y") elif format == '31 December 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d %B %Y") elif format == 'Fri, Dec 31, 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a, %b %d, %y") elif format == 'Fri 31/Dec 99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a %d/%b %y") elif format == 'Fri, December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%a, %B %d, %Y") elif format == 'Friday, December 31, 1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%A, %B %d, %Y") elif format == '12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%d") elif format == '99-12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%y-%m-%d") elif format == '1999-12-31': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%Y-%m-%d") elif format == '12-31-1999': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%d-%Y") elif format == '12/99': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%m-%y") elif format == '31/Dec': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%b") elif format == 'December': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%B") elif format == '52': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%U") # ------------------------------------------------ # Time elif format == '13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%H:%M") elif format == '13:37:46': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%H:%M:%S") elif format == '01:37 PM': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%I:%M %p") elif format == '01:37:46 PM': if not value: value = '' else: value = parser.parse(value) from pyasm.common import SPTDate timezone = my.get_option('timezone') if not timezone: pass elif timezone == "local": value = SPTDate.convert_to_local(value) else: value = SPTDate.convert_to_timezone(value, "EDT") value = value.strftime("%I:%M:%S %p") elif format == '31/12/99 13:37': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y %H:%M") elif format == '31/12/99 13:37:46': if not value: value = '' else: value = parser.parse(value) value = value.strftime("%d/%m/%y %H:%M:%S") elif format == 'DATETIME': if not value: value = '' else: value = parser.parse(value) setting = ProdSetting.get_value_by_key('DATETIME') if not setting: setting = "%Y-%m-%d %H:%M" value = value.strftime(setting) elif format == 'DATE': if not value: value = '' else: value = parser.parse(value) setting = ProdSetting.get_value_by_key('DATE') if not setting: setting = "%Y-%m-%d" value = value.strftime(setting) # ------------------------------------------------ # Scientific elif format == '-1.23E+03': if not value: value = '' else: try: value = "%.2e" % my.convert_to_float(value) except: value = "0.00" elif format == '-1.234E+03': if not value: value = '' else: try: value = "%.2e" % my.convert_to_float(value) except: value = "0.00" # ------------------------------------------------ # Boolean # false = 0, true = 1 elif format in ['True|False']: if value: value = 'True' else: value = 'False' elif format in ['true|false']: if value: value = 'true' else: value = 'false' elif format == 'Checkbox': div = DivWdg() div.add_class("spt_boolean_top") from pyasm.widget import CheckboxWdg checkbox = CheckboxWdg(my.get_name()) checkbox.set_option("value", "true") if value: checkbox.set_checked() div.add(checkbox) div.add_class('spt_format_checkbox_%s' % my.get_name()) version = my.parent_wdg.get_layout_version() if version == "2": pass else: checkbox.add_behavior({ 'type': 'click_up', 'propagate_evt': True, 'cbjs_action': ''' var cached_data = {}; var value_wdg = bvr.src_el; var top_el = bvr.src_el.getParent(".spt_boolean_top"); spt.dg_table.edit.widget = top_el; var key_code = spt.kbd.special_keys_map.ENTER; spt.dg_table.inline_edit_cell_cbk( value_wdg, cached_data ); ''' }) value = div # ------------------------------------------------ # Timecode elif format in [ 'MM:SS.FF', 'MM:SS:FF', 'MM:SS', 'HH:MM:SS.FF', 'HH:MM:SS:FF', 'HH:MM:SS' ]: fps = my.get_option('fps') if not fps: fps = 24 else: fps = int(fps) timecode = TimeCode(frames=value, fps=fps) value = timecode.get_timecode(format) # ------------------------------------------------ # Text formats elif format in ['wiki']: pass return value
class ExpressionElementWdg(TypeTableElementWdg): '''General purpose element widget for expressions''' ARGS_KEYS = { 'expression': { 'description': 'Expression to evaluate the widget', 'type': 'TextAreaWdg', 'order': 1, 'category': 'Options' }, 'display_expression': { 'description': 'Expression for display purposes', 'type': 'TextAreaWdg', 'order': 2, 'category': 'Options' }, 'display_format': { 'description': 'Predefined format for display', 'type': 'TextWdg', 'order': 3, 'category': 'Options' }, 'link_expression': { 'description': 'Expression for linking to another sobject', 'type': 'TextAreaWdg', 'order': 4, 'category': 'Options', }, 'link_view': { 'description': 'View to link result to another view', 'type': 'TextWdg', 'order': 5, 'category': 'Options', }, 'inline_styles': 'Styles to add to the DIV generated that contains the result of the expression', 'return': { 'descripton': 'Determines what the expression return type should be', 'type': 'SelectWdg', 'values': 'single|list' }, 'bottom': { 'description': 'Expression to calculate the bottom row of the table', 'type': 'TextAreaWdg', }, 'group_bottom': { 'description': 'Expression to calculate the bottom of a group', 'type': 'TextAreaWdg', }, 'mode': { 'description': 'Display mode for this widget', 'type': 'SelectWdg', 'values': 'value|check|boolean', 'order': 3 }, 'expression_mode': { 'description': 'If absolute mode is selected, it does not relate to the current SObject', 'type': 'SelectWdg', 'values': 'default|absolute', 'order': 6 }, 'calc_mode': { 'description': '(ALPHA) fast|slow - fast uses new calculation mode. Only @SUM, @COUNT, @SOBJECT and @GET are current supported', 'type': 'SelectWdg', 'values': 'slow|fast', 'order': 7 }, 'show_retired': { 'description': 'true|false - true shows all the retired entries during the expression evaluation', 'type': 'SelectWdg', 'values': 'true|false', 'category': 'Options', 'order': 8 }, 'enable_eval_listener': { 'description': '''Currently javascript expression evaluation is not fully baked, so only use the client side evaluation listener when needed and NOT by default''', 'category': 'internal', }, 'use_cache': { 'description': 'Determines whether or not to use the cached value. Gets value from column with the same name as the element', 'type': 'SelectWdg', 'values': 'true|false', 'order': 0, 'category': 'Cache' }, 'order_by': { 'description': 'Turn on Order by', 'type': 'TextWdg', 'order': 8, 'category': 'Options' }, 'group_by': { 'description': 'Turn on Group by', 'type': 'SelectWdg', 'values': 'true|false', 'order': 9, 'category': 'Options' }, 'group_by_time': { 'description': 'Turn on Group by', 'type': 'SelectWdg', 'values': 'true|false', 'order': 10, 'category': 'Options' }, 'justify': { 'description': 'Result justification', 'type': 'SelectWdg', 'values': 'default|left|right|center', 'order': 11, 'category': 'Options' }, 'filter_name': { 'description': 'Name of filter to use', 'type': 'TextWdg', 'order': 12, 'category': 'Options' }, 'empty': { 'description': "vAlue to display if empty" } } def init(self): self.td = None self.expression = None self.alt_expression = None self.alt_result = None self.cache_results = None def preprocess(self): order_by = self.get_option("order_by") # for backward compatibility when order_by used to be true/false if not order_by or order_by == 'true': expression = self.get_option("expression") if expression.startswith("@GET(") and expression.endswith( ")") and expression.count("@") == 1: template = expression.lstrip("@GET(") template = template.rstrip(")") # remove white spaces template = template.strip() # if it's a simple local sType expression e.g. @GET(.id), strip the . if template.startswith("."): template = template.lstrip('.') self.set_option("order_by", template) self.init_kwargs() def get_required_columns(self): '''method to get the require columns for this''' return [] def get_header_option_wdg(self): return if self.kwargs.get("use_cache2") not in ['true', True]: return div = DivWdg() div.add("Last Calculated: 5 days ago<br/><hr/>") div.add("Recalculate") div.add_class("hand") #from tactic.ui.widget import ActionButtonWdg #button = ActionButtonWdg(title="Recalculate") #div.add(button) div.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var table = bvr.src_el.getParent(".spt_table"); //var search_keys = spt.dg_table.get_search_keys(); var search_keys = spt.dg_table.get_selected_search_keys(table); if (search_keys.length == 0) { spt.alert("No rows selected"); return; } var header = bvr.src_el.getParent(".spt_table_th"); var element_name = header.getAttribute("spt_element_name"); spt.app_busy.show("Recalculating ..."); var kwargs = { element_name: element_name, search_keys: search_keys, } spt.app_busy.show("Recalculating ..."); var server = TacticServerStub.get(); var class_name = 'tactic.ui.table.ExpressionRecalculateCmd'; server.execute_cmd(class_name, kwargs); spt.app_busy.hide("Recalculating ..."); ''' }) return div def is_sortable(self): use_cache = self.get_option("use_cache") in ['true', True] if use_cache: return True order_by = self.get_option("order_by") # false is the word to prevent the auto-adoption (preprocess) of the expression to order-by if order_by and order_by != 'false': parts = order_by.split(".") if "connect" in parts: return False return True else: return False def is_groupable(self): use_cache = self.get_option("use_cache") in ['true', True] if use_cache: return True group_by = self.get_option("group_by") if group_by: return True else: return False def is_time_groupable(self): group_by = self.get_option("group_by_time") if group_by: return True else: return False def get_vars(self): # create variables element_name = self.get_name() self.vars = {'ELEMENT_NAME': element_name} # get info from search critiera # FIXME: this should be formalized search_vars = Container.get("Message:search_vars") if search_vars: for name, value in search_vars.items(): self.vars[name] = value return self.vars def get_input_by_arg_key(self, key): if key == 'expression': input = TextAreaWdg("option_expression") else: input = TextWdg("value") return input get_input_by_arg_key = classmethod(get_input_by_arg_key) def handle_td(self, td): if self.alt_result: td.add_attr("spt_input_value", self.alt_result) elif self.alt_result: td.add_attr("spt_input_value", self.value) super(ExpressionElementWdg, self).handle_td(td) def is_editable(self): return 'optional' def _get_result(self, sobject, expression): '''get the result of the expression''' element_name = self.get_name() use_cache = self.kwargs.get("use_cache") if use_cache == "true": try: return sobject.get_value(element_name) except Exception as e: print "Error: ", e.message if type(sobject) != types.ListType: if sobject.is_insert(): return '' self.vars = { 'ELEMENT_NAME': element_name, 'ELEMENT': element_name, 'SOBJECT_ID': sobject.get_id(), 'SOBJECT_CODE': sobject.get_code(), } return_type = self.kwargs.get("return") if return_type == 'single': single = True list = False elif return_type == 'list': single = False list = True else: single = True list = False # if this expression is an absolute expression, then don't bother # with the sobject expression_mode = self.get_option('expression_mode') if expression_mode == 'absolute': sobject = None calc_mode = self.get_option("calc_mode") if not calc_mode: calc_mode = 'slow' #calc_mode = 'fast' # parse the expression parser = ExpressionParser() if calc_mode == 'fast': if self.cache_results == None: self.cache_results = parser.eval( expression, self.sobjects, vars=self.vars, dictionary=True, show_retired=self.show_retired) if isinstance(self.cache_results, basestring): if self.cache_results: self.cache_results = eval(self.cache_results) else: self.cache_results = {} search_key = sobject.get_search_key() result = self.cache_results.get(search_key) if single: if result and len(result): result = result[0] else: result = '' else: result = parser.eval(expression, sobject, vars=self.vars, single=single, list=list, show_retired=self.show_retired) # FIXME: don't know how to do this any other way try: if not list: result = result.get_display_value() except AttributeError, e: pass if list and result: # turn non basestring into string encoded_result = [] for res in result: if isinstance(res, datetime.datetime): res = SPTDate.convert_to_local(res) res = str(res) elif not isinstance(res, basestring): res = unicode(res).encode('utf-8', 'ignore') encoded_result.append(res) #delimiter = ', ' #result = delimiter.join(encoded_result) result = encoded_result if result == None or result == []: result = '' if isinstance(result, datetime.datetime): result = SPTDate.convert_to_local(result) return result
def execute(my): start = time.time() from pyasm.common import SPTDate timestamp = SPTDate.now() timestamp = SPTDate.add_gmt_timezone(timestamp) timestamp = SPTDate.convert_to_local(timestamp) format = '%Y-%m-%d %H:%M:%S' timestamp = timestamp.strftime(format) updates = my.kwargs.get("updates") if isinstance(updates, basestring): updates = jsonloads(updates) last_timestamp = my.kwargs.get("last_timestamp") #assert last_timestamp if not last_timestamp: my.info = { "updates": {}, "timestamp": timestamp } return last_timestamp = parser.parse(last_timestamp) last_timestamp = SPTDate.add_gmt_timezone(last_timestamp) # give 2 seconds of extra room last_timestamp = last_timestamp - timedelta(seconds=2) # get out all of the search_keys client_keys = set() client_stypes = set() for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) # it could be a list search_key = handler.get_search_key() else: search_key = values.get("search_key") if search_key: if isinstance(search_key, list): search_key_set = set(search_key) else: search_key_set = set() search_key_set.add(search_key) client_keys.update(search_key_set) stype = values.get("search_type") if stype: client_stypes.add(stype) # find all of the search that have changed changed_keys = set() changed_types = set() for check_type in ['sthpw/change_timestamp', 'sthpw/sobject_log']: search = Search(check_type) search.add_filter("timestamp", last_timestamp, op=">") search.add_filters("search_type", ["sthpw/sobject_log", "sthpw/status_log"], op="not in") changed_sobjects = search.get_sobjects() for sobject in changed_sobjects: search_type = sobject.get_value("search_type") search_code = sobject.get_value("search_code") if search_type.startswith("sthpw/"): search_key = "%s?code=%s" % (search_type, search_code) else: search_key = "%s&code=%s" % (search_type, search_code) changed_keys.add(u'%s'%search_key) changed_types.add(search_type) intersect_keys = client_keys.intersection(changed_keys) from pyasm.web import HtmlElement results = {} for id, values_list in updates.items(): if isinstance(values_list, dict): values_list = [values_list] for values in values_list: handler = values.get("handler") if handler: handler = Common.create_from_class_path(handler) # handler can return a list of search_keys search_key = handler.get_search_key() else: search_key = values.get("search_key") stype = values.get("search_type") if search_key: if isinstance(search_key, list): search_key_set = set(search_key) else: search_key_set = set() search_key_set.add(search_key) # filter for search_type first if it exists # check if any search_key is contained in intersect_keys, skip if not if stype and stype in changed_types: if len(intersect_keys - search_key_set) == len(intersect_keys): continue elif len(intersect_keys - search_key_set) == len(intersect_keys): continue # evaluate any compare expressions compare = values.get("compare") if compare: search_key = values.get("search_key") if search_key: sobject = Search.get_by_search_key(search_key) else: sobject = None cmp_result = Search.eval(compare, sobject, single=True) if cmp_result == True: continue # some value to display value = "Loading ..." else: value = HtmlElement.eval_update(values) if value == None: continue results[id] = value my.info = { "updates": results, "timestamp": timestamp } #print "Dyn Cmd duration", time.time() - start return results