Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

139 wiersze
3.9 KiB

  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
  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. script_path = os.path.join(get_module_path(webnotes.conn.get_value("DocType", report.ref_doctype, "module")),
  15. "report", scrub(report.name), scrub(report.name) + ".js")
  16. if os.path.exists(script_path):
  17. with open(script_path, "r") as script:
  18. return script.read()
  19. elif report.javascript:
  20. return report.javascript
  21. else:
  22. return "wn.query_reports['%s']={}" % report_name
  23. @webnotes.whitelist()
  24. def run(report_name, filters=None):
  25. report = webnotes.doc("Report", report_name)
  26. if filters and isinstance(filters, basestring):
  27. filters = json.loads(filters)
  28. if not webnotes.has_permission(report.ref_doctype, "report"):
  29. webnotes.msgprint(_("Must have report permission to access this report."),
  30. raise_exception=True)
  31. if report.report_type=="Query Report":
  32. if not report.query:
  33. webnotes.msgprint(_("Must specify a Query to run"), raise_exception=True)
  34. if not report.query.lower().startswith("select"):
  35. webnotes.msgprint(_("Query must be a SELECT"), raise_exception=True)
  36. result = [list(t) for t in webnotes.conn.sql(report.query, filters)]
  37. columns = [c[0] for c in webnotes.conn.get_description()]
  38. else:
  39. method_name = scrub(webnotes.conn.get_value("DocType", report.ref_doctype, "module")) \
  40. + ".report." + scrub(report.name) + "." + scrub(report.name) + ".execute"
  41. columns, result = webnotes.get_method(method_name)(filters or {})
  42. result = get_filtered_data(report.ref_doctype, columns, result)
  43. if cint(report.add_total_row) and result:
  44. result = add_total_row(result, columns)
  45. return {
  46. "result": result,
  47. "columns": columns
  48. }
  49. def add_total_row(result, columns):
  50. total_row = [""]*len(columns)
  51. for row in result:
  52. for i, col in enumerate(columns):
  53. col = col.split(":")
  54. if len(col) > 1 and col[1] in ["Currency", "Int", "Float"] and flt(row[i]):
  55. total_row[i] = flt(total_row[i]) + flt(row[i])
  56. first_col = columns[0].split(":")
  57. if len(first_col) > 1 and first_col[1] not in ["Currency", "Int", "Float"]:
  58. total_row[0] = "Total"
  59. result.append(total_row)
  60. return result
  61. def get_filtered_data(ref_doctype, columns, data):
  62. result = []
  63. linked_doctypes = get_linked_doctypes(columns)
  64. match_filters = get_user_match_filters(linked_doctypes, ref_doctype)
  65. if match_filters:
  66. matched_columns = get_matched_columns(linked_doctypes, match_filters)
  67. for row in data:
  68. match = True
  69. for col, idx in matched_columns.items():
  70. if row[idx] not in match_filters[col]:
  71. match = False
  72. if match:
  73. result.append(row)
  74. else:
  75. for row in data:
  76. result.append(row)
  77. return result
  78. def get_linked_doctypes(columns):
  79. linked_doctypes = {}
  80. for idx, col in enumerate(columns):
  81. col = col.split(":")
  82. if len(col) > 1 and col[1].startswith("Link"):
  83. link_dt = col[1].split("/")[1]
  84. linked_doctypes[link_dt] = idx
  85. return linked_doctypes
  86. def get_user_match_filters(doctypes, ref_doctype):
  87. match_filters = {}
  88. doctypes_meta = {}
  89. tables = []
  90. doctypes[ref_doctype] = None
  91. for dt in doctypes:
  92. tables.append("`tab" + dt + "`")
  93. doctypes_meta[dt] = webnotes.model.doctype.get(dt)
  94. webnotes.widgets.reportview.tables = tables
  95. webnotes.widgets.reportview.doctypes = doctypes_meta
  96. for dt in doctypes:
  97. match_filters.update(webnotes.widgets.reportview.build_match_conditions(dt,
  98. None, False))
  99. return match_filters
  100. def get_matched_columns(linked_doctypes, match_filters):
  101. col_idx_map = {}
  102. for dt, idx in linked_doctypes.items():
  103. link_field = dt.lower().replace(" ", "_")
  104. if link_field in match_filters:
  105. col_idx_map[link_field] = idx
  106. return col_idx_map