中国本土应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

311 lines
10KB

  1. # -*- coding: utf-8 -*-
  2. import logging
  3. import base64
  4. from pdb import _rstr
  5. import time
  6. from lxml import etree
  7. from odoo import api, fields, models, _
  8. import xmltodict
  9. from odoo.addons.oec_im_wecom_api.api.wecom_abstract_api import ApiException
  10. _logger = logging.getLogger(__name__)
  11. WECOM_DEPARTMENT_MAPPING_ODOO_DEPARTMENT = {
  12. "Id": "wecom_department_id", # 部门Id
  13. "Name": "name", # 部门名称
  14. "ParentId": "wecom_department_parent_id", # 父部门id
  15. "Order": "wecom_department_order", # 主部门
  16. }
  17. class Department(models.Model):
  18. _inherit = "hr.department"
  19. category_ids = fields.Many2many(
  20. "hr.employee.category",
  21. "department_category_rel",
  22. "dmp_id",
  23. "category_id",
  24. groups="hr.group_hr_manager",
  25. string="Tags",
  26. )
  27. wecom_department_id = fields.Integer(
  28. string="WeCom department ID",
  29. readonly=True,
  30. default="0",
  31. )
  32. wecom_department_parent_id = fields.Integer(
  33. "WeCom parent department ID",
  34. readonly=True,
  35. )
  36. wecom_department_order = fields.Char(
  37. "WeCom department sort",
  38. default="1",
  39. readonly=True,
  40. )
  41. is_wecom_department = fields.Boolean(
  42. string="WeCom Department",
  43. readonly=True,
  44. default=False,
  45. )
  46. # ------------------------------------------------------------
  47. # 同步企微部门
  48. # ------------------------------------------------------------
  49. @api.model
  50. def sync_wecom_deps(self):
  51. """
  52. 下载部门列表
  53. """
  54. start_time = time.time()
  55. company = self.env.context.get("company_id")
  56. if type(company) == int:
  57. company = self.env["res.company"].browse(company)
  58. tasks = []
  59. app_config = self.env["wecom.app_config"].sudo()
  60. contacts_sync_hr_department_id = int(
  61. app_config.get_param(
  62. company.contacts_app_id.id, "contacts_sync_hr_department_id"
  63. )
  64. ) # 需要同步的企业微信部门ID
  65. print(contacts_sync_hr_department_id, type(contacts_sync_hr_department_id))
  66. return tasks
  67. def department_data_cleaning(self, departments):
  68. """[summary]
  69. 部门数据清洗
  70. 删除 id 为 1 的部门
  71. 将部门的 parentid=1 改为 parentid=0
  72. Args:
  73. json ([type]): [description]index
  74. """
  75. for department in departments:
  76. if department.get("parentid") == 1:
  77. department["parentid"] = 0
  78. for index, department in enumerate(departments):
  79. if department.get("id") == 1:
  80. del departments[index]
  81. return departments
  82. def download_department(self, company, wecom_department):
  83. """
  84. 下载部门
  85. """
  86. # 查询数据库是否存在相同的企业微信部门ID,有则更新,无则新建
  87. department = self.sudo().search(
  88. [
  89. ("wecom_department_id", "=", wecom_department["id"]),
  90. ("is_wecom_department", "=", True),
  91. ("company_id", "=", company.id),
  92. "|",
  93. ("active", "=", True),
  94. ("active", "=", False),
  95. ],
  96. limit=1,
  97. )
  98. result = {}
  99. if not department:
  100. result = self.create_department(company, department, wecom_department)
  101. else:
  102. result = self.update_department(company, department, wecom_department)
  103. return result
  104. def create_department(self, company, department, wecom_department):
  105. """
  106. 创建部门
  107. """
  108. try:
  109. department.create(
  110. {
  111. "name": wecom_department["name"],
  112. "wecom_department_id": wecom_department["id"],
  113. "wecom_department_parent_id": wecom_department["parentid"],
  114. "wecom_department_order": wecom_department["order"],
  115. "is_wecom_department": True,
  116. "company_id": company.id,
  117. }
  118. )
  119. except Exception as e:
  120. result = _("Error creating Department [%s], error details:%s") % (
  121. wecom_department["name"],
  122. str(e),
  123. )
  124. _logger.warning(result)
  125. return {
  126. "name": "add_department",
  127. "state": False,
  128. "time": 0,
  129. "msg": result,
  130. }
  131. def update_department(self, company, department, wecom_department):
  132. """
  133. 更新部门
  134. """
  135. try:
  136. department.write(
  137. {
  138. "name": wecom_department["name"],
  139. "wecom_department_parent_id": wecom_department["parentid"],
  140. "wecom_department_order": wecom_department["order"],
  141. "is_wecom_department": True,
  142. "company_id": company.id,
  143. }
  144. )
  145. except Exception as e:
  146. result = _("Error updating Department [%s], error details:%s") % (
  147. wecom_department["name"],
  148. str(e),
  149. )
  150. _logger.warning(result)
  151. return {
  152. "name": "update_department",
  153. "state": False,
  154. "time": 0,
  155. "msg": result,
  156. }
  157. def set_parent_department(self, company):
  158. """[summary]
  159. 由于json数据是无序的,故在同步到本地数据库后,需要设置新增企业微信部门的上级部门
  160. """
  161. params = self.env["ir.config_parameter"].sudo()
  162. debug = params.get_param("wecom.debug_enabled")
  163. departments = self.search(
  164. [("is_wecom_department", "=", True), ("company_id", "=", company.id)]
  165. )
  166. results = []
  167. for department in departments:
  168. if department.wecom_department_parent_id:
  169. parent_department = self.get_parent_department_by_wecom_department_id(
  170. department, company
  171. )
  172. if not parent_department:
  173. pass
  174. else:
  175. try:
  176. department.write(
  177. {
  178. "parent_id": parent_department.id,
  179. }
  180. )
  181. except Exception as e:
  182. result = _(
  183. "Error setting parent department for company %s, Error details:%s"
  184. ) % (company.name, repr(e))
  185. if debug:
  186. _logger.warning(result)
  187. results.append(
  188. {
  189. "name": "set_parent_department",
  190. "state": False,
  191. "time": 0,
  192. "msg": result,
  193. }
  194. )
  195. return results # 返回失败的结果
  196. def get_parent_department_by_wecom_department_id(self, department, company):
  197. """[summary]
  198. 通过企微部门id 获取上级部门
  199. Args:
  200. department ([type]): [description]
  201. departments ([type]): [descriptions]
  202. """
  203. parent_department = self.search(
  204. [
  205. ("wecom_department_id", "=", department.wecom_department_parent_id),
  206. ("company_id", "=", company.id),
  207. ]
  208. )
  209. return parent_department
  210. # ------------------------------------------------------------
  211. # 企微通讯录事件
  212. # ------------------------------------------------------------
  213. def wecom_event_change_contact_party(self, cmd):
  214. xml_tree = self.env.context.get("xml_tree")
  215. company_id = self.env.context.get("company_id")
  216. xml_tree_str = etree.fromstring(bytes.decode(xml_tree))
  217. dic = lxml_to_dict(xml_tree_str)["xml"]
  218. # print("department dic", dic)
  219. domain = [
  220. "|",
  221. ("active", "=", True),
  222. ("active", "=", False),
  223. ]
  224. department = (
  225. self.env["hr.department"]
  226. .sudo()
  227. .search([("company_id", "=", company_id.id)] + domain)
  228. )
  229. callback_department = department.search(
  230. [("wecom_department_id", "=", dic["Id"])] + domain,
  231. limit=1,
  232. )
  233. update_dict = {}
  234. parent_department = False
  235. if "ParentId" in dic:
  236. if dic["ParentId"] == "1":
  237. pass
  238. else:
  239. parent_department = department.search(
  240. [("wecom_department_id", "=", int(dic["ParentId"]))],
  241. limit=1,
  242. )
  243. for key, value in dic.items():
  244. if (
  245. key == "ToUserName"
  246. or key == "FromUserName"
  247. or key == "CreateTime"
  248. or key == "Event"
  249. or key == "MsgType"
  250. or key == "ChangeType"
  251. ):
  252. # 忽略掉 不需要的key
  253. pass
  254. else:
  255. if key in WECOM_DEPARTMENT_MAPPING_ODOO_DEPARTMENT.keys():
  256. if WECOM_DEPARTMENT_MAPPING_ODOO_DEPARTMENT[key] != "":
  257. update_dict[
  258. WECOM_DEPARTMENT_MAPPING_ODOO_DEPARTMENT[key]
  259. ] = value
  260. else:
  261. _logger.info(
  262. _(
  263. "There is no mapping for field [%s], please contact the developer."
  264. )
  265. % key
  266. )
  267. if parent_department:
  268. update_dict.update({"parent_id": parent_department.id})
  269. else:
  270. update_dict.update({"parent_id": False})
  271. update_dict.update({"company_id": company_id.id, "is_wecom_department": True})
  272. if cmd == "create":
  273. callback_department.create(update_dict)
  274. elif cmd == "update":
  275. if "wecom_department_id" in update_dict:
  276. del update_dict["wecom_department_id"]
  277. if "wecom_department_parent_id" in update_dict:
  278. del update_dict["wecom_department_parent_id"]
  279. # print("执行更新部门", update_dict)
  280. callback_department.write(update_dict)
  281. elif cmd == "delete":
  282. callback_department.unlink()
上海开阖软件有限公司 沪ICP备12045867号-1