# vim: ts=4 et sts=4 sw=4 autoindent import Pyro.core from sndcs.EmployeeFactory import EmployeeFactory from sndcs.IndirectFactory import IndirectFactory from sndcs.OperationFactory import OperationFactory from sndcs.LaborDtlFactory import LaborDtlFactory from sndcs.Config import config from sndcs_common.SndcsExceptions import * from sndcs_common.PyroProxyMixin import PyroProxyMixin from MiddleKit.Run.ObjectStore import UnknownObjectError from sndcs_common.Logger import logger log = logger.getLogger("sndcsd") class EmployeeProxyFactory(Pyro.core.ObjBase): """ The most common usage is to use one of the __init__ functions to return a transient EmployeeProxy proxy object representing a single employee. The proxy's disconnect() method must be called when the proxy object is no longer needed or the server will get cluttered up with left over proxy objects. Can use the daemon's setTransientsCleanupAge function to reap left over objects but this seems dangerous since the clint won't know that's it proxy doesn't represent a valid object anymore. """ def __init__(self): Pyro.core.ObjBase.__init__(self) # Get the Pyro namespace from the config self.namespace = config.get("pyro", "namespace", "sndcs") ### __init__ functions ### ### From EmployeeFactory ### def setEmployeeByEmpId(self, emp_id): """ Explicit __init__ function to set the employee.""" employee = EmployeeFactory().getEmployeeByEmpId(emp_id) if not employee: raise SndcsEmployeeError("No employee with empId = '%s'" % (emp_id)) proxy = EmployeeProxy() proxy.namespace = self.namespace proxy.employee = employee self.getDaemon().connect(proxy) log.debug("Returning employee proxy object %s.", proxy) return proxy.getProxy() def setEmployeeBySerialNum(self, serialNum): """ Explicit __init__ function to set the employee.""" employee = EmployeeFactory().getEmployeeBySerialNum(serialNum) if not employee: raise SndcsEmployeeError("No employee with serialNum = '%s'" % (serialNum)) proxy = EmployeeProxy() proxy.namespace = self.namespace proxy.employee = employee self.getDaemon().connect(proxy) log.debug("Returning employee proxy object %s.", proxy) return proxy.getProxy() ### Miscelaneous ### ### From EmployeeFactory ### def getEmployees(self): pass def getActiveEmployees(self): pass def getActiveEmployeeAndActivityData(self): """ A major utility function. Returns data structures representing logged in users and their activities. {} serialNum firstName lastName properName activities[] serialNum type description """ data = [] employees = EmployeeFactory().getActiveEmployees() if employees: for employee in employees: if employee.shift(): shift_name = employee.shift().name() shift_start_time = employee.shift().startTime() else: shift_name = None shift_start_time = None if employee.isClockedIn(): clock_in_stamp = employee.activeLaborHed().startStamp() else: clock_in_stamp = None emp = {"serialNum":employee.serialNum(), "firstName":employee.firstName(), "lastName":employee.lastName(), "properName":employee.properName(),"departments": employee.departments(),"shift": shift_name,"shift_start_time": shift_start_time,"clocked_in_stamp": clock_in_stamp } activities = employee.getActivities() act = [] if activities: for activity in activities: if activity["object"]: labordtl_id = activity["object"].serialNum() else: labordtl_id = None act.append({"serialNum":labordtl_id, "type":activity["type"], "description":activity["description"]}) emp["activities"] = act data.append(emp) return data class EmployeeProxy(Pyro.core.ObjBase, PyroProxyMixin): ### Utilities ### ### From Employee.py ### def properName(self): return self.employee.properName() def isClockedIn(self): return bool(self.employee.activeLaborHed()) def isCurrentIndirectActivity(self, code = None, serialNum = None): """Either pass indirect activity code or serial num""" assert code or serialNum assert not (code and serialNum) if code: indirect = IndirectFactory().getIndirectByCode(code) if not indirect: return False else: return self.employee.isCurrentIndirectActivity(indirect) elif serialNum: indirect = IndirectFactory().getIndirectBySerialNum(serialNum) if not indirect: return False else: return self.employee.isCurrentIndirectActivity(indirect) def isCurrentProductionActivity(self, serialNum, jobType = "Production"): """ Pass the operation's serialNum """ operation = OperationFactory().getOperationBySerialNum(serialNum) if not operation: return False else: return self.employee.isCurrentProductionActivity(operation, jobType) def clockIn(self, start_date_time = None, terminal_id = None): self.employee.clockIn(start_date_time, terminal_id) def clockOut(self, end_date_time = None, terminal_id = None): self.employee.clockOut(end_date_time, terminal_id) def endAllLaborDtl(self, terminal_id = None): self.employee.endAllLaborDtl(terminal_id) def getActiveLaborDetails(self): details = [] dtls = self.employee.getActiveLaborDetails() for x in dtls: details.append(x.dataDict()) return details def getActiveProductionLaborDetails(self): details = [] dtls = self.employee.getActiveProductionLaborDetails() for x in dtls: details.append(x.dataDict()) return details def getActiveProductionAndSetupLaborDetails(self): details = [] dtls = self.employee.getActiveProductionAndSetupLaborDetails() for x in dtls: details.append(x.dataDict()) return details def getActivities(self): activities = [] act = self.employee.getActivities() for x in act: # If idle "object" will be None if not x["object"]: serial_num = None else: serial_num = x["object"].serialNum() activities.append({"labordtl_id":serial_num, "type":x["type"], "description":x["description"]}) return activities def getNumberActiveProductionLaborDetails(self): return self.employee.getNumberActiveProductionLaborDetails() def getNumberActiveProductionAndSetupLaborDetails(self): return self.employee.getNumberActiveProductionAndSetupLaborDetails() def getNumberActiveLaborDetails(self): return self.employee.getNumberActiveLaborDetails() def isGanged(self): return self.employee.isGanged() def isSuspended(self): if self.employee.isClockedIn(): return self.employee.isSuspended() def resumeAllLaborDtls(self,terminal_id = None): self.employee.resumeAllLaborDtls( terminal_id = terminal_id ) def suspendAllLaborDtls(self): self.employee.suspendAllLaborDtl() def stopAllActiveLaborDtls(self, terminal_id = None): #Only stops ACTIVE LaborDtl's self.employee.stopAllActiveLaborDtls( terminal_id ) def log_on_off_lunch_break(self, type=1, terminal_id = None): self.employee.log_on_off_lunch_break(type, terminal_id) def startProduction(self, operation_id, jobType = "Production", terminal_id = None): try: operation = OperationFactory().getOperationBySerialNum(operation_id) except UnknownObjectError: raise SndcsOperationError("No operation exists with serialNum = '%s'" % (operation_id)) self.employee.startProduction(operation, jobType, terminal_id) def startIndirect(self, indirect_serial_num = None, indirect_code = None, terminal_id = None, global_indirect = False): if indirect_serial_num: try: indirect = IndirectFactory().getIndirectBySerialNum(int(indirect_serial_num)) except UnknownObjectError: raise SndcsIndirectError("No indirect activity exists with serialNum = '%s'" % (indirect_serial_num)) else: try: indirect = IndirectFactory().getIndirectByCode(indirect_code) except UnknownObjectError: raise SndcsIndirectError("No indirect activity exists with code = '%s'" % (indirect_code)) self.employee.startIndirect(indirect, terminal_id, global_indirect) def startStopContinueLaborDtls(self, starts = None, stops = None, continues = None, terminal_id = None, jobType = "Production"): # Turn start operation and indirect serialNums into operation and indirect objects if starts: for x in starts: if x["operation"]: operation_id = x["operation"] try: operation = OperationFactory().getOperationBySerialNum(int(operation_id)) except UnknownObjectError: raise SndcsOperationError("No operation exists with serialNum = '%s'" % (operation_id)) x["operation"] = operation elif x["indirect"]: indirect_id = x["indirect"]["indirect_id"] try: indirect = IndirectFactory().getIndirectBySerialNum(int(indirect_id)) except UnknownObjectError: raise SndcsIndirectError("No indirect activity exists with serialNum = '%s'" % (indirect_id)) x["indirect"] = indirect # Turn stop laborDtl serialNums into laborDtl objects (and employee_id in to Employee object if operation is completed) if stops: for x in stops: labordtl_id = x["labordtl"]["labordtl_id"] try: labordtl = LaborDtlFactory().getLaborDtlBySerialNum(int(labordtl_id)) except UnknownObjectError: raise SndcsLaborDtlError("No laborDtl exists with serialNum = '%s'" % (labordtl_id)) x["labordtl"] = labordtl if "completed_by" in x: employee_id = x["completed_by"] try: employee = EmployeeFactory().getEmployeeBySerialNum(int(employee_id)) except UnknownObjectError: raise SndcsLaborDtlError("No employee exists with serialNum = '%s'" % (employee_id)) x["completed_by"] = employee # Turn continue laborDtl serialNums into laborDtl objects if continues: for x in continues: labordtl_id = x["labordtl"]["labordtl_id"] try: labordtl = LaborDtlFactory().getLaborDtlBySerialNum(int(labordtl_id)) except UnknownObjectError: raise SndcsLaborDtlError("No laborDtl exists with serialNum = '%s'" % (labordtl_id)) x["labordtl"] = labordtl self.employee.startStopContinueLaborDtls(starts, stops, continues, terminal_id, jobType = jobType) ### Getters and Setters ### def serialNum(self): return self.employee.serialNum() def firstName(self): return self.employee.firstName() def lastName(self): return self.employee.lastName() def email(self): return self.employee.email() def createDate(self): return self.employee.createDate() def address(self): return self.employee.address() def city(self): return self.employee.city() def state(self): state = self.employee.state() if state: return state.desription() else: return None def zipCode(self): return self.employee.zipCode() def homePhone(self): return self.employee.homePhone() def workPhone(self): return self.employee.workPhone() def cellPhone(self): return self.employee.cellPhone() def fax(self): return self.employee.fax() def comments(self): return self.employee.comments() def pinNumber(self): return self.employee.pinNumber() def empId(self): return self.employee.empId() def departments(self): departments = [] for x in self.employee.department(): departments.extend([x.code()]) return departments def picture(self): picture = self.employee.picture() if picture: return picture.data() else: return None def picture_md5sum(self): picture = self.picture() if not picture is None: import md5 return md5.new(picture).hexdigest() else: return None def activeLaborHed(self): """ Be sure to call disconnect() on returned proxy objects """ hed = self.employee.activeLaborHed() if hed: proxy_factory = Pyro.core.getProxyForURI(self.formatPyronameString(sel.namespace, ["LaborHed"])) proxy = proxy_factory.setLaborHedBySerialNum(hed.serialNum()) return proxy else: return None ### Cleanup ### def disconnect(self): daemon = self.getDaemon() log.debug("Disconnecting employee proxy object %s.", self) daemon.disconnect(self) def _gotReaped(self): log.warning("%s got reaped.", self)