customeranalytics 0.1__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 (254) hide show
  1. customeranalytics/__init__.py +319 -0
  2. customeranalytics/configs.py +480 -0
  3. customeranalytics/data_storage_configurations/__init__.py +245 -0
  4. customeranalytics/data_storage_configurations/data_access.py +165 -0
  5. customeranalytics/data_storage_configurations/data_works_pipeline.py +207 -0
  6. customeranalytics/data_storage_configurations/es_create_index.py +544 -0
  7. customeranalytics/data_storage_configurations/logger.py +36 -0
  8. customeranalytics/data_storage_configurations/query_es.py +157 -0
  9. customeranalytics/data_storage_configurations/reports.py +684 -0
  10. customeranalytics/data_storage_configurations/schedule_data_integration.py +355 -0
  11. customeranalytics/docs/queries.yaml +245 -0
  12. customeranalytics/docs/web_configs.yaml +2 -0
  13. customeranalytics/exploratory_analysis/__init__.py +109 -0
  14. customeranalytics/exploratory_analysis/churn.py +232 -0
  15. customeranalytics/exploratory_analysis/cohorts.py +535 -0
  16. customeranalytics/exploratory_analysis/descriptive_statistics.py +470 -0
  17. customeranalytics/exploratory_analysis/funnels.py +407 -0
  18. customeranalytics/exploratory_analysis/product_analytics.py +340 -0
  19. customeranalytics/exploratory_analysis/promotion_analytics.py +299 -0
  20. customeranalytics/exploratory_analysis/rfm.py +202 -0
  21. customeranalytics/exploratory_analysis/sample_data/sample_data_avg_order_count_per_promo_per_cust.csv +99 -0
  22. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_1_search.csv +2 -0
  23. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_2_search.csv +46 -0
  24. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_3_search.csv +2 -0
  25. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_4_search.csv +2 -0
  26. customeranalytics/exploratory_analysis/sample_data/sample_data_churn.csv +2 -0
  27. customeranalytics/exploratory_analysis/sample_data/sample_data_churn_weekly.csv +10 -0
  28. customeranalytics/exploratory_analysis/sample_data/sample_data_client_feature_predicted.csv +1590 -0
  29. customeranalytics/exploratory_analysis/sample_data/sample_data_client_kpis.csv +7060 -0
  30. customeranalytics/exploratory_analysis/sample_data/sample_data_clvrfm_anomaly.csv +561 -0
  31. customeranalytics/exploratory_analysis/sample_data/sample_data_clvsegments_amount.csv +8 -0
  32. customeranalytics/exploratory_analysis/sample_data/sample_data_customer_journey.csv +18 -0
  33. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_clv.csv +103 -0
  34. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_downloads.csv +68 -0
  35. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_from_1_to_2.csv +66 -0
  36. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_from_2_to_3.csv +64 -0
  37. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_from_3_to_4.csv +55 -0
  38. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_dimension_values.csv +199 -0
  39. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_funnel.csv +36 -0
  40. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_funnel_downloads.csv +68 -0
  41. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_inorganic_ratio.csv +6070 -0
  42. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_orders.csv +57 -0
  43. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_organic_orders.csv +64 -0
  44. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_products_of_sales.csv +12574 -0
  45. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_promotion_discount.csv +64 -0
  46. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_promotion_revenue.csv +6070 -0
  47. customeranalytics/exploratory_analysis/sample_data/sample_data_dcohort_anomaly.csv +6 -0
  48. customeranalytics/exploratory_analysis/sample_data/sample_data_dcohort_anomaly_2.csv +118 -0
  49. customeranalytics/exploratory_analysis/sample_data/sample_data_deliver.csv +47 -0
  50. customeranalytics/exploratory_analysis/sample_data/sample_data_deliver_kpis.csv +2 -0
  51. customeranalytics/exploratory_analysis/sample_data/sample_data_deliver_weekday_hour.csv +25 -0
  52. customeranalytics/exploratory_analysis/sample_data/sample_data_dfunnel_anomaly.csv +118 -0
  53. customeranalytics/exploratory_analysis/sample_data/sample_data_dimension_kpis.csv +199 -0
  54. customeranalytics/exploratory_analysis/sample_data/sample_data_dorders_anomaly.csv +85 -0
  55. customeranalytics/exploratory_analysis/sample_data/sample_data_frequency_clusters.csv +6 -0
  56. customeranalytics/exploratory_analysis/sample_data/sample_data_frequency_recency.csv +3740 -0
  57. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_funnel.csv +25 -0
  58. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_funnel_downloads.csv +25 -0
  59. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_inorganic_ratio.csv +2353 -0
  60. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_orders.csv +25 -0
  61. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_organic_orders.csv +2353 -0
  62. customeranalytics/exploratory_analysis/sample_data/sample_data_inorganic_orders_per_promotion_per_day.csv +6070 -0
  63. customeranalytics/exploratory_analysis/sample_data/sample_data_kpis.csv +2 -0
  64. customeranalytics/exploratory_analysis/sample_data/sample_data_monetary_clusters.csv +6 -0
  65. customeranalytics/exploratory_analysis/sample_data/sample_data_monetary_frequency.csv +3740 -0
  66. customeranalytics/exploratory_analysis/sample_data/sample_data_monthly_funnel.csv +5 -0
  67. customeranalytics/exploratory_analysis/sample_data/sample_data_monthly_funnel_downloads.csv +5 -0
  68. customeranalytics/exploratory_analysis/sample_data/sample_data_monthly_orders.csv +4 -0
  69. customeranalytics/exploratory_analysis/sample_data/sample_data_most_combined_products.csv +11 -0
  70. customeranalytics/exploratory_analysis/sample_data/sample_data_most_ordered_categories.csv +11 -0
  71. customeranalytics/exploratory_analysis/sample_data/sample_data_most_ordered_products.csv +11 -0
  72. customeranalytics/exploratory_analysis/sample_data/sample_data_order_and_payment_amount_differences.csv +91 -0
  73. customeranalytics/exploratory_analysis/sample_data/sample_data_prepare.csv +101 -0
  74. customeranalytics/exploratory_analysis/sample_data/sample_data_prepare_weekday_hour.csv +25 -0
  75. customeranalytics/exploratory_analysis/sample_data/sample_data_product_kpis.csv +201 -0
  76. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_amount_accept.csv +11 -0
  77. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_amount_reject.csv +7 -0
  78. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_orders_accept.csv +11 -0
  79. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_orders_reject.csv +11 -0
  80. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_comparison.csv +91 -0
  81. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_kpis.csv +99 -0
  82. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_number_of_customer.csv +99 -0
  83. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_amount_accept.csv +81 -0
  84. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_amount_reject.csv +11 -0
  85. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_orders_accept.csv +55 -0
  86. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_orders_reject.csv +37 -0
  87. customeranalytics/exploratory_analysis/sample_data/sample_data_purchase_amount_distribution.csv +22 -0
  88. customeranalytics/exploratory_analysis/sample_data/sample_data_recency_clusters.csv +6 -0
  89. customeranalytics/exploratory_analysis/sample_data/sample_data_recency_monetary.csv +3740 -0
  90. customeranalytics/exploratory_analysis/sample_data/sample_data_rfm.csv +2001 -0
  91. customeranalytics/exploratory_analysis/sample_data/sample_data_ride.csv +101 -0
  92. customeranalytics/exploratory_analysis/sample_data/sample_data_ride_weekday_hour.csv +25 -0
  93. customeranalytics/exploratory_analysis/sample_data/sample_data_segmentation.csv +11 -0
  94. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_daily_before_after_amount.csv +10 -0
  95. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_daily_before_after_orders.csv +9 -0
  96. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_monthly_before_after_amount.csv +10 -0
  97. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_monthly_before_after_orders.csv +11 -0
  98. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_weekly_before_after_amount.csv +10 -0
  99. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_weekly_before_after_orders.csv +10 -0
  100. customeranalytics/exploratory_analysis/sample_data/sample_data_user_counts_per_order_seq.csv +47 -0
  101. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_average_order_per_user.csv +13 -0
  102. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_average_payment_amount.csv +13 -0
  103. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_average_session_per_user.csv +13 -0
  104. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_downloads.csv +13 -0
  105. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_from_1_to_2.csv +13 -0
  106. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_from_2_to_3.csv +13 -0
  107. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_from_3_to_4.csv +12 -0
  108. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_funnel.csv +25 -0
  109. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_funnel_downloads.csv +25 -0
  110. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_orders.csv +10 -0
  111. customeranalytics/ml_process/__init__.py +64 -0
  112. customeranalytics/ml_process/ab_test.py +615 -0
  113. customeranalytics/ml_process/anomaly_detection.py +456 -0
  114. customeranalytics/ml_process/clv_prediction.py +301 -0
  115. customeranalytics/ml_process/customer_segmentation.py +354 -0
  116. customeranalytics/ml_process/delivery_analytics.py +754 -0
  117. customeranalytics/utils.py +186 -0
  118. customeranalytics/web/app/__init__.py +37 -0
  119. customeranalytics/web/app/base/__init__.py +9 -0
  120. customeranalytics/web/app/base/forms.py +16 -0
  121. customeranalytics/web/app/base/models.py +43 -0
  122. customeranalytics/web/app/base/routes.py +126 -0
  123. customeranalytics/web/app/base/static/assets/css/app.css +20 -0
  124. customeranalytics/web/app/base/static/assets/fonts/Inter-Black.woff +0 -0
  125. customeranalytics/web/app/base/static/assets/fonts/Inter-Black.woff2 +0 -0
  126. customeranalytics/web/app/base/static/assets/fonts/Inter-BlackItalic.woff +0 -0
  127. customeranalytics/web/app/base/static/assets/fonts/Inter-BlackItalic.woff2 +0 -0
  128. customeranalytics/web/app/base/static/assets/fonts/Inter-Bold.woff +0 -0
  129. customeranalytics/web/app/base/static/assets/fonts/Inter-Bold.woff2 +0 -0
  130. customeranalytics/web/app/base/static/assets/fonts/Inter-BoldItalic.woff +0 -0
  131. customeranalytics/web/app/base/static/assets/fonts/Inter-BoldItalic.woff2 +0 -0
  132. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBold.woff +0 -0
  133. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBold.woff2 +0 -0
  134. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBoldItalic.woff +0 -0
  135. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBoldItalic.woff2 +0 -0
  136. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLight-BETA.woff +0 -0
  137. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLight-BETA.woff2 +0 -0
  138. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLightItalic-BETA.woff +0 -0
  139. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLightItalic-BETA.woff2 +0 -0
  140. customeranalytics/web/app/base/static/assets/fonts/Inter-Italic.woff +0 -0
  141. customeranalytics/web/app/base/static/assets/fonts/Inter-Italic.woff2 +0 -0
  142. customeranalytics/web/app/base/static/assets/fonts/Inter-Light-BETA.woff +0 -0
  143. customeranalytics/web/app/base/static/assets/fonts/Inter-Light-BETA.woff2 +0 -0
  144. customeranalytics/web/app/base/static/assets/fonts/Inter-LightItalic-BETA.woff +0 -0
  145. customeranalytics/web/app/base/static/assets/fonts/Inter-LightItalic-BETA.woff2 +0 -0
  146. customeranalytics/web/app/base/static/assets/fonts/Inter-Medium.woff +0 -0
  147. customeranalytics/web/app/base/static/assets/fonts/Inter-Medium.woff2 +0 -0
  148. customeranalytics/web/app/base/static/assets/fonts/Inter-MediumItalic.woff +0 -0
  149. customeranalytics/web/app/base/static/assets/fonts/Inter-MediumItalic.woff2 +0 -0
  150. customeranalytics/web/app/base/static/assets/fonts/Inter-Regular.woff +0 -0
  151. customeranalytics/web/app/base/static/assets/fonts/Inter-Regular.woff2 +0 -0
  152. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBold.woff +0 -0
  153. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBold.woff2 +0 -0
  154. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBoldItalic.woff +0 -0
  155. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBoldItalic.woff2 +0 -0
  156. customeranalytics/web/app/base/static/assets/fonts/Inter-Thin-BETA.woff +0 -0
  157. customeranalytics/web/app/base/static/assets/fonts/Inter-Thin-BETA.woff2 +0 -0
  158. customeranalytics/web/app/base/static/assets/fonts/Inter-ThinItalic-BETA.woff +0 -0
  159. customeranalytics/web/app/base/static/assets/fonts/Inter-ThinItalic-BETA.woff2 +0 -0
  160. customeranalytics/web/app/base/static/assets/fonts/Inter-italic.var.woff2 +0 -0
  161. customeranalytics/web/app/base/static/assets/fonts/Inter-upright.var.woff2 +0 -0
  162. customeranalytics/web/app/base/static/assets/fonts/Inter.var.woff2 +0 -0
  163. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.eot +0 -0
  164. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.svg +3570 -0
  165. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.ttf +0 -0
  166. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.woff +0 -0
  167. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.woff2 +0 -0
  168. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.eot +0 -0
  169. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.svg +801 -0
  170. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.ttf +0 -0
  171. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.woff +0 -0
  172. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.woff2 +0 -0
  173. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.eot +0 -0
  174. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.svg +5028 -0
  175. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.ttf +0 -0
  176. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.woff +0 -0
  177. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.woff2 +0 -0
  178. customeranalytics/web/app/base/static/assets/img/avatars/avatar-1.png +0 -0
  179. customeranalytics/web/app/base/static/assets/img/avatars/avatar-2.png +0 -0
  180. customeranalytics/web/app/base/static/assets/img/avatars/avatar-3.png +0 -0
  181. customeranalytics/web/app/base/static/assets/img/avatars/avatar-4.png +0 -0
  182. customeranalytics/web/app/base/static/assets/img/avatars/avatar-5.png +0 -0
  183. customeranalytics/web/app/base/static/assets/img/avatars/info.jpeg +0 -0
  184. customeranalytics/web/app/base/static/assets/img/icons/customanality.png +0 -0
  185. customeranalytics/web/app/base/static/assets/img/icons/icon-48x48.png +0 -0
  186. customeranalytics/web/app/base/static/assets/js/app.js +2 -0
  187. customeranalytics/web/app/base/static/assets/js/app.js.LICENSE +566 -0
  188. customeranalytics/web/app/base/static/assets/js/app.js.LICENSE.txt +556 -0
  189. customeranalytics/web/app/base/static/assets/js/modules/bootstrap.js +15 -0
  190. customeranalytics/web/app/base/static/assets/js/modules/chartjs.js +4 -0
  191. customeranalytics/web/app/base/static/assets/js/modules/feather.js +8 -0
  192. customeranalytics/web/app/base/static/assets/js/modules/flatpickr.js +4 -0
  193. customeranalytics/web/app/base/static/assets/js/modules/moment.js +4 -0
  194. customeranalytics/web/app/base/static/assets/js/modules/sidebar.js +23 -0
  195. customeranalytics/web/app/base/static/assets/js/modules/theme.js +16 -0
  196. customeranalytics/web/app/base/templates/accounts/login.html +81 -0
  197. customeranalytics/web/app/base/templates/accounts/register.html +80 -0
  198. customeranalytics/web/app/base/templates/includes/footer.html +28 -0
  199. customeranalytics/web/app/base/templates/includes/navigation.html +51 -0
  200. customeranalytics/web/app/base/templates/includes/scripts.html +3 -0
  201. customeranalytics/web/app/base/templates/includes/sidebar.html +146 -0
  202. customeranalytics/web/app/base/templates/layouts/base-fullscreen.html +36 -0
  203. customeranalytics/web/app/base/templates/layouts/base.html +84 -0
  204. customeranalytics/web/app/base/util.py +30 -0
  205. customeranalytics/web/app/home/__init__.py +9 -0
  206. customeranalytics/web/app/home/forms.py +1039 -0
  207. customeranalytics/web/app/home/models.py +438 -0
  208. customeranalytics/web/app/home/profiles.py +310 -0
  209. customeranalytics/web/app/home/routes.py +386 -0
  210. customeranalytics/web/app/home/search.py +288 -0
  211. customeranalytics/web/app/home/static/assets/img/avatars/avatar-1.png +0 -0
  212. customeranalytics/web/app/home/static/assets/img/avatars/avatar-2.png +0 -0
  213. customeranalytics/web/app/home/static/assets/img/avatars/avatar-3.png +0 -0
  214. customeranalytics/web/app/home/static/assets/img/avatars/avatar-4.png +0 -0
  215. customeranalytics/web/app/home/static/assets/img/avatars/avatar-5.png +0 -0
  216. customeranalytics/web/app/home/static/assets/img/icons/customanality.png +0 -0
  217. customeranalytics/web/app/home/static/assets/img/icons/icon-48x48.png +0 -0
  218. customeranalytics/web/app/home/templates/abtest-product.html +280 -0
  219. customeranalytics/web/app/home/templates/abtest-promotion.html +362 -0
  220. customeranalytics/web/app/home/templates/abtest-segments.html +298 -0
  221. customeranalytics/web/app/home/templates/add-data-delivery.html +184 -0
  222. customeranalytics/web/app/home/templates/add-data-product.html +177 -0
  223. customeranalytics/web/app/home/templates/add-data-purchase.html +392 -0
  224. customeranalytics/web/app/home/templates/anomaly.html +261 -0
  225. customeranalytics/web/app/home/templates/clv.html +211 -0
  226. customeranalytics/web/app/home/templates/cohorts.html +308 -0
  227. customeranalytics/web/app/home/templates/customer-segmentation.html +308 -0
  228. customeranalytics/web/app/home/templates/data-es.html +152 -0
  229. customeranalytics/web/app/home/templates/data-execute.html +397 -0
  230. customeranalytics/web/app/home/templates/delivery.html +404 -0
  231. customeranalytics/web/app/home/templates/funnel-customer.html +240 -0
  232. customeranalytics/web/app/home/templates/funnel-session.html +236 -0
  233. customeranalytics/web/app/home/templates/index.html +524 -0
  234. customeranalytics/web/app/home/templates/index2.html +515 -0
  235. customeranalytics/web/app/home/templates/page-403.html +46 -0
  236. customeranalytics/web/app/home/templates/page-404.html +45 -0
  237. customeranalytics/web/app/home/templates/page-500.html +45 -0
  238. customeranalytics/web/app/home/templates/pages-blank.html +33 -0
  239. customeranalytics/web/app/home/templates/pages-sign-in.html +67 -0
  240. customeranalytics/web/app/home/templates/pages-sign-up.html +61 -0
  241. customeranalytics/web/app/home/templates/product.html +203 -0
  242. customeranalytics/web/app/home/templates/profile.html +1009 -0
  243. customeranalytics/web/app/home/templates/rfm.html +254 -0
  244. customeranalytics/web/app/home/templates/search.html +167 -0
  245. customeranalytics/web/app/home/templates/settings.html +205 -0
  246. customeranalytics/web/app/home/templates/stats-desc.html +230 -0
  247. customeranalytics/web/app/home/templates/stats-purchase.html +221 -0
  248. customeranalytics/web/config.py +30 -0
  249. customeranalytics/web/db.sqlite3 +0 -0
  250. customeranalytics/web/run.py +30 -0
  251. customeranalytics-0.1.dist-info/METADATA +1102 -0
  252. customeranalytics-0.1.dist-info/RECORD +254 -0
  253. customeranalytics-0.1.dist-info/WHEEL +4 -0
  254. customeranalytics-0.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,288 @@
1
+ import sys, os, inspect, logging
2
+ currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
3
+ parentdir = os.path.dirname(currentdir)
4
+ sys.path.insert(0, parentdir)
5
+
6
+ from sqlalchemy import create_engine, MetaData
7
+ from os.path import join
8
+
9
+ try: from utils import convert_dt_to_day_str, abspath_for_sample_data, convert_to_date
10
+ except: from customeranalytics.utils import convert_dt_to_day_str, abspath_for_sample_data
11
+
12
+ try: from configs import query_path, default_es_port, default_es_host, default_message, schedule_columns, data_types_for_search
13
+ except: from customeranalytics.configs import query_path, default_es_port, default_es_host, default_message, schedule_columns, data_types_for_search
14
+
15
+
16
+ import pandas as pd
17
+ from datetime import datetime
18
+ from flask_login import current_user
19
+
20
+ try: from data_storage_configurations import connection_check, create_index, check_elasticsearch, QueryES
21
+ except: from customeranalytics.data_storage_configurations import connection_check, create_index, check_elasticsearch, QueryES
22
+
23
+ try: from exploratory_analysis import ea_configs
24
+ except: from customeranalytics.exploratory_analysis import ea_configs
25
+
26
+ try: from ml_process import ml_configs
27
+ except: from customeranalytics.ml_process import ml_configs
28
+
29
+ from .forms import RealData
30
+
31
+
32
+ engine = create_engine('sqlite://///' + join(abspath_for_sample_data(), "web", 'db.sqlite3'),
33
+ connect_args={'check_same_thread': False})
34
+ metadata = MetaData()
35
+ con = engine.connect()
36
+
37
+
38
+ reports = RealData()
39
+
40
+
41
+ def ngrams_2(word):
42
+ """
43
+ word with string form is converted to 2 ngrams
44
+ Example;
45
+ 'test'; (t, e), (e, s), (s, t)
46
+ :param word:
47
+ """
48
+ ngrams = []
49
+ for i in range(len(word)):
50
+ if word[i] != word[-1]:
51
+ ngrams.append((word[i], word[i+1]))
52
+ return ngrams
53
+
54
+
55
+ class Search:
56
+ def __init__(self):
57
+ """
58
+ There are 4 types of search;
59
+ - product
60
+ - client
61
+ - promotion
62
+ - dimension
63
+
64
+ Each type of search represents an individual dashboard with results.
65
+ When expected search value is typed in the search bar;
66
+ 1. Results are checked individually for each type of search.
67
+ a. create ngrams of search value
68
+ b. create ngrams for each list of search types.
69
+ c. calculate the similarity between ngrams of search value and ngrams for each list of search types.
70
+ d. remove score = 0.
71
+ e. find the top score and assign it as a detected search result.
72
+ 2. Create a temporary .csv file at temporary_folder_path that is assigned by the user.
73
+ These are 3 charts of .csv files;
74
+ a. chart_2_search.csv is positioned at right top,
75
+ b. chart_3_search.csv is positioned at left bottom,
76
+ c. chart_4_search.csv is positioned at right bottom,
77
+ There are 4 KPIs with 1 .csv file;
78
+ a. chart_1_search.csv is positioned ad the left top. These KPIs will be changed
79
+
80
+ 3. Each chart of data is created at temporary file
81
+ (chart_1_search.csv, .., chart_4_search.csv) will be removed after the dashboard is shown at the user interface.
82
+ 4. Each search type has individual charts and KPIs.
83
+ So, each creation of charts and KPIs .csv files must be applied individually.
84
+
85
+ """
86
+ self.temporary_path = None
87
+ self.search_metrics = ['promotion', 'product', 'client', 'dimension']
88
+ self.query_body = {"query": {}}
89
+ self.intersect_count = lambda x, y: len(set(x) & set(y))
90
+ self.user_data = pd.DataFrame()
91
+ # product, promotion, dimension, client search charts and KPIs
92
+ self.product_kpis = ['Average Product Sold Per Customer',
93
+ 'Total Product Revenue',
94
+ 'Total Product Discount', 'Number of Customer who purchase the Product']
95
+ self.promotion_kpis = ['Average Daily Order with Promotion',
96
+ 'Average Daily Revenue with Promotion',
97
+ 'Average Daily Discount with Promotion',
98
+ 'Unique Client Count who used the Promotion']
99
+ self.product_charts = ["Total Number of Products per Day",
100
+ "Before - After Time Periods Customers' Total Purchase Count Test (Test Accepted!)",
101
+ "Before - After Time Periods Customers' Total Purchase Count Test (Test Rejected!)"]
102
+ self.promotion_charts = ["Daily Order Count with Promotion",
103
+ "Daily Revenue with Promotion",
104
+ "Daily Discount with Promotion"]
105
+ self.client_charts = ["Possible Future Purchase of the Customer"]
106
+ self.client_kpis = ["Total Order Count of the Customer",
107
+ "Order Frequency of the Customer (hr)",
108
+ "Total Hour Count from the last time the customer purchased (recency)",
109
+ "Average Payment Amount of the Customer"]
110
+ self.dimension_charts = ["Daily Total Order Count With Dimension",
111
+ "Daily Total Purchase Amount With Dimension",
112
+ "Daily Total Unique Client Count With Dimension"]
113
+ self.dimension_kpis = ["Total Order Count", "Total Purchase Amount",
114
+ "Total Unique Client Count", "Total Discount Amount"]
115
+
116
+ self.data_types = data_types_for_search
117
+ self.query_column = {'product': "products", "client": "client",
118
+ "promotion": "promotion_id", "dimension": "dimension"}
119
+
120
+ def get_temporary_path(self):
121
+ """
122
+ query for fetching the temporary folder path
123
+ """
124
+ try:
125
+ es_con = pd.read_sql(""" SELECT * FROM es_connection """, con).to_dict('records')[0]
126
+ self.temporary_path = es_con['directory']
127
+ except:
128
+ connection, message = False, """
129
+ ElasticSearch Connection Failed Check ES port/host or temporary path or Add new ElasticSearch connection
130
+ """
131
+ self.temporary_path = None
132
+
133
+ def get_search_similarity_score(self, search_value, search_list):
134
+ """
135
+ similarity score with ngrams 2
136
+ similarity score =
137
+ the total intersection of ngrams (searching word & word from the searching list) / count of ngrams of searching word
138
+
139
+ :param search_value: value for searching at products, dimensions, clients, promotions
140
+ :param search_list: list of searching data
141
+ """
142
+ if self.intersect_count([search_value], search_list) > 0:
143
+ return search_value, 1
144
+ else:
145
+ sv_ngram = ngrams_2(search_value) # searching word of 2 ngrams
146
+ ngrams_intersections = []
147
+ for i in search_list:
148
+ _ngram = ngrams_2(i) # all possible search list of 2 ngrams
149
+ ngrams_intersections.append((self.intersect_count(_ngram, sv_ngram), i))
150
+ search_value = list(sorted(ngrams_intersections))[-1]
151
+ score = search_value[0] / len(sv_ngram)
152
+ return search_value[1], score
153
+
154
+ def get_search_value(self, type, search_value):
155
+ """
156
+ :param type : client, product, dimension, promotion
157
+ :param search_value : value for searching at products, dimensions, clients, promotions
158
+ """
159
+ search_result, similarity_score, searches = search_value, 0, []
160
+ try:
161
+ if type == 'product':
162
+ searches = list(self.collect_report('product_kpis')['products'].unique())
163
+ if type == 'promotion':
164
+ searches = list(self.collect_report('promotion_kpis')['promotion_id'].unique())
165
+ if type == 'client':
166
+ searches = list(self.collect_report('client_kpis')['client'].unique())
167
+ if type == 'dimension':
168
+ searches = list(self.collect_report('dimension_kpis')['dimension'].unique())
169
+ search_result, similarity_score = self.get_search_similarity_score(search_value, searches)
170
+ except Exception as e:
171
+ print(e)
172
+ search_result = search_value
173
+ return search_result, similarity_score
174
+
175
+ def collect_report(self, report_name):
176
+ """
177
+ If there is a report need as .csv format
178
+ :param report_name: name of the report fetch from build-in temporary report folder
179
+ """
180
+ report = reports.fetch_report(report_name)
181
+ if report is False:
182
+ print("reports is not generated")
183
+ return pd.DataFrame()
184
+ else:
185
+ return report
186
+
187
+ def visualization_data_for_search(self, type, value):
188
+ """
189
+ Each type of search is visualized individually.
190
+ Products; 4 KPIs and 3 charts
191
+ Promotions; 4 KPIs and 3 charts
192
+ Clients; 4 KPIs and 1 chart
193
+ Dimensions; 4 KPIs and 3 charts
194
+
195
+ Each chart and KPI of data fetch from imported .csv files at temporary report folder
196
+ after built-in report processes are finalized.
197
+ :param type: search type; promotions, products, clients, dimensions
198
+ :param value: value for searching
199
+ """
200
+ _query = "{} == @value".format(self.query_column[type])
201
+ for data_type in self.data_types[type]:
202
+ try:
203
+ result = pd.DataFrame()
204
+ for r in data_type[1]:
205
+ result = pd.concat([result, self.collect_report(r).query(_query)])
206
+ if len({'date', 'daily'} & set(list(result.columns))) != 0: # covert date columns to timestamp
207
+ date_column = list({'date', 'daily'} & set(list(result.columns)))[0]
208
+ result[date_column] = result[date_column].apply(lambda x: convert_to_date(x))
209
+ result = result.sort_values(date_column, ascending=True)
210
+ result.to_csv(join(self.temporary_path, "build_in_reports", "main", data_type[0] + '_search.csv'),
211
+ index=False)
212
+ except Exception as e:
213
+ print(e)
214
+
215
+ def search_results(self, search_value):
216
+ """
217
+ 1. check for the temporary folder path.
218
+ 2. check each search type separately and calculate the max similarity scores.
219
+ 3. if there is not observed score of more than 0, show the sample data on search dashboard.
220
+
221
+ :param value: value for searching
222
+ """
223
+ self.get_temporary_path()
224
+ results = {'search_type': 'product', 'has_results': False, 'search_value': search_value}
225
+ try:
226
+ data = []
227
+ for m in self.search_metrics:
228
+ _search_value, _similarity_score = self.get_search_value(m, search_value)
229
+ data.append({'search_value': _search_value, 'similarity_score': _similarity_score, 'search_type': m})
230
+ data = pd.DataFrame(data).query("similarity_score != 0")
231
+ if len(data) != 0:
232
+ data = data.sort_values(by='similarity_score', ascending=False).to_dict('records')[0]
233
+ self.visualization_data_for_search(type=data['search_type'], value=data['search_value'])
234
+ data['has_results'] = True
235
+ results = data
236
+ except Exception as e:
237
+ results = {'search_type': 'product', 'has_results': False}
238
+ return results
239
+
240
+ def get_search_chart_names(self, search_type):
241
+ """
242
+ These are the title of the charts and KPIs at the search dashboard according to the search type.
243
+ :param search_type: search type; promotions, products, clients, dimensions
244
+ """
245
+ chart_names = {}
246
+ if search_type == 'product':
247
+ _charts = self.product_charts
248
+ _kpis = self.product_kpis
249
+ if search_type == 'promotion':
250
+ _charts = self.promotion_charts
251
+ _kpis = self.promotion_kpis
252
+ if search_type == 'client':
253
+ _charts = self.client_charts
254
+ _kpis = self.client_kpis
255
+ if search_type == 'dimension':
256
+ _charts = self.dimension_charts
257
+ _kpis = self.dimension_kpis
258
+ for i in zip(range(2, len(_charts) + 2), _charts):
259
+ chart_names["chart_{}_search".format(str(i[0]))] = i[1]
260
+ for i in zip(range(1, len(_kpis) + 1), _kpis):
261
+ chart_names['kpi_' + str(i[0])] = i[1]
262
+ return chart_names
263
+
264
+ def convert_kpi_names_to_numeric_names(self, graph_json):
265
+ """
266
+ :param graph_json: json file for charts and KPIs in order to show on .html file
267
+ """
268
+ return {'kpi_' + str(k[1]): graph_json['kpis'][k[0]] for k in zip(list(graph_json['kpis'].keys()), range(1, 5))}
269
+
270
+ def delete_search_data(self, results):
271
+ """
272
+ After showing the results in the dashboards, removing .csv files from the temporary folder path.
273
+ """
274
+ if results['has_results']:
275
+ for i in range(1, 5):
276
+ _file = join(self.temporary_path, "build_in_reports", "main", 'chart_{}_search.csv'.format(str(i)))
277
+ try:
278
+ os.unlink(_file)
279
+ except Exception as e:
280
+ print("no file is observed!!!")
281
+
282
+
283
+
284
+
285
+
286
+
287
+
288
+
@@ -0,0 +1,280 @@
1
+ {% extends "layouts/base.html" %}
2
+
3
+ {% block title %} A/B Test Product {% endblock %}
4
+
5
+ <!-- Specific Page CSS goes HERE -->
6
+ {% block stylesheets %}{% endblock stylesheets %}
7
+
8
+ {% block content %}
9
+
10
+ <main class="content">
11
+ <div class="container-fluid p-0">
12
+ <h5 class="h3 mb-3">A/B Test Product</h5>
13
+ <div class="col-md-12">
14
+ <div class="card">
15
+ <div class="card-body">
16
+ <div class="row">
17
+ <div class="accordion" id="accordionExample">
18
+ <div class="card">
19
+ <div class="card-header" id="headingOne">
20
+ <h5 class="card-title my-1">
21
+ <a href="#" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne" style="color:green;font-size:12px">
22
+ Filters
23
+ </a>
24
+ </h5>
25
+ </div>
26
+ <div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#accordionExample">
27
+ <form method="POST">
28
+ <div class="row">
29
+ <div class="col-md-6">
30
+ <div class="card">
31
+ <div class="card-body">
32
+ <div class="card">
33
+ <div class="card-header">
34
+ <h5 class="card-title mb-0">Dimension selection</h5>
35
+ </div>
36
+ <div class="card-body">
37
+ <select name="index" id="index" class="form-control">
38
+ {% for d in filters['dimensions'] %}
39
+ {% if d == 'There is no available report. Please execute Schedule Data Process' %}
40
+ <option value= "main">{{ d }}</option>
41
+ {% endif %}
42
+ {% if d != 'There is no available report. Please execute Schedule Data Process' %}
43
+ <option value="{{ d }}">{{ d }}</option>
44
+ {% endif %}
45
+ {% endfor %}
46
+ </select>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ </div>
52
+
53
+ <div class="col-md-6">
54
+ <div class="card flex-fil">
55
+ <div class="card-body col-12">
56
+ <div class="col-12 ">
57
+ <div class="align-self-center w-100">
58
+ <div class="chart">
59
+ <input name="date" id="datetimepicker-dashboard" hidden>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ </div>
66
+
67
+ <div class="card-header">
68
+ <button type="submit" class="btn btn-pill btn-primary">Apply</button>
69
+ </div>
70
+ </div>
71
+ </form>
72
+
73
+ </div>
74
+ </div>
75
+
76
+ <div class="card">
77
+ <div class="card-header" id="headingTwo">
78
+ <h5 class="card-title my-1">
79
+ <a href="#" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="true" aria-controls="collapseOne" style="color:green;font-size:12px">
80
+ Infos
81
+ </a>
82
+ </h5>
83
+ </div>
84
+ <div id="collapseTwo" class="collapse show" aria-labelledby="headingTwo" data-parent="#accordionExample">
85
+ <div class="card-body ">
86
+ <ul>
87
+ <li>
88
+ <strong style="color:green;">A/B Test Products </strong> are bunch of testes which compares effect of Products to the business.
89
+ There are two metrics which help us to measure comparison values.
90
+ These are Number of orders counts per product and Average purchase amount per product.
91
+ Products of Purchasement related to these metrics are tested with Before - After Analysis
92
+ in order to the answer the question that is "Is there any significant increase/decrease
93
+ on Order Count / Average Payment Amount per User after the Products is purchased?"
94
+ While we need to see to the product which increases/decreases the number of orders and the average purchase amount,
95
+ This Section can help us to find the right product for the business.
96
+ </li>
97
+
98
+ <li>
99
+ <div class="card-header">
100
+ <h5 class="card-title" style="color:green;">Hypothesis are;</h5>
101
+ <div class="card-header">
102
+ <div class="row">H0 : These is no significant Difference with A - B of order count / purchase amount.</div>
103
+ <div class="row">H1 : These is significant Difference with A - B of order count / purchase amount.</div>
104
+ </div>
105
+ </div>
106
+ </li>
107
+ <li>
108
+ <div class="card-header">
109
+ <h5 class="card-title" style="color:green;">Bootstrapping Method;</h5>
110
+ <div class="card-header">
111
+ <div class="row">
112
+ Each test process are applied with Boostraping Method.
113
+ So, Iteratively randomly selected A and B sample customers of order count / average purchase amount will be tested acceptable enough time.
114
+ Each iteration A - B samples are randomly selected.
115
+ Accepted ratio will show us the confidence of our test results. For instance, There are 100 tests and 75 of them are ended with H0 Accepted.
116
+ So, test are % 75 our test are H0 Accepted.
117
+ </div>
118
+ </div>
119
+ </div>
120
+ </li>
121
+
122
+ <li>
123
+ <div class="card-header">
124
+ <h5 class="card-title" style="color:green;">How are Before - After Product Usage Tests designed?</h5>
125
+ It might be very confusion and it might seem very sophisticated A/B Test process,
126
+ however it basically compares products related to customers of product selection at the basket.
127
+ Each product selection at the basket is tested separately.
128
+ Each timestamp of the selected product at the basket are collected for each product per customer individually.
129
+ Each customers of one week before product selection and one week after the product selection time periods are compared with to metrics which are
130
+ order count and average purchase amount. We aim to detect significant increase after time period
131
+ while comparing to before time period about purchase amount or order count.
132
+
133
+ <div class="card-header">
134
+ <div class="row" style="color:green;">related charts are;</div>
135
+ <div class="card-header">
136
+ <div class="row mb-1">'Before - After Time Periods Customers' Average Purchase Payment Amount Test (Test Accepted!) ',</div>
137
+ <div class="row mb-1">'Before - After Time Periods Customers' Average Purchase Payment Amount Test (Test Rejected!)',</div>
138
+ <div class="row mb-1">'Before - After Time Periods Customers' Total Purchase Count Test (Test Accepted!)',</div>
139
+ <div class="row mb-1">'Before - After Time Periods Customers' Total Purchase Count Test (Test Rejected!)'</div>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ </li>
144
+ </ul>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ </div>
149
+
150
+ <div class="col-md-6">
151
+ <div class="card">
152
+ <div class="card-header">
153
+ <h5 class="card-title">Before - After Time Periods Customers' Average Purchase <strong> Payment Amount</strong> Test <strong> (Test Accepted!)</strong> {% if data_type['product_usage_before_after_amount_accept'] == False %} <strong style="color:red;"> sample data </strong> {% endif %} </h5>
154
+ <div class="row">
155
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> A :</strong> Avg. purc. amount <strong style="color:green;"> Before the basket with selected product</strong> per customer, per product.</h6>
156
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> B :</strong> Avg. purc. amount <strong style="color:green;"> After the basket with selected product</strong> per customer, per product</h6>
157
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> Test Accepted :</strong> <strong style="color:green;" > Significant Increase</strong> on Avg. purc. amount after the product is selected in ordered basket.</h6>
158
+ <h6 class="card-subtitle text-muted mb-1">- Each Test are applied individually (per product).</h6>
159
+ </div>
160
+ </div>
161
+ <div id="product_usage_ba_a_accept_id" class="plotly-gra ph-div" style="height:400px;"></div>
162
+ </div>
163
+ </div>
164
+ <div class="col-md-6">
165
+ <div class="card">
166
+ <div class="card-header">
167
+ <h5 class="card-title">Before - After Time Periods Customers' Average Purchase <strong> Payment Amount</strong> Test <strong> (Test Rejected!)</strong> {% if data_type['product_usage_before_after_amount_reject'] == False %} <strong style="color:red;"> sample data </strong> {% endif %} </h5>
168
+ <div class="row">
169
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> A :</strong> Avg. purc. amount <strong style="color:green;"> Before the basket with selected product</strong> per customer, per product.</h6>
170
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> B :</strong> Avg. purc. amount <strong style="color:green;"> After the basket with selected product</strong> per customer, per product</h6>
171
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> Test Rejected :</strong> <strong style="color:green;" > Significant Decrease</strong> on Avg. purc. amount after the product is selected in ordered basket.</h6>
172
+ <h6 class="card-subtitle text-muted mb-1">- Each Test are applied individually (per product).</h6>
173
+ </div>
174
+ </div>
175
+ <div class="card-body">
176
+ <div id="product_usage_ba_a_reject_id" class="plotly-gra ph-div" style="height:400px;"></div>
177
+ </div>
178
+ </div>
179
+ </div>
180
+ </div>
181
+ <div class="row">
182
+ <div class="col-md-6">
183
+ <div class="card">
184
+ <div class="card-header">
185
+ <h5 class="card-title">Before - After Time Periods Customers' <strong> Total Purchase Count</strong> Test <strong> (Test Accepted!)</strong> {% if data_type['product_usage_before_after_orders_accept'] == False %} <strong style="color:red;"> sample data </strong> {% endif %}</h5>
186
+ <div class="row">
187
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> A :</strong> Total P. Count <strong style="color:green;"> Before the basket with selected product</strong> per customer, per product.</h6>
188
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> B :</strong> Total P. Count <strong style="color:green;"> After the basket with selected product</strong> per customer, per product</h6>
189
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> Test Accepted :</strong> <strong style="color:green;" > Significant Increase</strong> on Total P. Counts after the product is selected in ordered basket.</h6>
190
+ <h6 class="card-subtitle text-muted mb-1">- Each Test are applied individually (per product).</h6>
191
+ </div>
192
+ </div>
193
+ <div class="card-body">
194
+ <div id="product_usage_ba_o_accept_id" class="plotly-gra ph-div" style="height:400px;"></div>
195
+ </div>
196
+ </div>
197
+ </div>
198
+ <div class="col-md-6">
199
+ <div class="card">
200
+ <div class="card-header">
201
+ <h5 class="card-title">Before - After Time Periods Customers' <strong> Total Purchase Count</strong> Test <strong> (Test Rejected!)</strong> {% if data_type['product_usage_before_after_orders_reject'] == False %} <strong style="color:red;"> sample data </strong> {% endif %}</h5>
202
+ <div class="row">
203
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> A :</strong> Total P. Count <strong style="color:green;"> Before the basket with selected product</strong> per customer, per product.</h6>
204
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> B :</strong> Total P. Count <strong style="color:green;"> After the basket with selected product</strong> per customer, per product</h6>
205
+ <h6 class="card-subtitle text-muted mb-1">- <strong style="color:green;"> Test Rejected :</strong> <strong style="color:green;" > Significant Decrease</strong> on Total P. Counts after the product is selected in ordered basket.</h6>
206
+ <h6 class="card-subtitle text-muted mb-1">- Each Test are applied individually (per product).</h6>
207
+ </div>
208
+ </div>
209
+ <div class="card-body">
210
+ <div id="product_usage_ba_o_reject_id" class="plotly-gra ph-div" style="height:400px;"></div>
211
+ </div>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ </div>
216
+ </div>
217
+ </div>
218
+ </div>
219
+ </main>
220
+
221
+ {% endblock content %}
222
+
223
+ <!-- Specific Page JS goes HERE -->
224
+ {% block javascripts %}
225
+ <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
226
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
227
+ <script>
228
+
229
+
230
+
231
+ var product_usage_ba_a_a = {{product_use_ba_a_accept | safe}};
232
+
233
+ Plotly.plot('product_usage_ba_a_accept_id', // the ID of the div, created above
234
+ product_usage_ba_a_a.trace, product_usage_ba_a_a.layout, {});
235
+
236
+
237
+ var product_usage_ba_a_r = {{product_use_ba_a_reject | safe}};
238
+
239
+ Plotly.plot('product_usage_ba_a_reject_id', // the ID of the div, created above
240
+ product_usage_ba_a_r.trace, product_usage_ba_a_r.layout, {});
241
+
242
+
243
+ var product_usage_ba_o_a = {{product_use_ba_o_accept | safe}};
244
+
245
+ Plotly.plot('product_usage_ba_o_accept_id', // the ID of the div, created above
246
+ product_usage_ba_o_a.trace, product_usage_ba_o_a.layout, {});
247
+
248
+
249
+ var product_usage_ba_o_r = {{product_use_ba_o_reject | safe}};
250
+
251
+ Plotly.plot('product_usage_ba_o_reject_id', // the ID of the div, created above
252
+ product_usage_ba_o_r.trace, product_usage_ba_o_r.layout, {});
253
+
254
+
255
+ function myFunction() {
256
+ // Get the checkbox
257
+ var checkBox = document.getElementById("myCheck");
258
+ // Get the output text
259
+ var text = document.getElementById("text");
260
+
261
+ // If the checkbox is checked, display the output text
262
+ if (checkBox.checked == true){
263
+ text.style.display = "block";
264
+ } else {
265
+ text.style.display = "none";
266
+ }
267
+ }
268
+ </script>
269
+
270
+ <script>
271
+ document.addEventListener("DOMContentLoaded", function() {
272
+ document.getElementById("datetimepicker-dashboard").flatpickr({
273
+ inline: true,
274
+
275
+ prevArrow: "<span class=\"fas fa-chevron-left\" title=\"Previous month\"></span>",
276
+ nextArrow: "<span class=\"fas fa-chevron-right\" title=\"Next month\"></span>",
277
+ });
278
+ });
279
+ </script>
280
+ {% endblock javascripts %}