def synchronous_dingtalk_department(self, repeat_type=None): """ 同步钉钉部门 :return: """ for company in self.company_ids: client = dt.get_client(self, dt.get_dingtalk_config(self, company)) result = client.department.list(fetch_child=True) for res in result: data = { 'company_id': company.id, 'name': res.get('name'), 'ding_id': res.get('id'), } if repeat_type == 'name': domain = [('name', '=', res.get('name')), ('company_id', '=', company.id)] else: domain = [('ding_id', '=', res.get('id')), ('company_id', '=', company.id)] h_department = self.env['hr.department'].sudo().search(domain) if h_department: h_department.sudo().write(data) else: self.env['hr.department'].sudo().create(data) self.env.cr.commit() return True
def create_ding_department(self): if not self.user_has_groups('dingtalk_mc.manage_groups'): raise UserError("您没有创建/上传到钉钉部门的权限!") for res in self: client = dt.get_client( self, dt.get_dingtalk_config(self, res.company_id)) if res.ding_id: raise UserError("部门:(%s)已存在了钉钉ID,不能再进行上传。" % res.name) data = {'name': res.name} # 获取父部门ding_id if res.is_root: data.update({'parentid': 1}) else: if res.parent_id: data.update({ 'parentid': res.parent_id.ding_id if res.parent_id.ding_id else '' }) else: raise UserError("请选择上级部门或则根部门。") try: result = client.department.create(data) res.write({'ding_id': result}) res.message_post(body=u"上传钉钉成功。", message_type='notification') except Exception as e: raise UserError(e) return {'type': 'ir.actions.act_window_close'}
def write_dingtalk_chat(self): """ 修改会话 :return: """ self.ensure_one() client = dt.get_client(self, dt.get_dingtalk_config(self, self.company_id)) try: result = client.post( 'chat/update', { 'chatid': self.chat_id, 'name': self.name, 'owner': self.employee_id.ding_id, 'showHistoryType': self.show_history_type, 'searchable': self.searchable, 'validationType': self.validation_type, 'mentionAllAuthority': self.mention_all_authority, 'chatBannedType': self.chat_banned_type, 'managementType': self.management_ype, }) except Exception as e: raise UserError(e) logging.info(">>>更新群会话结果{}".format(result)) if result.get('errcode') == 0: self.message_post(body="群会话已更新!", message_type='notification') else: raise UserError(result.get('errmsg'))
def del_chat_users(self): """ 删除群成员 :return: """ for res in self: chat_id = self.env.context.get('active_id', False) ding_chat = self.env['dingtalk.mc.chat'].browse(chat_id) user_list = list() for emp in res.user_ids: if not emp.ding_id: raise UserError( _("员工{}:在钉钉中不存在,请选择其他人员!").format(emp.name)) user_list.append(emp.ding_id) chatid = ding_chat.chat_id del_useridlist = user_list try: client = dt.get_client( self, dt.get_dingtalk_config(self, ding_chat.company_id)) result = client.chat.update(chatid, del_useridlist=del_useridlist) logging.info(">>>删除群成员返回结果%s", result) if result.get('errcode') == 0: for user in res.user_ids: ding_chat.write({'useridlist': [(3, user.id)]}) ding_chat.message_post(body=_("群成员已删除!"), message_type='notification') else: raise UserError( _('群成员更新失败,详情为:{}').format(result.get('errmsg'))) except Exception as e: raise UserError(e)
def create_dingtalk_chat(self): """ 创建会话 :return: """ self.ensure_one() client = dt.get_client(self, dt.get_dingtalk_config(self, self.company_id)) user_list = self.check_employee_ding_id() try: result = client.post( 'chat/create', { 'name': self.name, 'owner': self.employee_id.ding_id, 'useridlist': user_list, 'showHistoryType': self.show_history_type, 'searchable': self.searchable, 'validationType': self.validation_type, 'mentionAllAuthority': self.mention_all_authority, 'chatBannedType': self.chat_banned_type, 'managementType': self.management_ype, }) except Exception as e: raise UserError(e) logging.info(">>>创建群会话结果{}".format(result)) if result.get('errcode') == 0: self.write({'chat_id': result.get('chatid'), 'state': 'normal'}) self.message_post(body=_("群会话已创建!群会话的ID:{}").format( result.get('chatid')), message_type='notification') else: raise UserError(result.get('errmsg'))
def send_dingtalk_test_message(self): """ 点击群会话发送群消息按钮 :return: """ self.ensure_one() chat_id = self.env.context.get('active_id', False) ding_chat = self.env['dingtalk.mc.chat'].browse(chat_id) msg = { "msgtype": "text", "text": { "content": self.message } } try: client = dt.get_client(self, dt.get_dingtalk_config(self, ding_chat.company_id)) result = client.chat.send(ding_chat.chat_id, msg) # 创建消息日志 self.env['dingtalk.message.log'].create({ 'company_id': self.env.user.company_id.id, 'name': "发送群消息", 'msg_type': "chat", 'body': self.message, 'result': result, }) except Exception as e: raise UserError(e)
def update_call_back(self): """ 更新事件 :return: """ self.ensure_one() call_list = list() for call in self.call_ids: call_list.append(call.value) try: client = dt.get_client(self, dt.get_dingtalk_config(self, self.company_id)) result = client.post('call_back/update_call_back', { 'call_back_tag': call_list, 'aes_key': self.aes_key, 'token': self.token, 'url': self.url, }) except Exception as e: raise UserError("更新失败!原因:{}".format(e)) if result.get('errcode') == 0: self.write({'state': '01'}) self.message_post(body=u"更新回调事件成功") else: raise UserError("更新失败!原因:{}".format(result.get('errmsg'))) return {'type': 'ir.actions.act_window_close'}
def get_callback_list(self): for company in self.company_ids: client = dt.get_client(self, dt.get_dingtalk_config(self, company)) try: result = client.callback.get_call_back() _logger.info(result) tag_list = list() for tag in result.get('call_back_tag'): callback_list = self.env['dingtalk.callback.list'].sudo( ).search([('value', '=', tag)]) if callback_list: tag_list.append(callback_list[0].id) domain = [('url', '=', result.get('url')), ('company_id', '=', company.id)] callbacks = self.env['dingtalk.callback.manage'].sudo().search( domain) data = { 'call_ids': [(6, 0, tag_list)], 'url': result.get('url'), 'aes_key': result.get('aes_key'), 'token': result.get('token'), 'state': '01', 'company_id': company.id, } if callbacks: callbacks.sudo().write(data) else: self.env['dingtalk.callback.manage'].sudo().create(data) except Exception as e: raise UserError(e) return {'type': 'ir.actions.act_window_close'}
def set_visible_scopes(self): """ 设置可见范围 :return: """ self.ensure_one() miroapp_id = self.miroapp_id client = dt.get_client(self, dt.get_dingtalk_config(self, miroapp_id.company_id)) user_list = list() dept_list = list() for user in self.employee_ids: user_list.append(user.ding_id) for dept in self.department_ids: dept_list.append(dept.ding_id) try: result = client.post('microapp/set_visible_scopes', { 'agentId': miroapp_id.agent_id, 'isHidden': self.is_hidden, 'deptVisibleScopes': dept_list, 'userVisibleScopes': user_list, }) except Exception as e: raise UserError(e) if result.get('errcode') == 0: miroapp_id.write({ 'is_hidden': self.is_hidden, 'department_ids': [(6, 0, self.department_ids.ids)], 'employee_ids': [(6, 0, self.employee_ids.ids)], }) miroapp_id.message_post(body=_("可见范围更新成功!"), message_type='notification') else: raise UserError(result.get('errmsg'))
def synchronous_dingtalk_category(self, company): """ 同步标签 :return: """ client = dt.get_client(self, dt.get_dingtalk_config(self, company)) try: results = client.ext.listlabelgroups() category_list = list() for res in results: for labels in res.get('labels'): category_list.append({ 'name': labels.get('name'), 'ding_id': labels.get('id'), 'ding_category_type': res.get('name'), 'company_id': company.id, }) for category in category_list: res_category = self.env['res.partner.category'].sudo().search([ ('ding_id', '=', category.get('ding_id')), ('company_id', '=', company.id) ]) if res_category: res_category.sudo().write(category) else: self.env['res.partner.category'].sudo().create(category) except Exception as e: raise UserError(e)
def web_dingtalk_auto_signin_action(self, **kw): """ 通过获得的【免登授权码或者临时授权码】获取用户信息 :param kw: :return: """ auth_code = kw.get('authCode') logging.info(">>>免登授权码: %s", auth_code) config = request.env['dingtalk.mc.config'].sudo().search( [('m_login', '=', True)], limit=1) client = dt.get_client( request, dt.get_dingtalk_config(request, config.company_id)) result = client.user.getuserinfo(auth_code) domain = [('ding_id', '=', result.userid), ('company_id', '=', config.company_id.id)] employee = request.env['hr.employee'].sudo().search(domain, limit=1) if not employee: _logger.info(_("系统对应员工不存在!")) return self._do_err_redirect(_("系统对应员工不存在!")) _logger.info(">>>员工:{}正在尝试登录系统".format(employee.name)) if not employee.ding_id: _logger.info(_("员工不存在钉钉ID,请维护后再试!")) return self._do_err_redirect(_("员工不存在钉钉ID,请维护后再试!")) if not employee.user_id: return self._do_err_redirect(_("你还没有关联系统用户,请联系管理员处理!")) ensure_db() dbname = request.session.db if not http.db_filter([dbname]): return BadRequest() registry = registry_get(dbname) with registry.cursor() as cr: try: env = api.Environment(cr, SUPERUSER_ID, {}) credentials = env['res.users'].sudo().auth_oauth( 'dingtalk', employee.ding_id) cr.commit() url = '/web' resp = login_and_redirect(*credentials, redirect_url=url) if werkzeug.urls.url_parse( resp.location ).path == '/web' and not request.env.user.has_group( 'base.group_user'): resp.location = '/' return resp except AttributeError: _logger.error(">>>未在数据库'%s'上安装auth_signup:oauth注册已取消。" % (dbname, )) url = "/web/login?oauth_error=1" except AccessDenied: _logger.info( '>>>DingTalk-OAuth2: 访问被拒绝,在存在有效会话的情况下重定向到主页,而未设置Cookie') url = "/web/login?oauth_error=3" redirect = werkzeug.utils.redirect(url, 303) redirect.autocorrect_location_header = False return redirect except Exception as e: _logger.exception("OAuth2: %s" % str(e)) url = "/web/login?oauth_error=2" return http.redirect_with_hash(url)
def _delete_dingtalk_department_by_id(self, ding_id, company): client = dt.get_client(self, dt.get_dingtalk_config(self, company)) try: result = client.department.delete(ding_id) _logger.info("已在钉钉上删除Id:{}的部门".format(result)) except Exception as e: raise UserError(e) return
def get_user_duration(self, company, emp, biz_type, from_time, to_time, duration_type): """ 获取预计算时长 :param company: 公司 :param emp: 员工 :param biz_type: 1:加班,2:出差,3:请假 :param from_time: 起始日期 :param to_time: 结束日期 :param duration_type: 0:按自然日计算;1:按工作日计算 :return: """ month_code = "{}/{}".format(from_time[:4], from_time[5:7]) client = dt.get_client(self, dt.get_dingtalk_config(self, company)) try: result = client.post( '/topapi/attendance/approve/duration/calculate', { 'userid': emp.ding_id, 'biz_type': biz_type, # 1:加班,2:出差,3:请假 'from_time': from_time, 'to_time': to_time, 'duration_unit': 'day', 'calculate_model': duration_type, # 0:按自然日计算;1:按工作日计算 }) except Exception as e: raise UserError(e) if result.get('errcode') == 0: result = result.get('result') duration = result.get('duration') new_data = { 'company_id': company.id, 'employee_id': emp.id, 'start_date': from_time, 'end_date': to_time, } domain = [('employee_id', '=', emp.id), ('month_code', '=', month_code)] emp_month = self.env['hr.month.attendance'].search(domain) if biz_type == 1: if emp_month: emp_month.write({'overtime_days': duration}) else: new_data.update({'overtime_days': duration}) self.env['hr.month.attendance'].create(new_data) elif biz_type == 2: if emp_month: emp_month.write({'travel_days': duration}) else: new_data.update({'travel_days': duration}) self.env['hr.month.attendance'].create(new_data) elif biz_type == 3: if emp_month: emp_month.write({'leave_days': duration}) else: new_data.update({'leave_days': duration}) self.env['hr.month.attendance'].create(new_data)
def process_dingtalk_chat(self, user_id, sign_time, company): """ 接受来自钉钉回调的处理 :return: """ with api.Environment.manage(): with self.pool.cursor() as new_cr: new_cr.autocommit(True) self = self.with_env(self.env(cr=new_cr)) start_time = int(sign_time) - 1002 end_time = int(sign_time) + 1002 client = dt.get_client(self, dt.get_dingtalk_config(self, company)) try: result = client.post( 'topapi/checkin/record/get', { 'userid_list': user_id, 'start_time': str(start_time), 'end_time': str(end_time), 'cursor': 0, 'size': 100, }) except Exception as e: _logger.info(e) return if result.get('errcode') == 0: r_result = result.get('result') for data in r_result.get('page_list'): domain = [('ding_id', '=', data.get('userid')), ('company_id', '=', company.id)] emp = self.env['hr.employee'].sudo().search(domain, limit=1) self.env['dingtalk.signs.list'].sudo().create({ 'company_id': company.id, 'emp_id': emp.id if emp else False, 'checkin_time': dt.timestamp_to_local_date( data.get('checkin_time'), self), 'place': data.get('place'), 'visit_user': data.get('visit_user'), 'detail_place': data.get('detail_place'), 'remark': data.get('remark'), 'latitude': data.get('latitude'), 'longitude': data.get('longitude'), }) else: logging.info(">>>获取用户签到记录失败,原因:{}".format( result.get('errmsg'))) return True
def get_visible_scopes(self): """ 获取应用的可见范围 :return: """ for res in self: client = dt.get_client(res, dt.get_dingtalk_config(res, res.company_id)) try: result = client.post('microapp/visible_scopes', {'agentId': res.agent_id}) except Exception as e: raise UserError(e) if result.get('errcode') == 0: # 获取当前公司下的所有本部门列表 dept_dict = dict() departments = self.env['hr.department'].sudo().search([ ('company_id', '=', res.company_id.id), ('ding_id', '!=', '') ]) for dept in departments: dept_dict[dept.ding_id] = dept.id # 获取所有员工 emp_dict = dict() emps = self.env['hr.employee'].sudo().search([ ('company_id', '=', res.company_id.id), ('ding_id', '!=', '') ]) for emp in emps: emp_dict[emp.ding_id] = emp.id is_hidden = result.get('isHidden') user_list = list() dept_list = list() try: for dept in result.get('deptVisibleScopes'): if dept_dict.get(dept): dept_list.append(dept_dict.get(dept)) for user_id in result.get('userVisibleScopes'): if emp_dict.get(user_id): user_list.append(emp_dict.get(user_id)) except Exception as e: msg = '获取应用:{} 的可见列表数据错误!{}; 错误:{}'.format( res.name, result, str(e)) _logger.info(msg) res.message_post(body=msg, message_type='notification') res.write({ 'is_hidden': is_hidden, 'department_ids': [(6, 0, dept_list)], 'employee_ids': [(6, 0, user_list)], }) else: raise UserError('获取应用的可见范围失败,详情为:{}'.format( result.get('errmsg')))
def synchronous_dingtalk_partner(self, company): """ 同步联系人 :param company: :return: """ client = dt.get_client(self, dt.get_dingtalk_config(self, company)) try: results = client.ext.list(offset=0, size=100) _logger.info(results) for res in results: # 获取标签 label_list = list() for label in res.get('labelIds'): category = self.env['res.partner.category'].sudo().search( [('ding_id', '=', label), ('company_id', '=', company.id)], limit=1) if category: label_list.append(category.id) data = { 'name': res.get('name'), 'function': res.get('title'), 'category_id': [(6, 0, label_list)], # 标签 'ding_id': res.get('userId'), # 钉钉用户id 'comment': res.get('remark'), # 备注 'street': res.get('address'), # 地址 'mobile': res.get('mobile'), # 手机 'phone': res.get('mobile'), # 电话 'ding_company_name': res.get('company_name'), # 钉钉公司名称 'company_id': company.id } # 获取负责人 if res.get('followerUserId'): follower_user = self.env['hr.employee'].sudo().search( [('ding_id', '=', res.get('followerUserId')), ('company_id', '=', company.id)], limit=1) if follower_user: data.update({'ding_employee_id': follower_user.id}) partner = self.env['res.partner'].sudo().search([ ('ding_id', '=', res.get('userId')), ('company_id', '=', company.id) ]) if partner: partner.sudo().write(data) else: self.env['res.partner'].sudo().create(data) except Exception as e: raise UserError(e) return
def _delete_dingtalk_employee_by_id(self, ding_id, company): """ 删除钉钉员工 :param ding_id: :param company: :return: """ client = dt.get_client(self, dt.get_dingtalk_config(self, company)) try: result = client.user.delete(ding_id) _logger.info(_("已在钉钉上删除Id:{}的员工".format(result))) except Exception as e: raise UserError(e) return
def start_synchronous_data(self): """ 花名册同步 :return: """ self.ensure_one() for company in self.company_ids: client = dt.get_client(self, dt.get_dingtalk_config(self, company)) emp_data = self.get_employee_to_dict(company.id) userid_list = self.get_onjob_userid_list(client) self.create_employee_roster(client, dt.list_cut(userid_list, 20), emp_data, company.id) return {'type': 'ir.actions.act_window_close'}
def get_department_info(self, dept_id, event_type, company): """ 获取部门详情 :param dept_id: :param event_type: :param company: :return: """ try: client = dt.get_client(self, dt.get_dingtalk_config(self, company)) result = client.department.get(dept_id) except Exception as e: _logger.info("获取部门详情失败:{}".format(e)) return if result.get('errcode') == 0: data = { 'name': result.get('name'), 'ding_id': result.get('id'), 'company_id': company.id, } if result.get('parentid') != 1: domain = [('ding_id', '=', result.get('parentid')), ('company_id', '=', company.id)] partner_department = self.env['hr.department'].sudo().search( domain, limit=1) if partner_department: data.update({'parent_id': partner_department.id}) else: data['is_root'] = True depts = result.get('deptManagerUseridList').split("|") manage_users = self.env['hr.employee'].sudo().search([ ('ding_id', 'in', depts), ('company_id', '=', company.id) ]) if manage_users: data.update({ 'manager_user_ids': [(6, 0, manage_users.ids)], 'manager_id': manage_users[0].id }) domain = [('ding_id', '=', result.get('id')), ('company_id', '=', company.id)] if event_type == 'org_dept_create': h_department = self.env['hr.department'].sudo().search(domain) if not h_department: self.env['hr.department'].sudo().create(data) elif event_type == 'org_dept_modify': h_department = self.env['hr.department'].sudo().search(domain) if h_department: h_department.sudo().write(data) return True
def unlink(self): """ 重写删除方法 :return: """ for res in self: if res.state == '01': _logger.info(">>>删除事件...") try: client = dt.get_client(self, dt.get_dingtalk_config(self, res.company_id)) result = client.callback.delete_call_back() _logger.info("删除回调事件:{}".format(result)) except Exception as e: _logger.info(e) super(DingTalkCallback, self).unlink()
def create_ding_employee(self): """ 上传员工到钉钉 :return: """ for res in self: self._check_user_identity(res) client = dt.get_client( self, dt.get_dingtalk_config(self, res.company_id)) # 获取部门ding_id department_list = list() if not res.department_id: raise UserError("请选择员工部门!") elif res.department_ids: department_list = res.department_ids.mapped('ding_id') department_list.append(res.department_id.ding_id) else: department_list.append(res.department_id.ding_id) data = { 'name': res.name, # 名称 'department': department_list, # 部门 'position': res.job_title if res.job_title else '', # 职位 'mobile': res.mobile_phone if res.mobile_phone else res.work_phone, # 手机 'tel': res.work_phone if res.work_phone else res.mobile_phone, # 手机 'workPlace': res.work_location if res.work_location else '', # 办公地址 'remark': res.notes if res.notes else '', # 备注 'email': res.work_email if res.work_email else '', # 邮箱 'jobnumber': res.din_jobnumber if res.din_jobnumber else '', # 工号 'hiredDate': dt.datetime_to_stamp(res.din_hiredDate) if res.din_hiredDate else '', # 入职日期 } try: result = client.user.create(data) res.write({'ding_id': result}) res.message_post(body=u"已上传至钉钉", message_type='notification') except Exception as e: raise UserError(e) return {'type': 'ir.actions.act_window_close'}
def send_post_dingtalk(self, data, company): client = dt.get_client(self, dt.get_dingtalk_config(self, company)) try: result = client.attendance.list(data.get('workDateFrom'), data.get('workDateTo'), user_ids=data.get('userIdList'), offset=data.get('offset'), limit=data.get('limit')) if result.get('errcode') == 0: data_list = list() for rec in result.get('recordresult'): # 员工 emp_id = self.env['hr.employee'].sudo().search( [('ding_id', '=', rec.get('userId')), ('company_id', '=', company.id)], limit=1) data_list.append({ 'company_id': company.id, 'employee_id': emp_id.id if emp_id else False, 'work_date': dt.timestamp_to_local_date(rec.get('workDate'), self), # 工作日 'record_id': rec.get('id'), 'check_type': rec.get('checkType'), 'timeResult': rec.get('timeResult'), # 时间结果 'locationResult': rec.get('locationResult'), # 考勤结果 'baseCheckTime': dt.get_time_stamp(rec.get('baseCheckTime')), # 基准时间 'check_in': dt.get_time_stamp(rec.get('userCheckTime')), 'sourceType': rec.get('sourceType'), # 数据来源 }) self.env['hr.attendance.result'].sudo().create(data_list) if result.get('hasMore'): return True else: return False else: raise UserError('请求失败,原因为:{}'.format(result.get('errmsg'))) except Exception as e: raise UserError(e)
def update_ding_employee(self): """ 修改员工时同步至钉钉 :return: """ for res in self: self._check_user_identity(res) client = dt.get_client( self, dt.get_dingtalk_config(self, res.company_id)) # 获取部门ding_id department_list = list() if not res.department_id: raise UserError("请选择员工部门!") elif res.department_ids: department_list = res.department_ids.mapped('ding_id') if res.department_id.ding_id not in res.department_ids.mapped( 'ding_id'): department_list.append(res.department_id.ding_id) else: department_list.append(res.department_id.ding_id) data = { 'userid': res.ding_id, # userid 'name': res.name, # 名称 'department': department_list, # 部门 'position': res.job_title if res.job_title else '', # 职位 'mobile': res.mobile_phone if res.mobile_phone else res.work_phone, # 手机 'tel': res.work_phone if res.work_phone else '', # 手机 'workPlace': res.work_location if res.work_location else '', # 办公地址 'remark': res.notes if res.notes else '', # 备注 'email': res.work_email if res.work_email else '', # 邮箱 'jobnumber': res.din_jobnumber if res.din_jobnumber else '', # 工号 'isSenior': res.din_isSenior, # 高管模式 'isHide': res.din_isHide, # 隐藏手机号 } if res.din_hiredDate: hiredDate = dt.datetime_to_stamp(res.din_hiredDate) data.update({'hiredDate': hiredDate}) try: result = client.user.update(data) _logger.info(_(result)) res.message_post(body=u"已成功更新至钉钉", message_type='notification') except Exception as e: raise UserError(e) return {'type': 'ir.actions.act_window_close'}
def approval_result(self): """ 发起审批 :param self: :return: """ # 获取钉钉审批配置 model_id = self.env['ir.model'].sudo().search([('model', '=', self._name)]).id domain = [('oa_model_id', '=', model_id), ('company_id', '=', self.env.user.company_id.id)] approval = self.env['dingtalk.approval.control'].sudo().search(domain, limit=1) _logger.info("提交'%s'单据至钉钉进行审批..." % approval.name) # 钉钉审批模型编码 process_code = approval.template_id.process_code # 获取表单参数 form_values = get_form_values(self, approval) # 发起人和发起人部门 user_id, dept_id = get_originator_user_id(self) # 获取审批人和抄送人列表 approvers_users = approval.get_approvers_users() cc_users, cc_type = approval.get_cc_users() data = { 'process_code': process_code, # 审批模型编号 'originator_user_id': user_id, # 发起人 'dept_id': dept_id, # 发起部门 'form_component_values': form_values # 表单参数 } if approvers_users: if approval.approval_type == 'turn': data.update({'approvers': approvers_users}) # 依次审批人列表 else: data.update({'approvers_v2': approvers_users}) # 会签、或签审批人列表 if cc_users and cc_type: data.update({ 'cc_list': cc_users, # 抄送列表 'cc_position': cc_type # 抄送时间 }) # ----提交至钉钉--- client = dt.get_client(self, dt.get_dingtalk_config(self, self.env.user.company_id)) try: url = 'topapi/processinstance/create' result = client.post(url, data) except Exception as e: raise UserError(e) _logger.info(result) return result, approval
def update_ding_department(self): if not self.user_has_groups('dingtalk_mc.manage_groups'): raise UserError("您没有修改/更新到钉钉部门的权限!") for res in self: client = dt.get_client( self, dt.get_dingtalk_config(self, res.company_id)) data = { 'id': res.ding_id, # id 'name': res.name, # 部门名称 'parentid': res.parent_id.ding_id, # 父部门id } if res.is_root: data.update({'parentid': 1}) try: result = client.department.update(data) _logger.info(result) res.message_post(body=u"更新钉钉部门成功", message_type='notification') except Exception as e: raise UserError(e) return {'type': 'ir.actions.act_window_close'}
def get_template(self): """ 获取审批模板 :return: """ self.ensure_one() for company in self.company_ids: company_id = company.id client = dt.get_client(self, dt.get_dingtalk_config(self, company)) offset = 0 size = 100 while True: try: result = client.post('topapi/process/listbyuserid', {'offset': offset, 'size': size}) except Exception as e: raise UserError(e) if result.get('errcode') == 0: result = result.get('result') for process in result.get('process_list'): data = { 'name': process.get('name'), 'icon_avatar_url': process.get('icon_url'), 'process_code': process.get('process_code'), 'url': process.get('url'), 'company_id': company_id, } domain = [('company_id', '=', company_id), ('process_code', '=', process.get('process_code'))] template = self.env['dingtalk.approval.template'].search(domain) if template: template.write(data) else: self.env['dingtalk.approval.template'].create(data) if result.get('next_cursor'): offset += result.get('next_cursor') else: break else: raise UserError('获取审批模板失败,详情为:{}'.format(result.get('errmsg'))) return {'type': 'ir.actions.act_window_close'}
def get_miroapp_list(self): """ 获取审批模板 :return: """ self.ensure_one() for company in self.company_ids: company_id = company.id client = dt.get_client(self, dt.get_dingtalk_config(self, company)) try: result = client.post('microapp/list', {}) except Exception as e: raise UserError(e) if result.get('errcode') == 0: for app in result.get('appList'): data = { 'name': app.get('name'), 'icon_avatar_url': app.get('appIcon'), 'agent_id': app.get('agentId'), 'app_desc': app.get('appDesc'), 'is_self': 'y' if app.get('isSelf') else 'n', 'home_link': app.get('homepageLink'), 'pc_link': app.get('pcHomepageLink'), 'state': str(app.get('appStatus')), 'oa_link': app.get('ompLink'), 'company_id': company_id, } domain = [('company_id', '=', company_id), ('agent_id', '=', app.get('agentId'))] miroapps = self.env['dingtalk.miroapp.list'].search(domain) if miroapps: miroapps.write(data) else: miroapps = self.env['dingtalk.miroapp.list'].create(data) miroapps.get_visible_scopes() else: break else: raise UserError('获取审批模板失败,详情为:{}'.format(result.get('errmsg'))) return {'type': 'ir.actions.act_window_close'}
def get_department_details(self): """ 获取部门详情 :return: """ for company in self.company_ids: client = dt.get_client(self, dt.get_dingtalk_config(self, company)) departments = self.env['hr.department'].sudo().search([ ('company_id', '=', company.id), ('ding_id', '!=', '') ]) for dept in departments: result = client.department.get(dept.ding_id) dept_date = dict() if result.get('errcode') == 0: if result.get('parentid') == 1: dept_date['is_root'] = True else: doamin = [('ding_id', '=', result.get('parentid')), ('company_id', '=', company.id)] partner_dept = self.env['hr.department'].sudo().search( doamin, limit=1) if partner_dept: dept_date['parent_id'] = partner_dept.id if result.get('deptManagerUseridList'): depts = result.get('deptManagerUseridList').split("|") manage_users = self.env['hr.employee'].sudo().search([ ('ding_id', 'in', depts), ('company_id', '=', company.id) ]) dept_date.update({ 'manager_user_ids': [(6, 0, manage_users.ids)], 'manager_id': manage_users[0].id }) if dept_date: dept.sudo().write(dept_date) self.env.cr.commit() return True
def synchronous_dingtalk_employee(self, repeat_type=None): """ 同步钉钉部门员工列表 :return: """ for company in self.company_ids: departments = self.env['hr.department'].sudo().search([ ('ding_id', '!=', ''), ('company_id', '=', company.id) ]) client = dt.get_client(self, dt.get_dingtalk_config(self, company)) for dept in departments: emp_offset = 0 emp_size = 100 while True: _logger.info(">>>开始获取%s部门的员工", dept.name) result_state = self.get_dingtalk_employees( client, dept, emp_offset, emp_size, company, repeat_type) if result_state: emp_offset = emp_offset + 1 else: break self.env.cr.commit() return True
def get_employee_info(self, user_id, event_type, company): """ 获取用户详情执行函数 :param user_id: :param event_type: :param company: :return: """ try: client = dt.get_client(self, dt.get_dingtalk_config(self, company)) result = client.user.get(user_id) except Exception as e: _logger.info("获取用户详情失败:{}".format(e)) return if result.get('errcode') == 0: data = { 'name': result.get('name'), # 员工名称 'ding_id': result.get('userid'), # 钉钉用户Id 'din_unionid': result.get('unionid'), # 钉钉唯一标识 'mobile_phone': result.get('mobile'), # 手机号 'work_phone': result.get('tel'), # 分机号 'work_location': result.get('workPlace'), # 办公地址 'notes': result.get('remark'), # 备注 'job_title': result.get('position'), # 职位 'work_email': result.get('email'), # email 'din_jobnumber': result.get('jobnumber'), # 工号 'ding_avatar_url': result.get('avatar') if result.get('avatar') else '', # 钉钉头像url 'din_isSenior': result.get('isSenior'), # 高管模式 'din_isAdmin': result.get('isAdmin'), # 是管理员 'din_isBoss': result.get('isBoss'), # 是老板 'din_isHide': result.get('isHide'), # 隐藏手机号 'din_active': result.get('active'), # 是否激活 'din_isLeaderInDepts': result.get('isLeaderInDepts'), # 是否为部门主管 'din_orderInDepts': result.get('orderInDepts'), # 所在部门序位 'company_id': company.id } # 支持显示国际手机号 if result.get('stateCode') != '86': data.update({ 'mobile_phone': '+{}-{}'.format(result.get('stateCode'), result.get('mobile')), }) if result.get('hiredDate'): date_str = dt.timestamp_to_local_date(result.get('hiredDate'), obj=self) data.update({'din_hiredDate': date_str}) if result.get('department'): dep_ding_ids = result.get('department') dep_list = self.env['hr.department'].sudo().search([ ('ding_id', 'in', dep_ding_ids), ('company_id', '=', company.id) ]) data.update({ 'department_ids': [(6, 0, dep_list.ids)], 'department_id': dep_list[0].id if dep_list else False }) # 当为新建时以名称进行搜索 if event_type == 'user_add_org': employee = self.env['hr.employee'].sudo().search( [('name', '=', result.get('name')), ('company_id', '=', company.id)], limit=1) if not employee: self.env['hr.employee'].sudo().create(data) else: employee.sudo().write(data) else: employee = self.env['hr.employee'].sudo().search( [('ding_id', '=', user_id), ('company_id', '=', company.id)], limit=1) if employee: employee.sudo().write(data) else: _logger.info("从钉钉同步员工时发生意外,原因为:{}".format(result.get('errmsg'))) return True