您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

162 行
4.5 KiB

  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. import webnotes
  5. import os, json
  6. import types
  7. from webnotes import _
  8. from webnotes.modules import scrub, get_module_path
  9. from webnotes.utils import flt, cint
  10. import webnotes.widgets.reportview
  11. @webnotes.whitelist()
  12. def get_script(report_name):
  13. report = webnotes.doc("Report", report_name)
  14. module = webnotes.conn.get_value("DocType", report.ref_doctype, "module")
  15. module_path = get_module_path(module)
  16. report_folder = os.path.join(module_path, "report", scrub(report.name))
  17. script_path = os.path.join(report_folder, scrub(report.name) + ".js")
  18. script = None
  19. if os.path.exists(script_path):
  20. with open(script_path, "r") as script:
  21. script = script.read()
  22. if not script and report.javascript:
  23. script = report.javascript
  24. if not script:
  25. script = "wn.query_reports['%s']={}" % report_name
  26. # load translations
  27. if webnotes.lang != "en":
  28. webnotes.response["__messages"] = webnotes.get_lang_dict("report", report_name)
  29. return script
  30. @webnotes.whitelist()
  31. def run(report_name, filters=None):
  32. report = webnotes.doc("Report", report_name)
  33. if filters and isinstance(filters, basestring):
  34. filters = json.loads(filters)
  35. if not webnotes.has_permission(report.ref_doctype, "report"):
  36. webnotes.msgprint(_("Must have report permission to access this report."),
  37. raise_exception=True)
  38. if report.report_type=="Query Report":
  39. if not report.query:
  40. webnotes.msgprint(_("Must specify a Query to run"), raise_exception=True)
  41. if not report.query.lower().startswith("select"):
  42. webnotes.msgprint(_("Query must be a SELECT"), raise_exception=True)
  43. result = [list(t) for t in webnotes.conn.sql(report.query, filters)]
  44. columns = [c[0] for c in webnotes.conn.get_description()]
  45. else:
  46. module = webnotes.conn.get_value("DocType", report.ref_doctype, "module")
  47. if report.is_standard=="Yes":
  48. method_name = scrub(module) + ".report." + scrub(report.name) + "." + scrub(report.name) + ".execute"
  49. columns, result = webnotes.get_attr(method_name)(filters or {})
  50. result = get_filtered_data(report.ref_doctype, columns, result)
  51. if cint(report.add_total_row) and result:
  52. result = add_total_row(result, columns)
  53. return {
  54. "result": result,
  55. "columns": columns
  56. }
  57. def add_total_row(result, columns):
  58. total_row = [""]*len(columns)
  59. has_percent = []
  60. for row in result:
  61. for i, col in enumerate(columns):
  62. col = col.split(":")
  63. if len(col) > 1:
  64. if col[1] in ["Currency", "Int", "Float", "Percent"] and flt(row[i]):
  65. total_row[i] = flt(total_row[i]) + flt(row[i])
  66. if col[1] == "Percent" and i not in has_percent:
  67. has_percent.append(i)
  68. for i in has_percent:
  69. total_row[i] = total_row[i] / len(result)
  70. first_col = columns[0].split(":")
  71. if len(first_col) > 1 and first_col[1] not in ["Currency", "Int", "Float", "Percent"]:
  72. total_row[0] = "Total"
  73. result.append(total_row)
  74. return result
  75. def get_filtered_data(ref_doctype, columns, data):
  76. result = []
  77. linked_doctypes = get_linked_doctypes(columns)
  78. match_filters = get_user_match_filters(linked_doctypes, ref_doctype)
  79. if match_filters:
  80. matched_columns = get_matched_columns(linked_doctypes, match_filters)
  81. for row in data:
  82. match = True
  83. for col, idx in matched_columns.items():
  84. if row[idx] not in match_filters[col]:
  85. match = False
  86. if match:
  87. result.append(row)
  88. else:
  89. for row in data:
  90. result.append(row)
  91. return result
  92. def get_linked_doctypes(columns):
  93. linked_doctypes = {}
  94. for idx, col in enumerate(columns):
  95. col = col.split(":")
  96. if len(col) > 1 and col[1].startswith("Link"):
  97. link_dt = col[1].split("/")[1]
  98. linked_doctypes[link_dt] = idx
  99. return linked_doctypes
  100. def get_user_match_filters(doctypes, ref_doctype):
  101. match_filters = {}
  102. doctypes_meta = {}
  103. tables = []
  104. for dt in doctypes:
  105. tables.append("`tab" + dt + "`")
  106. doctypes_meta[dt] = webnotes.model.doctype.get(dt)
  107. webnotes.local.reportview_tables = tables
  108. webnotes.local.reportview_doctypes = doctypes_meta
  109. for dt in doctypes:
  110. match_filters.update(webnotes.widgets.reportview.build_match_conditions(dt,
  111. None, False))
  112. return match_filters
  113. def get_matched_columns(linked_doctypes, match_filters):
  114. if "owner" in match_filters:
  115. match_filters["profile"] = match_filters["owner"]
  116. col_idx_map = {}
  117. for dt, idx in linked_doctypes.items():
  118. link_field = dt.lower().replace(" ", "_")
  119. if link_field in match_filters:
  120. col_idx_map[link_field] = idx
  121. return col_idx_map