report_style.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. # -*- coding: utf-8 -*-
  2. from odoo import models, fields, api, tools
  3. from odoo.exceptions import ValidationError
  4. # from . import base_infor
  5. from .report_sources.source_base import SourceBase, GROUP_FIELD, SUM_FIELD, EXPRESSION_FIELD
  6. from ..utils.report_field import ReportField
  7. from ..utils.report_info import ReportInfo
  8. from odoo.utils.constant import REPORT_TYPE, ANALYSE, ER_WEI, CHART, SINGLE_HEAD, DOUBLE_HEAD, TABLE_HEAD_TYPE, \
  9. CHART_TYPE, LINE, BAR
  10. from odoo.utils.model_util.query_model_helper import QueryModelHelper
  11. from odoo.utils.model_util import const_model
  12. from odoo.utils.model_util.const import DEFAULT_COUNT_PER_PAGE, get_digit_capacity_4_save_setting
  13. SOURCE = [(obj.name, obj.name) for obj in SourceBase.get_all_source()]
  14. DEFAULT_WIDTH = 100
  15. DEFAULT_HEIGHT = 800
  16. ER_WEI_DEFAULT_WIDTH = 80
  17. ER_WEI_DEFAULT_OTHER_WIDTH = 200
  18. ER_WEI_MIN_WIDTH = 20
  19. class ReportStyle(models.Model):
  20. _name = 'jc_bi.report_style'
  21. _description = '样式'
  22. _module = 'jc_bi'
  23. name = fields.Char(string=u'名称', required=True)
  24. width = fields.Integer('宽度%') # 不设置取100%
  25. height = fields.Integer('高度') # 单位:px。不设置取800
  26. source = fields.Selection(SOURCE, string=u'数据源')
  27. report_type = fields.Selection(REPORT_TYPE, string=u'报表类型', default=ANALYSE)
  28. # is_double_head = fields.Selection(TABLE_HEAD_TYPE, string=u'是否双表头', default=SINGLE_HEAD)
  29. # 分析表:
  30. lock_column_count = fields.Integer('锁定前N列')
  31. count_per_page = fields.Integer('查询结果每页行数')
  32. detail = fields.One2many('jc_bi.report_style_analyse_detail', 'report_style_id',
  33. string=u'报表样式设置分析表明细', copy=True)
  34. # 二维表
  35. row_name = fields.Char(u'行名') # table.field 第一列
  36. row_name_show = fields.Char(u'行名')
  37. first_column_width = fields.Integer(u'第一列宽度(px)') # 默认80
  38. column_name = fields.Char(u'列名') # table.field 可变列
  39. column_name_show = fields.Char(u'列名')
  40. other_column_width = fields.Integer(u'其他列宽度(px,第一行)') # 默认200
  41. indication_detail = fields.One2many('jc_bi.report_style_indication_detail', 'report_style_id',
  42. string=u'报表样式设置二维表明细', copy=True)
  43. # 图表
  44. unit_name = fields.Char(u'单位') # table.field
  45. unit_name_show = fields.Char(u'单位')
  46. x_name = fields.Char(u'X轴') # table.field
  47. x_name_show = fields.Char(u'X轴')
  48. chart_type = fields.Selection(CHART_TYPE, u'图类型', default=LINE)
  49. chart_detail = fields.One2many('jc_bi.report_style_chart_detail', 'report_style_id',
  50. string=u'报表样式设置图表明细', copy=True)
  51. def get_er_wei_column_width(self):
  52. return ReportStyle._get_valid_er_wei_width(self.first_column_width, ER_WEI_DEFAULT_WIDTH, ER_WEI_MIN_WIDTH), \
  53. ReportStyle._get_valid_er_wei_width(self.other_column_width, ER_WEI_DEFAULT_OTHER_WIDTH,
  54. ER_WEI_MIN_WIDTH)
  55. @staticmethod
  56. def _get_valid_er_wei_width(width, default_width, min_width):
  57. if not width:
  58. return default_width
  59. if width < min_width:
  60. width = min_width
  61. return width
  62. @api.model
  63. def save_style(self, style_id, style_info):
  64. # print('style_id:', style_id)
  65. # print('style_info:', style_info)
  66. report_type = style_info[0]
  67. if report_type == ANALYSE:
  68. return self._save_analyse(report_type, style_id, style_info)
  69. if report_type == ER_WEI:
  70. return self._save_indication(report_type, style_id, style_info)
  71. if report_type == CHART:
  72. return self._save_chart(report_type, style_id, style_info)
  73. raise ValidationError('报表类型错误:' + report_type)
  74. def _save_analyse(self, report_type, style_id, style_info):
  75. name, width, height, source = style_info[1]
  76. lock_column_count, count_per_page, field_list = style_info[2]
  77. style_id = int(style_id)
  78. setting = None
  79. if style_id:
  80. setting = self.env[self._name].sudo().browse(style_id)
  81. ReportStyle._save_diff_analyse(setting, name, width, height, source, report_type, lock_column_count,
  82. count_per_page)
  83. for d in setting.detail:
  84. d.unlink()
  85. # elif setting.report_type == ER_WEI:
  86. # for d in setting.indication_detail:
  87. # d.unlink()
  88. # elif setting.report_type == CHART:
  89. # for d in setting.chart_detail:
  90. # d.unlink()
  91. if not setting:
  92. val = dict(name=name, width=width, height=height, source=source, report_type=report_type,
  93. lock_column_count=lock_column_count, count_per_page=count_per_page)
  94. setting = self.env[self._name].sudo().create(val)
  95. self._add_analyse_detail(setting, field_list, 'jc_bi.report_style_analyse_detail')
  96. return setting.id
  97. def _save_indication(self, report_type, style_id, style_info):
  98. name, width, height, source = style_info[1]
  99. selected_indicator_list, row_id_name, column_id_name, first_column_width, other_column_width = style_info[2]
  100. style_id = int(style_id)
  101. setting = None
  102. if style_id:
  103. setting = self.env[self._name].sudo().browse(style_id)
  104. ReportStyle._save_diff_er_wei(setting, name, width, height, source, report_type, column_id_name,
  105. row_id_name, first_column_width, other_column_width)
  106. for d in setting.indication_detail:
  107. d.unlink()
  108. if not setting:
  109. val = dict(name=name, width=width, height=height, source=source, report_type=report_type,
  110. column_name=column_id_name[0], column_name_show=column_id_name[1], row_name=row_id_name[0],
  111. row_name_show=row_id_name[1], first_column_width=first_column_width,
  112. other_column_width=other_column_width)
  113. setting = self.env[self._name].sudo().create(val)
  114. self._add_chart_detail(setting, selected_indicator_list, 'jc_bi.report_style_indication_detail')
  115. return setting.id
  116. def _save_chart(self, report_type, style_id, style_info):
  117. name, width, height, source = style_info[1]
  118. selected_indicator_list, unit_id_name, x_id_name, chart_type = style_info[2]
  119. style_id = int(style_id)
  120. setting = None
  121. if style_id:
  122. setting = self.env[self._name].sudo().browse(style_id)
  123. ReportStyle._save_diff_chart(setting, name, width, height, source, report_type, unit_id_name, x_id_name,
  124. chart_type)
  125. for d in setting.chart_detail:
  126. d.unlink()
  127. if not setting:
  128. val = dict(name=name, width=width, height=height, source=source, report_type=report_type,
  129. unit_name=unit_id_name[0], unit_name_show=unit_id_name[1], x_name=x_id_name[0],
  130. x_name_show=x_id_name[1], chart_type=chart_type)
  131. setting = self.env[self._name].sudo().create(val)
  132. self._add_chart_detail(setting, selected_indicator_list, 'jc_bi.report_style_chart_detail')
  133. return setting.id
  134. @staticmethod
  135. def _save_diff_common(setting, name, width, height, source, report_type):
  136. if setting.name != name:
  137. setting.name = name
  138. if setting.width != width:
  139. setting.width = width
  140. if setting.height != height:
  141. setting.height = height
  142. if setting.source != source:
  143. # print('source different, old:', setting.source, ', new:', source)
  144. setting.source = source
  145. if setting.report_type != report_type:
  146. # print('report_type different, old:', setting.report_type, ', new:', report_type)
  147. setting.report_type = report_type
  148. return
  149. @staticmethod
  150. def _save_diff_analyse(setting, name, width, height, source, report_type, lock_column_count, count_per_page):
  151. ReportStyle._save_diff_common(setting, name, width, height, source, report_type)
  152. if setting.lock_column_count != lock_column_count:
  153. setting.lock_column_count = lock_column_count
  154. if setting.count_per_page != count_per_page:
  155. setting.count_per_page = count_per_page
  156. return
  157. @staticmethod
  158. def _save_diff_er_wei(setting, name, width, height, source, report_type, column_id_name, row_id_name,
  159. first_column_width, other_column_width):
  160. ReportStyle._save_diff_common(setting, name, width, height, source, report_type)
  161. if setting.column_name != column_id_name[0]:
  162. setting.column_name = column_id_name[0]
  163. if setting.column_name_show != column_id_name[1]:
  164. setting.column_name_show = column_id_name[1]
  165. if setting.row_name != row_id_name[0]:
  166. setting.row_name = row_id_name[0]
  167. if setting.row_name_show != row_id_name[1]:
  168. setting.row_name_show = row_id_name[1]
  169. if setting.first_column_width != first_column_width:
  170. setting.first_column_width = first_column_width
  171. if setting.other_column_width != other_column_width:
  172. setting.other_column_width = other_column_width
  173. return
  174. @staticmethod
  175. def _save_diff_chart(setting, name, width, height, source, report_type, unit_id_name, x_id_name, chart_type):
  176. ReportStyle._save_diff_common(setting, name, width, height, source, report_type)
  177. if setting.unit_name != unit_id_name[0]:
  178. setting.unit_name = unit_id_name[0]
  179. if setting.unit_name_show != unit_id_name[1]:
  180. setting.unit_name_show = unit_id_name[1]
  181. if setting.x_name != x_id_name[0]:
  182. setting.x_name = x_id_name[0]
  183. if setting.x_name_show != x_id_name[1]:
  184. setting.x_name_show = x_id_name[1]
  185. if setting.chart_type != chart_type:
  186. setting.chart_type = chart_type
  187. return
  188. def _add_analyse_detail(self, record, setting_list, detail_model):
  189. for row in setting_list:
  190. val = {
  191. 'report_style_id': record.id,
  192. 'field': row[0],
  193. 'sequence': row[1],
  194. 'show_name': row[2],
  195. 'new_show_name': row[3],
  196. 'is_sum': row[4],
  197. 'is_number': row[5],
  198. 'upper_limit': row[6],
  199. 'upper_characters_color': row[7],
  200. 'upper_background_color': row[8],
  201. 'lower_limit': row[9],
  202. 'lower_characters_color': row[10],
  203. 'lower_background_color': row[11],
  204. 'width': row[12],
  205. 'order_number': row[13],
  206. 'asc_desc': row[14],
  207. 'is_average': row[15],
  208. 'dividend': row[16],
  209. 'divisor': row[17],
  210. 'digit_capacity': get_digit_capacity_4_save_setting(row[18]),
  211. 'is_compute': row[19],
  212. 'is_compute_exp': row[20]}
  213. self.env[detail_model].sudo().create(val)
  214. return
  215. def _add_chart_detail(self, record, setting_list, detail_model):
  216. for row in setting_list:
  217. val = {
  218. 'report_style_id': record.id,
  219. 'indicator_field': row[0],
  220. 'indicator_name': row[1],
  221. 'indicator_show_name': row[2],
  222. }
  223. self.env[detail_model].sudo().create(val)
  224. return
  225. def query_setting(self, model_name):
  226. # model_id = self.env['ir.model']._get_id(model_name)
  227. # domain = [('model_id', '=', model_id)]
  228. # print('query_setting model_name:', model_name)
  229. # print('query_setting model_id:', model_id)
  230. # print('query_setting domain:', domain)
  231. domain = [('model', '=', model_name), '|', ('user_id', '=', self._uid), ('user_id', '=', False)]
  232. return self.sudo().search(domain, limit=1, order='id desc')
  233. @api.model
  234. def get_source_and_report_type(self, detail_field, reference_field):
  235. helper = self._get_bi_helper(detail_field, reference_field)
  236. helper.set_setting([], [], [[], []], None)
  237. field_list = helper.get_fields(['source', 'report_type'])
  238. # print('style info:', field_list)
  239. return field_list
  240. @api.model
  241. def query_style(self, style_id):
  242. # print('style_id:', style_id)
  243. record = self.sudo().browse(int(style_id))
  244. style_info = [style_id, record.name, record.width, record.height, record.source, record.report_type]
  245. detail_field, reference_field = ReportStyle._get_detail_field_info(record.source)
  246. source_type_info = self.sudo().get_source_and_report_type(detail_field, reference_field)
  247. return [style_info, source_type_info]
  248. @staticmethod
  249. def _get_detail_field_info(source):
  250. exist_source = SourceBase.get_source(source)
  251. if not exist_source:
  252. return None, None
  253. return exist_source.detail_field, exist_source.reference_field
  254. def _get_analyse_show(self):
  255. detail_list = [d.new_show_name if d.new_show_name else d.show_name for d in self.detail]
  256. detail_info = '】【'.join(detail_list)
  257. if detail_info:
  258. detail_info = '【' + detail_info + '】'
  259. else:
  260. detail_info = '无显示字段'
  261. return detail_info
  262. def _get_er_wei_show(self):
  263. detail_list = [d.indicator_show_name if d.indicator_show_name else d.indicator_name for d in
  264. self.indication_detail]
  265. detail_info = '】【'.join(detail_list)
  266. if detail_info:
  267. detail_info = '【' + detail_info + '】'
  268. else:
  269. detail_info = '无指标'
  270. _format = '{}({}px)/{}({}px): {}'
  271. return _format.format(self.row_name_show, self.first_column_width, self.column_name_show,
  272. self.other_column_width, detail_info)
  273. def _get_chart_show(self):
  274. detail_list = [d.indicator_show_name if d.indicator_show_name else d.indicator_name for d in self.chart_detail]
  275. detail_info = '】【'.join(detail_list)
  276. if detail_info:
  277. detail_info = '【' + detail_info + '】'
  278. else:
  279. detail_info = '无指标'
  280. _format = '{}/{}: {}'
  281. return _format.format(self.unit_name_show, self.x_name_show, detail_info)
  282. def get_style(self):
  283. report_type = self.get_report_type_show()
  284. if self.report_type == ANALYSE:
  285. detail_info = self._get_analyse_show()
  286. elif self.report_type == ER_WEI:
  287. detail_info = self._get_er_wei_show()
  288. elif self.report_type == CHART:
  289. detail_info = self._get_chart_show()
  290. else:
  291. detail_info = '不支持的报表类型'
  292. return [self.id, self.name, self.width, self.height, self.source, report_type, detail_info]
  293. def get_report_type_show(self):
  294. for key, name in REPORT_TYPE:
  295. if self.report_type == key:
  296. if key == CHART:
  297. chart_type_show = self._get_chart_type_show()
  298. name = '{}: {}'.format(name, chart_type_show)
  299. return name
  300. return REPORT_TYPE[0][1]
  301. def _get_chart_type_show(self):
  302. for key, name in CHART_TYPE:
  303. if self.chart_type == key:
  304. return name
  305. return CHART_TYPE[0][1]
  306. def get_width(self):
  307. return self.width if self.width else DEFAULT_WIDTH
  308. def get_height(self):
  309. return self.height if self.height else DEFAULT_HEIGHT