django-advanced-report-builder 1.2.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (360) hide show
  1. advanced_report_builder/.DS_Store +0 -0
  2. advanced_report_builder/.ruff_cache/.gitignore +2 -0
  3. advanced_report_builder/.ruff_cache/0.11.9/16555798982502606642 +0 -0
  4. advanced_report_builder/.ruff_cache/CACHEDIR.TAG +1 -0
  5. advanced_report_builder/__init__.py +0 -0
  6. advanced_report_builder/admin.py +264 -0
  7. advanced_report_builder/apps.py +7 -0
  8. advanced_report_builder/column_types.py +26 -0
  9. advanced_report_builder/columns.py +296 -0
  10. advanced_report_builder/customise.py +2 -0
  11. advanced_report_builder/data_merge/__init__.py +0 -0
  12. advanced_report_builder/data_merge/utils.py +112 -0
  13. advanced_report_builder/data_merge/widget.py +30 -0
  14. advanced_report_builder/duplicate.py +171 -0
  15. advanced_report_builder/exceptions.py +9 -0
  16. advanced_report_builder/field_types.py +466 -0
  17. advanced_report_builder/field_utils.py +401 -0
  18. advanced_report_builder/filter_query.py +862 -0
  19. advanced_report_builder/form_utils.py +12 -0
  20. advanced_report_builder/generate_series.py +14 -0
  21. advanced_report_builder/globals.py +276 -0
  22. advanced_report_builder/includes.py +72 -0
  23. advanced_report_builder/migrations/0001_initial.py +246 -0
  24. advanced_report_builder/migrations/0002_auto_20220209_1657.py +23 -0
  25. advanced_report_builder/migrations/0003_auto_20220215_1219.py +42 -0
  26. advanced_report_builder/migrations/0004_customreport.py +27 -0
  27. advanced_report_builder/migrations/0005_auto_20220303_0958.py +84 -0
  28. advanced_report_builder/migrations/0006_auto_20220310_1147.py +32 -0
  29. advanced_report_builder/migrations/0007_auto_20220322_1939.py +23 -0
  30. advanced_report_builder/migrations/0008_auto_20220404_1144.py +28 -0
  31. advanced_report_builder/migrations/0009_auto_20230428_1554.py +53 -0
  32. advanced_report_builder/migrations/0010_auto_20230428_2033.py +23 -0
  33. advanced_report_builder/migrations/0011_auto_20230620_1449.py +23 -0
  34. advanced_report_builder/migrations/0012_auto_20230718_1642.py +24 -0
  35. advanced_report_builder/migrations/0013_reportqueryorder.py +30 -0
  36. advanced_report_builder/migrations/0014_auto_20240706_2207.py +24 -0
  37. advanced_report_builder/migrations/0015_report_user_created_report_user_updated.py +26 -0
  38. advanced_report_builder/migrations/0016_calendarreport_dashboardreport_options_and_more.py +74 -0
  39. advanced_report_builder/migrations/0017_alter_barchartreport_options_and_more.py +57 -0
  40. advanced_report_builder/migrations/0018_reportquery_target_target_period_type.py +24 -0
  41. advanced_report_builder/migrations/0019_multicellstyle_and_more.py +107 -0
  42. advanced_report_builder/migrations/0020_alter_multicellstyle_font_size.py +18 -0
  43. advanced_report_builder/migrations/0021_multivalueheldquery_and_more.py +36 -0
  44. advanced_report_builder/migrations/0022_dashboardreport_show_options_report_template_style_and_more.py +44 -0
  45. advanced_report_builder/migrations/0023_rename_colour_target_default_colour_and_more.py +41 -0
  46. advanced_report_builder/migrations/0024_alter_target_period_type.py +18 -0
  47. advanced_report_builder/migrations/__init__.py +0 -0
  48. advanced_report_builder/models.py +954 -0
  49. advanced_report_builder/report_builder.py +28 -0
  50. advanced_report_builder/signals.py +3 -0
  51. advanced_report_builder/static/.DS_Store +0 -0
  52. advanced_report_builder/static/advanced_report_builder/.DS_Store +0 -0
  53. advanced_report_builder/static/advanced_report_builder/chart-js/js/chart.esm.js +10553 -0
  54. advanced_report_builder/static/advanced_report_builder/chart-js/js/chart.js +13190 -0
  55. advanced_report_builder/static/advanced_report_builder/chart-js/js/chart.min.js +13 -0
  56. advanced_report_builder/static/advanced_report_builder/chart-js/js/chartjs-adapter-moment.min.js +8 -0
  57. advanced_report_builder/static/advanced_report_builder/chart-js/js/chartjs-plugin-datalabels.min.js +7 -0
  58. advanced_report_builder/static/advanced_report_builder/chart-js/js/chunks/helpers.segment.js +2499 -0
  59. advanced_report_builder/static/advanced_report_builder/chart-js/js/helpers.esm.js +7 -0
  60. advanced_report_builder/static/advanced_report_builder/d3/js/d3.js +20196 -0
  61. advanced_report_builder/static/advanced_report_builder/d3/js/d3.min.js +2 -0
  62. advanced_report_builder/static/advanced_report_builder/d3-funnel/js/d3-funnel.js +6087 -0
  63. advanced_report_builder/static/advanced_report_builder/d3-funnel/js/d3-funnel.min.js +2 -0
  64. advanced_report_builder/static/advanced_report_builder/dashboard/js/dashboard.js +19 -0
  65. advanced_report_builder/static/advanced_report_builder/dot/js/.gitignore +31 -0
  66. advanced_report_builder/static/advanced_report_builder/dot/js/.travis.yml +9 -0
  67. advanced_report_builder/static/advanced_report_builder/dot/js/LICENSE-DOT.txt +24 -0
  68. advanced_report_builder/static/advanced_report_builder/dot/js/README.md +90 -0
  69. advanced_report_builder/static/advanced_report_builder/dot/js/bin/dot-packer +52 -0
  70. advanced_report_builder/static/advanced_report_builder/dot/js/bower.json +21 -0
  71. advanced_report_builder/static/advanced_report_builder/dot/js/doT.js +141 -0
  72. advanced_report_builder/static/advanced_report_builder/dot/js/doT.min.js +8 -0
  73. advanced_report_builder/static/advanced_report_builder/dot/js/doU.js +56 -0
  74. advanced_report_builder/static/advanced_report_builder/dot/js/index.js +143 -0
  75. advanced_report_builder/static/advanced_report_builder/dot/js/package.json +46 -0
  76. advanced_report_builder/static/advanced_report_builder/fullcalendar/.DS_Store +0 -0
  77. advanced_report_builder/static/advanced_report_builder/fullcalendar/LICENSE.txt +20 -0
  78. advanced_report_builder/static/advanced_report_builder/fullcalendar/README.md +10 -0
  79. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/LICENSE.txt +20 -0
  80. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/README.md +8 -0
  81. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/af.js +30 -0
  82. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ar-dz.js +31 -0
  83. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ar-kw.js +31 -0
  84. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ar-ly.js +31 -0
  85. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ar-ma.js +31 -0
  86. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ar-sa.js +31 -0
  87. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ar-tn.js +31 -0
  88. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ar.js +31 -0
  89. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/bg.js +31 -0
  90. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/bs.js +32 -0
  91. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ca.js +30 -0
  92. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/cs.js +32 -0
  93. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/da.js +30 -0
  94. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/de.js +33 -0
  95. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/el.js +30 -0
  96. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/en-au.js +17 -0
  97. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/en-gb.js +17 -0
  98. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/en-nz.js +17 -0
  99. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/es-us.js +30 -0
  100. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/es.js +30 -0
  101. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/et.js +32 -0
  102. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/eu.js +30 -0
  103. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/fa.js +33 -0
  104. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/fi.js +30 -0
  105. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/fr-ca.js +27 -0
  106. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/fr-ch.js +31 -0
  107. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/fr.js +31 -0
  108. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/gl.js +30 -0
  109. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/he.js +27 -0
  110. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/hi.js +32 -0
  111. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/hr.js +32 -0
  112. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/hu.js +30 -0
  113. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/id.js +30 -0
  114. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/is.js +30 -0
  115. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/it.js +32 -0
  116. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ja.js +28 -0
  117. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ka.js +32 -0
  118. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/kk.js +32 -0
  119. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ko.js +26 -0
  120. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/lb.js +30 -0
  121. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/lt.js +30 -0
  122. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/lv.js +32 -0
  123. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/mk.js +28 -0
  124. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ms.js +32 -0
  125. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/nb.js +30 -0
  126. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/nl.js +30 -0
  127. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/nn.js +30 -0
  128. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/pl.js +30 -0
  129. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/pt-br.js +28 -0
  130. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/pt.js +30 -0
  131. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ro.js +32 -0
  132. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/ru.js +32 -0
  133. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/sk.js +32 -0
  134. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/sl.js +30 -0
  135. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/sq.js +32 -0
  136. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/sr-cyrl.js +32 -0
  137. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/sr.js +32 -0
  138. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/sv.js +30 -0
  139. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/th.js +25 -0
  140. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/tr.js +30 -0
  141. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/uk.js +32 -0
  142. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/vi.js +32 -0
  143. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/zh-cn.js +33 -0
  144. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales/zh-tw.js +26 -0
  145. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales-all.js +1348 -0
  146. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/locales-all.min.js +1 -0
  147. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/main.css +1052 -0
  148. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/main.d.ts +2730 -0
  149. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/main.esm.js +8558 -0
  150. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/main.js +8717 -0
  151. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/main.min.css +1 -0
  152. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/main.min.js +6 -0
  153. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/core/package.json +30 -0
  154. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/daygrid/LICENSE.txt +20 -0
  155. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/daygrid/README.md +8 -0
  156. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/daygrid/main.css +78 -0
  157. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/daygrid/main.d.ts +310 -0
  158. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/daygrid/main.esm.js +1627 -0
  159. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/daygrid/main.js +1641 -0
  160. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/daygrid/main.min.css +1 -0
  161. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/daygrid/main.min.js +6 -0
  162. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/daygrid/package.json +33 -0
  163. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/fullcalendar-yearview/LICENSE +21 -0
  164. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/fullcalendar-yearview/css/main.css +85 -0
  165. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/fullcalendar-yearview/js/main.js +2018 -0
  166. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/google-calendar/LICENSE.txt +20 -0
  167. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/google-calendar/README.md +8 -0
  168. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/google-calendar/main.d.ts +20 -0
  169. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/google-calendar/main.esm.js +162 -0
  170. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/google-calendar/main.js +170 -0
  171. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/google-calendar/main.min.js +6 -0
  172. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/google-calendar/package.json +33 -0
  173. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/interaction/LICENSE.txt +20 -0
  174. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/interaction/README.md +8 -0
  175. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/interaction/main.d.ts +323 -0
  176. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/interaction/main.esm.js +2132 -0
  177. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/interaction/main.js +2143 -0
  178. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/interaction/main.min.js +6 -0
  179. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/interaction/package.json +33 -0
  180. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/list/LICENSE.txt +20 -0
  181. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/list/README.md +8 -0
  182. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/list/main.css +118 -0
  183. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/list/main.d.ts +33 -0
  184. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/list/main.esm.js +335 -0
  185. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/list/main.js +343 -0
  186. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/list/main.min.css +1 -0
  187. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/list/main.min.js +6 -0
  188. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/list/package.json +33 -0
  189. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/luxon/LICENSE.txt +20 -0
  190. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/luxon/README.md +8 -0
  191. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/luxon/main.d.ts +14 -0
  192. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/luxon/main.esm.js +162 -0
  193. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/luxon/main.js +170 -0
  194. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/luxon/main.min.js +6 -0
  195. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/luxon/package.json +34 -0
  196. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment/LICENSE.txt +20 -0
  197. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment/README.md +8 -0
  198. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment/main.d.ts +14 -0
  199. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment/main.esm.js +102 -0
  200. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment/main.js +110 -0
  201. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment/main.min.js +6 -0
  202. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment/package.json +34 -0
  203. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment-timezone/LICENSE.txt +20 -0
  204. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment-timezone/README.md +8 -0
  205. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment-timezone/main.d.ts +11 -0
  206. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment-timezone/main.esm.js +58 -0
  207. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment-timezone/main.js +64 -0
  208. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment-timezone/main.min.js +6 -0
  209. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/moment-timezone/package.json +35 -0
  210. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/rrule/LICENSE.txt +20 -0
  211. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/rrule/README.md +8 -0
  212. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/rrule/main.d.ts +9 -0
  213. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/rrule/main.esm.js +121 -0
  214. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/rrule/main.js +128 -0
  215. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/rrule/main.min.js +6 -0
  216. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/rrule/package.json +34 -0
  217. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/timegrid/LICENSE.txt +20 -0
  218. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/timegrid/README.md +8 -0
  219. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/timegrid/main.css +309 -0
  220. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/timegrid/main.d.ts +220 -0
  221. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/timegrid/main.esm.js +1345 -0
  222. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/timegrid/main.js +1357 -0
  223. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/timegrid/main.min.css +1 -0
  224. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/timegrid/main.min.js +6 -0
  225. advanced_report_builder/static/advanced_report_builder/fullcalendar/packages/timegrid/package.json +36 -0
  226. advanced_report_builder/static/advanced_report_builder/fullcalendar/vendor/rrule.js +3782 -0
  227. advanced_report_builder/static/advanced_report_builder/jquery_extendext/js/jQuery.extendext.js +132 -0
  228. advanced_report_builder/static/advanced_report_builder/jquery_extendext/js/jQuery.extendext.min.js +9 -0
  229. advanced_report_builder/static/advanced_report_builder/moment/locales.js +9769 -0
  230. advanced_report_builder/static/advanced_report_builder/moment/locales.min.js +1 -0
  231. advanced_report_builder/static/advanced_report_builder/moment/moment-with-locales.js +14289 -0
  232. advanced_report_builder/static/advanced_report_builder/moment/moment-with-locales.min.js +1 -0
  233. advanced_report_builder/static/advanced_report_builder/moment/moment.min.js +1 -0
  234. advanced_report_builder/static/advanced_report_builder/query_builder/.DS_Store +0 -0
  235. advanced_report_builder/static/advanced_report_builder/query_builder/css/.DS_Store +0 -0
  236. advanced_report_builder/static/advanced_report_builder/query_builder/css/query-builder.dark.css +173 -0
  237. advanced_report_builder/static/advanced_report_builder/query_builder/css/query-builder.dark.min.css +6 -0
  238. advanced_report_builder/static/advanced_report_builder/query_builder/css/query-builder.default.css +173 -0
  239. advanced_report_builder/static/advanced_report_builder/query_builder/css/query-builder.default.min.css +6 -0
  240. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.ar.js +80 -0
  241. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.az.js +79 -0
  242. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.bg.js +79 -0
  243. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.cs.js +79 -0
  244. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.da.js +56 -0
  245. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.de.js +76 -0
  246. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.el.js +80 -0
  247. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.en.js +83 -0
  248. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.es.js +81 -0
  249. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.fa-IR.js +79 -0
  250. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.fr.js +83 -0
  251. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.he.js +81 -0
  252. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.it.js +79 -0
  253. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.nl.js +76 -0
  254. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.no.js +54 -0
  255. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.pl.js +80 -0
  256. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.pt-BR.js +80 -0
  257. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.pt-PT.js +75 -0
  258. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.ro.js +54 -0
  259. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.ru.js +77 -0
  260. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.sq.js +78 -0
  261. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.tr.js +82 -0
  262. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.ua.js +79 -0
  263. advanced_report_builder/static/advanced_report_builder/query_builder/i18n/query-builder.zh-CN.js +80 -0
  264. advanced_report_builder/static/advanced_report_builder/query_builder/js/.DS_Store +0 -0
  265. advanced_report_builder/static/advanced_report_builder/query_builder/js/plugins/.DS_Store +0 -0
  266. advanced_report_builder/static/advanced_report_builder/query_builder/js/plugins/currency/plugin.js +30 -0
  267. advanced_report_builder/static/advanced_report_builder/query_builder/js/query-builder.js +6200 -0
  268. advanced_report_builder/static/advanced_report_builder/query_builder/js/query-builder.min.js +7 -0
  269. advanced_report_builder/static/advanced_report_builder/query_builder/js/query-builder.standalone.js +6477 -0
  270. advanced_report_builder/static/advanced_report_builder/query_builder/js/query-builder.standalone.min.js +7 -0
  271. advanced_report_builder/static/advanced_report_builder/query_builder/scss/.DS_Store +0 -0
  272. advanced_report_builder/static/advanced_report_builder/query_builder/scss/dark.scss +19 -0
  273. advanced_report_builder/static/advanced_report_builder/query_builder/scss/default.scss +186 -0
  274. advanced_report_builder/static/advanced_report_builder/query_builder/scss/plugins/_bt-checkbox.scss +12 -0
  275. advanced_report_builder/static/advanced_report_builder/query_builder/scss/plugins/_bt-tooltip-errors.scss +9 -0
  276. advanced_report_builder/static/advanced_report_builder/query_builder/scss/plugins/_filter-description.scss +21 -0
  277. advanced_report_builder/static/advanced_report_builder/query_builder/scss/plugins/_invert.scss +5 -0
  278. advanced_report_builder/static/advanced_report_builder/query_builder/scss/plugins/_sortable.scss +28 -0
  279. advanced_report_builder/static/advanced_report_builder/query_builder/scss/plugins/bt-tooltip-errors.scss +9 -0
  280. advanced_report_builder/static/advanced_report_builder/query_builder/scss/plugins/filter-description.scss +21 -0
  281. advanced_report_builder/static/advanced_report_builder/query_builder/scss/plugins/invert.scss +5 -0
  282. advanced_report_builder/static/advanced_report_builder/query_builder/scss/plugins/sortable.scss +27 -0
  283. advanced_report_builder/template_types.py +34 -0
  284. advanced_report_builder/templates/advanced_report_builder/calendar/description_modal.html +12 -0
  285. advanced_report_builder/templates/advanced_report_builder/calendar/middle.html +33 -0
  286. advanced_report_builder/templates/advanced_report_builder/calendar/modal.html +10 -0
  287. advanced_report_builder/templates/advanced_report_builder/calendar/report.html +80 -0
  288. advanced_report_builder/templates/advanced_report_builder/charts/bar/middle.html +122 -0
  289. advanced_report_builder/templates/advanced_report_builder/charts/funnel/middle.html +46 -0
  290. advanced_report_builder/templates/advanced_report_builder/charts/funnel/report.html +34 -0
  291. advanced_report_builder/templates/advanced_report_builder/charts/line/middle.html +119 -0
  292. advanced_report_builder/templates/advanced_report_builder/charts/modal.html +12 -0
  293. advanced_report_builder/templates/advanced_report_builder/charts/modal_field.html +13 -0
  294. advanced_report_builder/templates/advanced_report_builder/charts/pie/middle.html +58 -0
  295. advanced_report_builder/templates/advanced_report_builder/charts/report.html +33 -0
  296. advanced_report_builder/templates/advanced_report_builder/data_merge/data_merge.html +144 -0
  297. advanced_report_builder/templates/advanced_report_builder/datatables/fields/modal.html +13 -0
  298. advanced_report_builder/templates/advanced_report_builder/datatables/fields/single_query_builder.html +87 -0
  299. advanced_report_builder/templates/advanced_report_builder/datatables/modal.html +13 -0
  300. advanced_report_builder/templates/advanced_report_builder/datatables/onclick_menu.html +14 -0
  301. advanced_report_builder/templates/advanced_report_builder/datatables/report.html +37 -0
  302. advanced_report_builder/templates/advanced_report_builder/datatables/select_pivot.html +199 -0
  303. advanced_report_builder/templates/advanced_report_builder/error.html +21 -0
  304. advanced_report_builder/templates/advanced_report_builder/extra_query_modal.html +13 -0
  305. advanced_report_builder/templates/advanced_report_builder/kanban/description_modal.html +12 -0
  306. advanced_report_builder/templates/advanced_report_builder/kanban/middle.html +63 -0
  307. advanced_report_builder/templates/advanced_report_builder/kanban/modal.html +10 -0
  308. advanced_report_builder/templates/advanced_report_builder/kanban/report.html +71 -0
  309. advanced_report_builder/templates/advanced_report_builder/multi_values/held_modal.html +14 -0
  310. advanced_report_builder/templates/advanced_report_builder/multi_values/middle.html +61 -0
  311. advanced_report_builder/templates/advanced_report_builder/multi_values/modal.html +15 -0
  312. advanced_report_builder/templates/advanced_report_builder/multi_values/report.html +19 -0
  313. advanced_report_builder/templates/advanced_report_builder/query_builder.html +88 -0
  314. advanced_report_builder/templates/advanced_report_builder/query_modal.html +12 -0
  315. advanced_report_builder/templates/advanced_report_builder/select_column.html +230 -0
  316. advanced_report_builder/templates/advanced_report_builder/single_values/gauge_middle.html +143 -0
  317. advanced_report_builder/templates/advanced_report_builder/single_values/middle.html +63 -0
  318. advanced_report_builder/templates/advanced_report_builder/single_values/modal.html +13 -0
  319. advanced_report_builder/templates/advanced_report_builder/single_values/report.html +56 -0
  320. advanced_report_builder/toggle.py +9 -0
  321. advanced_report_builder/urls.py +237 -0
  322. advanced_report_builder/utils.py +171 -0
  323. advanced_report_builder/variable_date.py +670 -0
  324. advanced_report_builder/view_types.py +27 -0
  325. advanced_report_builder/views/.DS_Store +0 -0
  326. advanced_report_builder/views/__init__.py +0 -0
  327. advanced_report_builder/views/bar_charts.py +746 -0
  328. advanced_report_builder/views/calendar.py +745 -0
  329. advanced_report_builder/views/charts_base.py +625 -0
  330. advanced_report_builder/views/custom.py +147 -0
  331. advanced_report_builder/views/dashboard.py +357 -0
  332. advanced_report_builder/views/datatables/__init__.py +0 -0
  333. advanced_report_builder/views/datatables/datatables.py +151 -0
  334. advanced_report_builder/views/datatables/modal.py +1151 -0
  335. advanced_report_builder/views/datatables/utils.py +701 -0
  336. advanced_report_builder/views/error_pod.py +50 -0
  337. advanced_report_builder/views/funnel_charts.py +289 -0
  338. advanced_report_builder/views/helpers.py +22 -0
  339. advanced_report_builder/views/kanban.py +868 -0
  340. advanced_report_builder/views/line_charts.py +415 -0
  341. advanced_report_builder/views/modals_base.py +213 -0
  342. advanced_report_builder/views/multi_value.py +1160 -0
  343. advanced_report_builder/views/pie_charts.py +290 -0
  344. advanced_report_builder/views/query_modal/__init__.py +0 -0
  345. advanced_report_builder/views/query_modal/mixin.py +161 -0
  346. advanced_report_builder/views/query_modal/modal.py +274 -0
  347. advanced_report_builder/views/report.py +241 -0
  348. advanced_report_builder/views/report_utils_mixin.py +312 -0
  349. advanced_report_builder/views/reports.py +154 -0
  350. advanced_report_builder/views/single_values.py +792 -0
  351. advanced_report_builder/views/targets/__init__.py +0 -0
  352. advanced_report_builder/views/targets/utils.py +251 -0
  353. advanced_report_builder/views/targets/views.py +139 -0
  354. advanced_report_builder/views/value_base.py +198 -0
  355. advanced_report_builder/widgets.py +5 -0
  356. django_advanced_report_builder-1.2.9.dist-info/METADATA +35 -0
  357. django_advanced_report_builder-1.2.9.dist-info/RECORD +360 -0
  358. django_advanced_report_builder-1.2.9.dist-info/WHEEL +5 -0
  359. django_advanced_report_builder-1.2.9.dist-info/licenses/LICENSE +21 -0
  360. django_advanced_report_builder-1.2.9.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1151 @@
1
+ import base64
2
+ import json
3
+
4
+ from crispy_forms.bootstrap import StrictButton
5
+ from crispy_forms.layout import Div
6
+ from django.apps import apps
7
+ from django.forms import BooleanField, CharField, ChoiceField, IntegerField
8
+ from django.urls import reverse
9
+ from django_modals.fields import FieldEx
10
+ from django_modals.form_helpers import HorizontalNoEnterHelper
11
+ from django_modals.modals import FormModal
12
+ from django_modals.processes import PERMISSION_OFF, PROCESS_EDIT_DELETE
13
+ from django_modals.widgets.select2 import Select2Multiple
14
+ from django_modals.widgets.widgets import Toggle
15
+
16
+ from advanced_report_builder.column_types import (
17
+ CURRENCY_COLUMNS,
18
+ DATE_FIELDS,
19
+ LINK_COLUMNS,
20
+ NUMBER_FIELDS,
21
+ REVERSE_FOREIGN_KEY_BOOL_COLUMNS,
22
+ REVERSE_FOREIGN_KEY_CHOICE_COLUMNS,
23
+ REVERSE_FOREIGN_KEY_DATE_COLUMNS,
24
+ REVERSE_FOREIGN_KEY_STR_COLUMNS,
25
+ )
26
+ from advanced_report_builder.globals import (
27
+ ALIGNMENT_CHOICE_RIGHT,
28
+ ALIGNMENT_CHOICES,
29
+ ANNOTATION_VALUE_CHOICES,
30
+ ANNOTATIONS_CHOICES,
31
+ DATE_FORMAT_TYPES,
32
+ REVERSE_FOREIGN_KEY_ANNOTATION_BOOLEAN_CHOICES,
33
+ REVERSE_FOREIGN_KEY_ANNOTATION_DATE_ARRAY,
34
+ REVERSE_FOREIGN_KEY_ANNOTATION_DATE_CHOICES,
35
+ REVERSE_FOREIGN_KEY_DELIMITER_CHOICES,
36
+ )
37
+ from advanced_report_builder.models import ReportType, TableReport
38
+ from advanced_report_builder.toggle import RBToggle
39
+ from advanced_report_builder.utils import (
40
+ decode_attribute,
41
+ encode_attribute,
42
+ get_report_builder_class,
43
+ split_attr,
44
+ )
45
+ from advanced_report_builder.views.charts_base import ChartBaseFieldForm
46
+ from advanced_report_builder.views.modals_base import (
47
+ QueryBuilderModalBase,
48
+ QueryBuilderModalBaseMixin,
49
+ )
50
+ from advanced_report_builder.views.query_modal.mixin import MultiQueryModalMixin
51
+
52
+
53
+ class TableModal(MultiQueryModalMixin, QueryBuilderModalBase):
54
+ template_name = 'advanced_report_builder/datatables/modal.html'
55
+ size = 'xl'
56
+ model = TableReport
57
+ process = PROCESS_EDIT_DELETE
58
+ permission_delete = PERMISSION_OFF
59
+ show_order_by = False
60
+
61
+ widgets = {'report_tags': Select2Multiple}
62
+
63
+ form_fields = [
64
+ 'name',
65
+ 'notes',
66
+ (
67
+ 'has_clickable_rows',
68
+ {
69
+ 'widget': Toggle(
70
+ attrs={
71
+ 'data-onstyle': 'success',
72
+ 'data-on': 'YES',
73
+ 'data-off': 'NO',
74
+ }
75
+ )
76
+ },
77
+ ),
78
+ 'link_field',
79
+ 'order_by_field',
80
+ (
81
+ 'order_by_ascending',
82
+ {
83
+ 'widget': Toggle(
84
+ attrs={
85
+ 'data-onstyle': 'success',
86
+ 'data-on': 'YES',
87
+ 'data-off': 'NO',
88
+ }
89
+ )
90
+ },
91
+ ),
92
+ 'page_length',
93
+ 'report_type',
94
+ 'report_tags',
95
+ 'table_fields',
96
+ 'pivot_fields',
97
+ ]
98
+
99
+ def form_setup(self, form, *_args, **_kwargs):
100
+ url = reverse(
101
+ 'advanced_report_builder:table_field_modal',
102
+ kwargs={'slug': 'selector-99999-data-FIELD_INFO-report_type_id-REPORT_TYPE_ID'},
103
+ )
104
+
105
+ pivot_url = reverse(
106
+ 'advanced_report_builder:table_pivot_modal',
107
+ kwargs={'slug': 'selector-99999-data-FIELD_INFO-report_type_id-REPORT_TYPE_ID'},
108
+ )
109
+
110
+ form.add_trigger(
111
+ 'has_clickable_rows',
112
+ 'onchange',
113
+ [
114
+ {
115
+ 'selector': '#div_id_link_field',
116
+ 'values': {'checked': 'show'},
117
+ 'default': 'hide',
118
+ },
119
+ ],
120
+ )
121
+
122
+ form.fields['notes'].widget.attrs['rows'] = 3
123
+
124
+ if 'data' in _kwargs:
125
+ link_field = _kwargs['data'].get('link_field')
126
+ order_by_field = _kwargs['data'].get('order_by_field')
127
+ report_type_id = _kwargs['data'].get('report_type')
128
+ report_type = ReportType.objects.filter(id=report_type_id).first() # can be None
129
+ else:
130
+ link_field = form.instance.link_field
131
+ order_by_field = form.instance.order_by_field
132
+ report_type = form.instance.report_type
133
+
134
+ self.setup_field(
135
+ field_type='link',
136
+ form=form,
137
+ field_name='link_field',
138
+ selected_field_id=link_field,
139
+ report_type=report_type,
140
+ )
141
+
142
+ self.setup_field(
143
+ field_type='order',
144
+ form=form,
145
+ field_name='order_by_field',
146
+ selected_field_id=order_by_field,
147
+ report_type=report_type,
148
+ )
149
+
150
+ fields = [
151
+ 'name',
152
+ 'notes',
153
+ 'report_type',
154
+ 'report_tags',
155
+ FieldEx(
156
+ 'has_clickable_rows',
157
+ template='django_modals/fields/label_checkbox.html',
158
+ ),
159
+ 'link_field',
160
+ 'order_by_field',
161
+ FieldEx(
162
+ 'order_by_ascending',
163
+ template='django_modals/fields/label_checkbox.html',
164
+ ),
165
+ FieldEx('page_length', template='django_modals/fields/label_checkbox.html'),
166
+ FieldEx(
167
+ 'table_fields',
168
+ template='advanced_report_builder/select_column.html',
169
+ extra_context={'select_column_url': url, 'command_prefix': ''},
170
+ ),
171
+ FieldEx(
172
+ 'pivot_fields',
173
+ template='advanced_report_builder/datatables/select_pivot.html',
174
+ extra_context={'select_column_url': pivot_url},
175
+ ),
176
+ ]
177
+
178
+ if self.object.id:
179
+ self.add_extra_queries(form=form, fields=fields)
180
+
181
+ return fields
182
+
183
+ def form_valid(self, form):
184
+ org_id = self.object.pk if hasattr(self, 'object') else None
185
+ instance = form.save(commit=False)
186
+ instance._current_user = self.request.user
187
+ instance.save()
188
+ self.post_save(created=org_id is None, form=form)
189
+ if not self.response_commands:
190
+ self.add_command('reload')
191
+ return self.command_response()
192
+
193
+ def ajax_get_fields(self, **kwargs):
194
+ report_type_id = kwargs['report_type']
195
+ report_builder_class, base_model = self.get_report_builder_class(report_type_id=report_type_id)
196
+ fields = []
197
+ tables = []
198
+ pivot_fields = []
199
+ self._get_fields(
200
+ base_model=base_model,
201
+ fields=fields,
202
+ tables=tables,
203
+ report_builder_class=report_builder_class,
204
+ pivot_fields=pivot_fields,
205
+ include_mathematical_columns=True,
206
+ )
207
+
208
+ self.add_command('report_fields', data=json.dumps({'fields': fields, 'tables': tables}))
209
+ self.add_command('report_pivots', data=json.dumps({'pivot_fields': pivot_fields}))
210
+
211
+ return self.command_response()
212
+
213
+ def select2_link_field(self, **kwargs):
214
+ return self.get_fields_for_select2(
215
+ field_type='link',
216
+ report_type=kwargs['report_type'],
217
+ search_string=kwargs.get('search'),
218
+ )
219
+
220
+ def select2_order_by_field(self, **kwargs):
221
+ return self.get_fields_for_select2(
222
+ field_type='order',
223
+ report_type=kwargs['report_type'],
224
+ search_string=kwargs.get('search'),
225
+ )
226
+
227
+
228
+ class TableFieldForm(ChartBaseFieldForm):
229
+ cancel_class = 'btn-secondary modal-cancel'
230
+
231
+ def cancel_button(self, css_class=cancel_class, **kwargs):
232
+ commands = [{'function': 'close'}]
233
+ return self.button('Cancel', commands, css_class, **kwargs)
234
+
235
+ def submit_button(self, css_class='btn-success modal-submit', button_text='Submit', **kwargs):
236
+ if self.django_field is not None and isinstance(self.django_field, NUMBER_FIELDS + CURRENCY_COLUMNS):
237
+ return StrictButton(
238
+ button_text,
239
+ onclick=f'save_modal_{self.form_id}()',
240
+ css_class=css_class,
241
+ **kwargs,
242
+ )
243
+ else:
244
+ return super().submit_button(css_class, button_text, **kwargs)
245
+
246
+ def is_mathematical_field(self, data):
247
+ return self.django_field is None and data['field'] in [
248
+ 'rb_addition',
249
+ 'rb_subtraction',
250
+ 'rb_times',
251
+ 'rb_division',
252
+ 'rb_percentage',
253
+ ]
254
+
255
+ def setup_modal(self, *args, **kwargs):
256
+ data = json.loads(base64.b64decode(self.slug['data']))
257
+ report_type, base_model = self.get_report_type_details()
258
+
259
+ self.fields['title'] = CharField(initial=data['title'])
260
+ data_attr = split_attr(data)
261
+ self.fields['display_heading'] = BooleanField(required=False, widget=RBToggle(), label='Display heading')
262
+ if int(data_attr.get('display_heading', 1)) == 1:
263
+ self.fields['display_heading'].initial = True
264
+
265
+ has_existing_annotations = self.col_type_override is not None and self.col_type_override.annotations is not None
266
+
267
+ if self.django_field is not None and isinstance(self.django_field, DATE_FIELDS):
268
+ self.setup_date_fields(data_attr)
269
+ elif self.django_field is not None and isinstance(self.django_field, NUMBER_FIELDS):
270
+ self.setup_number_fields(
271
+ data_attr=data_attr,
272
+ base_model=base_model,
273
+ report_type=report_type,
274
+ has_existing_annotations=has_existing_annotations,
275
+ )
276
+ elif isinstance(self.col_type_override, CURRENCY_COLUMNS):
277
+ self.setup_currency_fields(
278
+ data_attr=data_attr,
279
+ base_model=base_model,
280
+ report_type=report_type,
281
+ has_existing_annotations=has_existing_annotations,
282
+ )
283
+ elif isinstance(self.col_type_override, LINK_COLUMNS):
284
+ self.setup_link_fields(data_attr=data_attr)
285
+ elif isinstance(self.col_type_override, REVERSE_FOREIGN_KEY_STR_COLUMNS):
286
+ self.setup_reverse_foreign_str_key(data_attr=data_attr)
287
+ elif isinstance(self.col_type_override, REVERSE_FOREIGN_KEY_BOOL_COLUMNS):
288
+ self.setup_reverse_foreign_bool_key(data_attr=data_attr)
289
+ elif isinstance(self.col_type_override, REVERSE_FOREIGN_KEY_CHOICE_COLUMNS):
290
+ self.setup_reverse_foreign_choice_key(data_attr=data_attr)
291
+ elif isinstance(self.col_type_override, REVERSE_FOREIGN_KEY_DATE_COLUMNS):
292
+ self.setup_reverse_foreign_date_key(data_attr=data_attr)
293
+ elif self.col_type_override.annotations is not None:
294
+ self.setup_annotation_fields(data_attr=data_attr)
295
+ elif self.is_mathematical_field(data=data):
296
+ self.setup_standard_mathematical_fields(data=data, data_attr=data_attr)
297
+ else:
298
+ self.fields['annotation_label'] = BooleanField(required=False, widget=RBToggle())
299
+ if 'annotation_label' in data_attr and data_attr['annotation_label'] == '1':
300
+ self.fields['annotation_label'].initial = True
301
+ super().setup_modal(*args, **kwargs)
302
+
303
+ def setup_annotation_fields(self, data_attr):
304
+ self.fields['show_table_totals'] = BooleanField(required=False, widget=RBToggle(), label='Show totals')
305
+ if 'show_totals' in data_attr and data_attr['show_totals'] == '1':
306
+ self.fields['show_table_totals'].initial = True
307
+
308
+ def setup_currency_fields(self, data_attr, base_model, report_type, has_existing_annotations):
309
+ if has_existing_annotations:
310
+ self.fields['append_annotation_query'] = BooleanField(
311
+ required=False, widget=RBToggle(), label='Append annotation query'
312
+ )
313
+ if 'append_annotation_query' in data_attr and data_attr['append_annotation_query'] == '1':
314
+ self.fields['append_annotation_query'].initial = True
315
+ else:
316
+ self.fields['annotations_type'] = ChoiceField(choices=[(0, '-----')] + ANNOTATIONS_CHOICES, required=False)
317
+ if 'annotations_type' in data_attr:
318
+ self.fields['annotations_type'].initial = data_attr['annotations_type']
319
+ else:
320
+ self.fields['alignment'].initial = ALIGNMENT_CHOICE_RIGHT
321
+
322
+ annotation_column_help_text = 'Not required however useful for mathematical columns.'
323
+ self.fields['annotation_column_id'] = CharField(required=False, help_text=annotation_column_help_text)
324
+ if 'annotation_column_id' in data_attr:
325
+ self.fields['annotation_column_id'].initial = decode_attribute(data_attr['annotation_column_id'])
326
+
327
+ self.fields['show_table_totals'] = BooleanField(required=False, widget=RBToggle(), label='Show totals')
328
+ if 'show_totals' in data_attr and data_attr['show_totals'] == '1':
329
+ self.fields['show_table_totals'].initial = True
330
+
331
+ self.fields['alignment'] = ChoiceField(choices=ALIGNMENT_CHOICES, required=False)
332
+ if 'alignment' in data_attr:
333
+ self.fields['alignment'].initial = data_attr['alignment']
334
+ else:
335
+ self.fields['alignment'].initial = ALIGNMENT_CHOICE_RIGHT
336
+ self.fields['has_filter'] = BooleanField(required=False, widget=RBToggle())
337
+
338
+ self.fields['filter'] = CharField(required=False)
339
+
340
+ if data_attr.get('has_filter') == '1':
341
+ self.fields['has_filter'].initial = True
342
+ if 'filter' in data_attr:
343
+ self.fields['filter'].initial = decode_attribute(data_attr['filter'])
344
+
345
+ self.fields['multiple_columns'] = BooleanField(required=False, widget=RBToggle())
346
+
347
+ report_builder_class = get_report_builder_class(model=base_model, report_type=report_type)
348
+ fields = []
349
+ self._get_query_builder_foreign_key_fields(
350
+ base_model=base_model,
351
+ report_builder_class=report_builder_class,
352
+ fields=fields,
353
+ )
354
+
355
+ self.fields['multiple_column_field'] = ChoiceField(choices=fields, required=False)
356
+
357
+ if data_attr.get('multiple_columns') == '1':
358
+ self.fields['multiple_columns'].initial = True
359
+ self.fields['multiple_column_field'].initial = data_attr.get('multiple_column_field')
360
+ if data_attr.get('append_column_title') == '1':
361
+ self.fields['append_column_title'].initial = True
362
+
363
+ def setup_link_fields(self, data_attr):
364
+ self.fields['link_html'] = CharField(required=False)
365
+ if 'link_html' in data_attr:
366
+ self.fields['link_html'].initial = decode_attribute(data_attr['link_html'])
367
+ self.fields['link_css'] = CharField(required=False)
368
+ if 'link_css' in data_attr:
369
+ self.fields['link_css'].initial = decode_attribute(data_attr['link_css'])
370
+ self.fields['is_icon'] = BooleanField(required=False, widget=RBToggle())
371
+ if 'is_icon' in data_attr and data_attr['is_icon'] == '1':
372
+ self.fields['is_icon'].initial = True
373
+
374
+ def setup_reverse_foreign_str_key(self, data_attr):
375
+ self.fields['delimiter_type'] = ChoiceField(choices=REVERSE_FOREIGN_KEY_DELIMITER_CHOICES, required=False)
376
+ if 'delimiter_type' in data_attr:
377
+ self.fields['delimiter_type'].initial = data_attr['delimiter_type']
378
+ self.fields['has_filter'] = BooleanField(required=False, widget=RBToggle())
379
+ self.fields['filter'] = CharField(required=False)
380
+ if data_attr.get('has_filter') == '1':
381
+ self.fields['has_filter'].initial = True
382
+ if 'filter' in data_attr:
383
+ self.fields['filter'].initial = decode_attribute(data_attr['filter'])
384
+
385
+ def setup_reverse_foreign_bool_key(self, data_attr):
386
+ self.fields['annotations_type'] = ChoiceField(
387
+ choices=REVERSE_FOREIGN_KEY_ANNOTATION_BOOLEAN_CHOICES,
388
+ required=False,
389
+ label='Type',
390
+ )
391
+ if 'annotations_type' in data_attr:
392
+ self.fields['annotations_type'].initial = data_attr['annotations_type']
393
+ self.fields['has_filter'] = BooleanField(required=False, widget=RBToggle())
394
+ self.fields['filter'] = CharField(required=False)
395
+ if data_attr.get('has_filter') == '1':
396
+ self.fields['has_filter'].initial = True
397
+ if 'filter' in data_attr:
398
+ self.fields['filter'].initial = decode_attribute(data_attr['filter'])
399
+
400
+ def setup_reverse_foreign_choice_key(self, data_attr):
401
+ self.fields['delimiter_type'] = ChoiceField(choices=REVERSE_FOREIGN_KEY_DELIMITER_CHOICES, required=False)
402
+ if 'delimiter_type' in data_attr:
403
+ self.fields['delimiter_type'].initial = data_attr['delimiter_type']
404
+ self.fields['has_filter'] = BooleanField(required=False, widget=RBToggle())
405
+ self.fields['filter'] = CharField(required=False)
406
+ if data_attr.get('has_filter') == '1':
407
+ self.fields['has_filter'].initial = True
408
+ if 'filter' in data_attr:
409
+ self.fields['filter'].initial = decode_attribute(data_attr['filter'])
410
+
411
+ def setup_reverse_foreign_date_key(self, data_attr):
412
+ self.fields['annotations_type'] = ChoiceField(
413
+ choices=REVERSE_FOREIGN_KEY_ANNOTATION_DATE_CHOICES,
414
+ required=False,
415
+ label='Type',
416
+ )
417
+ if 'annotations_type' in data_attr:
418
+ self.fields['annotations_type'].initial = data_attr['annotations_type']
419
+ self.fields['delimiter_type'] = ChoiceField(choices=REVERSE_FOREIGN_KEY_DELIMITER_CHOICES, required=False)
420
+ if 'delimiter_type' in data_attr:
421
+ self.fields['delimiter_type'].initial = data_attr['delimiter_type']
422
+ self.fields['date_format'] = ChoiceField(choices=[(0, '-----')] + DATE_FORMAT_TYPES, required=False)
423
+ if 'date_format' in data_attr:
424
+ self.fields['date_format'].initial = data_attr['date_format']
425
+ self.fields['has_filter'] = BooleanField(required=False, widget=RBToggle())
426
+ self.fields['filter'] = CharField(required=False)
427
+ if data_attr.get('has_filter') == '1':
428
+ self.fields['has_filter'].initial = True
429
+ if 'filter' in data_attr:
430
+ self.fields['filter'].initial = decode_attribute(data_attr['filter'])
431
+
432
+ def setup_date_fields(self, data_attr):
433
+ self.fields['annotations_value'] = ChoiceField(
434
+ choices=[(0, '-----')] + ANNOTATION_VALUE_CHOICES, required=False
435
+ )
436
+ if 'annotations_value' in data_attr:
437
+ self.fields['annotations_value'].initial = data_attr['annotations_value']
438
+ self.fields['date_format'] = ChoiceField(choices=[(0, '-----')] + DATE_FORMAT_TYPES, required=False)
439
+ if 'date_format' in data_attr:
440
+ self.fields['date_format'].initial = data_attr['date_format']
441
+
442
+ def setup_number_fields(self, data_attr, base_model, report_type, has_existing_annotations):
443
+ if has_existing_annotations:
444
+ self.fields['append_annotation_query'] = BooleanField(
445
+ required=False, widget=RBToggle(), label='Append annotation query'
446
+ )
447
+ if 'append_annotation_query' in data_attr and data_attr['append_annotation_query'] == '1':
448
+ self.fields['append_annotation_query'].initial = True
449
+ else:
450
+ self.fields['annotations_type'] = ChoiceField(choices=[(0, '-----')] + ANNOTATIONS_CHOICES, required=False)
451
+ if 'annotations_type' in data_attr:
452
+ self.fields['annotations_type'].initial = data_attr['annotations_type']
453
+
454
+ annotation_column_help_text = 'Not required however useful for mathematical columns.'
455
+ self.fields['annotation_column_id'] = CharField(required=False, help_text=annotation_column_help_text)
456
+ if 'annotation_column_id' in data_attr:
457
+ self.fields['annotation_column_id'].initial = decode_attribute(data_attr['annotation_column_id'])
458
+
459
+ self.fields['show_table_totals'] = BooleanField(required=False, widget=RBToggle(), label='Show totals')
460
+ if 'show_totals' in data_attr and data_attr['show_totals'] == '1':
461
+ self.fields['show_table_totals'].initial = True
462
+
463
+ self.fields['alignment'] = ChoiceField(choices=ALIGNMENT_CHOICES, required=False)
464
+ if 'alignment' in data_attr:
465
+ self.fields['alignment'].initial = data_attr['alignment']
466
+ else:
467
+ self.fields['alignment'].initial = ALIGNMENT_CHOICE_RIGHT
468
+
469
+ self.fields['decimal_places'] = IntegerField()
470
+ self.fields['decimal_places'].initial = int(data_attr.get('decimal_places', 0))
471
+ self.fields['has_filter'] = BooleanField(required=False, widget=RBToggle())
472
+
473
+ self.fields['filter'] = CharField(required=False)
474
+
475
+ if data_attr.get('has_filter') == '1':
476
+ self.fields['has_filter'].initial = True
477
+ if 'filter' in data_attr:
478
+ self.fields['filter'].initial = decode_attribute(data_attr['filter'])
479
+
480
+ self.fields['multiple_columns'] = BooleanField(required=False, widget=RBToggle())
481
+
482
+ report_builder_class = get_report_builder_class(model=base_model, report_type=report_type)
483
+ fields = []
484
+ self._get_query_builder_foreign_key_fields(
485
+ base_model=base_model,
486
+ report_builder_class=report_builder_class,
487
+ fields=fields,
488
+ )
489
+
490
+ self.fields['multiple_column_field'] = ChoiceField(choices=fields, required=False)
491
+
492
+ if data_attr.get('multiple_columns') == '1':
493
+ self.fields['multiple_columns'].initial = True
494
+ self.fields['multiple_column_field'].initial = data_attr.get('multiple_column_field')
495
+ if data_attr.get('append_column_title') == '1':
496
+ self.fields['append_column_title'].initial = True
497
+
498
+ def setup_standard_mathematical_fields(self, data, data_attr):
499
+ self.fields['hidden'] = BooleanField(required=False, widget=RBToggle(), label='Hidden')
500
+ if int(data_attr.get('hidden', 0)) == 1:
501
+ self.fields['hidden'].initial = True
502
+
503
+ self.fields['column_id'] = CharField(required=False)
504
+ if 'column_id' in data_attr:
505
+ self.fields['column_id'].initial = decode_attribute(data_attr['column_id'])
506
+ if data['field'] in ['rb_division', 'rb_percentage']:
507
+ self.fields['numerator_column'] = CharField(required=False)
508
+ if 'numerator_column' in data_attr:
509
+ self.fields['numerator_column'].initial = decode_attribute(data_attr['numerator_column'])
510
+ self.fields['denominator_column'] = CharField(required=False)
511
+ if 'denominator_column' in data_attr:
512
+ self.fields['denominator_column'].initial = decode_attribute(data_attr['denominator_column'])
513
+ elif data['field'] == 'rb_times':
514
+ self.fields['multiplicand_column'] = CharField(required=False)
515
+ if 'multiplicand_column' in data_attr:
516
+ self.fields['multiplicand_column'].initial = decode_attribute(data_attr['multiplicand_column'])
517
+ self.fields['multiplier_column'] = CharField(required=False)
518
+ if 'multiplier_column' in data_attr:
519
+ self.fields['multiplier_column'].initial = decode_attribute(data_attr['multiplier_column'])
520
+ else: # add and sub
521
+ self.fields['first_value_column'] = CharField(required=False)
522
+ if 'first_value_column' in data_attr:
523
+ self.fields['first_value_column'].initial = decode_attribute(data_attr['first_value_column'])
524
+ self.fields['second_value_column'] = CharField(required=False)
525
+ if 'second_value_column' in data_attr:
526
+ self.fields['second_value_column'].initial = decode_attribute(data_attr['second_value_column'])
527
+ self.fields['decimal_places'] = IntegerField()
528
+ self.fields['decimal_places'].initial = int(data_attr.get('decimal_places', 0))
529
+ self.fields['show_table_totals'] = BooleanField(required=False, widget=RBToggle(), label='Show totals')
530
+ if 'show_totals' in data_attr and data_attr['show_totals'] == '1':
531
+ self.fields['show_table_totals'].initial = True
532
+
533
+ self.fields['alignment'] = ChoiceField(choices=ALIGNMENT_CHOICES, required=False)
534
+ if 'alignment' in data_attr:
535
+ self.fields['alignment'].initial = data_attr['alignment']
536
+ else:
537
+ self.fields['alignment'].initial = ALIGNMENT_CHOICE_RIGHT
538
+
539
+ def save_mathematical_fields(self, data, attributes):
540
+ if self.cleaned_data['hidden']:
541
+ attributes.append('hidden-1')
542
+
543
+ alignment = self.cleaned_data.get('alignment')
544
+ attributes.append(f'alignment-{alignment}')
545
+ if self.cleaned_data['column_id']:
546
+ b64_column_id = encode_attribute(self.cleaned_data['column_id'])
547
+ attributes.append(f'column_id-{b64_column_id}')
548
+ if data['field'] in ['rb_division', 'rb_percentage']:
549
+ if self.cleaned_data['numerator_column']:
550
+ b64_numerator_column = encode_attribute(self.cleaned_data['numerator_column'])
551
+ attributes.append(f'numerator_column-{b64_numerator_column}')
552
+ if self.cleaned_data['denominator_column']:
553
+ b64_denominator_column = encode_attribute(self.cleaned_data['denominator_column'])
554
+ attributes.append(f'denominator_column-{b64_denominator_column}')
555
+ elif data['field'] == 'rb_times':
556
+ if self.cleaned_data['multiplicand_column']:
557
+ b64_multiplicand_column = encode_attribute(self.cleaned_data['multiplicand_column'])
558
+ attributes.append(f'multiplicand_column-{b64_multiplicand_column}')
559
+ if self.cleaned_data['multiplier_column']:
560
+ b64_multiplier_column = encode_attribute(self.cleaned_data['multiplier_column'])
561
+ attributes.append(f'multiplier_column-{b64_multiplier_column}')
562
+ else:
563
+ if self.cleaned_data['first_value_column']:
564
+ b64_first_value_column = encode_attribute(self.cleaned_data['first_value_column'])
565
+ attributes.append(f'first_value_column-{b64_first_value_column}')
566
+ if self.cleaned_data['second_value_column']:
567
+ b64_second_value_column = encode_attribute(self.cleaned_data['second_value_column'])
568
+ attributes.append(f'second_value_column-{b64_second_value_column}')
569
+
570
+ attributes.append(f'decimal_places-{self.cleaned_data.get("decimal_places", 0)}')
571
+ if self.cleaned_data['show_table_totals']:
572
+ attributes.append('show_totals-1')
573
+
574
+ def save_number_fields(self, attributes):
575
+ alignment = self.cleaned_data.get('alignment')
576
+ attributes.append(f'alignment-{alignment}')
577
+ if 'annotations_type' in self.cleaned_data and int(self.cleaned_data['annotations_type']) != 0:
578
+ attributes.append(f'annotations_type-{self.cleaned_data["annotations_type"]}')
579
+ elif 'append_annotation_query' in self.cleaned_data and self.cleaned_data['append_annotation_query']:
580
+ attributes.append('append_annotation_query-1')
581
+ if self.cleaned_data['annotation_column_id']:
582
+ b64_annotation_column_id = encode_attribute(self.cleaned_data['annotation_column_id'])
583
+ attributes.append(f'annotation_column_id-{b64_annotation_column_id}')
584
+ if self.cleaned_data['show_table_totals']:
585
+ attributes.append('show_totals-1')
586
+ if self.cleaned_data['decimal_places'] > 0:
587
+ attributes.append(f'decimal_places-{self.cleaned_data["decimal_places"]}')
588
+ self.save_filter(attributes=attributes)
589
+
590
+ def save_date_fields(self, attributes):
591
+ if self.cleaned_data['annotations_value']:
592
+ attributes.append(f'annotations_value-{self.cleaned_data["annotations_value"]}')
593
+ if self.cleaned_data['date_format']:
594
+ attributes.append(f'date_format-{self.cleaned_data["date_format"]}')
595
+
596
+ def save_currency_fields(self, attributes):
597
+ alignment = self.cleaned_data.get('alignment')
598
+ attributes.append(f'alignment-{alignment}')
599
+ if 'annotations_type' in self.cleaned_data and int(self.cleaned_data['annotations_type']) != 0:
600
+ attributes.append(f'annotations_type-{self.cleaned_data["annotations_type"]}')
601
+ elif 'append_annotation_query' in self.cleaned_data and self.cleaned_data['append_annotation_query']:
602
+ attributes.append('append_annotation_query-1')
603
+ if self.cleaned_data['annotation_column_id']:
604
+ b64_annotation_column_id = encode_attribute(self.cleaned_data['annotation_column_id'])
605
+ attributes.append(f'annotation_column_id-{b64_annotation_column_id}')
606
+ if self.cleaned_data['show_table_totals']:
607
+ attributes.append('show_totals-1')
608
+ self.save_filter(attributes=attributes)
609
+
610
+ def save_filter(self, attributes):
611
+ if self.cleaned_data['has_filter']:
612
+ attributes.append('has_filter-1')
613
+ if self.cleaned_data['filter']:
614
+ b64_filter = encode_attribute(self.cleaned_data['filter'])
615
+ attributes.append(f'filter-{b64_filter}')
616
+ if self.cleaned_data['multiple_columns']:
617
+ attributes.append('multiple_columns-1')
618
+ attributes.append(f'multiple_column_field-{self.cleaned_data["multiple_column_field"]}')
619
+
620
+ def save_link_fields(self, attributes):
621
+ if self.cleaned_data['link_css']:
622
+ b64_link_css = encode_attribute(self.cleaned_data['link_css'])
623
+ attributes.append(f'link_css-{b64_link_css}')
624
+ if self.cleaned_data['link_html']:
625
+ b64_link_html = encode_attribute(self.cleaned_data['link_html'])
626
+ attributes.append(f'link_html-{b64_link_html}')
627
+ if self.cleaned_data['is_icon'] and self.cleaned_data['is_icon']:
628
+ attributes.append('is_icon-1')
629
+
630
+ def save_reverse_foreign_key_str_fields(self, attributes):
631
+ if int(self.cleaned_data['delimiter_type']) != 0:
632
+ attributes.append(f'delimiter_type-{self.cleaned_data["delimiter_type"]}')
633
+ if self.cleaned_data['has_filter']:
634
+ attributes.append('has_filter-1')
635
+ if self.cleaned_data['filter']:
636
+ b64_filter = encode_attribute(self.cleaned_data['filter'])
637
+ attributes.append(f'filter-{b64_filter}')
638
+
639
+ def save_reverse_foreign_key_bool_fields(self, attributes):
640
+ if int(self.cleaned_data['annotations_type']) != 0:
641
+ attributes.append(f'annotations_type-{self.cleaned_data["annotations_type"]}')
642
+ if self.cleaned_data['has_filter']:
643
+ attributes.append('has_filter-1')
644
+ if self.cleaned_data['filter']:
645
+ b64_filter = encode_attribute(self.cleaned_data['filter'])
646
+ attributes.append(f'filter-{b64_filter}')
647
+
648
+ def save_reverse_foreign_key_choice_fields(self, attributes):
649
+ if int(self.cleaned_data['delimiter_type']) != 0:
650
+ attributes.append(f'delimiter_type-{self.cleaned_data["delimiter_type"]}')
651
+ if self.cleaned_data['has_filter']:
652
+ attributes.append('has_filter-1')
653
+ if self.cleaned_data['filter']:
654
+ b64_filter = encode_attribute(self.cleaned_data['filter'])
655
+ attributes.append(f'filter-{b64_filter}')
656
+
657
+ def save_reverse_foreign_key_date_fields(self, attributes):
658
+ if int(self.cleaned_data['annotations_type']) != 0:
659
+ attributes.append(f'annotations_type-{self.cleaned_data["annotations_type"]}')
660
+ if int(self.cleaned_data['delimiter_type']) != 0:
661
+ attributes.append(f'delimiter_type-{self.cleaned_data["delimiter_type"]}')
662
+ if self.cleaned_data['date_format']:
663
+ attributes.append(f'date_format-{self.cleaned_data["date_format"]}')
664
+ if self.cleaned_data['has_filter']:
665
+ attributes.append('has_filter-1')
666
+ if self.cleaned_data['filter']:
667
+ b64_filter = encode_attribute(self.cleaned_data['filter'])
668
+ attributes.append(f'filter-{b64_filter}')
669
+
670
+ def save_annotations_fields(self, attributes):
671
+ if self.cleaned_data['show_table_totals']:
672
+ attributes.append('show_totals-1')
673
+
674
+ def get_additional_attributes(self):
675
+ attributes = []
676
+ data = json.loads(base64.b64decode(self.slug['data']))
677
+ self.get_report_type_details()
678
+
679
+ if self.cleaned_data['display_heading']:
680
+ attributes.append('display_heading-1')
681
+ else:
682
+ attributes.append('display_heading-0')
683
+
684
+ if self.django_field is not None and isinstance(self.django_field, DATE_FIELDS):
685
+ self.save_date_fields(attributes=attributes)
686
+ elif self.django_field is not None and isinstance(self.django_field, NUMBER_FIELDS):
687
+ self.save_number_fields(attributes=attributes)
688
+ elif isinstance(self.col_type_override, CURRENCY_COLUMNS):
689
+ self.save_currency_fields(attributes=attributes)
690
+ elif isinstance(self.col_type_override, LINK_COLUMNS):
691
+ self.save_link_fields(attributes=attributes)
692
+ elif isinstance(self.col_type_override, REVERSE_FOREIGN_KEY_STR_COLUMNS):
693
+ self.save_reverse_foreign_key_str_fields(attributes=attributes)
694
+ elif isinstance(self.col_type_override, REVERSE_FOREIGN_KEY_BOOL_COLUMNS):
695
+ self.save_reverse_foreign_key_bool_fields(attributes=attributes)
696
+ elif isinstance(self.col_type_override, REVERSE_FOREIGN_KEY_CHOICE_COLUMNS):
697
+ self.save_reverse_foreign_key_choice_fields(attributes=attributes)
698
+ elif isinstance(self.col_type_override, REVERSE_FOREIGN_KEY_DATE_COLUMNS):
699
+ self.save_reverse_foreign_key_date_fields(attributes=attributes)
700
+ elif self.col_type_override.annotations is not None:
701
+ self.save_annotations_fields(attributes=attributes)
702
+ elif self.is_mathematical_field(data=data):
703
+ self.save_mathematical_fields(data=data, attributes=attributes)
704
+ else:
705
+ if self.cleaned_data['annotation_label'] and self.cleaned_data['annotation_label']:
706
+ attributes.append('annotation_label-1')
707
+
708
+ if attributes:
709
+ return '-'.join(attributes)
710
+ return None
711
+
712
+
713
+ class TableFieldModal(QueryBuilderModalBaseMixin, FormModal):
714
+ form_class = TableFieldForm
715
+ size = 'xl'
716
+ template_name = 'advanced_report_builder/datatables/fields/modal.html'
717
+ no_header_x = True
718
+ helper_class = HorizontalNoEnterHelper
719
+ update_selection_command = 'update_selection'
720
+
721
+ @property
722
+ def modal_title(self):
723
+ data = json.loads(base64.b64decode(self.slug['data']))
724
+ return f'Edit {data["title"]}'
725
+
726
+ def form_valid(self, form):
727
+ selector = self.slug['selector']
728
+
729
+ _attr = form.get_additional_attributes()
730
+ self.add_command(
731
+ {
732
+ 'function': 'set_attr',
733
+ 'selector': f'#{selector}',
734
+ 'attr': 'data-attr',
735
+ 'val': _attr,
736
+ }
737
+ )
738
+
739
+ self.add_command(
740
+ {
741
+ 'function': 'html',
742
+ 'selector': f'#{selector} span',
743
+ 'html': form.cleaned_data['title'],
744
+ }
745
+ )
746
+ self.add_command({'function': self.update_selection_command})
747
+ return self.command_response('close')
748
+
749
+ def form_setup(self, form, *_args, **_kwargs):
750
+ data = json.loads(base64.b64decode(self.slug['data']))
751
+ report_builder_class, base_model = self.get_report_builder_class(report_type_id=self.slug['report_type_id'])
752
+ django_field, col_type_override, _, _ = self.get_field_details(
753
+ base_model=base_model,
754
+ field=data['field'],
755
+ report_builder_class=report_builder_class,
756
+ )
757
+ has_existing_annotations = col_type_override is not None and col_type_override.annotations is not None
758
+
759
+ if django_field is not None and isinstance(django_field, NUMBER_FIELDS):
760
+ return self.layout_number_field(form=form, has_existing_annotations=has_existing_annotations)
761
+ elif isinstance(col_type_override, CURRENCY_COLUMNS):
762
+ return self.layout_currency_field(form=form, has_existing_annotations=has_existing_annotations)
763
+
764
+ elif isinstance(col_type_override, LINK_COLUMNS):
765
+ return self.layout_link_field()
766
+ elif isinstance(col_type_override, REVERSE_FOREIGN_KEY_STR_COLUMNS):
767
+ return self.layout_reverse_foreign_key_str_field(form=form, col_type_override=col_type_override)
768
+
769
+ elif isinstance(col_type_override, REVERSE_FOREIGN_KEY_BOOL_COLUMNS):
770
+ return self.layout_reverse_foreign_key_bool_field(form=form, col_type_override=col_type_override)
771
+
772
+ elif isinstance(col_type_override, REVERSE_FOREIGN_KEY_CHOICE_COLUMNS):
773
+ return self.layout_reverse_foreign_key_choice_field(form=form, col_type_override=col_type_override)
774
+
775
+ elif isinstance(col_type_override, REVERSE_FOREIGN_KEY_DATE_COLUMNS):
776
+ self.layout_reverse_foreign_key_date_field(form=form, col_type_override=col_type_override)
777
+
778
+ return None
779
+
780
+ def layout_number_field(self, form, has_existing_annotations):
781
+ if has_existing_annotations:
782
+ annotations_type_field = 'append_annotation_query'
783
+ form.add_trigger(
784
+ 'append_annotation_query',
785
+ 'onchange',
786
+ [
787
+ {
788
+ 'selector': '#annotations_fields_div',
789
+ 'values': {'checked': 'show'},
790
+ 'default': 'hide',
791
+ }
792
+ ],
793
+ )
794
+ else:
795
+ annotations_type_field = 'annotations_type'
796
+ form.add_trigger(
797
+ 'annotations_type',
798
+ 'onchange',
799
+ [
800
+ {
801
+ 'selector': '#annotations_fields_div',
802
+ 'values': {'0': 'hide'},
803
+ 'default': 'show',
804
+ }
805
+ ],
806
+ )
807
+
808
+ form.add_trigger(
809
+ 'has_filter',
810
+ 'onchange',
811
+ [
812
+ {
813
+ 'selector': '#filter_fields_div',
814
+ 'values': {'checked': 'show'},
815
+ 'default': 'hide',
816
+ }
817
+ ],
818
+ )
819
+
820
+ form.add_trigger(
821
+ 'multiple_columns',
822
+ 'onchange',
823
+ [
824
+ {
825
+ 'selector': '#multiple_columns_fields_div',
826
+ 'values': {'checked': 'show'},
827
+ 'default': 'hide',
828
+ },
829
+ ],
830
+ )
831
+
832
+ return [
833
+ 'title',
834
+ 'display_heading',
835
+ 'show_table_totals',
836
+ 'decimal_places',
837
+ 'alignment',
838
+ annotations_type_field,
839
+ Div(
840
+ 'annotation_column_id',
841
+ FieldEx(
842
+ 'has_filter',
843
+ template='django_modals/fields/label_checkbox.html',
844
+ field_class='col-6 input-group-sm',
845
+ ),
846
+ Div(
847
+ FieldEx(
848
+ 'filter',
849
+ template='advanced_report_builder/datatables/fields/single_query_builder.html',
850
+ ),
851
+ css_id='filter_fields_div',
852
+ ),
853
+ FieldEx(
854
+ 'multiple_columns',
855
+ template='django_modals/fields/label_checkbox.html',
856
+ field_class='col-6 input-group-sm',
857
+ ),
858
+ Div(
859
+ FieldEx('multiple_column_field'),
860
+ css_id='multiple_columns_fields_div',
861
+ ),
862
+ css_id='annotations_fields_div',
863
+ ),
864
+ ]
865
+
866
+ def layout_currency_field(self, form, has_existing_annotations):
867
+ if has_existing_annotations:
868
+ annotations_type_field = 'append_annotation_query'
869
+ form.add_trigger(
870
+ 'append_annotation_query',
871
+ 'onchange',
872
+ [
873
+ {
874
+ 'selector': '#annotations_fields_div',
875
+ 'values': {'checked': 'show'},
876
+ 'default': 'hide',
877
+ }
878
+ ],
879
+ )
880
+
881
+ else:
882
+ annotations_type_field = 'annotations_type'
883
+ form.add_trigger(
884
+ 'annotations_type',
885
+ 'onchange',
886
+ [
887
+ {
888
+ 'selector': '#annotations_fields_div',
889
+ 'values': {'0': 'hide'},
890
+ 'default': 'show',
891
+ }
892
+ ],
893
+ )
894
+
895
+ form.add_trigger(
896
+ 'has_filter',
897
+ 'onchange',
898
+ [
899
+ {
900
+ 'selector': '#filter_fields_div',
901
+ 'values': {'checked': 'show'},
902
+ 'default': 'hide',
903
+ }
904
+ ],
905
+ )
906
+
907
+ form.add_trigger(
908
+ 'multiple_columns',
909
+ 'onchange',
910
+ [
911
+ {
912
+ 'selector': '#multiple_columns_fields_div',
913
+ 'values': {'checked': 'show'},
914
+ 'default': 'hide',
915
+ },
916
+ ],
917
+ )
918
+ return [
919
+ 'title',
920
+ 'display_heading',
921
+ 'show_table_totals',
922
+ 'alignment',
923
+ annotations_type_field,
924
+ Div(
925
+ 'annotation_column_id',
926
+ FieldEx(
927
+ 'has_filter',
928
+ template='django_modals/fields/label_checkbox.html',
929
+ field_class='col-6 input-group-sm',
930
+ ),
931
+ Div(
932
+ FieldEx(
933
+ 'filter',
934
+ template='advanced_report_builder/datatables/fields/single_query_builder.html',
935
+ ),
936
+ css_id='filter_fields_div',
937
+ ),
938
+ FieldEx(
939
+ 'multiple_columns',
940
+ template='django_modals/fields/label_checkbox.html',
941
+ field_class='col-6 input-group-sm',
942
+ ),
943
+ Div(
944
+ FieldEx('multiple_column_field'),
945
+ css_id='multiple_columns_fields_div',
946
+ ),
947
+ css_id='annotations_fields_div',
948
+ ),
949
+ ]
950
+
951
+ def layout_link_field(self):
952
+ return ['title', 'display_heading', 'link_css', 'link_html', 'is_icon']
953
+
954
+ def layout_reverse_foreign_key_str_field(self, form, col_type_override):
955
+ form.add_trigger(
956
+ 'has_filter',
957
+ 'onchange',
958
+ [
959
+ {
960
+ 'selector': '#filter_fields_div',
961
+ 'values': {'checked': 'show'},
962
+ 'default': 'hide',
963
+ }
964
+ ],
965
+ )
966
+
967
+ return [
968
+ 'title',
969
+ 'display_heading',
970
+ 'delimiter_type',
971
+ FieldEx(
972
+ 'has_filter',
973
+ template='django_modals/fields/label_checkbox.html',
974
+ field_class='col-6 input-group-sm',
975
+ ),
976
+ Div(
977
+ FieldEx(
978
+ 'filter',
979
+ template='advanced_report_builder/datatables/fields/single_query_builder.html',
980
+ extra_context={'report_builder_class_name': col_type_override.report_builder_class_name},
981
+ ),
982
+ css_id='filter_fields_div',
983
+ ),
984
+ ]
985
+
986
+ def layout_reverse_foreign_key_bool_field(self, form, col_type_override):
987
+ form.add_trigger(
988
+ 'has_filter',
989
+ 'onchange',
990
+ [
991
+ {
992
+ 'selector': '#filter_fields_div',
993
+ 'values': {'checked': 'show'},
994
+ 'default': 'hide',
995
+ }
996
+ ],
997
+ )
998
+
999
+ return [
1000
+ 'title',
1001
+ 'display_heading',
1002
+ 'annotations_type',
1003
+ FieldEx(
1004
+ 'has_filter',
1005
+ template='django_modals/fields/label_checkbox.html',
1006
+ field_class='col-6 input-group-sm',
1007
+ ),
1008
+ Div(
1009
+ FieldEx(
1010
+ 'filter',
1011
+ template='advanced_report_builder/datatables/fields/single_query_builder.html',
1012
+ extra_context={'report_builder_class_name': col_type_override.report_builder_class_name},
1013
+ ),
1014
+ css_id='filter_fields_div',
1015
+ ),
1016
+ ]
1017
+
1018
+ def layout_reverse_foreign_key_choice_field(self, form, col_type_override):
1019
+ form.add_trigger(
1020
+ 'has_filter',
1021
+ 'onchange',
1022
+ [
1023
+ {
1024
+ 'selector': '#filter_fields_div',
1025
+ 'values': {'checked': 'show'},
1026
+ 'default': 'hide',
1027
+ }
1028
+ ],
1029
+ )
1030
+
1031
+ return [
1032
+ 'title',
1033
+ 'display_heading',
1034
+ 'delimiter_type',
1035
+ FieldEx(
1036
+ 'has_filter',
1037
+ template='django_modals/fields/label_checkbox.html',
1038
+ field_class='col-6 input-group-sm',
1039
+ ),
1040
+ Div(
1041
+ FieldEx(
1042
+ 'filter',
1043
+ template='advanced_report_builder/datatables/fields/single_query_builder.html',
1044
+ extra_context={'report_builder_class_name': col_type_override.report_builder_class_name},
1045
+ ),
1046
+ css_id='filter_fields_div',
1047
+ ),
1048
+ ]
1049
+
1050
+ def layout_reverse_foreign_key_date_field(self, form, col_type_override):
1051
+ form.add_trigger(
1052
+ 'has_filter',
1053
+ 'onchange',
1054
+ [
1055
+ {
1056
+ 'selector': '#filter_fields_div',
1057
+ 'values': {'checked': 'show'},
1058
+ 'default': 'hide',
1059
+ }
1060
+ ],
1061
+ )
1062
+
1063
+ form.add_trigger(
1064
+ 'annotations_type',
1065
+ 'onchange',
1066
+ [
1067
+ {
1068
+ 'selector': '#div_id_delimiter_type',
1069
+ 'values': {f'{REVERSE_FOREIGN_KEY_ANNOTATION_DATE_ARRAY}': 'show'},
1070
+ 'default': 'hide',
1071
+ },
1072
+ ],
1073
+ )
1074
+
1075
+ return [
1076
+ 'title',
1077
+ 'display_heading',
1078
+ 'date_format',
1079
+ 'annotations_type',
1080
+ 'delimiter_type',
1081
+ FieldEx(
1082
+ 'has_filter',
1083
+ template='django_modals/fields/label_checkbox.html',
1084
+ field_class='col-6 input-group-sm',
1085
+ ),
1086
+ Div(
1087
+ FieldEx(
1088
+ 'filter',
1089
+ template='advanced_report_builder/datatables/fields/single_query_builder.html',
1090
+ extra_context={'report_builder_class_name': col_type_override.report_builder_class_name},
1091
+ ),
1092
+ css_id='filter_fields_div',
1093
+ ),
1094
+ ]
1095
+
1096
+ def ajax_get_query_builder_fields(self, **kwargs):
1097
+ field_auto_id = kwargs['field_auto_id']
1098
+ report_builder_class_name = kwargs.get('report_builder_class_name')
1099
+
1100
+ if report_builder_class_name != '' and report_builder_class_name is not None:
1101
+ app_label, model, report_builder_fields_str = report_builder_class_name.split('.')
1102
+ new_model = apps.get_model(app_label, model)
1103
+ report_builder_class = get_report_builder_class(model=new_model, class_name=report_builder_fields_str)
1104
+ query_builder_filters = []
1105
+ self._get_query_builder_fields(
1106
+ base_model=new_model,
1107
+ query_builder_filters=query_builder_filters,
1108
+ report_builder_class=report_builder_class,
1109
+ )
1110
+ else:
1111
+ report_type_id = self.slug['report_type_id']
1112
+ query_builder_filters = self.get_query_builder_report_type_field(report_type_id=report_type_id)
1113
+ return self.command_response(f'query_builder_{field_auto_id}', data=json.dumps(query_builder_filters))
1114
+
1115
+
1116
+ class TablePivotForm(ChartBaseFieldForm):
1117
+ cancel_class = 'btn-secondary modal-cancel'
1118
+
1119
+ def setup_modal(self, *args, **kwargs):
1120
+ data = json.loads(base64.b64decode(self.slug['data']))
1121
+ self.fields['title'] = CharField(initial=data['title'])
1122
+ super().setup_modal(*args, **kwargs)
1123
+
1124
+ def cancel_button(self, css_class=cancel_class, **kwargs):
1125
+ commands = [{'function': 'close'}]
1126
+ return self.button('Cancel', commands, css_class, **kwargs)
1127
+
1128
+
1129
+ class TablePivotModal(QueryBuilderModalBaseMixin, FormModal):
1130
+ form_class = TablePivotForm
1131
+ size = 'xl'
1132
+ no_header_x = True
1133
+
1134
+ @property
1135
+ def modal_title(self):
1136
+ data = json.loads(base64.b64decode(self.slug['data']))
1137
+ return f'Edit {data["title"]}'
1138
+
1139
+ def form_valid(self, form):
1140
+ selector = self.slug['selector']
1141
+
1142
+ self.add_command(
1143
+ {
1144
+ 'function': 'html',
1145
+ 'selector': f'#{selector} span',
1146
+ 'html': form.cleaned_data['title'],
1147
+ }
1148
+ )
1149
+
1150
+ self.add_command({'function': 'update_pivot_selection'})
1151
+ return self.command_response('close')