class Meeting(ModelSQL, ModelView): "cooperative_ar" __name__ = "cooperative.meeting" type = fields.Selection([ ('ordinaria', 'Ordinaria'), ('extraordinaria', 'Extraordinaria'), ('reunion', 'Reunion'), ], 'Type', required=True) status = fields.Selection([ ('planned', 'Planned'), ('complete', 'Complete'), ], 'Status', required=True) start_date = fields.Date('Start Date', states=STATES) start_time = fields.Time('Start Time', states=STATES) end_time = fields.Time('End Time', states=STATES) partners = fields.Many2Many('cooperative.partner-meeting', 'meeting', 'partner', 'Partner') record = fields.Text( 'Record', states=STATES, )
class RrhhHorariosLegajo(ModelSQL, ModelView): 'Horarios de Empleados' __name__ = 'rrhh.horarioslegajo' name = fields.Many2One('company.employee', 'Empleado', required=True) #~ cod_hor = fields.Char('Codigo',help='Codigo Horario', size=10, required=False) #~ des_hor = fields.Char('Descripcion', help='Descripcion del Horario', size=20, required=False) fecha_horario = fields.Date('Fecha Actualizacion') tip_tur = fields.Selection([ ('Dia' ,'Dia'),('Tarde', 'Tarde'),('Noche', 'Noche'),('Mixto', 'Mixto')], 'Turno', sort=False, required=False) entrada = fields.Time('Entrada') salida = fields.Time('Salida') def get_horario_des(self, name): return self.horario.des_hor def get_horario_turno(self, name): return self.horario.tip_tur def get_horario_entrada(self, name): return self.horario.entrada def get_horario_salida(self, name): return self.horario.salida
class Attendance(ModelSQL, ModelView): """ Attendance """ __name__ = 'attendance.attendance' employee = fields.Many2One('company.employee', 'Employee') shift = fields.Many2One('attendance.shiftdetails', 'Shift') date = fields.Date('Date') in_time = fields.Time('In Time') out_time = fields.Time('Out Time') is_holiday = fields.Boolean('Is Holiday') is_absent = fields.Function(fields.Boolean('Is Absent'), 'get_is_absent') leave_applied = fields.Boolean('Leave Applied') leave_reason = fields.Char('Leave Reason') leave_type = fields.Selection([ ('none', 'None'), ('cl', 'Casual Leave'), ('lop', 'Loss of Pay'), ('compoff', 'Compansatory Off'), ], 'Type of Leave') """leave_session = fields.Selection([ ('none','None'), ('first', 'First Session'), ('second','Second Session'), ('full','Full Session'), ])""" payroll_leaves = fields.Many2One('payroll.payroll', 'Payroll') def get_is_absent(self, name): return (not self.is_holiday) and (not self.in_time)
class RrhhCv(ModelSQL, ModelView): 'Curriculum Vitae' __name__ = 'rrhh.cv' estado_cv = fields.Selection([ ('CITADO', 'Citado'), ('ANULADO', 'Anulado'), ('PENDIENTE', 'Pendiente'), (None, ''), ], 'Estado CV', sort=False, required=True) nombre = fields.Char('Apellido y Nombre',40) photo1 = fields.Binary('Foto', states = STATES) fecha_presen = fields.Date('Fecha de Presentacion') fecha_nac = fields.Date('Fecha Nac.') cuil = fields.Char('Cuil',13) telefono = fields.Char('Telefono',30) celular = fields.Char('Celular',20) direccion = fields.Char('Calle',20) altura = fields.Char('Altura',10) piso = fields.Char('Piso',5) dto = fields.Char('Dto.',5) entrecalle = fields.Char('Entre Calle',20) localidad = fields.Char('Localidad',20) ccosto = fields.Many2One('gnuhealth.hospital.building', 'Edificio') categoria = fields.Many2One('rrhh.categoria', 'Categoria') convenio = fields.Selection([ ('SI', 'Si'), ('NO', 'No'), ], 'Convenio', sort=False, required=True) sueldo = fields.Numeric('Sueldo', digits=(10,2)) tliqui = fields.Selection([ ('M', 'Mensual'), ('Q', 'Quincena'), ], 'Tipo Liquidacion', sort=False, required=True) tip_tur = fields.Selection([ ('Dia' ,'Dia'),('Tarde', 'Tarde'),('Noche', 'Noche'),('Mixto', 'Mixto')], 'Turno', sort=False, required=False) entrada = fields.Time('Hor.Entrada') salida = fields.Time('Hor.Salida') observaciones = fields.Text('Observaciones') evaluacion = fields.Text('Evaluacion') otros = fields.Text('Otros') cv_photo1 = fields.Binary('Imagen1', states = STATES) cv_photo2 = fields.Binary('Imagen2', states = STATES) cv_photo3 = fields.Binary('Imagen3', states = STATES) email = fields.Char('E-Mail',40) #~ --------------- Calculo de edad del empleado ---------------- edad_emple = fields.Function(fields.Char('Edad de Postulante',7, on_change_with=['date_nac']),"on_change_with_date_agecv") def on_change_with_date_agecv(self,name=None): import datetime fecha_1=datetime.date.today().year fecha_2= self.date_nac.year diff = fecha_1 - fecha_2 years = str(diff) return years + ' años'
class TADAJourney(ModelSQL, ModelView): '''TA/DA Journey''' __name__ = 'exam_section.ta_da.journey' ta_da = fields.Many2One('exam_section.ta_da_bill', 'TA/DA Bill') journey_type = fields.Selection([('forward', 'Forward'), ('return', 'Return')], 'Journey Type', required=True) mode_of_transport = fields.Selection([('air', 'Air'), ('rail', 'Rail'), ('road', 'Road')], 'Mode of Transport', required=True) departure_place = fields.Char('Departure Place', required=True) departure_date = fields.Date('Departure Date', required=True) departure_time = fields.Time('Departure Time', required=True) arrival_place = fields.Char('Arrival Place', required=True) arrival_date = fields.Date('Arrival Date', required=True) arrival_time = fields.Time('Arrival Time', required=True) amount = fields.Float('Amount', required=True) @staticmethod def default_amount(): return 0 @classmethod def __setup__(cls): super().__setup__() cls._error_messages.update({ 'date_error': 'From date is more than to date', 'amount_lt_0': 'Amount cannot be less than 0' }) @classmethod def validate(cls, records): super(TADAJourney, cls).validate(records) for record in records: record.check_date() record.check_amount() def check_date(self): '''Check whether departure date is greater than arrival date or not''' if self.departure_date > self.arrival_date: self.raise_user_error('date_error') def check_amount(self): '''Check whether amount is less than zero or not''' if self.amount < 0: self.raise_user_error('amount_lt_0')
class RrhhHorarios(ModelSQL, ModelView): 'Horarios' __name__ = 'rrhh.horarios' #~ name = fields.Many2One('company.employee', 'Empleado', required=True) cod_hor = fields.Char('Codigo',help='Codigo Horario', size=10, required=False) des_hor = fields.Char('Descripcion', help='Descripcion del Horario', size=40, required=False) tip_tur = fields.Selection([ ('Dia' ,'Dia'),('Tarde', 'Tarde'),('Noche', 'Noche'),('Mixto', 'Mixto')], 'Turno', sort=False, required=False) entrada = fields.Time('Hor.Entrada') salida = fields.Time('Hor.Salida')
class OTEmployeeLog(ModelSQL, ModelView): 'OT Employee Log' __name__ = 'ot.employee.log' date = fields.Date('Date') time_from = fields.Time('Time From') time_to = fields.Time('Time To') hours = fields.TimeDelta('Hours') vehicle_no = fields.Char('Vehicle No.') ot_employee_details = fields.Many2One('ot.employee.details', 'OT Employee Details')
class TimeDefault(ModelSQL): 'Time Default' __name__ = 'test.time_default' time = fields.Time(string='Time', help='Test time', required=False) @staticmethod def default_time(): return datetime.time(16, 30)
class EncounterComponent(UnionMixin, BaseComponent): '''Component The unionized encounter component. This is the model to which the encounter points its One2Many field. ''' __name__ = 'gnuhealth.encounter.component' component_type = fields.Function(fields.Char('Type'), 'get_component_type_name') start_time_time = fields.Function(fields.Time('Start', format='%H:%M'), 'get_start_time_time') @classmethod def __setup__(cls): super(EncounterComponent, cls).__setup__() if hasattr(cls, '_buttons'): pass else: cls._buttons = {} cls._buttons['btn_open'] = {'readonly': Eval(False)} @classmethod def __register__(cls, module_name): # TableHandler = backend.get('TableHandler') super(ModelSQL, cls).__register__(module_name) return @staticmethod def union_models(): thelist = EncounterComponentType.get_selection_list() return [x[3] for x in thelist] @classmethod def get_start_time_time(cls, instances, name): # return self.start_time.strftime('%H:%M') gstt = lambda x: utils.localtime(x.start_time).time() return dict([(i.id, gstt(i)) for i in instances]) def get_component_type_name(self, name): id_names = EncounterComponentType.get_selection_list() title_index = self.id % len(id_names) return id_names[title_index][2] def get_report_info(self, name): real_component = self.union_unshard(self.id) return real_component.get_report_info(name) def get_is_union(self, name): return True @classmethod @ModelView.button_action( 'health_encounter.health_wizard_encounter_edit_component') def btn_open(cls, components, *a, **k): pass
class Horario(ModelSQL, ModelView): 'Horario' _name = 'cefiro.horario' _description = __doc__ name = fields.Char('nombre') diaDeSemana = fields.Selection([('lun', 'Lunes'), ('mar', 'Martes'), ('mier', u'Miércoles'), ('jue', 'Jueves'), ('vie', 'Viernes'), ('sab', u'Sábado'), ('dom', 'Domingo')], u'Día') hora = fields.Time('Hora')
class ShiftDetails(ModelSQL, ModelView): """ Shift Details """ __name__ = 'attendance.shiftdetails' slot = fields.Char('Slot') in_time = fields.Time('In Time') out_time = fields.Time('Out Time') monday = fields.Boolean('Monday') tuesday = fields.Boolean('Tuesday') wednesday = fields.Boolean('Wednesday') thursday = fields.Boolean('Thursday') friday = fields.Boolean('Friday') saturday = fields.Boolean('Saturday') sunday = fields.Boolean('Sunday') no_days = fields.Function(fields.Integer('Number of days per week'), 'get_no_of_days') def get_no_of_days(self, name): return (self.monday + self.tuesday + self.wednesday + self.thursday + self.friday + self.saturday + self.sunday)
class InpatientMedicationAdminTimes(ModelSQL, ModelView): 'Inpatient Medication Admin Times' __name__ = "gnuhealth.inpatient.medication.admin_time" name = fields.Many2One('gnuhealth.inpatient.medication', 'Medication') admin_time = fields.Time("Time") dose = fields.Float('Dose', help='Amount of medication (eg, 250 mg) per dose') dose_unit = fields.Many2One( 'gnuhealth.dose.unit', 'dose unit', help='Unit of measure for the medication to be taken') remarks = fields.Text('Remarks', help='specific remarks for this dose')
class CreateAppointmentStart(ModelView): 'Create Appointments Start' __name__ = 'gnuhealth.calendar.create.appointment.start' healthprof = fields.Many2One('gnuhealth.healthprofessional', 'Health Prof', required=True) specialty = fields.Many2One('gnuhealth.specialty', 'Specialty', required=True, on_change_with=['healthprof']) institution = fields.Many2One('party.party', 'Health Center', domain=[('is_institution', '=', True)], required=True) institution = fields.Many2One('party.party', 'Health Center', domain=[('is_institution', '=', True)], required=True) date_start = fields.Date('Start Date', required=True) date_end = fields.Date('End Date', required=True) time_start = fields.Time('Start Time', required=True) time_end = fields.Time('End Time', required=True) appointment_minutes = fields.Integer('Appointment Minutes', required=True) monday = fields.Boolean('Monday') tuesday = fields.Boolean('Tuesday') wednesday = fields.Boolean('Wednesday') thursday = fields.Boolean('Thursday') friday = fields.Boolean('Friday') saturday = fields.Boolean('Saturday') sunday = fields.Boolean('Sunday') def on_change_with_specialty(self): # Return the Current / Main speciality of the Health Professional # if this speciality has been specified in the HP record. if (self.healthprof and self.healthprof.main_specialty): specialty = self.healthprof.main_specialty.specialty.id return specialty
class CreateAppointmentStart(ModelView): 'Create Appointments Start' __name__ = 'gnuhealth.calendar.create.appointment.start' healthprof = fields.Many2One('gnuhealth.healthprofessional', 'Health Prof', required=True) specialty = fields.Many2One('gnuhealth.specialty', 'Specialty', required=True) institution = fields.Many2One('gnuhealth.institution', 'Institution', required=True) date_start = fields.Date('Start Date', required=True) date_end = fields.Date('End Date', required=True) time_start = fields.Time('Start Time', required=True, format='%H:%M') time_end = fields.Time('End Time', required=True, format='%H:%M') appointment_minutes = fields.Integer('Appointment Minutes', required=True) monday = fields.Boolean('Monday') tuesday = fields.Boolean('Tuesday') wednesday = fields.Boolean('Wednesday') thursday = fields.Boolean('Thursday') friday = fields.Boolean('Friday') saturday = fields.Boolean('Saturday') sunday = fields.Boolean('Sunday') @staticmethod def default_institution(): HealthInst = Pool().get('gnuhealth.institution') return HealthInst.get_institution() @fields.depends('healthprof') def on_change_with_specialty(self): # Return the Current / Main speciality of the Health Professional # if this speciality has been specified in the HP record. if (self.healthprof and self.healthprof.main_specialty): specialty = self.healthprof.main_specialty.specialty.id return specialty
class Consulta(ModelSQL, ModelView): 'Consulta' _name = 'cefiro.consulta' _description = __doc__ name = fields.Char('nombreDeFecha') fecha = fields.Date('Fecha de la Consulta') hora = fields.Time('Hora') psicologos = fields.Many2Many('cefiro.encuentropsi', 'evento', 'persona', 'Psicologos') pacientes = fields.Many2Many('cefiro.encuentro', 'evento', 'persona', 'Pacientes') estudiantes = fields.Many2Many('cefiro.encuentroest', 'evento', 'persona', 'Estudiantes') consultorio = fields.Many2One('cefiro.consultorio', 'Consultorio')
class Time(ModelSQL): 'Time' __name__ = 'test.time' time = fields.Time(string='Time', help='Test time', required=False)
class Horario(ModelSQL, ModelView): "Horario" __name__ = 'training.horario' name = fields.Char('Horario') domingo = fields.Boolean('Domingo') lunes = fields.Boolean('Lunes') martes = fields.Boolean('Martes') miercoles = fields.Boolean('Miercoles') jueves = fields.Boolean('Jueves') viernes = fields.Boolean('Viernes') hora_inicio = fields.Time('Hora de Inicio', required=True) hora_fin = fields.Time('Hora de Finalizacion', required=True) @fields.depends('hora_inicio', 'hora_fin', 'domingo', 'lunes', 'martes', 'miercoles', 'jueves', 'viernes') def on_change_domingo(self): name = self.on_change_dia() self.name = name @fields.depends('hora_inicio', 'hora_fin', 'domingo', 'lunes', 'martes', 'miercoles', 'jueves', 'viernes') def on_change_lunes(self): name = self.on_change_dia() self.name = name @fields.depends('hora_inicio', 'hora_fin', 'domingo', 'lunes', 'martes', 'miercoles', 'jueves', 'viernes') def on_change_martes(self): name = self.on_change_dia() self.name = name @fields.depends('hora_inicio', 'hora_fin', 'domingo', 'lunes', 'martes', 'miercoles', 'jueves', 'viernes') def on_change_miercoles(self): name = self.on_change_dia() self.name = name @fields.depends('hora_inicio', 'hora_fin', 'domingo', 'lunes', 'martes', 'miercoles', 'jueves', 'viernes') def on_change_jueves(self): name = self.on_change_dia() self.name = name @fields.depends('hora_inicio', 'hora_fin', 'domingo', 'lunes', 'martes', 'miercoles', 'jueves', 'viernes') def on_change_viernes(self): name = self.on_change_dia() self.name = name @fields.depends('hora_inicio', 'hora_fin', 'domingo', 'lunes', 'martes', 'miercoles', 'jueves', 'viernes') def on_change_hora_inicio(self): name = self.on_change_dia() self.name = name @fields.depends('hora_inicio', 'hora_fin', 'domingo', 'lunes', 'martes', 'miercoles', 'jueves', 'viernes') def on_change_hora_fin(self): name = self.on_change_dia() self.name = name def on_change_dia(self): name = ' ' if self.domingo: name += 'Domingo / ' if self.lunes: name += 'Lunes / ' if self.martes: name += 'Martes / ' if self.miercoles: name += 'Miercoles / ' if self.jueves: name += 'Jueves / ' if self.viernes: name += 'Viernes / ' hora_inicio = '' hora_fin = '' if self.hora_inicio: hora_inicio = self.hora_inicio.strftime("%H:%M") if self.hora_fin: hora_fin = self.hora_fin.strftime("%H:%M") name = name + hora_inicio + ' - ' + hora_fin return name def get_rec_name(self, name): if self.name: return self.name else: return '' @classmethod def search_rec_name(cls, name, clause): _, operator, value = clause if operator.startswith('!') or operator.startswith('not '): bool_op = 'AND' else: bool_op = 'OR' domain = [ bool_op, ('name', operator, value), ('name', operator, value), ] return domain @classmethod def __setup__(cls): super(Horario, cls).__setup__() cls._order.insert(0, ('name', 'ASC'))
class Activity(Workflow, ModelSQL, ModelView): 'Activity' __name__ = "activity.activity" code = fields.Char('Code', readonly=True, select=True) activity_type = fields.Many2One('activity.type', 'Type', required=True) subject = fields.Char('Subject') resource = fields.Reference('Resource', selection='get_resource') date = fields.Date('Date', required=True, select=True) duration = fields.TimeDelta('Duration') time = fields.Time('Time') dtstart = fields.DateTime('Start Date', select=True) dtend = fields.DateTime('End Date', select=True) state = fields.Selection([ ('planned', 'Planned'), ('done', 'Held'), ('canceled', 'Not Held'), ], 'State', required=True) description = fields.Text('Description') employee = fields.Many2One('company.employee', 'Employee', required=True) location = fields.Char('Location') party = fields.Many2One('party.party', 'Party') summary = fields.Function(fields.Char('Summary'), 'get_summary') calendar_color = fields.Function(fields.Char('Color'), 'get_calendar_color') calendar_background_color = fields.Function(fields.Char('Background Color'), 'get_calendar_background_color') day_busy_hours = fields.Function(fields.TimeDelta('Day Busy Hours'), 'get_day_busy_hours') @classmethod def __setup__(cls): super(Activity, cls).__setup__() cls._order = [ ('dtstart', 'DESC'), ('subject', 'ASC'), ('id', 'DESC'), ] cls._transitions |= set(( ('planned', 'done'), ('planned', 'canceled'), ('done', 'planned'), ('done', 'canceled'), ('canceled', 'planned'), ('canceled', 'done'), )) cls._buttons.update({ 'plan': { 'invisible': Eval('state') == 'planned', 'icon': 'activity', 'depends': ['state'], }, 'cancel': { 'invisible': Eval('state') == 'canceled', 'icon': 'tryton-cancel', 'depends': ['state'], }, 'do': { 'invisible': Eval('state') == 'done', 'icon': 'tryton-ok', 'depends': ['state'], }, }) @classmethod def __register__(cls, module_name): TableHandler = backend.TableHandler cursor = Transaction().connection.cursor() sql_table = cls.__table__() code_exists = True date_exists = True if backend.TableHandler.table_exist(cls._table): table = backend.TableHandler(cls, module_name) code_exists = table.column_exist('code') date_exists = table.column_exist('date') super(Activity, cls).__register__(module_name) table = backend.TableHandler(cls, module_name) # Migration from 3.2: Remove type and direction fields table.not_null_action('type', action='remove') table.not_null_action('direction', action='remove') # Migration from 3.2: Add code field if (not code_exists and table.column_exist('type') and table.column_exist('direction')): cursor.execute(*sql_table.update( columns=[sql_table.code], values=[sql_table.id], where=sql_table.code == Null)) table.not_null_action('code', action='add') # Migration from 3.4.1: subject is no more required table.not_null_action('subject', 'remove') # Migration from 5.2 if not date_exists: cursor.execute(*sql_table.update( columns=[sql_table.date, sql_table.time], values=[Cast(sql_table.dtstart, 'DATE'), Cast(sql_table.dtstart, 'TIME')])) cursor.execute(*sql_table.update( columns=[sql_table.duration], values=[sql_table.dtend - sql_table.dtstart], where=sql_table.dtend != Null)) cursor.execute(*sql_table.update( columns=[sql_table.state], values=['done'], where=sql_table.state == 'held')) cursor.execute(*sql_table.update( columns=[sql_table.state], values=['canceled'], where=sql_table.state == 'not_held')) @classmethod @ModelView.button @Workflow.transition('planned') def plan(cls, activities): pass @classmethod @ModelView.button @Workflow.transition('done') def do(cls, activities): pass @classmethod @ModelView.button @Workflow.transition('canceled') def cancel(cls, activities): pass @fields.depends('resource', '_parent_party.id', 'party') def on_change_with_party(self, name=None): if (self.resource and not isinstance(self.resource, str) and self.resource.id > 0): return Activity._resource_party(self.resource) return self.party.id if self.party else None def get_rec_name(self, name): if self.subject: return '[%s] %s' % (self.code, self.subject) return self.code @classmethod def search_rec_name(cls, name, clause): return ['OR', ('code',) + tuple(clause[1:]), ('subject',) + tuple(clause[1:]), ] @staticmethod def default_employee(): User = Pool().get('res.user') user = User(Transaction().user) return user.employee and user.employee.id or None @staticmethod def default_state(): return 'planned' @staticmethod def default_resource(): return None @classmethod def default_party(cls): resource = cls.default_resource() return Activity._resource_party(resource) @staticmethod def _resource_party(resource): if not resource or resource.id < 0: return model = resource and str(resource).partition(',')[0] Relation = Pool().get(model) if model == 'party.party': return resource.id if 'party' in Relation._fields.keys(): if resource.party: return resource.party.id return None @fields.depends('activity_type', 'duration') def on_change_activity_type(self): if not self.activity_type: return if not self.duration is None: return self.duration = self.activity_type.default_duration @classmethod def get_timezone(cls): Company = Pool().get('company.company') company_id = Transaction().context.get('company') if company_id: company = Company(company_id) if company.timezone: return pytz.timezone(company.timezone) @classmethod def utc_to_local(cls, value): timezone = cls.get_timezone() if not timezone: return value converted = value converted = timezone.localize(value) converted = value + converted.utcoffset() return converted @classmethod def local_to_utc(cls, value): timezone = cls.get_timezone() if not timezone: return value converted = timezone.localize(value) converted = value - converted.utcoffset() return converted @fields.depends('dtstart') def on_change_dtstart(self): if not self.dtstart: return dt = self.utc_to_local(self.dtstart) self.date = dt.date() if dt.time() == datetime.time(): # When time is 0:00 we consider it is a full-day activity # as the calendar view does not provide a mechanism to distinguish # between an event at midnight and a full-day event. # # Given that events at midnight are very unfrequent, this is the # best default self.time = None else: self.time = dt.time() @classmethod def get_resource(cls): 'Return list of Model names for resource Reference' Reference = Pool().get('activity.reference') res = [(None, '')] for _type in Reference.search([]): res.append((_type.model.model, _type.model.name)) return res @classmethod def create(cls, vlist): pool = Pool() Sequence = pool.get('ir.sequence') Config = pool.get('activity.configuration') sequence = Config(1).activity_sequence if not sequence: raise UserError(gettext('activity.no_activity_sequence')) vlist = [x.copy() for x in vlist] for vals in vlist: vals['code'] = Sequence.get_id(sequence.id) vals.update(cls.update_dates(vals)) return super(Activity, cls).create(vlist) @classmethod def write(cls, *args): actions = iter(args) args = [] for activities, values in zip(actions, actions): for activity in activities: args.append([activity]) args.append(cls.update_dates(values, activity)) super().write(*args) @classmethod def update_dates(cls, values, record=None): values = values.copy() if not 'date' in values: dtstart = None if 'dtstart' in values: dtstart = values['dtstart'] elif record: dtstart = record.dtstart if 'dtend' in values: dtend = values['dtend'] values['date'] = dtstart.date() values['time'] = dtstart.time() values['duration'] = dtend - dtstart return values if record: for field in ('date', 'time', 'duration'): if not field in values: values[field] = getattr(record, field) date = values.get('date') time = values.get('time') duration = values.get('duration') dtstart = datetime.datetime.combine(date, time or datetime.time()) dtstart = cls.local_to_utc(dtstart) dtend = None if time and duration: dtend = dtstart + duration values['dtstart'] = dtstart values['dtend'] = dtend return values def get_summary(self, name): if self.subject: text = self.subject elif self.party: text = self.party.rec_name elif self.code: text = self.code else: text = '' text += ' (%s)' % self.activity_type.rec_name if self.duration: text += '\n%s' % timedelta_to_string(self.duration) if self.day_busy_hours: if not self.duration: text += '\n-' text += ' / %s' % timedelta_to_string(self.day_busy_hours) text += '\n@' + self.employee.rec_name return text def get_calendar_color(self, name): rgb = RGB(self.calendar_background_color) if rgb.gray() > 128: return 'black' return 'white' def get_calendar_background_color(self, name): # Use Tryton's default color by default color = '#ABD6E3' context = Transaction().context if context.get('activity_color_type', False): if self.activity_type and self.activity_type.color: color = self.activity_type.color else: if self.employee and self.employee.color: color = self.employee.color if self.state != 'planned': rgb = RGB(color) rgb.increase_ratio(0.8) color = rgb.hex() return color @classmethod def get_day_busy_hours(cls, activities, name): cursor = Transaction().connection.cursor() table = cls.__table__() employees = [x.employee.id for x in activities] min_date = min([x.date for x in activities]) max_date = max([x.date for x in activities]) query = table.select( table.employee, table.date, Sum(table.duration), where=((table.employee.in_(employees)) & (table.date >= min_date) & (table.date <= max_date)), group_by=(table.employee, table.date)) cursor.execute(*query) records = cursor.fetchall() sums = {} for record in records: sums[(record[0], record[1])] = record[2] res = {} for activity in activities: res[activity.id] = sums.get((activity.employee.id, activity.date), datetime.timedelta()) return res
class ShipmentTracking(ModelSQL, ModelView): """Shipment Tracking """ __name__ = 'shipment.tracking' _rec_name = 'tracking_number' #: Boolean to indicate if tracking number is master. is_master = fields.Boolean("Is Master ?", readonly=True, select=True) origin = fields.Reference('Origin', selection='get_origin', select=True, readonly=True) tracking_number = fields.Char("Tracking Number", required=True, select=True, readonly=True) carrier = fields.Many2One('carrier', 'Carrier', required=True, readonly=True) tracking_url = fields.Char("Tracking Url", readonly=True) delivery_date = fields.Date("Delivery Date", readonly=True) delivery_time = fields.Time("Delivery Time", readonly=True) state = fields.Selection([ ('waiting', 'Waiting'), ('in_transit', 'In Transit'), ('exception', 'Exception'), ('delivered', 'Delivered'), ('out_for_delivery', 'Out For Delivery'), ('failure', 'Failure'), ('returned', 'Returned'), ('cancelled', 'Cancelled'), ('unknown', 'Unknown'), ('pending_cancellation', 'Pending Cancellation'), ], 'State', readonly=True, required=True, select=True) @staticmethod def default_state(): return 'waiting' @classmethod def __setup__(cls): """ Setup the class before adding to pool """ super(ShipmentTracking, cls).__setup__() cls._buttons.update({ 'cancel_tracking_number_button': { 'invisible': Eval('state') == 'cancelled', }, 'refresh_status_button': {}, }) def cancel_tracking_number(self): "Cancel tracking number" self.state = 'cancelled' self.save() @classmethod @ModelView.button def cancel_tracking_number_button(cls, tracking_numbers): """ Cancel tracking numbers """ for tracking_number in tracking_numbers: tracking_number.cancel_tracking_number() def refresh_status(self): """ Downstream module can implement this """ pass @classmethod @ModelView.button def refresh_status_button(cls, tracking_numbers): """ Update tracking numbers state """ for tracking_number in tracking_numbers: tracking_number.refresh_status() @classmethod def refresh_tracking_numbers_cron(cls): """ This is a cron method, responsible for updating state of shipments. """ states_to_refresh = [ 'pending_cancellation', 'failure', 'waiting', 'in_transit', ] tracking_numbers = cls.search([ ('state', 'in', states_to_refresh), ]) for tracking_number in tracking_numbers: tracking_number.refresh_status() @classmethod def _get_origin(cls): 'Return list of Model names for origin Reference' return ['stock.shipment.out', 'stock.package'] @classmethod def get_origin(cls): Model = Pool().get('ir.model') models = cls._get_origin() models = Model.search([ ('model', 'in', models), ]) return [(None, '')] + [(m.model, m.name) for m in models]
class PatientRounding(ModelSQL, ModelView): 'Patient Rounding' __name__ = 'gnuhealth.patient.rounding' STATES = {'readonly': Eval('state') == 'done'} name = fields.Many2One('gnuhealth.inpatient.registration', 'Registration Code', required=True, states=STATES) code = fields.Char('Code', states=STATES) health_professional = fields.Many2One('gnuhealth.healthprofessional', 'Health Professional', readonly=True) evaluation_start = fields.DateTime('Start', required=True, states=STATES) evaluation_end = fields.DateTime('End', readonly=True) state = fields.Selection([ (None, ''), ('draft', 'In Progress'), ('done', 'Done'), ], 'State', readonly=True) environmental_assessment = fields.Char( 'Environment', help="Environment" " assessment . State any disorder in the room.", states=STATES) weight = fields.Integer('Weight', help="Measured weight, in kg", states=STATES) # The 6 P's of rounding pain = fields.Boolean('Pain', help="Check if the patient is in pain", states=STATES) pain_level = fields.Integer('Pain', help="Enter the pain level, from 1 to " "10", states={ 'invisible': ~Eval('pain'), 'readonly': Eval('state') == 'done' }) potty = fields.Boolean('Potty', help="Check if the patient needs to " "urinate / defecate", states=STATES) position = fields.Boolean('Position', help="Check if the patient needs to " "be repositioned or is unconfortable", states=STATES) proximity = fields.Boolean('Proximity', help="Check if personal items, " "water, alarm, ... are not in easy reach", states=STATES) pump = fields.Boolean('Pumps', help="Check if there is any issues with " "the pumps - IVs ... ", states=STATES) personal_needs = fields.Boolean('Personal needs', help="Check if the " "patient requests anything", states=STATES) # Vital Signs systolic = fields.Integer('Systolic Pressure', states=STATES) diastolic = fields.Integer('Diastolic Pressure', states=STATES) bpm = fields.Integer('Heart Rate', help='Heart rate expressed in beats per minute', states=STATES) respiratory_rate = fields.Integer( 'Respiratory Rate', help='Respiratory rate expressed in breaths per minute', states=STATES) osat = fields.Integer('Oxygen Saturation', help='Oxygen Saturation(arterial).', states=STATES) temperature = fields.Float('Temperature', help='Temperature in celsius', states=STATES) # Diuresis diuresis = fields.Integer('Diuresis', help="volume in ml", states=STATES) urinary_catheter = fields.Boolean('Urinary Catheter', states=STATES) #Glycemia glycemia = fields.Integer('Glycemia', help='Blood Glucose level', states=STATES) depression = fields.Boolean('Depression signs', help="Check this if the " "patient shows signs of depression", states=STATES) evolution = fields.Selection([ (None, ''), ('n', 'Status Quo'), ('i', 'Improving'), ('w', 'Worsening'), ], 'Evolution', help="Check your judgement of current " "patient condition", sort=False, states=STATES) round_summary = fields.Text('Round Summary', states=STATES) signed_by = fields.Many2One( 'gnuhealth.healthprofessional', 'Signed by', readonly=True, states={'invisible': Equal(Eval('state'), 'draft')}, help="Health Professional that signed the rounding") warning = fields.Boolean( 'Warning', help="Check this box to alert the " "supervisor about this patient rounding. A warning icon will be shown " "in the rounding list", states=STATES) warning_icon = fields.Function(fields.Char('Warning Icon'), 'get_warn_icon') procedures = fields.One2Many( 'gnuhealth.rounding_procedure', 'name', 'Procedures', help="List of the procedures in this rounding. Please " "enter the first one as the main procedure", states=STATES) report_start_date = fields.Function(fields.Date('Start Date'), 'get_report_start_date') report_start_time = fields.Function(fields.Time('Start Time'), 'get_report_start_time') report_end_date = fields.Function(fields.Date('End Date'), 'get_report_end_date') report_end_time = fields.Function(fields.Time('End Time'), 'get_report_end_time') @staticmethod def default_health_professional(): pool = Pool() HealthProf = pool.get('gnuhealth.healthprofessional') healthprof = HealthProf.get_health_professional() return healthprof @staticmethod def default_evaluation_start(): return datetime.now() @staticmethod def default_state(): return 'draft' @classmethod def __setup__(cls): super(PatientRounding, cls).__setup__() cls._error_messages.update({ 'health_professional_warning': 'No health professional associated to this user', }) cls._buttons.update( {'end_rounding': { 'invisible': ~Eval('state').in_(['draft']), }}) cls._order.insert(0, ('evaluation_start', 'DESC')) @classmethod @ModelView.button def end_rounding(cls, roundings): # End the rounding pool = Pool() HealthProfessional = pool.get('gnuhealth.healthprofessional') # Change the state of the rounding to "Done" signing_hp = HealthProfessional.get_health_professional() cls.write( roundings, { 'state': 'done', 'signed_by': signing_hp, 'evaluation_end': datetime.now() }) @classmethod def create(cls, vlist): Sequence = Pool().get('ir.sequence') Config = Pool().get('gnuhealth.sequences') vlist = [x.copy() for x in vlist] for values in vlist: if not values.get('code'): config = Config(1) values['code'] = Sequence.get_id( config.patient_rounding_sequence.id) return super(PatientRounding, cls).create(vlist) @classmethod def validate(cls, roundings): super(PatientRounding, cls).validate(roundings) for rounding in roundings: rounding.check_health_professional() def check_health_professional(self): if not self.health_professional: self.raise_user_error('health_professional_warning') def get_report_start_date(self, name): Company = Pool().get('company.company') timezone = None company_id = Transaction().context.get('company') if company_id: company = Company(company_id) if company.timezone: timezone = pytz.timezone(company.timezone) dt = self.evaluation_start return datetime.astimezone(dt.replace(tzinfo=pytz.utc), timezone).date() def get_report_start_time(self, name): Company = Pool().get('company.company') timezone = None company_id = Transaction().context.get('company') if company_id: company = Company(company_id) if company.timezone: timezone = pytz.timezone(company.timezone) dt = self.evaluation_start return datetime.astimezone(dt.replace(tzinfo=pytz.utc), timezone).time() def get_report_end_date(self, name): Company = Pool().get('company.company') timezone = None company_id = Transaction().context.get('company') if company_id: company = Company(company_id) if company.timezone: timezone = pytz.timezone(company.timezone) dt = self.evaluation_end return datetime.astimezone(dt.replace(tzinfo=pytz.utc), timezone).date() def get_report_end_time(self, name): Company = Pool().get('company.company') timezone = None company_id = Transaction().context.get('company') if company_id: company = Company(company_id) if company.timezone: timezone = pytz.timezone(company.timezone) dt = self.evaluation_end return datetime.astimezone(dt.replace(tzinfo=pytz.utc), timezone).time() def get_warn_icon(self, name): if self.warning: return 'gnuhealth-warning'
class Surgery(ModelSQL, ModelView): 'Surgery' __name__ = 'gnuhealth.surgery' def surgery_duration(self, name): if (self.surgery_end_date and self.surgery_date): return self.surgery_end_date - self.surgery_date else: return None def patient_age_at_surgery(self, name): if (self.patient.name.dob and self.surgery_date): rdelta = relativedelta(self.surgery_date.date(), self.patient.name.dob) years_months_days = str(rdelta.years) + 'y ' \ + str(rdelta.months) + 'm ' \ + str(rdelta.days) + 'd' return years_months_days else: return None patient = fields.Many2One('gnuhealth.patient', 'Patient', required=True) admission = fields.Many2One('gnuhealth.appointment', 'Admission') operating_room = fields.Many2One('gnuhealth.hospital.or', 'Operating Room') code = fields.Char('Code', readonly=True, help="Health Center code / sequence") procedures = fields.One2Many( 'gnuhealth.operation', 'name', 'Procedures', help="List of the procedures in the surgery. Please enter the first " "one as the main procedure") supplies = fields.One2Many( 'gnuhealth.surgery_supply', 'name', 'Supplies', help="List of the supplies required for the surgery") pathology = fields.Many2One('gnuhealth.pathology', 'Condition', help="Base Condition / Reason") classification = fields.Selection([ (None, ''), ('o', 'Optional'), ('r', 'Required'), ('u', 'Urgent'), ('e', 'Emergency'), ], 'Urgency', help="Urgency level for this surgery", sort=False) surgeon = fields.Many2One('gnuhealth.healthprofessional', 'Surgeon', help="Surgeon who did the procedure") anesthetist = fields.Many2One('gnuhealth.healthprofessional', 'Anesthetist', help="Anesthetist in charge") surgery_date = fields.DateTime('Date', help="Start of the Surgery") surgery_end_date = fields.DateTime( 'End', states={ 'required': Equal(Eval('state'), 'done'), }, help="Automatically set when the surgery is done." "It is also the estimated end time when confirming the surgery.") surgery_length = fields.Function( fields.TimeDelta('Duration', states={ 'invisible': And(Not(Equal(Eval('state'), 'done')), Not(Equal(Eval('state'), 'signed'))) }, help="Length of the surgery"), 'surgery_duration') state = fields.Selection([ ('draft', 'Draft'), ('confirmed', 'Confirmed'), ('cancelled', 'Cancelled'), ('in_progress', 'In Progress'), ('done', 'Done'), ('signed', 'Signed'), ], 'State', readonly=True, sort=False) signed_by = fields.Many2One( 'gnuhealth.healthprofessional', 'Signed by', readonly=True, states={'invisible': Not(Equal(Eval('state'), 'signed'))}, help="Health Professional that signed this surgery document") # age is deprecated in GNU Health 2.0 age = fields.Char('Estimative Age', help="Use this field for historical purposes, \ when no date of surgery is given") computed_age = fields.Function( fields.Char('Age', help="Computed patient age at the moment of the surgery"), 'patient_age_at_surgery') gender = fields.Function(fields.Selection([ (None, ''), ('m', 'Male'), ('f', 'Female'), ('f-m', 'Female -> Male'), ('m-f', 'Male -> Female'), ], 'Gender'), 'get_patient_gender', searcher='search_patient_gender') description = fields.Char('Description') preop_mallampati = fields.Selection([ (None, ''), ('Class 1', 'Class 1: Full visibility of tonsils, uvula and soft ' 'palate'), ('Class 2', 'Class 2: Visibility of hard and soft palate, ' 'upper portion of tonsils and uvula'), ('Class 3', 'Class 3: Soft and hard palate and base of the uvula are ' 'visible'), ('Class 4', 'Class 4: Only Hard Palate visible'), ], 'Mallampati Score', sort=False) preop_bleeding_risk = fields.Boolean( 'Risk of Massive bleeding', help="Patient has a risk of losing more than 500 " "ml in adults of over 7ml/kg in infants. If so, make sure that " "intravenous access and fluids are available") preop_oximeter = fields.Boolean('Pulse Oximeter in place', help="Pulse oximeter is in place " "and functioning") preop_site_marking = fields.Boolean( 'Surgical Site Marking', help="The surgeon has marked the surgical incision") preop_antibiotics = fields.Boolean( 'Antibiotic Prophylaxis', help="Prophylactic antibiotic treatment within the last 60 minutes") preop_sterility = fields.Boolean( 'Sterility confirmed', help="Nursing team has confirmed sterility of the devices and room") preop_asa = fields.Selection([ (None, ''), ('ps1', 'PS 1 : Normal healthy patient'), ('ps2', 'PS 2 : Patients with mild systemic disease'), ('ps3', 'PS 3 : Patients with severe systemic disease'), ('ps4', 'PS 4 : Patients with severe systemic disease that is' ' a constant threat to life '), ('ps5', 'PS 5 : Moribund patients who are not expected to' ' survive without the operation'), ('ps6', 'PS 6 : A declared brain-dead patient who organs are' ' being removed for donor purposes'), ], 'ASA PS', help="ASA pre-operative Physical Status", sort=False) preop_rcri = fields.Many2One( 'gnuhealth.rcri', 'RCRI', help='Patient Revised Cardiac Risk Index\n' 'Points 0: Class I Very Low (0.4% complications)\n' 'Points 1: Class II Low (0.9% complications)\n' 'Points 2: Class III Moderate (6.6% complications)\n' 'Points 3 or more : Class IV High (>11% complications)') surgical_wound = fields.Selection([ (None, ''), ('I', 'Clean . Class I'), ('II', 'Clean-Contaminated . Class II'), ('III', 'Contaminated . Class III'), ('IV', 'Dirty-Infected . Class IV'), ], 'Surgical wound', sort=False) extra_info = fields.Text('Extra Info') anesthesia_report = fields.Text('Anesthesia Report') institution = fields.Many2One('gnuhealth.institution', 'Institution') report_surgery_date = fields.Function(fields.Date('Surgery Date'), 'get_report_surgery_date') report_surgery_time = fields.Function(fields.Time('Surgery Time'), 'get_report_surgery_time') surgery_team = fields.One2Many( 'gnuhealth.surgery_team', 'name', 'Team Members', help="Professionals Involved in the surgery") postoperative_dx = fields.Many2One( 'gnuhealth.pathology', 'Post-op dx', states={ 'invisible': And(Not(Equal(Eval('state'), 'done')), Not(Equal(Eval('state'), 'signed'))) }, help="Post-operative diagnosis") @staticmethod def default_institution(): HealthInst = Pool().get('gnuhealth.institution') institution = HealthInst.get_institution() return institution @staticmethod def default_surgery_date(): return datetime.now() @staticmethod def default_surgeon(): pool = Pool() HealthProf = pool.get('gnuhealth.healthprofessional') surgeon = HealthProf.get_health_professional() return surgeon @staticmethod def default_state(): return 'draft' def get_patient_gender(self, name): return self.patient.gender @classmethod def search_patient_gender(cls, name, clause): res = [] value = clause[2] res.append(('patient.name.gender', clause[1], value)) return res # Show the gender and age upon entering the patient # These two are function fields (don't exist at DB level) @fields.depends('patient') def on_change_patient(self): gender = None age = '' self.gender = self.patient.gender self.computed_age = self.patient.age @classmethod def create(cls, vlist): Sequence = Pool().get('ir.sequence') Config = Pool().get('gnuhealth.sequences') vlist = [x.copy() for x in vlist] for values in vlist: if not values.get('code'): config = Config(1) values['code'] = Sequence.get_id( config.surgery_code_sequence.id) return super(Surgery, cls).create(vlist) @classmethod def __setup__(cls): super(Surgery, cls).__setup__() cls._error_messages.update({ 'end_date_before_start': 'End time "%(end_date)s" BEFORE ' 'surgery date "%(surgery_date)s"', 'or_is_not_available': 'Operating Room is not available' }) cls._order.insert(0, ('surgery_date', 'DESC')) cls._buttons.update({ 'confirmed': { 'invisible': And(Not(Equal(Eval('state'), 'draft')), Not(Equal(Eval('state'), 'cancelled'))), }, 'cancel': { 'invisible': Not(Equal(Eval('state'), 'confirmed')), }, 'start': { 'invisible': Not(Equal(Eval('state'), 'confirmed')), }, 'done': { 'invisible': Not(Equal(Eval('state'), 'in_progress')), }, 'signsurgery': { 'invisible': Not(Equal(Eval('state'), 'done')), }, }) @classmethod def validate(cls, surgeries): super(Surgery, cls).validate(surgeries) for surgery in surgeries: surgery.validate_surgery_period() def validate_surgery_period(self): Lang = Pool().get('ir.lang') language, = Lang.search([ ('code', '=', Transaction().language), ]) if (self.surgery_end_date and self.surgery_date): if (self.surgery_end_date < self.surgery_date): self.raise_user_error( 'end_date_before_start', { 'surgery_date': Lang.strftime(self.surgery_date, language.code, language.date), 'end_date': Lang.strftime(self.surgery_end_date, language.code, language.date), }) @classmethod def write(cls, surgeries, vals): # Don't allow to write the record if the surgery has been signed if surgeries[0].state == 'signed': cls.raise_user_error( "This surgery is at state Done and has been signed\n" "You can no longer modify it.") return super(Surgery, cls).write(surgeries, vals) ## Method to check for availability and make the Operating Room reservation # for the associated surgery @classmethod @ModelView.button def confirmed(cls, surgeries): surgery_id = surgeries[0] Operating_room = Pool().get('gnuhealth.hospital.or') cursor = Transaction().connection.cursor() # Operating Room and end surgery time check if (not surgery_id.operating_room or not surgery_id.surgery_end_date): cls.raise_user_error("Operating Room and estimated end time " "are needed in order to confirm the surgery") or_id = surgery_id.operating_room.id cursor.execute( "SELECT COUNT(*) \ FROM gnuhealth_surgery \ WHERE (surgery_date::timestamp,surgery_end_date::timestamp) \ OVERLAPS (timestamp %s, timestamp %s) \ AND (state = %s or state = %s) \ AND operating_room = CAST(%s AS INTEGER) ", (surgery_id.surgery_date, surgery_id.surgery_end_date, 'confirmed', 'in_progress', str(or_id))) res = cursor.fetchone() if (surgery_id.surgery_end_date < surgery_id.surgery_date): cls.raise_user_error("The Surgery end date must later than the \ Start") if res[0] > 0: cls.raise_user_error('or_is_not_available') else: cls.write(surgeries, {'state': 'confirmed'}) # Cancel the surgery and set it to draft state # Free the related Operating Room @classmethod @ModelView.button def cancel(cls, surgeries): surgery_id = surgeries[0] Operating_room = Pool().get('gnuhealth.hospital.or') cls.write(surgeries, {'state': 'cancelled'}) # Start the surgery @classmethod @ModelView.button def start(cls, surgeries): surgery_id = surgeries[0] Operating_room = Pool().get('gnuhealth.hospital.or') cls.write( surgeries, { 'state': 'in_progress', 'surgery_date': datetime.now(), 'surgery_end_date': datetime.now() }) Operating_room.write([surgery_id.operating_room], {'state': 'occupied'}) # Finnish the surgery # Free the related Operating Room @classmethod @ModelView.button def done(cls, surgeries): surgery_id = surgeries[0] Operating_room = Pool().get('gnuhealth.hospital.or') cls.write(surgeries, { 'state': 'done', 'surgery_end_date': datetime.now() }) Operating_room.write([surgery_id.operating_room], {'state': 'free'}) # Sign the surgery document, and the surgical act. @classmethod @ModelView.button def signsurgery(cls, surgeries): surgery_id = surgeries[0] # Sign, change the state of the Surgery to "Signed" # and write the name of the signing health professional signing_hp = Pool().get( 'gnuhealth.healthprofessional').get_health_professional() if not signing_hp: cls.raise_user_error( "No health professional associated to this user !") cls.write(surgeries, {'state': 'signed', 'signed_by': signing_hp}) def get_report_surgery_date(self, name): Company = Pool().get('company.company') timezone = None company_id = Transaction().context.get('company') if company_id: company = Company(company_id) if company.timezone: timezone = pytz.timezone(company.timezone) dt = self.surgery_date return datetime.astimezone(dt.replace(tzinfo=pytz.utc), timezone).date() def get_report_surgery_time(self, name): Company = Pool().get('company.company') timezone = None company_id = Transaction().context.get('company') if company_id: company = Company(company_id) if company.timezone: timezone = pytz.timezone(company.timezone) dt = self.surgery_date return datetime.astimezone(dt.replace(tzinfo=pytz.utc), timezone).time() @classmethod def search_rec_name(cls, name, clause): if clause[1].startswith('!') or clause[1].startswith('not '): bool_op = 'AND' else: bool_op = 'OR' return [ bool_op, ('patient', ) + tuple(clause[1:]), ('code', ) + tuple(clause[1:]), ]
class TimeRequired(ModelSQL): 'Time' __name__ = 'test.time_required' time = fields.Time(string='Time', help='Test time', required=True)
class TimeFormat(ModelSQL): 'Time Format' __name__ = 'test.time_format' time = fields.Time(string='Time', format='%H:%M')
class OTEmployeeDetails(Workflow, ModelSQL, ModelView): 'OT Employee details' __name__ = 'ot.employee.details' employee = fields.Many2One( 'company.employee', 'Employee', states={'readonly': ~Eval('state').in_(['draft'])}, depends=['state']) date_from = fields.Date('Date From', states={'readonly': ~Eval('state').in_(['draft'])}, depends=['state']) date_to = fields.Date('Date From', states={'readonly': ~Eval('state').in_(['draft'])}, depends=['state']) duty_hrs_from = fields.Time( 'Duty Hrs From', states={'readonly': ~Eval('state').in_(['draft'])}, depends=['state']) duty_hrs_to = fields.Time( 'Duty Hrs To', states={'readonly': ~Eval('state').in_(['draft'])}, depends=['state']) salary_code = fields.Char( 'Salary Code', states={'readonly': ~Eval('state').in_(['draft'])}, depends=['state']) ota_rate = fields.Float('OTA Rate(Per Hr)', states={'readonly': ~Eval('state').in_(['draft'])}, depends=['state']) vehicle_no = fields.Char( 'Vehicle No.', states={'readonly': ~Eval('state').in_(['draft'])}, depends=['state']) state = fields.Selection([('draft', 'Draft'), ('confirm', 'Confirm'), ('cancel_emp', 'Cancel'), ('f_to_hod', 'Forwarded to HoD'), ('f_to_ro', 'Forwarded to RO'), ('f_to_ao', 'Forwarded to AO'), ('cancel_ro', 'Cancelled by RO '), ('cancel_hod', 'Cancelled by HoD'), ('approve_ao', 'Approved by AO'), ('cancel_ao', 'Cancelled by AO')], 'Status', readonly=True) ot_employee_log = fields.One2Many( 'ot.employee.log', 'ot_employee_details', 'OT Details', states={'readonly': ~Eval('state').in_(['draft'])}, depends=['state']) @classmethod def __setup__(cls): super().__setup__() cls._transitions |= set(( ('draft', 'confirm'), ('confirm', 'f_to_ro'), ('cancel', 'cancel_emp'), ('f_to_ro', 'f_to_hod'), ('f_to_hod', 'f_to_ao'), ('f_to_ro', 'cancel_ro'), ('f_to_hod', 'cancel_hod'), ('f_to_ao', 'approve_ao'), ('f_to_ao', 'cancel_ao'), )) cls._buttons.update({ 'submit_to_ro': { 'invisible': ~Eval('state').in_(['draft']), 'depends': ['state'], }, 'confirm': { 'invisible': ~Eval('state').in_(['draft']), 'depends': ['state'], }, 'cancel': { 'invisible': ~Eval('state').in_(['confirm']), 'depends': ['state'], }, 'cancel_submission_ro': { 'invisible': ~Eval('state').in_(['f_to_ro']), 'depends': ['state'], }, 'submit_to_hod': { 'invisible': ~Eval('state').in_(['approve_ro']), 'depends': ['state'], }, 'cancel_submission_hod': { 'invisible': ~Eval('state').in_(['f_to_hod']), 'depends': ['state'], }, 'submit_to_ao': { 'invisible': ~Eval('state').in_(['approve_hod']), 'depends': ['state'], }, 'approve_for_ao': { 'invisible': ~Eval('state').in_(['f_to_ao']), 'depends': ['state'], }, 'cancel_submission_ao': { 'invisible': ~Eval('state').in_(['f_to_ao']), 'depends': ['state'], }, }) @staticmethod def default_state(): return 'draft' @classmethod @ModelView.button @Workflow.transition('f_to_ro') def submit_to_ro(cls, records): pass @classmethod @ModelView.button @Workflow.transition('f_to_hod') def submit_to_hod(cls, records): pass @classmethod @ModelView.button @Workflow.transition('f_to_ao') def submit_to_ao(cls, records): pass @classmethod @ModelView.button @Workflow.transition('confirm') def confirm(cls, records): pass @classmethod @ModelView.button @Workflow.transition('cancel') def cancel(cls, records): pass @classmethod @ModelView.button @Workflow.transition('cancel_ro') def cancel_submission_ro(cls, records): pass @classmethod @ModelView.button @Workflow.transition('cancel_hod') def cancel_submission_hod(cls, records): pass @classmethod @ModelView.button @Workflow.transition('approve_ao') def approve_for_ao(cls, records): pass @classmethod @ModelView.button @Workflow.transition('cancel_ao') def cancel_submission_ao(cls, records): pass
class EventCreator(Model): 'Event Creator' start_date = fields.DateTime('Start Date', required=True) frequence_selection = fields.Selection( FREQUENCE_OPTIONS, 'Select Frequence', sort=False) detail_frequence = fields.Float('Frequence', required=True) detail_frequence_selection = fields.Selection( DETAIL_FREQUENCE_OPTIONS, 'Frequence', required=True, sort=False) specific_day = fields.Selection([ (None, ''), ('monday', 'Monday'), ('tuesday', 'Tuesday'), ('wednesday', 'Wednesday'), ('thursday', 'Thursday'), ('friday', 'Friday'), ('saturday', 'Saturday'), ('sunday', 'Sunday') ], 'Specific Day', states={ 'invisible': Eval('frequence_selection') != 'weekly', }, depends=['frequence_selection']) specific_time = fields.Time('Specific Time', states={ 'invisible': Eval('frequence_selection') != 'daily', }, depends=['frequence_selection']) only_workdays = fields.Boolean('Allow working days only') finish_selection = fields.Selection([ (None, ''), ('date', 'Date'), ('quantity', 'Quantity'), ], 'Ends on', sort=False) end_repetition = fields.Integer('Repetition Qty.', states={ 'invisible': Eval('finish_selection') != 'quantity', 'required': Eval('finish_selection') == 'quantity', }, depends=['finish_selection']) end_date = fields.DateTime('End Date', states={ 'invisible': Eval('finish_selection') != 'date', 'required': Eval('finish_selection') == 'date', }, depends=['finish_selection']) @fields.depends('frequence_selection') def on_change_frequence_selection(self): if self.frequence_selection: self.detail_frequence, self.detail_frequence_selection = ( FREQUENCE_OPTIONS_VALUE_MAP[self.frequence_selection]) @classmethod def create_events(cls, records, create_method): events = [] for record in records: if record.finish_selection == 'quantity': events.extend( cls.create_fixed_events(record, create_method)) elif record.finish_selection == 'date': events.extend( cls.create_events_until_date(record, create_method)) else: raise UserError(gettext( 'lims_tools.missing_end_condition')) #events.append(create_method(record)) return events @classmethod def create_fixed_events(cls, record, create_method): events = [] start_date = record.start_date frequence = record.detail_frequence frequence_selection = record.detail_frequence_selection date = start_date while len(events) < record.end_repetition: event = {} event['scheduled_date'] = date event['week_day'] = date.weekday() date = date + cls.get_delta(frequence, frequence_selection) new_event = create_method(record, event) if new_event: events.append(new_event) return events @classmethod def create_events_until_date(cls, record, create_method): events = [] start_date = record.start_date frequence = record.detail_frequence frequence_selection = record.detail_frequence_selection date = start_date while date < record.end_date: event = {} event['scheduled_date'] = date event['week_day'] = date.weekday() date = date + cls.get_delta(frequence, frequence_selection) new_event = create_method(record, event) if new_event: events.append(new_event) return events @classmethod def get_delta(cls, frequence, unit): if unit == 'minutes': return timedelta(minutes=frequence) elif unit == 'hours': return timedelta(hours=frequence) elif unit == 'days': return timedelta(days=frequence) elif unit == 'weeks': return timedelta(weeks=frequence) elif unit == 'months': return timedelta(days=frequence * 30) elif unit == 'years': return timedelta(days=frequence * 365) return timedelta()
class SaleMeeting(ModelView, ModelSQL): 'Sale Opportunity Meeting' __name__ = 'sale.meeting' _order_name = 'hora' opportunity = fields.Many2One( 'sale.opportunity', 'Opportunity', ) fecha = fields.Date('Fecha', required=True) hora = fields.Time('Hora', required=True) descripcion = fields.Text('Descripcion', required=True) asesor = fields.Many2One('company.employee', 'Asesor', domain=[('company', '=', Eval('company'))], required=True, readonly=True) medio_contacto = fields.Selection( [ ('Llamar', 'Llamar'), ('Correo', 'Enviar correo'), ('Whatsapp', 'Whatsapp'), ('SMS', 'SMS'), ('Visita', 'Visita'), ('Otro', 'Otro'), ], 'Medio', sort=False, required=True, ) hora_ = fields.Function(fields.Char('Hora'), 'get_hora') party = fields.Function(fields.Many2One('party.party', 'Cliente'), 'get_party') user = fields.Many2One('res.user', 'Usuario', readonly=True) def get_hora(self, name): hora = self.hora hour = self.hora.hour minute = self.hora.minute hora_ = 'Hora ' + str(hour) + ':' + str(minute) return hora_ def get_party(self, name): if self.opportunity: return self.opportunity.party.id @classmethod def default_user(cls): pool = Pool() User = pool.get('res.user') cursor = Transaction().connection.cursor() user = User(Transaction().user).id return user @classmethod def default_date(cls): pool = Pool() Date = pool.get('ir.date') return Date.today() @classmethod def default_asesor(cls): User = Pool().get('res.user') employee_id = None if Transaction().context.get('employee'): employee_id = Transaction().context['employee'] else: user = User(Transaction().user) if user.employee: employee_id = user.employee.id if employee_id: return employee_id