from datetime import datetime, timedeltafrom odoo import fields, models, apiclass NebulaTeacherAppointment(models.Model): _name = "nebula.teacher.appointment" _description = "教练预约单" _order = 'name' active = fields.Boolean('是否有效', default=True) name = fields.Char('教练预约简情', size=30) # TODO: 预约时间不得小于当天,未做处理 appointment_date = fields.Date('预约日期', default=datetime.now()) teacher_name = fields.Many2one('nebula.teacher', string='教练工号', size=8, required=True, domain=[('active', '=', True)]) teacher_full_name = fields.Char('教练姓名', related='teacher_name.full_name', store=True) teacher_mobile = fields.Char('教练手机', related='teacher_name.mobile') date_docket = fields.Datetime('单据日期', required=True, readonly=True, index=True, default=fields.Datetime.now) user_id = fields.Many2one('res.users', string='创建人', index=True, readonly=True, default=lambda self: self.env.user) order_line = fields.One2many('nebula.teacher.appointment.line', 'order_id', string='预约明细', auto_join=True) _sql_constraints = [('check_uniq_name', 'unique(appointment_date, name)', '一个教练一个日期预约单')] @api.onchange('teacher_name', 'appointment_date') def _onchange_name_date(self): if self.appointment_date and self.teacher_name: self.name = _make_name(self.appointment_date, self.teacher_name.name, self.teacher_name.full_name) def button_teacher_time(self): """ 功能: 生成指定教练本日预约。 从传入的self中得到指定的教练和日期,删除旧子表,再创建新子表 1.调插入子表程序 """ # todo : 应该有时间判断,大于等于今天才能操作,未写 _insert_line_table(self, self.id, self.appointment_date, self.teacher_name.id) def button_all_time(self): # 所有教练本日预约 # todo : 应该有时间判断,大于等于今天才能操作,未写 """ 功能: 生成所有教练本日预约。 从传入的self中得到指定的教练和日期,生成所有教练本日预约单。 1. 删除除了传入的教练外所有本日主表,子表会自动删除删除。 2.查找本日预约表中所有教练,循环生成除了本教练外主表, 3.查找教练预约表本日所有记录,遍历生成子表 """ # 1. 删除除了传入的教练外所有本日主表,子表会自动删除删除。 appointment_date = self.appointment_date domain = [('teacher_name', '!=', self.teacher_name.id), # 教练排除 ('active', '=', True), ('appointment_date', '=', appointment_date)] self.env['nebula.teacher.appointment'].search(domain).unlink() # 2. 查找本日预约表中所有教练,生成主表 begin_time = datetime.strftime(appointment_date, "%Y-%m-%d 00:00:00") end_time = datetime.strftime(appointment_date, "%Y-%m-%d 23:59:59") domain = [('active', '=', True), ('appointment_begin_date', '>=', begin_time), ('appointment_begin_date', '<=', end_time), ('teacher_name', '!=', self.teacher_name.id), ('complete_begin_date', '=', None)] field_names = ['teacher_name', 'teacher_full_name'] records = self.env['nebula.appointment'].search_read(domain, field_names, order='teacher_name desc') old_name = '' for record in records: record_name = _make_name(self.appointment_date, record['teacher_name'][1], record['teacher_full_name']) if old_name != record_name: # 不是重名 old_name = record_name new_record = { 'teacher_name': record['teacher_name'][0], 'appointment_date': self.appointment_date, 'name': record_name, } self.env['nebula.teacher.appointment'].create(new_record) # 3.查找教练预约表本日所有记录,遍历生成子表 domain = [('active', '=', True), ('appointment_date', '=', appointment_date)] field_names = ['teacher_name'] records = self.env['nebula.teacher.appointment'].search_read(domain, field_names) for record in records: order_id = record['id'] teacher_id = record['teacher_name'][0] _insert_line_table(self, order_id, appointment_date, teacher_id)def _make_name(appointment_date, teacher_name, teacher_full_name): # 传入参数,生成默认name order_date = appointment_date + timedelta(hours=8) order_text = datetime.strftime(order_date, "%Y-%m-%d") record_name = '(' + teacher_name + ')' record_name += teacher_full_name + '^' record_name += order_text return record_namedef _insert_line_table(self, order_id, appointment_date, teacher_id): """ 功能:传入主表,然后生成子表 1.传入主表 2.删除主表对应的子表 3.查询预约表本教练所有预约情况 4. 逐条插入到子表 """ domain = [('order_id', '=', order_id)] self.env['nebula.teacher.appointment.line'].search(domain).unlink() begin_time = datetime.strftime(appointment_date, "%Y-%m-%d 00:00:00") end_time = datetime.strftime(appointment_date, "%Y-%m-%d 23:59:59") domain = [('active', '=', True), ('appointment_begin_date', '>=', begin_time), ('appointment_begin_date', '<=', end_time), ('teacher_name', '=', teacher_id), ('complete_begin_date', '=', None)] field_names = ['name'] items = self.env['nebula.appointment'].search_read(domain, field_names) for item in items: new_record = { 'order_id': order_id, # 主表ID 'appointment_name': item['id'], # 子表预约单ID } self.env['nebula.teacher.appointment.line'].create(new_record)class TeacherAppointmentLine(models.Model): _name = 'nebula.teacher.appointment.line' _description = '预约明细' @api.model def _select_car_type(self): records = self.env['nebula.car.type'].search([('active', '=', True)]) return [(r.name, r.name_type) for r in records] def _select_auto_type(self): records = self.env['nebula.auto.type'].search([]) return [(r.name, r.name_type) for r in records] @api.depends('complete_begin_date', 'complete_hours') def _calc_complete_end_date(self): for order in self: if order.complete_begin_date: begin_date = order.complete_begin_date add_hours = order.complete_hours begin_date += timedelta(hours=add_hours) begin_date -= timedelta(seconds=1) order.complete_end_date = begin_date order_id = fields.Many2one('nebula.teacher.appointment', string='教练预约单ID', required=True, ondelete='cascade', copy=False) appointment_name = fields.Many2one('nebula.appointment', string='预约单', size=8, readonly=True) auto_type_name = fields.Selection(selection='_select_auto_type', string='预约类型', related='appointment_name.auto_type_name') student_name = fields.Many2one('nebula.student', string='学员姓名', size=8, related='appointment_name.student_name') student_mobile = fields.Char('学员手机', related='student_name.mobile') appointment_begin_date = fields.Datetime('预约起始时间', related='appointment_name.appointment_begin_date', index=True) appointment_hours = fields.Integer('预约小时数', related='appointment_name.appointment_hours') appointment_end_date = fields.Datetime('预约结束时间', related='appointment_name.appointment_end_date') complete_begin_date = fields.Datetime('实际起始时间') # TODO: 当写该值的时候回写预约表 complete_hours = fields.Integer('实际小时数') # TODO: 当写该值的时候回写预约表 complete_end_date = fields.Datetime('实际结束时间', compute='_calc_complete_end_date', store=True) # TODO: 当写该值的时候回写预约表 car_name = fields.Many2one('nebula.car', string='车辆编号', size=8, related='appointment_name.car_name', domain=[('active', '=', True)]) license_plate = fields.Char('车辆牌照', related='car_name.license_plate') car_type_name = fields.Selection(selection='_select_car_type', string='车型', related='car_name.car_type_name') car_auto_type_name = fields.Selection(selection='_select_auto_type', string='排挡类', related='car_name.auto_type_name') work_charge_hour = fields.Integer('每小时收费', related='appointment_name.work_charge_hour') deposit = fields.Integer('学员缴费') # TODO: 当写该值的时候回写预约表 begin_address = fields.Text('上车地点', related='appointment_name.begin_address') end_address = fields.Text('下车地点', related='appointment_name.end_address') note = fields.Text('备注', related='appointment_name.note')