Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 
 

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