Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

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