base_archive.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. from odoo import models, fields, api
  2. from odoo.exceptions import ValidationError
  3. from odoo.osv import expression
  4. from odoo.tools import Query
  5. from odoo.utils import spell
  6. import logging
  7. import json
  8. from lxml import etree
  9. import re
  10. COLOR_DIC = {'1': 'red', '2': 'green', '3': 'navy', '4': 'brown', '5': 'pink', '6': 'fuchsia'}
  11. _logger = logging.getLogger(__name__)
  12. # ======================== 注意 =======================================
  13. # =========修改任何内容,需要同步修改所有档案基类文件里的内容。搜索本行即可=========
  14. class BaseInfo(models.Model):
  15. _name = 'base_info'
  16. _description = u'档案基类'
  17. _module = 'archives'
  18. # _active_name = 'available'
  19. name = fields.Char(string=u'名称', required=True)
  20. spell = fields.Char(string=u'首拼')
  21. coding = fields.Char(string=u'编码')
  22. available = fields.Boolean(string=u'是否有效', default=True)
  23. company_id = fields.Many2one('res.company', string=u'公司',
  24. domain=lambda self: self.get_company_domain(),
  25. default=lambda self: self.env['res.company']._company_default_get())
  26. @api.model
  27. def get_model_name(self):
  28. return self._name
  29. @api.model_create_multi
  30. @api.returns('self', lambda value: value.id)
  31. def create(self, values):
  32. spell.set_spell(values)
  33. result = super(BaseInfo, self).create(values)
  34. # self.add_log(u'创建', result)
  35. return result
  36. def write(self, values):
  37. spell.set_spell(values)
  38. result = super(BaseInfo, self).write(values)
  39. # self.add_log(u'修改', self)
  40. return result
  41. def copy(self, default=None):
  42. default = dict(default or {})
  43. copied_count = self.search_count(
  44. [('name', '=like', u"Copy of {}%".format(self.name))])
  45. if not copied_count:
  46. new_name = u"Copy of {}".format(self.name)
  47. else:
  48. new_name = u"Copy of {} ({})".format(self.name, copied_count)
  49. default['name'] = new_name
  50. self.add_log(u'复制', self)
  51. return super(BaseInfo, self).copy(default)
  52. @api.model
  53. def _name_search(self, name='', args=None, operator='ilike', limit=100, name_get_uid=None):
  54. args = list(args or [])
  55. if not self._rec_name:
  56. _logger.warning("Cannot execute name_search, no _rec_name defined on %s", self._name)
  57. elif not (name == '' and operator == 'ilike'):
  58. if hasattr(self, 'coding'):
  59. args += ['|', '|', ('spell', 'ilike', name), (self._rec_name, operator, name),
  60. ('coding', 'ilike', name)]
  61. else:
  62. args += ['|', ('spell', 'ilike', name), (self._rec_name, operator, name), ]
  63. if hasattr(self, 'company_id'):
  64. args += ['|', ('company_id', 'in', self.env['res.users'].sudo().browse(self._uid).company_ids.ids),
  65. ('company_id', '=', False)]
  66. return self._search(args, limit=limit, access_rights_uid=name_get_uid)
  67. def unlink(self):
  68. self.add_log(u'删除', self)
  69. for bill in self:
  70. super(BaseInfo, bill).unlink()
  71. return True
  72. def add_log(self, operation, bills): # 注意:不要在前面加@api.model,否则添加保存的日志会报错
  73. self.env['archives.log'].add_log(operation=operation, model_name=bills._name, bill_id=bills.id,
  74. bill_name=bills.name)
  75. return
  76. def set_available(self):
  77. self.available = True
  78. self.add_log(u"启用", self)
  79. def un_set_available(self):
  80. self.available = False
  81. self.add_log(u"停用", self)
  82. @api.model
  83. def default_get(self, fields_):
  84. res = super(BaseInfo, self).default_get(fields_)
  85. _need_set_fields = self.env['archives.set_customer_setting'].get_need_set_fields(self._name)
  86. self.env['archives.set_customer_setting'].set_default(res, self._name, fields_, _need_set_fields)
  87. return res
  88. @api.model
  89. def _where_calc(self, domain, active_test=True):
  90. """Computes the WHERE clause needed to implement an OpenERP domain.
  91. :param domain: the domain to compute
  92. :type domain: list
  93. :param active_test: whether the default filtering of records with ``active``
  94. field set to ``False`` should be applied.
  95. :return: the query expressing the given domain as provided in domain
  96. :rtype: osv.query.Query
  97. """
  98. if self._active_name and active_test and self._context.get('active_test', True):
  99. # the item[0] trick below works for domain items and '&'/'|'/'!'
  100. # operators too
  101. if not any(item[0] == self._active_name for item in domain):
  102. domain = [(self._active_name, '=', 1)] + domain
  103. elif 'available' in self._fields and active_test and self._context.get('active_test', True):
  104. if not any(item[0] == 'available' for item in domain):
  105. domain = [('available', '=', True)] + domain
  106. if domain:
  107. return expression.expression(domain, self).query
  108. else:
  109. return Query(self.env.cr, self._table, self._table_query)
  110. def set_auxiliary_name(self):
  111. return self.env['archives.set_auxiliary_name'].send_and_open(self._name, self._description)
  112. # def modify_field_name(self):
  113. # return self.env['archives.set_modify_field_name'].get_wizard_page(self._name, self._description)
  114. #
  115. # @api.model
  116. # def load_views(self, views, options=None):
  117. # res = super(BaseInfo, self).load_views(views, options=None)
  118. # environment = self.env['archives.set_modify_field_name']
  119. # environment.modify_field_invisible(res, self._name)
  120. # return res
  121. @api.model
  122. def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
  123. """
  124. 增加对中文排序时按拼音排序的支持
  125. Private implementation of search() method, allowing specifying the uid to use for the access right check.
  126. This is useful for example when filling in the selection list for a drop-down and avoiding access rights errors,
  127. by specifying ``access_rights_uid=1`` to bypass access rights check, but not ir.rules!
  128. This is ok at the security level because this method is private and not callable through XML-RPC.
  129. :param access_rights_uid: optional user ID to use when checking access rights
  130. (not for ir.rules, this is only for ir.model.access)
  131. :return: a list of record ids or an integer (if count is True)
  132. """
  133. model = self.with_user(access_rights_uid) if access_rights_uid else self
  134. model.check_access_rights('read')
  135. if expression.is_false(self, args):
  136. # optimization: no need to query, as no record satisfies the domain
  137. return 0 if count else []
  138. # the flush must be done before the _where_calc(), as the latter can do some selects
  139. self._flush_search(args, order=order)
  140. query = self._where_calc(args)
  141. self._apply_ir_rules(query, 'read')
  142. if count:
  143. # Ignore order, limit and offset when just counting, they don't make sense and could
  144. # hurt performance
  145. query_str, params = query.select("count(1)")
  146. self._cr.execute(query_str, params)
  147. res = self._cr.fetchone()
  148. return res[0]
  149. order_value = self._generate_order_by(order, query).replace('ORDER BY ', '')
  150. query.order = self._handle_chinese_order(order_value)
  151. query.limit = limit
  152. query.offset = offset
  153. return query
  154. def _handle_chinese_order(self, order):
  155. """
  156. 处理排序字段,如果是按照name排序,则修改为支持拼音排序的形式
  157. postgresql中汉字默认是按照ASCII进行排序,需使用 convert_to(name, 'GBK')进行字符集转化
  158. :param order:
  159. :return:
  160. """
  161. order_lst = order.strip().split(' ')
  162. order_method = ''
  163. order_field = order_lst[0]
  164. if len(order_lst) == 2:
  165. order_method = order_lst[1]
  166. order_table_name, order_field_name = order_field.strip().split('.')
  167. if order_field_name.strip() == '"name"':
  168. return f"convert_to({order_field}, 'GBK') {order_method}"
  169. return order
  170. @api.model
  171. def fields_get(self, all_fields=None, attributes=None):
  172. res = super(BaseInfo, self).fields_get(all_fields, attributes)
  173. if 'form_edit' in self.env['ir.module.module']._installed():
  174. if 'form_edit.modify_field_name' in self.env:
  175. environment = self.env['form_edit.modify_field_name']
  176. environment.modify_field_name(res, self._name)
  177. return res
  178. @api.model
  179. def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
  180. result = super(BaseInfo, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, )
  181. doc = etree.XML(result.get('arch', ''))
  182. m = etree.tostring(doc)
  183. if 'form_edit' in self.env['ir.module.module']._installed():
  184. if view_type == 'form':
  185. company = self.env.company.id
  186. setting = self.env['form_edit.modify_field_name'].sudo().search(
  187. [('user_id', '=', 2),
  188. ('table', '=', self._name), ('xml_type', '=', 'form'), ('company_id', '=', company)])
  189. if not setting:
  190. # setting = self.update_default_setting(setting, doc, setting.table_show_name)
  191. # else:
  192. setting = self.create_default_setting(self._name, doc, self._description)
  193. # res_dict = self.get_detail_dict(setting)
  194. head_field_sequence = setting.head_fields_sequence
  195. other_field_sequence = setting.other_fields_sequence
  196. second_field_sequence = setting.second_fields_sequence
  197. third_field_sequence = setting.third_fields_sequence
  198. fourth_field_sequence = setting.fourth_fields_sequence
  199. fifth_field_sequence = setting.fifth_fields_sequence
  200. col = setting.show_col_number
  201. col_other = setting.show_col_number_other
  202. col_second = setting.second_col
  203. col_third = setting.third_col
  204. col_fourth = setting.fourth_col
  205. col_fifth = setting.fifth_col
  206. full_screen = setting.full_screen
  207. # 表头分列
  208. if col:
  209. doc = self.get_col_value(doc, col, 'head')
  210. # 其它页分列
  211. if col_other:
  212. doc = self.get_col_value(doc, col_other, 'other')
  213. # 第二页分列
  214. if col_second:
  215. doc = self.get_col_value(doc, col_second, 'second')
  216. # 第三页分列
  217. if col_third:
  218. doc = self.get_col_value(doc, col_third, 'third')
  219. # 第四页分列
  220. if col_fourth:
  221. doc = self.get_col_value(doc, col_fourth, 'fourth')
  222. # 第五页页分列
  223. if col_fifth:
  224. doc = self.get_col_value(doc, col_fifth, 'fifth')
  225. #  表头排序
  226. if head_field_sequence:
  227. res = self.get_head_field_name(head_field_sequence)
  228. group_top = "//sheet//group[@name='group_top']"
  229. doc, result = self.get_sequence_fields(res, group_top, doc, setting.table, modify_setting=setting,
  230. result=result)
  231. dd = etree.tostring(doc)
  232. # 其它页排序
  233. if other_field_sequence:
  234. res = self.get_head_field_name(other_field_sequence)
  235. group_other = "//sheet//group[@name='group_other']"
  236. doc, result = self.get_sequence_fields(res, group_other, doc, setting.table, result=result,
  237. modify_setting=setting, flag=True)
  238. dd = etree.tostring(doc)
  239. # 第二页页排序
  240. if second_field_sequence:
  241. res = self.get_head_field_name(second_field_sequence)
  242. group_second = "//sheet//group[@name='group_second']"
  243. doc, result = self.get_sequence_fields(res, group_second, doc, setting.table, result=result,
  244. modify_setting=setting, flag=True)
  245. dd = etree.tostring(doc)
  246. # 第三页排序
  247. if third_field_sequence:
  248. res = self.get_head_field_name(third_field_sequence)
  249. group_third = "//sheet//group[@name='group_third']"
  250. doc, result = self.get_sequence_fields(res, group_third, doc, setting.table, result=result,
  251. modify_setting=setting, flag=True)
  252. dd = etree.tostring(doc)
  253. # 第四页排序
  254. if fourth_field_sequence:
  255. res = self.get_head_field_name(fourth_field_sequence)
  256. group_fourth = "//sheet//group[@name='group_fourth']"
  257. doc, result = self.get_sequence_fields(res, group_fourth, doc, setting.table, result=result,
  258. modify_setting=setting, flag=True)
  259. dd = etree.tostring(doc)
  260. # 第五页排序
  261. if fifth_field_sequence:
  262. res = self.get_head_field_name(fifth_field_sequence)
  263. group_fifth = "//sheet//group[@name='group_fifth']"
  264. doc, result = self.get_sequence_fields(res, group_fifth, doc, setting.table, result=result,
  265. modify_setting=setting, flag=True)
  266. dd = etree.tostring(doc)
  267. # 全屏
  268. if full_screen:
  269. exist_style = doc.xpath('//style')
  270. if exist_style:
  271. style_text = exist_style[0].text
  272. if 'o_form_view ' not in style_text.split('.'):
  273. exist_style[
  274. 0].text = style_text + "\n .o_form_view .o_form_sheet_bg .o_form_sheet{\n max-width: 99%;\n }\n"
  275. else:
  276. node_location = doc.xpath('//form')[0]
  277. style = etree.Element('style')
  278. style.text = "\n .o_form_view .o_form_sheet_bg .o_form_sheet{\n max-width: 99%;\n }\n"
  279. node_location.insert(1, style)
  280. if not full_screen:
  281. exist_style = doc.xpath('//style')
  282. if exist_style:
  283. style_text = exist_style[0].text
  284. split_style_text = style_text.split("}\n")[0:-1]
  285. if 'o_form_view ' in style_text.split('.'):
  286. style_t = ""
  287. for _s in split_style_text:
  288. if 'o_form_view ' not in _s:
  289. style_t += "\n" + _s + "}\n"
  290. exist_style[0].text = style_t
  291. result['arch'] = etree.tostring(doc)
  292. return result
  293. # 根据序列中的ids 返回 反向的 字段名称
  294. def get_head_field_name(self, head_sequence):
  295. res = []
  296. result = []
  297. _l = [int(i) for i in head_sequence.split(',')]
  298. for _ in _l:
  299. f = self.env['ir.model.fields'].sudo().search([('id', '=', _)]).name
  300. res.append(f)
  301. return res
  302. def get_col_value(self, doc, col, flag):
  303. if flag == 'head':
  304. expr = "//group[@name='group_top']"
  305. elif flag == 'other':
  306. expr = "//group[@name='group_other']"
  307. elif flag == 'second':
  308. expr = "//group[@name='group_second']"
  309. elif flag == 'third':
  310. expr = "//group[@name='group_third']"
  311. elif flag == 'fourth':
  312. expr = "//page//group[@name='group_fourth']"
  313. else:
  314. expr = "//group[@name='group_fifth']"
  315. res_list = doc.xpath(expr)
  316. for res in res_list:
  317. res.set('col', str(col))
  318. return doc
  319. def get_sequence_fields(self, res, expr, doc, setting, result=None, modify_setting=None, flag=False):
  320. num = 1
  321. if result and flag:
  322. _doc = etree.XML(result.get('arch', ''))
  323. res_dic = {}
  324. for i in res:
  325. if not i:
  326. continue
  327. i = i
  328. if self.fields_exist(i, setting):
  329. node_expr = "//group//field[@name='{}']".format(i)
  330. if result and flag:
  331. node = _doc.xpath(node_expr)
  332. else:
  333. node = doc.xpath(node_expr)
  334. if node:
  335. res_dic[num] = node[-1]
  336. else:
  337. _fields = self.env[setting].fields_get().get(i)
  338. result.get('fields')[i] = _fields
  339. field = etree.Element('field')
  340. field.set('modifiers', '{}')
  341. field.set('name', i)
  342. field.set('options', json.dumps({'no_open': True, 'no_create': True}))
  343. res_dic[num] = field
  344. num += 1
  345. doc = self.clear_group_data(expr, doc)
  346. group_new = doc.xpath(expr)
  347. group_str = etree.tostring(group_new[0])
  348. for k, v in res_dic.items():
  349. group_new[0].insert(k, v)
  350. # 只读、必填、颜色
  351. res_setting = modify_setting.detail.filtered(lambda a: a.field_name in res)
  352. for i in res_setting:
  353. readonly = 1 if i.after_readonly == '1' else 0
  354. required = 1 if i.after_required == '1' else 0
  355. color = COLOR_DIC.get(i.select_color, False)
  356. expr = "//group//field[@name='{}']".format(i.field_name)
  357. dic = {}
  358. if doc.xpath(expr):
  359. if color:
  360. style_color = 'color:{};'.format(color)
  361. style = doc.xpath(expr)[0].attrib.get('style')
  362. if style:
  363. _style_color = style
  364. style_color = ';' + _style_color + ';' + style_color
  365. doc.xpath(expr)[0].set('style', style_color)
  366. modifiers = doc.xpath(expr)[0].attrib.get('modifiers')
  367. modifiers_dict = json.loads(modifiers)
  368. read_val = modifiers_dict.get('readonly', False)
  369. req_val = modifiers_dict.get('required', False)
  370. invisible_val = modifiers_dict.get('invisible', False)
  371. if isinstance(read_val, list):
  372. dic['readonly'] = read_val
  373. else:
  374. dic['readonly'] = readonly
  375. if isinstance(req_val, list):
  376. dic['required'] = req_val
  377. else:
  378. dic['required'] = required
  379. if invisible_val:
  380. dic['invisible'] = invisible_val
  381. modifiers_val = json.dumps(dic)
  382. doc.xpath(expr)[0].set('modifiers', modifiers_val)
  383. return doc, result
  384. def clear_group_data(self, expr, doc):
  385. ddd = etree.tostring(doc)
  386. group = doc.xpath(expr)[0]
  387. child_node = group.getchildren()
  388. for i in child_node:
  389. group.remove(i)
  390. return doc
  391. def fields_exist(self, field, setting):
  392. flag = False
  393. _fields = self.env[setting].fields_get().keys()
  394. if field in _fields:
  395. flag = True
  396. return flag
  397. def create_default_setting(self, table, doc, description):
  398. res_head, res_other, res_second, res_third, res_fourth, res_fifth, second_name, third_name, fourth_name, fifth_name = self.get_head_or_other_sequence(
  399. table, doc,
  400. description)
  401. bill = self.env['form_edit.modify_field_name'].sudo().create(
  402. {'table': table,
  403. 'user_id': 2,
  404. 'table_show_name': description,
  405. 'sequence_head_fields': [(6, 0, [int(i) for i in res_head])] if res_head else [],
  406. 'head_fields_sequence': ','.join(res_head) if res_head else '',
  407. 'sequence_other_fields': [(6, 0, [int(i) for i in res_other])] if res_other else [],
  408. 'other_fields_sequence': ','.join(res_other) if res_other else '',
  409. 'sequence_second_fields': [(6, 0, [int(i) for i in res_second])] if res_second else [],
  410. 'second_fields_sequence': ','.join(res_second) if res_second else '',
  411. 'second_name': second_name if second_name else '',
  412. 'sequence_third_fields': [(6, 0, [int(i) for i in res_third])] if res_third else [],
  413. 'third_fields_sequence': ','.join(res_third) if res_third else '',
  414. 'third_name': third_name if third_name else '',
  415. 'sequence_fourth_fields': [(6, 0, [int(i) for i in res_fourth])] if res_fourth else [],
  416. 'fourth_fields_sequence': ','.join(res_fourth) if res_fourth else '',
  417. 'fourth_name': fourth_name if fourth_name else '',
  418. 'sequence_fifth_fields': [(6, 0, [int(i) for i in res_fifth])] if res_fifth else [],
  419. 'fifth_fields_sequence': ','.join(res_fifth) if res_fifth else '',
  420. 'fifth_name': fifth_name if fifth_name else '',
  421. 'parent_table': table,
  422. 'company_id': self.env.company.id
  423. }
  424. )
  425. return bill
  426. def update_default_setting(self, setting, doc, description):
  427. res_head, res_other, res_second, res_third, res_fourth, res_fifth, second_name, third_name, fourth_name, fifth_name = self.get_head_or_other_sequence(
  428. setting,
  429. doc)
  430. head = self.get_invisible(res_head, setting.head_fields_sequence)
  431. other = self.get_invisible(res_other, setting.other_fields_sequence)
  432. second = self.get_invisible(res_second, setting.second_fields_sequence)
  433. third = self.get_invisible(res_third, setting.third_fields_sequence)
  434. fourth = self.get_invisible(res_fourth, setting.fourth_fields_sequence)
  435. fifth = self.get_invisible(res_fifth, setting.fifth_fields_sequence)
  436. val = {}
  437. if not setting.head_fields_sequence:
  438. if res_head:
  439. val['head_fields_sequence'] = ','.join(res_head),
  440. val['sequence_head_fields'] = [(6, 0, [int(i) for i in res_head])],
  441. else:
  442. if head:
  443. old = head
  444. head = setting.head_fields_sequence + head
  445. self.create_m2m(old, setting, 'sequence_head_fields', 'head')
  446. val['head_fields_sequence'] = head
  447. if not setting.other_fields_sequence:
  448. if res_other:
  449. val['sequence_other_fields'] = [(6, 0, [int(i) for i in res_other])],
  450. val['other_fields_sequence'] = ','.join(res_other),
  451. else:
  452. if other:
  453. old = other
  454. other = setting.other_fields_sequence + other
  455. self.create_m2m(old, setting, 'sequence_other_fields', 'other')
  456. val['other_fields_sequence'] = other
  457. if not setting.second_fields_sequence:
  458. if res_second:
  459. val['sequence_second_fields'] = [(6, 0, [int(i) for i in res_second])],
  460. val['second_fields_sequence'] = ','.join(res_second),
  461. val['second_name'] = second_name if second_name else '',
  462. else:
  463. if second:
  464. old = second
  465. second = setting.second_fields_sequence + second
  466. self.create_m2m(old, setting, 'sequence_second_fields', 'second')
  467. val['second_fields_sequence'] = second,
  468. val['second_name'] = second_name if second_name else '',
  469. if not setting.third_fields_sequence:
  470. if res_third:
  471. val['sequence_third_fields'] = [(6, 0, [int(i) for i in res_third])],
  472. val['third_fields_sequence'] = ','.join(res_third),
  473. val['third_name'] = third_name if third_name else ''
  474. else:
  475. if third:
  476. old = third
  477. third = setting.third_fields_sequence + third
  478. val['third_fields_sequence'] = third
  479. self.create_m2m(old, setting, 'sequence_third_fields', 'third')
  480. val['third_name'] = third_name if third_name else ''
  481. if not setting.fourth_fields_sequence:
  482. if res_fourth:
  483. val['sequence_fourth_fields'] = [(6, 0, [int(i) for i in res_fourth])],
  484. val['fourth_fields_sequence'] = ','.join(res_fourth),
  485. val['fourth_name'] = fourth_name if fourth_name else '',
  486. else:
  487. if fourth:
  488. old = fourth
  489. fourth = setting.fourth_fields_sequence + fourth
  490. val['fourth_fields_sequence'] = fourth,
  491. self.create_m2m(old, setting, 'sequence_fourth_fields', 'fourth')
  492. val['fourth_name'] = fourth_name if fourth_name else '',
  493. # 模块
  494. if not setting.fifth_fields_sequence:
  495. if res_fifth:
  496. val['sequence_fifth_fields'] = [(6, 0, [int(i) for i in res_fifth])],
  497. val['fifth_fields_sequence'] = ','.join(res_fifth),
  498. val['fifth_name'] = fifth_name if fifth_name else '',
  499. else:
  500. if fifth:
  501. old = fifth
  502. fifth = setting.fifth_fields_sequence + fifth
  503. val['fifth_fields_sequence'] = fifth
  504. self.create_m2m(old, setting, 'sequence_fifth_fields', 'fifth')
  505. val['fifth_name'] = fifth_name if fifth_name else '',
  506. # 模块
  507. setting.update(val)
  508. return setting
  509. def get_name_list(self, table, doc, expr, invisible_flag=None):
  510. list_name = []
  511. sequence_ids = []
  512. res = doc.xpath(expr)
  513. if res:
  514. child_node = res[0].getchildren()
  515. for ch in child_node:
  516. if invisible_flag:
  517. if ch.attrib.get('modifiers', False):
  518. modifiers_dic = json.loads(ch.attrib.get('modifiers'))
  519. n = ch.attrib.get('name')
  520. m = modifiers_dic.get('invisible')
  521. if m == 1:
  522. list_name.append(ch.attrib.get('name'))
  523. else:
  524. list_name.append(ch.attrib.get('name'))
  525. domain = [('model', '=', table), ('name', 'in', list_name)]
  526. sequence_ids = self.env['ir.model.fields'].sudo().search(domain)
  527. sequence_sort = sorted(sequence_ids, key=lambda field: list_name.index(field.name))
  528. sequence_ids = [str(i.id) for i in sequence_sort]
  529. return sequence_ids
  530. def get_head_or_other_sequence(self, table, doc, description=None):
  531. if description:
  532. _table = table
  533. else:
  534. _table = table.table
  535. expr = "//group[@name='group_top']"
  536. expr1 = "//group[@name='group_other']"
  537. expr2 = "//group[@name='group_second']"
  538. expr3 = "//group[@name='group_third']"
  539. expr4 = "//group[@name='group_fourth']"
  540. expr5 = "//group[@name='group_fourth']"
  541. second_name, third_name, fourth_name, fifth_name = '', '', '', ''
  542. head_invisible = self.get_name_list(_table, doc, expr,
  543. invisible_flag=True) # 获取参与计算的计算的second_name = {_Element: 1} <Element page at 0x7f10a484aa28>字段
  544. _head = self.get_compute_sequence(description, _table, doc, expr, table, 'head_fields_sequence')
  545. res_head = self.get_compute_sequence_list(_head, head_invisible)
  546. other_invisible = self.get_name_list(_table, doc, expr1, invisible_flag=True)
  547. _other = self.get_compute_sequence(description, _table, doc, expr1, table, 'other_fields_sequence')
  548. res_other = self.get_compute_sequence_list(_other, other_invisible)
  549. second_invisible = self.get_name_list(_table, doc, expr2, invisible_flag=True)
  550. _second = self.get_compute_sequence(description, _table, doc, expr2, table, 'second_fields_sequence')
  551. res_second = self.get_compute_sequence_list(_second, second_invisible)
  552. if res_second:
  553. second_name = doc.xpath(expr2)[0].getparent().attrib.get('string')
  554. third_invisible = self.get_name_list(_table, doc, expr3, invisible_flag=True)
  555. _third = self.get_compute_sequence(description, _table, doc, expr3, table, 'third_fields_sequence')
  556. res_third = self.get_compute_sequence_list(_third, third_invisible)
  557. if res_third:
  558. third_name = doc.xpath(expr3)[0].getparent().attrib.get('string')
  559. fourth_invisible = self.get_name_list(_table, doc, expr4, invisible_flag=True)
  560. _fourth = self.get_compute_sequence(description, _table, doc, expr4, table, 'fourth_fields_sequence')
  561. res_fourth = self.get_compute_sequence_list(_fourth, fourth_invisible)
  562. if res_fourth:
  563. fourth_name = doc.xpath(expr4)[0].getparent().attrib.get('string')
  564. fifth_invisible = self.get_name_list(_table, doc, expr5, invisible_flag=True)
  565. _fifth = self.get_compute_sequence(description, _table, doc, expr5, table, 'fifth_fields_sequence')
  566. res_fifth = self.get_compute_sequence_list(_fifth, fifth_invisible)
  567. if res_fifth:
  568. fifth_name = doc.xpath(expr5)[0].getparent().attrib.get('string')
  569. return res_head, res_other, res_second, res_third, res_fourth, res_fifth, second_name, third_name, fourth_name, fifth_name
  570. @staticmethod
  571. def get_compute_sequence_list(val, invisible_val):
  572. res = val
  573. res_ = [i for i in invisible_val if i not in val]
  574. res_list = filter(lambda a: a != 'None', res + res_)
  575. return list(res_list)
  576. def get_compute_sequence(self, description, _table, doc, expr, table, field):
  577. if description:
  578. res = self.get_name_list(_table, doc, expr)
  579. else:
  580. if getattr(table, field):
  581. res = [str(i) for i in getattr(table, field).split(',')]
  582. else:
  583. res = self.get_name_list(_table, doc, expr)
  584. return res
  585. def get_invisible(self, res, sequence):
  586. seq = ''
  587. if sequence:
  588. r_sequence = sequence.split(',')
  589. invisible = [i for i in res if i not in r_sequence]
  590. seq = ',' + ','.join(invisible) if invisible else ''
  591. return seq
  592. def create_m2m(self, other, setting, sequence, field):
  593. lis = other.split(',')[1:]
  594. lis = [int(i) for i in lis]
  595. setting_id = setting.id
  596. _lis = [i for i in lis if i not in getattr(setting, sequence).ids]
  597. if _lis:
  598. for i in lis:
  599. sql = """insert into modify_sequence_{}_fields (form_edit_modify_field_name_id,ir_model_fields_id) VALUES({},{})""".format(
  600. field, setting_id, i)
  601. self.env.cr.execute(sql)
  602. def get_company_domain(self):
  603. domain = []
  604. if hasattr(self, 'company_id'):
  605. domain = [('id', 'in', self.env['res.users'].sudo().browse(self._uid).company_ids.ids)]
  606. return domain
  607. def form_edit(self):
  608. if 'form_edit' in self.env['ir.module.module']._installed():
  609. table = {'table_id': self.id, 'model': self._name}
  610. return self.env['form_edit.modify_field_name'].get_wizard_page(table)
  611. else:
  612. raise ValidationError('请安装字段修改模块')
  613. def enter_handler(self):
  614. if 'enter_event' in self.env['ir.module.module']._installed():
  615. table = {'table_id': self.id, 'model': self._name}
  616. return self.env['enter_event.config'].get_config(table)
  617. else:
  618. raise ValidationError('请安装回车工具模块')
  619. def get_logic(self):
  620. table = {'table_id': self.id, 'model': self._name, 'company_id': self.company_id.id}
  621. return self.env['archives.work_logic_setting'].get_setting(table)
  622. def batch_finish(self):
  623. for i in self:
  624. if int(i.bill_state) == 10:
  625. i.finish()
  626. def batch_un_finish(self):
  627. for i in self:
  628. if int(i.bill_state) == 20:
  629. i.un_finish()
  630. @api.model
  631. def get_user_group(self):
  632. flag = False
  633. if self._uid in self.env.ref('archives.group_user_function_setting').users.ids:
  634. flag = True
  635. return flag
  636. @api.model
  637. def get_form_weight(self):
  638. flag = False
  639. if not self._fields.get('available', False):
  640. flag = True
  641. return flag
  642. class BaseInfoUnique(BaseInfo):
  643. _name = 'base_info_unique'
  644. _description = u'档案基类:无重名'
  645. @api.constrains('name')
  646. def _check_name(self):
  647. if self.name:
  648. result = self.search_count(
  649. [('name', '=', self.name), ('id', '!=', self.id)])
  650. if result:
  651. raise ValidationError('{档案}已存在')