From f4a21bfc9fa2c49e82ba3554fc1107649b4d9b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=81=A5=E6=98=8E?= Date: Fri, 9 Aug 2024 22:04:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1=20?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yuthon_wechat/models/wecom_apps.py | 6 +- yuthon_wechat/wizard/wecom_api_sync_wizard.py | 167 +++++++++--------- 2 files changed, 91 insertions(+), 82 deletions(-) diff --git a/yuthon_wechat/models/wecom_apps.py b/yuthon_wechat/models/wecom_apps.py index 88c1812ed..ab1f0bff7 100644 --- a/yuthon_wechat/models/wecom_apps.py +++ b/yuthon_wechat/models/wecom_apps.py @@ -46,7 +46,8 @@ class WeComApps(models.Model): result_data = self.sync_function_api("contacts", "DEPARTMENT_LIST", {}) if result_data["errcode"] == 0: wecom_departments = result_data.get("department", []) - return wecom_departments + return True, wecom_departments + return False, result_data def sync_user_list(self, department_id): user_list = [] @@ -56,7 +57,8 @@ class WeComApps(models.Model): result_data = self.sync_function_api("contacts", "USER_LIST", data) if result_data["errcode"] == 0: user_list = result_data.get("userlist", []) - return user_list + return True, user_list + return False, result_data def sync_send_message(self, user_id, message): wecom_app = self.sudo().env["wecom.apps.config"].search([("wecom_apps_type", "=", "message_send")], limit=1).wecom_apps_id diff --git a/yuthon_wechat/wizard/wecom_api_sync_wizard.py b/yuthon_wechat/wizard/wecom_api_sync_wizard.py index b7baf5a99..d77cdf4e2 100644 --- a/yuthon_wechat/wizard/wecom_api_sync_wizard.py +++ b/yuthon_wechat/wizard/wecom_api_sync_wizard.py @@ -2,6 +2,7 @@ import datetime import calendar from odoo import models, api, fields, _ +from odoo.exceptions import UserError class WeComApiSyncWizard(models.Model): @@ -21,89 +22,95 @@ class WeComApiSyncWizard(models.Model): # 先将部门全部归档 self.sudo().env["hr.department"].search([]).write({"active": False}) # 开始同步部门信息 - wecom_departments = self.sudo().env["wecom.apps"].sync_department_list() - for department in wecom_departments: - name = department.get("name", "") - wecom_id = department.get("id", 0) - wecom_name_en = department.get("name_en", "") - wecom_department_leader = department.get("department_leader", "") - wecom_order = department.get("order", "") - wecom_parent_id = department.get("parentid", 0) - hr_departments = self.sudo().env["hr.department"].with_context(active_test=False).search([("wecom_id", '=', wecom_id)]) - data = { - "name": name, - "wecom_id": wecom_id, - "wecom_name_en": wecom_name_en, - "wecom_department_leader": wecom_department_leader, - "wecom_order": wecom_order, - "wecom_parent_id": wecom_parent_id, - "active": True - } - if hr_departments: - hr_departments.write(data) - else: - self.sudo().env["hr.department"].create(data) - # 同步完成后开始进行部门上下级的划分 - new_departments = self.sudo().env["hr.department"].search([]) - for new_department in new_departments: - if new_department.wecom_id: - self.sudo().env["hr.department"].search([("wecom_parent_id", "=", new_department.wecom_id)]).write({ - "parent_id": new_department.id - }) + department_result, wecom_departments = self.sudo().env["wecom.apps"].sync_department_list() + if not department_result: + raise UserError(str(wecom_departments)) + if department_result: + for department in wecom_departments: + name = department.get("name", "") + wecom_id = department.get("id", 0) + wecom_name_en = department.get("name_en", "") + wecom_department_leader = department.get("department_leader", "") + wecom_order = department.get("order", "") + wecom_parent_id = department.get("parentid", 0) + hr_departments = self.sudo().env["hr.department"].with_context(active_test=False).search([("wecom_id", '=', wecom_id)]) + data = { + "name": name, + "wecom_id": wecom_id, + "wecom_name_en": wecom_name_en, + "wecom_department_leader": wecom_department_leader, + "wecom_order": wecom_order, + "wecom_parent_id": wecom_parent_id, + "active": True + } + if hr_departments: + hr_departments.write(data) + else: + self.sudo().env["hr.department"].create(data) + # 同步完成后开始进行部门上下级的划分 + new_departments = self.sudo().env["hr.department"].search([]) + for new_department in new_departments: + if new_department.wecom_id: + self.sudo().env["hr.department"].search([("wecom_parent_id", "=", new_department.wecom_id)]).write({ + "parent_id": new_department.id + }) if self.sync_name == '1': # 先将员工全部归档 self.sudo().env["hr.employee"].search([]).write({"active": False}) # 开始按照部门逐步获取员工 hr_departments = self.sudo().env["hr.department"].search([("wecom_id", "!=", False)]) for hr_department in hr_departments: - user_list = self.sudo().env["wecom.apps"].sync_user_list(hr_department.wecom_id) - for user in user_list: - biz_mail = user.get("biz_mail", "") - userid = user.get("userid", "") - name = user.get("name", "") - mobile = user.get("mobile", "") - telephone = user.get("telephone", "") - # todo 需要的字段整理到数据库 - """ - errcode 返回码 - errmsg 对返回码的文本描述内容 - userlist 成员列表 - userid 成员UserID。对应管理端的账号 - name 成员名称;第三方不可获取,调用时返回userid以代替name;代开发自建应用需要管理员授权才返回;对于非第三方创建的成员,第三方通讯录应用也不可获取;未返回名称的情况需要通过通讯录展示组件来展示名字 - mobile 手机号码,代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - department 成员所属部门id列表,仅返回该应用有查看权限的部门id。对授权了“组织架构信息”的第三方应用或授权了“组织架构信息”-“部门及父部门ID、部门负责人”的代开发应用,返回成员所属的全部部门id列表 - order 部门内的排序值,默认为0。数量必须和department一致,数值越大排序越前面。值范围是[0, 2^32) - position 职务信息;代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - gender 性别。0表示未定义,1表示男性,2表示女性。第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段。注:不可获取指返回值为0 - email 邮箱,代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - biz_mail 企业邮箱,代开发自建应用不返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - is_leader_in_dept 表示在所在的部门内是否为部门负责人。0-否;1-是。是一个列表,数量必须与department一致。第三方通讯录应用或者授权了“组织架构信息-应用可获取企业的部门组织架构信息-部门负责人”权限的第三方应用和代开发应用可获取;对于非第三方创建的成员,第三方通讯录应用不可获取;上游企业不可获取下游企业成员该字段 - direct_leader 直属上级UserID,返回在应用可见范围内的直属上级列表,最多有1个直属上级;第三方通讯录应用或者授权了“组织架构信息-应用可获取可见范围内成员组织架构信息-直属上级”权限的第三方应用和代开发应用可获取;对于非第三方创建的成员,第三方通讯录应用不可获取;上游企业不可获取下游企业成员该字段;代开发自建应用不可获取该字段 - avatar 头像url。 第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - thumb_avatar 头像缩略图url。第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - telephone 座机。代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - alias 别名;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - extattr 扩展属性,代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - status 激活状态: 1=已激活,2=已禁用,4=未激活,5=退出企业。 - 已激活代表已激活企业微信或已关注微信插件(原企业号)。未激活代表既未激活企业微信又未关注微信插件(原企业号)。 - qr_code 员工个人二维码,扫描可添加为外部联系人(注意返回的是一个url,可在浏览器上打开该url以展示二维码);第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - external_profile 成员对外属性,字段详情见对外属性;代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - external_position 对外职务,如果设置了该值,则以此作为对外展示的职务,否则以position来展示。代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - address 地址。代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 - open_userid 全局唯一。对于同一个服务商,不同应用获取到企业内同一个成员的open_userid是相同的,最多64个字节。仅第三方应用可获取 - main_department - """ - hr_employees = self.sudo().env["hr.employee"].with_context(active_test=False).search([("wecom_userid", '=', userid)]) - data = { - "active": True, - "work_email": biz_mail, - "wecom_userid": userid, - "name": name, - "department_id": hr_department.id, - "mobile_phone": mobile, - "work_phone": telephone, - } - if hr_employees: - hr_employees.write(data) - else: - self.sudo().env["hr.employee"].create(data) + user_result, user_list = self.sudo().env["wecom.apps"].sync_user_list(hr_department.wecom_id) + if not user_result: + raise UserError(str(user_result)) + if user_result: + for user in user_list: + biz_mail = user.get("biz_mail", "") + userid = user.get("userid", "") + name = user.get("name", "") + mobile = user.get("mobile", "") + telephone = user.get("telephone", "") + # todo 需要的字段整理到数据库 + """ + errcode 返回码 + errmsg 对返回码的文本描述内容 + userlist 成员列表 + userid 成员UserID。对应管理端的账号 + name 成员名称;第三方不可获取,调用时返回userid以代替name;代开发自建应用需要管理员授权才返回;对于非第三方创建的成员,第三方通讯录应用也不可获取;未返回名称的情况需要通过通讯录展示组件来展示名字 + mobile 手机号码,代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + department 成员所属部门id列表,仅返回该应用有查看权限的部门id。对授权了“组织架构信息”的第三方应用或授权了“组织架构信息”-“部门及父部门ID、部门负责人”的代开发应用,返回成员所属的全部部门id列表 + order 部门内的排序值,默认为0。数量必须和department一致,数值越大排序越前面。值范围是[0, 2^32) + position 职务信息;代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + gender 性别。0表示未定义,1表示男性,2表示女性。第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段。注:不可获取指返回值为0 + email 邮箱,代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + biz_mail 企业邮箱,代开发自建应用不返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + is_leader_in_dept 表示在所在的部门内是否为部门负责人。0-否;1-是。是一个列表,数量必须与department一致。第三方通讯录应用或者授权了“组织架构信息-应用可获取企业的部门组织架构信息-部门负责人”权限的第三方应用和代开发应用可获取;对于非第三方创建的成员,第三方通讯录应用不可获取;上游企业不可获取下游企业成员该字段 + direct_leader 直属上级UserID,返回在应用可见范围内的直属上级列表,最多有1个直属上级;第三方通讯录应用或者授权了“组织架构信息-应用可获取可见范围内成员组织架构信息-直属上级”权限的第三方应用和代开发应用可获取;对于非第三方创建的成员,第三方通讯录应用不可获取;上游企业不可获取下游企业成员该字段;代开发自建应用不可获取该字段 + avatar 头像url。 第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + thumb_avatar 头像缩略图url。第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + telephone 座机。代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + alias 别名;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + extattr 扩展属性,代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + status 激活状态: 1=已激活,2=已禁用,4=未激活,5=退出企业。 + 已激活代表已激活企业微信或已关注微信插件(原企业号)。未激活代表既未激活企业微信又未关注微信插件(原企业号)。 + qr_code 员工个人二维码,扫描可添加为外部联系人(注意返回的是一个url,可在浏览器上打开该url以展示二维码);第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + external_profile 成员对外属性,字段详情见对外属性;代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + external_position 对外职务,如果设置了该值,则以此作为对外展示的职务,否则以position来展示。代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + address 地址。代开发自建应用需要管理员授权才返回;第三方仅通讯录应用可获取;对于非第三方创建的成员,第三方通讯录应用也不可获取;上游企业不可获取下游企业成员该字段 + open_userid 全局唯一。对于同一个服务商,不同应用获取到企业内同一个成员的open_userid是相同的,最多64个字节。仅第三方应用可获取 + main_department + """ + hr_employees = self.sudo().env["hr.employee"].with_context(active_test=False).search([("wecom_userid", '=', userid)]) + data = { + "active": True, + "work_email": biz_mail, + "wecom_userid": userid, + "name": name, + "department_id": hr_department.id, + "mobile_phone": mobile, + "work_phone": telephone, + } + if hr_employees: + hr_employees.write(data) + else: + self.sudo().env["hr.employee"].create(data)