wordjelly-auth 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (275) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +35 -0
  5. data/app/assets/images/auth/activity.jpg +0 -0
  6. data/app/assets/images/auth/facebook.svg +1 -0
  7. data/app/assets/images/auth/google_oauth2.svg +1 -0
  8. data/app/assets/images/auth/js_pic3.jpg +0 -0
  9. data/app/assets/images/auth/profile.jpg +0 -0
  10. data/app/assets/javascripts/auth/admin_create_users.js +2 -0
  11. data/app/assets/javascripts/auth/application.js +20 -0
  12. data/app/assets/javascripts/auth/auth_dependencies.js +12 -0
  13. data/app/assets/javascripts/auth/auth_modals_and_navbar.js +218 -0
  14. data/app/assets/javascripts/auth/clients.js +2 -0
  15. data/app/assets/javascripts/auth/search.js +2 -0
  16. data/app/assets/javascripts/auth/shopping/discounts.js +2 -0
  17. data/app/assets/javascripts/auth/users/profiles.js +188 -0
  18. data/app/assets/stylesheets/auth/admin_create_users.css +4 -0
  19. data/app/assets/stylesheets/auth/application.scss +14 -0
  20. data/app/assets/stylesheets/auth/auth_default_css.scss +13 -0
  21. data/app/assets/stylesheets/auth/common-styles.scss +579 -0
  22. data/app/assets/stylesheets/auth/overrides.scss +26 -0
  23. data/app/assets/stylesheets/auth/search.css +4 -0
  24. data/app/assets/stylesheets/auth/shopping/discounts.css +4 -0
  25. data/app/assets/stylesheets/auth/users/profiles.scss +40 -0
  26. data/app/assets/stylesheets/scaffold.css +56 -0
  27. data/app/controllers/auth/admin_create_users_controller.rb +89 -0
  28. data/app/controllers/auth/application_controller.rb +97 -0
  29. data/app/controllers/auth/clients_controller.rb +105 -0
  30. data/app/controllers/auth/concerns/activity_controller_concern.rb +32 -0
  31. data/app/controllers/auth/concerns/devise_concern.rb +193 -0
  32. data/app/controllers/auth/concerns/omni_concern.rb +310 -0
  33. data/app/controllers/auth/concerns/otp_concern.rb +251 -0
  34. data/app/controllers/auth/concerns/shopping/cart_controller_concern.rb +105 -0
  35. data/app/controllers/auth/concerns/shopping/cart_item_controller_concern.rb +150 -0
  36. data/app/controllers/auth/concerns/shopping/discount_controller_concern.rb +97 -0
  37. data/app/controllers/auth/concerns/shopping/pay_u_money_controller_concern.rb +38 -0
  38. data/app/controllers/auth/concerns/shopping/payment_controller_concern.rb +101 -0
  39. data/app/controllers/auth/concerns/shopping/product_controller_concern.rb +68 -0
  40. data/app/controllers/auth/concerns/token_concern.rb +187 -0
  41. data/app/controllers/auth/confirmations_controller.rb +3 -0
  42. data/app/controllers/auth/mailgun_controller.rb +8 -0
  43. data/app/controllers/auth/omniauth_callbacks_controller.rb +6 -0
  44. data/app/controllers/auth/passwords_controller.rb +4 -0
  45. data/app/controllers/auth/profiles_controller.rb +156 -0
  46. data/app/controllers/auth/registrations_controller.rb +99 -0
  47. data/app/controllers/auth/search_controller.rb +61 -0
  48. data/app/controllers/auth/sessions_controller.rb +20 -0
  49. data/app/controllers/auth/shopping/cart_items_controller.rb +14 -0
  50. data/app/controllers/auth/shopping/carts_controller.rb +13 -0
  51. data/app/controllers/auth/shopping/discounts_controller.rb +19 -0
  52. data/app/controllers/auth/shopping/payments_controller.rb +13 -0
  53. data/app/controllers/auth/shopping/products_controller.rb +17 -0
  54. data/app/controllers/auth/shopping/shopping_controller.rb +86 -0
  55. data/app/controllers/auth/unlocks_controller.rb +3 -0
  56. data/app/controllers/auth/webhooks_controller.rb +3 -0
  57. data/app/helpers/auth/admin_create_users_helper.rb +2 -0
  58. data/app/helpers/auth/application_helper.rb +136 -0
  59. data/app/helpers/auth/clients_helper.rb +4 -0
  60. data/app/helpers/auth/resource_helper.rb +10 -0
  61. data/app/helpers/auth/search_helper.rb +2 -0
  62. data/app/helpers/auth/shopping/cart_items/cart_items_helper.rb +29 -0
  63. data/app/helpers/auth/shopping/carts/carts_helper.rb +25 -0
  64. data/app/helpers/auth/shopping/discounts/discounts_helper.rb +39 -0
  65. data/app/helpers/auth/shopping/payments/pay_u_money_helper.rb +56 -0
  66. data/app/helpers/auth/shopping/payments/payments_helper.rb +54 -0
  67. data/app/helpers/auth/shopping/products/products_helper.rb +52 -0
  68. data/app/helpers/auth/shopping/shopping_helper.rb +3 -0
  69. data/app/helpers/auth/users/profiles_helper.rb +12 -0
  70. data/app/jobs/otp_job.rb +92 -0
  71. data/app/mailers/application_mailer.rb +4 -0
  72. data/app/mailers/auth/notifier.rb +9 -0
  73. data/app/models/auth/admin_create_user.rb +3 -0
  74. data/app/models/auth/client.rb +52 -0
  75. data/app/models/auth/concerns/activity_concern.rb +112 -0
  76. data/app/models/auth/concerns/chief_model_concern.rb +73 -0
  77. data/app/models/auth/concerns/es_concern.rb +21 -0
  78. data/app/models/auth/concerns/notification_concern.rb +232 -0
  79. data/app/models/auth/concerns/notification_response_concern.rb +71 -0
  80. data/app/models/auth/concerns/owner_concern.rb +81 -0
  81. data/app/models/auth/concerns/shopping/cart_concern.rb +329 -0
  82. data/app/models/auth/concerns/shopping/cart_item_concern.rb +437 -0
  83. data/app/models/auth/concerns/shopping/discount_concern.rb +482 -0
  84. data/app/models/auth/concerns/shopping/discount_flow.txt +11 -0
  85. data/app/models/auth/concerns/shopping/pay_u_money_concern.rb +184 -0
  86. data/app/models/auth/concerns/shopping/payment_concern.rb +613 -0
  87. data/app/models/auth/concerns/shopping/product_concern.rb +102 -0
  88. data/app/models/auth/concerns/sms_otp_concern.rb +68 -0
  89. data/app/models/auth/concerns/user_concern.rb +788 -0
  90. data/app/models/auth/identity.rb +23 -0
  91. data/app/models/auth/shopping/cart.rb +3 -0
  92. data/app/models/auth/shopping/cart_item.rb +6 -0
  93. data/app/models/auth/shopping/cart_item_payment_result.rb +7 -0
  94. data/app/models/auth/shopping/discount.rb +4 -0
  95. data/app/models/auth/shopping/payment.rb +5 -0
  96. data/app/models/auth/shopping/product.rb +5 -0
  97. data/app/models/auth/user.rb +3 -0
  98. data/app/views/auth/admin_create_users/_admin_actions.html.erb +46 -0
  99. data/app/views/auth/admin_create_users/_form.html.erb +19 -0
  100. data/app/views/auth/admin_create_users/edit.html.erb +6 -0
  101. data/app/views/auth/admin_create_users/index.html.erb +25 -0
  102. data/app/views/auth/admin_create_users/new.html.erb +5 -0
  103. data/app/views/auth/admin_create_users/show.html.erb +8 -0
  104. data/app/views/auth/clients/_form.html.erb +41 -0
  105. data/app/views/auth/clients/edit.html.erb +6 -0
  106. data/app/views/auth/clients/index.html.erb +33 -0
  107. data/app/views/auth/clients/new.html.erb +5 -0
  108. data/app/views/auth/clients/show.html.erb +21 -0
  109. data/app/views/auth/confirmations/_enter_otp.html.erb +27 -0
  110. data/app/views/auth/confirmations/_get_otp_status.html.erb +25 -0
  111. data/app/views/auth/confirmations/_new_otp_input.js.erb +11 -0
  112. data/app/views/auth/confirmations/_resend_otp.js.erb +8 -0
  113. data/app/views/auth/confirmations/_resend_sms_otp.html.erb +18 -0
  114. data/app/views/auth/confirmations/_verify_otp.js.erb +64 -0
  115. data/app/views/auth/confirmations/create.js.erb +8 -0
  116. data/app/views/auth/confirmations/enter_otp.html.erb +7 -0
  117. data/app/views/auth/confirmations/get_otp_status.html.erb +3 -0
  118. data/app/views/auth/confirmations/new.html.erb +1 -0
  119. data/app/views/auth/confirmations/new.js.erb +16 -0
  120. data/app/views/auth/confirmations/otp_status_result.html.erb +20 -0
  121. data/app/views/auth/mailer/confirmation_instructions.html.erb +5 -0
  122. data/app/views/auth/mailer/password_change.html.erb +3 -0
  123. data/app/views/auth/mailer/reset_password_instructions.html.erb +8 -0
  124. data/app/views/auth/mailer/unlock_instructions.html.erb +7 -0
  125. data/app/views/auth/modals/_ajax_error_modal.html.erb +3 -0
  126. data/app/views/auth/modals/_ajax_error_modal_content.html.erb +0 -0
  127. data/app/views/auth/modals/_edit_account_content.html.erb +68 -0
  128. data/app/views/auth/modals/_edit_account_success_content.html.erb +5 -0
  129. data/app/views/auth/modals/_error_notification.html.erb +8 -0
  130. data/app/views/auth/modals/_forgot_password_content.html.erb +18 -0
  131. data/app/views/auth/modals/_forgot_password_success_content.html.erb +8 -0
  132. data/app/views/auth/modals/_login_default_content.html.erb +3 -0
  133. data/app/views/auth/modals/_login_forms.html.erb +13 -0
  134. data/app/views/auth/modals/_login_navigation_options.html.erb +12 -0
  135. data/app/views/auth/modals/_new_otp_input.html.erb +28 -0
  136. data/app/views/auth/modals/_oauth_and_submit.html.erb +21 -0
  137. data/app/views/auth/modals/_recaptcha_tags.html.erb +4 -0
  138. data/app/views/auth/modals/_resend_confirmation_content.html.erb +17 -0
  139. data/app/views/auth/modals/_resend_confirmation_success_content.html.erb +8 -0
  140. data/app/views/auth/modals/_resend_otp.html.erb +23 -0
  141. data/app/views/auth/modals/_resource_errors.js.erb +24 -0
  142. data/app/views/auth/modals/_sign_in_inputs.html.erb +10 -0
  143. data/app/views/auth/modals/_sign_in_needed_modal.html.erb +3 -0
  144. data/app/views/auth/modals/_sign_in_success_content.html.erb +5 -0
  145. data/app/views/auth/modals/_sign_up_inputs.html.erb +9 -0
  146. data/app/views/auth/modals/_sign_up_success_content.html.erb +1 -0
  147. data/app/views/auth/modals/_sign_up_success_inactive_content.html.erb +2 -0
  148. data/app/views/auth/modals/_unlock_content.html.erb +17 -0
  149. data/app/views/auth/modals/_verify_otp.html.erb +1 -0
  150. data/app/views/auth/modals/base_modal/_base.html.erb +25 -0
  151. data/app/views/auth/modals/login.js.erb +120 -0
  152. data/app/views/auth/modals/unlock_success_content.html.erb +8 -0
  153. data/app/views/auth/notifier/_email.html.erb +3 -0
  154. data/app/views/auth/notifier/notification.html.erb +2 -0
  155. data/app/views/auth/notifier/notification.text.erb +1 -0
  156. data/app/views/auth/omniauth_callbacks/failure.html.erb +4 -0
  157. data/app/views/auth/passwords/create.js.erb +12 -0
  158. data/app/views/auth/passwords/edit.html.erb +25 -0
  159. data/app/views/auth/passwords/new.html.erb +16 -0
  160. data/app/views/auth/passwords/new.js.erb +19 -0
  161. data/app/views/auth/profiles/_proxy_resource.html.erb +5 -0
  162. data/app/views/auth/profiles/set_proxy_resource.js.erb +1 -0
  163. data/app/views/auth/profiles/show.html.erb +8 -0
  164. data/app/views/auth/registrations/create.js.erb +40 -0
  165. data/app/views/auth/registrations/edit.html.erb +2 -0
  166. data/app/views/auth/registrations/edit.js.erb +5 -0
  167. data/app/views/auth/registrations/new.html.erb +33 -0
  168. data/app/views/auth/registrations/update.js.erb +47 -0
  169. data/app/views/auth/search/_search_bar.html.erb +11 -0
  170. data/app/views/auth/search/_search_result.html.erb +7 -0
  171. data/app/views/auth/search/_search_results.html.erb +4 -0
  172. data/app/views/auth/search/authenticated_user_search.js.erb +45 -0
  173. data/app/views/auth/search/authenticated_user_search.json +7 -0
  174. data/app/views/auth/sessions/create.js.erb +5 -0
  175. data/app/views/auth/sessions/new.html.erb +4 -0
  176. data/app/views/auth/sessions/new.js.erb +20 -0
  177. data/app/views/auth/shared/_devise_error_messages.html.erb +9 -0
  178. data/app/views/auth/shared/_links.html.erb +25 -0
  179. data/app/views/auth/shared/_object_errors.html.erb +12 -0
  180. data/app/views/auth/shared/_proxy_resource.html.erb +18 -0
  181. data/app/views/auth/shopping/cart_items/_form.html.erb +34 -0
  182. data/app/views/auth/shopping/cart_items/_show_cart_items_collection.html.erb +31 -0
  183. data/app/views/auth/shopping/cart_items/create_multiple.html.erb +6 -0
  184. data/app/views/auth/shopping/cart_items/create_multiple.json.erb +9 -0
  185. data/app/views/auth/shopping/cart_items/edit.html.erb +6 -0
  186. data/app/views/auth/shopping/cart_items/index.html.erb +52 -0
  187. data/app/views/auth/shopping/cart_items/new.html.erb +5 -0
  188. data/app/views/auth/shopping/cart_items/show.html.erb +13 -0
  189. data/app/views/auth/shopping/carts/_form.html.erb +35 -0
  190. data/app/views/auth/shopping/carts/_payment_links.html.erb +27 -0
  191. data/app/views/auth/shopping/carts/_remove_cart_item.html.erb +11 -0
  192. data/app/views/auth/shopping/carts/_show_cart_balance_info.html.erb +35 -0
  193. data/app/views/auth/shopping/carts/edit.html.erb +6 -0
  194. data/app/views/auth/shopping/carts/index.html.erb +43 -0
  195. data/app/views/auth/shopping/carts/new.html.erb +5 -0
  196. data/app/views/auth/shopping/carts/show.html.erb +46 -0
  197. data/app/views/auth/shopping/discounts/_form.html.erb +18 -0
  198. data/app/views/auth/shopping/discounts/_form_for_create_multiple_cart_items.html.erb +17 -0
  199. data/app/views/auth/shopping/discounts/_show_pending_discount_request.html.erb +17 -0
  200. data/app/views/auth/shopping/discounts/destroy.html.erb +2 -0
  201. data/app/views/auth/shopping/discounts/edit.html.erb +29 -0
  202. data/app/views/auth/shopping/discounts/index.html.erb +40 -0
  203. data/app/views/auth/shopping/discounts/new.html.erb +1 -0
  204. data/app/views/auth/shopping/discounts/show.html.erb +18 -0
  205. data/app/views/auth/shopping/discounts/update.html.erb +2 -0
  206. data/app/views/auth/shopping/payments/_approve_payment.html.erb +7 -0
  207. data/app/views/auth/shopping/payments/_cash_card_cheque.html.erb +24 -0
  208. data/app/views/auth/shopping/payments/_create_discount_coupon.html.erb +5 -0
  209. data/app/views/auth/shopping/payments/_form.html.erb +19 -0
  210. data/app/views/auth/shopping/payments/_gateway.html.erb +21 -0
  211. data/app/views/auth/shopping/payments/_proceed_to_gateway_or_verify_payment.html.erb +18 -0
  212. data/app/views/auth/shopping/payments/_refresh_payment.html.erb +7 -0
  213. data/app/views/auth/shopping/payments/_refund.html.erb +10 -0
  214. data/app/views/auth/shopping/payments/_show_payment_receipt.html.erb +12 -0
  215. data/app/views/auth/shopping/payments/edit.html.erb +6 -0
  216. data/app/views/auth/shopping/payments/index.html.erb +43 -0
  217. data/app/views/auth/shopping/payments/new.html.erb +13 -0
  218. data/app/views/auth/shopping/payments/show.html.erb +36 -0
  219. data/app/views/auth/shopping/products/_form.html.erb +27 -0
  220. data/app/views/auth/shopping/products/edit.html.erb +6 -0
  221. data/app/views/auth/shopping/products/index.html.erb +48 -0
  222. data/app/views/auth/shopping/products/index.json.erb +7 -0
  223. data/app/views/auth/shopping/products/new.html.erb +5 -0
  224. data/app/views/auth/shopping/products/show.html.erb +12 -0
  225. data/app/views/auth/shopping/products/show.json.erb +1 -0
  226. data/app/views/auth/unlocks/create.js.erb +12 -0
  227. data/app/views/auth/unlocks/new.html.erb +14 -0
  228. data/app/views/auth/unlocks/new.js.erb +17 -0
  229. data/app/views/auth/users/_search_result.html.erb +8 -0
  230. data/app/views/auth/users/profiles/_user_data.html.erb +4 -0
  231. data/app/views/auth/users/profiles/show.html.erb +54 -0
  232. data/app/views/layouts/auth/_modals.html.erb +2 -0
  233. data/app/views/layouts/auth/application.html.erb +17 -0
  234. data/app/views/layouts/auth/navbar/_navbar.html.erb +49 -0
  235. data/app/views/layouts/auth/navbar/_personalization.html.erb +17 -0
  236. data/app/views/layouts/auth/navbar/_progress_spinner.html.erb +11 -0
  237. data/app/views/layouts/mailer.html.erb +5 -0
  238. data/app/views/layouts/mailer.text.erb +1 -0
  239. data/config/initializers/active_model.rb +36 -0
  240. data/config/initializers/devise.rb +623 -0
  241. data/config/initializers/json.rb +10 -0
  242. data/config/initializers/omniauth.rb +447 -0
  243. data/config/initializers/redis.rb +2 -0
  244. data/config/initializers/redis.yml +14 -0
  245. data/config/locales/devise.en.yml +63 -0
  246. data/config/routes.rb +1 -0
  247. data/lib/assets/javascripts/data.js +126 -0
  248. data/lib/assets/javascripts/jquery.calendario.js +394 -0
  249. data/lib/assets/javascripts/jquery.tagcloud.js +92 -0
  250. data/lib/assets/javascripts/leanModal.js +236 -0
  251. data/lib/assets/javascripts/main.js +668 -0
  252. data/lib/assets/javascripts/modernizr.custom.63321.js +4 -0
  253. data/lib/assets/javascripts/payumoney.js +9 -0
  254. data/lib/assets/javascripts/search.js +36 -0
  255. data/lib/assets/javascripts/spinner.js +77 -0
  256. data/lib/assets/javascripts/trianglify.min.js +2 -0
  257. data/lib/assets/javascripts/you_need_to_sign_in.js.erb +478 -0
  258. data/lib/assets/stylesheets/calendar.css +111 -0
  259. data/lib/assets/stylesheets/calendar_modifications.scss +276 -0
  260. data/lib/auth.rb +32 -0
  261. data/lib/auth/custom_failure.rb +3 -0
  262. data/lib/auth/engine.rb +231 -0
  263. data/lib/auth/job_exception_handler.rb +7 -0
  264. data/lib/auth/mailgun.rb +28 -0
  265. data/lib/auth/notify.rb +8 -0
  266. data/lib/auth/omniauth/path.rb +104 -0
  267. data/lib/auth/partials.rb +12 -0
  268. data/lib/auth/rails/routes.rb +169 -0
  269. data/lib/auth/search/main.rb +97 -0
  270. data/lib/auth/sidekiq_up.rb +16 -0
  271. data/lib/auth/two_factor_otp.rb +202 -0
  272. data/lib/auth/url_shortener.rb +29 -0
  273. data/lib/auth/version.rb +3 -0
  274. data/lib/tasks/auth_tasks.rake +4 -0
  275. metadata +863 -0
@@ -0,0 +1,437 @@
1
+ ##NEED A SEPERATE MODEL THAT IMPLEMENTS IT
2
+ module Auth::Concerns::Shopping::CartItemConcern
3
+
4
+
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ include Auth::Concerns::Shopping::ProductConcern
9
+ include Auth::Concerns::OwnerConcern
10
+ include Auth::Concerns::EsConcern
11
+
12
+
13
+ included do
14
+
15
+ INDEX_DEFINITION = {
16
+ index_options: {
17
+ settings: {
18
+ index: {
19
+ analysis: {
20
+ filter: {
21
+ nGram_filter: {
22
+ type: "nGram",
23
+ min_gram: 2,
24
+ max_gram: 20,
25
+ token_chars: [
26
+ "letter",
27
+ "digit",
28
+ "punctuation",
29
+ "symbol"
30
+ ]
31
+ }
32
+ },
33
+ analyzer: {
34
+ nGram_analyzer: {
35
+ type: "custom",
36
+ tokenizer: "whitespace",
37
+ filter: [
38
+ "lowercase",
39
+ "asciifolding",
40
+ "nGram_filter"
41
+ ]
42
+ },
43
+ whitespace_analyzer: {
44
+ type: "custom",
45
+ tokenizer: "whitespace",
46
+ filter: [
47
+ "lowercase",
48
+ "asciifolding"
49
+ ]
50
+ }
51
+ }
52
+ }
53
+ }
54
+ },
55
+ mappings: {
56
+ "shopping/cart_item" => {
57
+ _all: {
58
+ index_analyzer: "nGram_analyzer",
59
+ search_analyzer: "whitespace_analyzer"
60
+ },
61
+ properties: {
62
+ name: {
63
+ type: "string",
64
+ index: "not_analyzed"
65
+ },
66
+ price: {
67
+ type: "double"
68
+ },
69
+ public: {
70
+ type: "string",
71
+ index: "not_analyzed",
72
+ include_in_all: false
73
+ },
74
+ resource_id: {
75
+ type: "string",
76
+ index: "not_analyzed"
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+
85
+
86
+
87
+ ##PERMITTED
88
+ ##the id of the product to which this cart item refers.
89
+ ##permitted
90
+ field :product_id, type: String
91
+
92
+ ##the user id who is buying this product.
93
+ ##not permitted
94
+ field :resource_id, type: String
95
+
96
+ ##PERMITTED
97
+ ##the number of this product that are being added to the cart
98
+ ##permitted
99
+ field :quantity, type: Integer, default: 1
100
+
101
+ ##PERMITTED
102
+
103
+ ##not permitted
104
+ field :parent_id, type: String
105
+
106
+ ##PERMITTED
107
+ ##is it being discounted, can be from 0 -> 100 percent discount
108
+ ##not permitted
109
+ field :discount, type: Float
110
+
111
+ ##PERMITTED
112
+ ##discount code to offer discounts
113
+ ##permitted
114
+ field :discount_code, type: String
115
+
116
+
117
+ ###################### product status fields ##################
118
+ ## one of the stages mentioned below.
119
+ field :accepted, type: Boolean
120
+
121
+
122
+ ################### which payment led to this cart item being accepted
123
+
124
+ field :accepted_by_payment_id, type: String
125
+
126
+ ### a percentage of the total price , at which to accept the order.
127
+ ## the current item is accepted only if (price*accept_order_at_percentage_of_price) <= available credit
128
+ field :accept_order_at_percentage_of_price, type: Float, default: 1.00
129
+
130
+
131
+ before_destroy do |document|
132
+
133
+ if !skip_callback?("before_destroy")
134
+ if document.accepted == true
135
+ false
136
+ end
137
+ end
138
+ end
139
+
140
+ =begin
141
+ after_validation do |document|
142
+ if !skip_callback?("after_validation")
143
+ document.refresh_accepted
144
+ end
145
+ end
146
+ =end
147
+ before_validation do |document|
148
+ if !skip_callback?("before_validation")
149
+ document.refresh_accepted
150
+ end
151
+ end
152
+
153
+
154
+ before_create do |document|
155
+ document.assign_product_attributes
156
+ end
157
+
158
+
159
+
160
+ validate :user_cannot_change_anything_if_payment_accepted
161
+ validate :product_id_exists?
162
+
163
+ before_save do |document|
164
+ document.public = "no"
165
+ end
166
+
167
+
168
+
169
+ end
170
+
171
+
172
+ module ClassMethods
173
+
174
+
175
+
176
+ ##used in cart_item_controller_concern#index
177
+ ## if there is a resource, will return all cart items with that resource id.
178
+ ## if there is no resource, will return all cart items with a nil rsource.
179
+ def find_cart_items(options)
180
+ conditions = {:resource_id => nil, :parent_id => nil}
181
+ conditions[:resource_id] = options[:resource].id.to_s if options[:resource]
182
+ Auth.configuration.cart_item_class.constantize.where(conditions)
183
+ end
184
+
185
+ end
186
+
187
+ ### this is an internal method, cannot be set by admin or anyone, it is done after validation, since it is not necessary for someone to be admin, even the user can call refresh on the record to get the new state of the acceptence.
188
+ ## just checks if the accepted by payment id exists, and if yes, then doesnt do anything, otherwise will update the cart item status as false.
189
+ def refresh_accepted
190
+
191
+ if self.accepted_by_payment_id
192
+
193
+ begin
194
+ payment = Auth.configuration.payment_class.constantize.find(self.accepted_by_payment_id)
195
+ ## check if this payment status is approved or not.
196
+ ## if the payment status is approved, then dont do anything to the cart item.(we don't retro check payment to cart item.)
197
+ ## if the payment status is not approved, then make the cart item accepted as false.
198
+ if (payment.payment_status.nil? || payment.payment_status == 0)
199
+ self.accepted = false
200
+ end
201
+ rescue Mongoid::Errors::DocumentNotFound
202
+
203
+ self.accepted = false
204
+ end
205
+ end
206
+
207
+ ## if it doesnt have a cart, then it cannot be accepted.
208
+ if self.parent_id.nil?
209
+ self.accepted = false
210
+ self.accepted_by_payment_id = nil
211
+ end
212
+
213
+
214
+ ## we should ideally do this in the payment.
215
+ ## so that it can actually do what it usually does.
216
+ ## we can set say refresh_payment.
217
+ ## but it may not pay for everything.
218
+ ## but that is the only way through.
219
+ ## so if the payment is accepted then the cart_items_accepted will not be triggered.
220
+ ## but if we update the first payment, then we can do it.
221
+ ## basically take the last payment and update it, force calling the set_cart_items_accepted
222
+ ## and suppose they are not successfully accepted, then what about validation errors ?
223
+ ## so that will have to be skipped in that case.
224
+ end
225
+
226
+ ## called from payment#update_cart_items_accepted
227
+ ## sets accepted to true or false depending on whether the cart has enough credit for the item.
228
+ ## does not SAVE.
229
+ def set_accepted(payment,override)
230
+
231
+ #puts "the existing self accepted is:"
232
+ #puts self.accepted.to_s
233
+
234
+ if cart_has_sufficient_credit_for_item?(payment.cart)
235
+
236
+ ## is it already accepted?
237
+ if self.accepted
238
+
239
+ return true
240
+ else
241
+
242
+ self.accepted = true
243
+ end
244
+ else
245
+ self.accepted = false
246
+ end
247
+
248
+
249
+
250
+
251
+
252
+ ## so that it doesnt do refresh_cart_item
253
+ self.skip_callbacks = {:before_validation => true}
254
+
255
+ ## this will first call validate
256
+ self.validate
257
+
258
+ ## if the accepted is being set as false, then it should be set like that, where it was true?
259
+ ##
260
+ self.accepted_by_payment_id = self.accepted ? payment.id.to_s : nil
261
+
262
+
263
+ ## if it hasnt changed, dont query and update anything.
264
+
265
+ return true unless self.accepted_changed?
266
+
267
+ if self.errors.full_messages.empty?
268
+
269
+ doc_after_update =
270
+
271
+ Auth.configuration.cart_item_class.constantize.
272
+ where({
273
+ "$and" => [
274
+ "accepted" => {
275
+ "$nin" => [self.accepted]
276
+ },
277
+ "_id" => BSON::ObjectId(self.id.to_s)
278
+ ]
279
+ }).
280
+ find_one_and_update(
281
+ {
282
+ "$set" => {
283
+ "accepted" => self.accepted,
284
+ "accepted_by_payment_id" => self.accepted_by_payment_id
285
+ }
286
+ },
287
+ {
288
+ :return_document => :after
289
+ }
290
+ )
291
+
292
+ puts "the doc after update is:"
293
+ puts doc_after_update.attributes.to_s
294
+
295
+ return false unless doc_after_update
296
+ return false if doc_after_update.accepted != self.accepted
297
+ return true
298
+ else
299
+ return false
300
+ end
301
+ end
302
+
303
+ ## debits an amount from the cart equal to (item_price*accept_order_at_percentage_of_price)
304
+ ## the #debit function returns the current cart credit.
305
+ ## return true or false depending on whether , after debiting there is any credit left in the cart or not.
306
+ def cart_has_sufficient_credit_for_item?(cart)
307
+ puts "cart credit is: #{cart.cart_credit}"
308
+ cart_has_credit = cart.debit((self.accept_order_at_percentage_of_price*self.price)) >= 0
309
+ puts "cart has credit is: #{cart_has_credit.to_s}"
310
+ cart_has_credit
311
+ end
312
+
313
+
314
+
315
+ ## unsets the cart item , if it has not been accepted upto now.
316
+ ## assume that a payment was made, this cart item was updated wth its id as success, but some others were not, so the payment was not saved. but this item has got accepted as true.
317
+ ## so whether or not the payment that was made exists, we dont allow the cart to be unset.
318
+ ## however in case the signed_in_resource is an admin -> it is allowed to unset the cart, whether the item is already accepted or not.
319
+ ## @used_in : cart_concern # add_or_remove
320
+ ## @return[Boolean] : result of saving the cart item.
321
+ def unset_cart
322
+ if self.signed_in_resource.is_admin?
323
+ self.parent_id = nil
324
+ self.accepted = nil
325
+ self.accepted_by_payment_id = nil
326
+ else
327
+ if (self.accepted.nil? || self.accepted == false)
328
+ self.parent_id = nil
329
+ self.accepted = nil
330
+ self.accepted_by_payment_id = nil
331
+ end
332
+ end
333
+ rs = self.save
334
+ puts self.errors.full_messages
335
+ rs
336
+ end
337
+
338
+
339
+ ## assigns a cart and resource, resource_id to the cart_item.
340
+ ## @returns : true or false depending on whether the cart item was successfully saved or not.
341
+ ## @used_in : cart_controller_concern # add_or_remove
342
+ def set_cart_and_resource(cart)
343
+ return true if self.parent_id
344
+ return false if (owner_matches(cart) == false)
345
+ self.parent_id = cart.id.to_s
346
+ self.accepted = nil
347
+ self.accepted_by_payment_id = nil
348
+ self.save
349
+ end
350
+
351
+ #######################################################
352
+ ##
353
+ ## VALIDATIONS
354
+ ##
355
+ #######################################################
356
+
357
+ ## as long as it is not the accepted_by_payment id that has gone from nil to something, if anything else in the cart_item has changed, and the user is not an admin, and there is an accepted_by_payment id, then the error will be triggered.
358
+ ## these conditions are applicable to the gateway payment, or any other payment also.
359
+ ## and this has happened because the same item was pushed back in.
360
+ def user_cannot_change_anything_if_payment_accepted
361
+ if !self.signed_in_resource.is_admin?
362
+
363
+ ## THE USER CAN : UPDATE A PAYMENT TO MAKE THIS CART ITEM ACCEPTED / REJECTED.
364
+ ## if the payment status is changing, let it be, because this is an internal updated.
365
+
366
+ return if self.new_record?
367
+
368
+ puts "accepted changed? #{self.accepted_changed?.to_s}"
369
+
370
+ return if self.accepted_changed?
371
+
372
+ ## THE USER CAN REMOVE THE CART ITEM FROM A CART, AS LONG AS IT HAS NOT BEEN ACCEPTED.
373
+ ## if the item is being removed from the cart, while it has not yet been accepted.
374
+ return if self.parent_id_changed? && self.parent_id.nil? && (self.accepted.nil? || self.accepted == false)
375
+
376
+
377
+ ## THE USER CAN CHANGE ANY OTHER STUFF ALSO AS LONG AS THE ACCEPTED IS NIL OR FALSE
378
+ return if (self.accepted.nil? || self.accepted == false)
379
+
380
+
381
+ ## THE LAST SITUATION IS WHEN THE ITEM WAS ACCEPTED, AND NOW WE ARE UPDATING IT AS FALSE, AND ALSO THE PAYMENT ID AS NIL, THIS IS ALLOWED, BECAUSE IT IS WHAT HAPPENS IF THE ACCEPTING PAYMENT IS NIL OR ITS STATUS IS NOT APPROVED.
382
+
383
+
384
+
385
+ ## otherwise, the updated_by_payment_id, changes only when we are doing a gateway payment or any payment actually.
386
+ self.errors.add(:quantity,"you cannot change this item since payment has already been made")
387
+ # if self.accepted_by_payment_id && self.changed? && !self.new_record? && !(self.accepted_by_payment_id_changed? && self.accepted_by_payment_id_was.nil?)
388
+ end
389
+ end
390
+
391
+ def product_id_exists?
392
+ begin
393
+ Auth.configuration.product_class.constantize.find(self.product_id)
394
+ rescue
395
+ self.errors.add(:product_id,"this product id does not exist")
396
+ end
397
+ end
398
+
399
+ ## before creating the document assigns attributes defined in the def #product_attributes_to_assign, to the cart item.
400
+ def assign_product_attributes
401
+ begin
402
+ if self.product_id
403
+ if product = Auth.configuration.product_class.constantize.find(product_id)
404
+ product_attributes_to_assign.each do |attr|
405
+ ## only if the present attribute is nil, then we assign it from the product.
406
+ if self.respond_to? attr.to_sym
407
+ if self.send("#{attr}").nil?
408
+ self.send("#{attr}=",product.send("#{attr}"))
409
+ end
410
+ end
411
+ end
412
+ end
413
+ end
414
+ rescue
415
+
416
+ end
417
+ end
418
+
419
+ def product_attributes_to_assign
420
+ ["name","price"]
421
+ end
422
+
423
+ ## this is got by multiplying the price of the cart item by the minimum_acceptable at field.
424
+ def minimum_price_required_to_accept_cart_item
425
+ price*accept_order_at_percentage_of_price
426
+ end
427
+
428
+ def as_indexed_json(options={})
429
+ {
430
+ name: name,
431
+ price: price,
432
+ resource_id: resource_id,
433
+ public: public
434
+ }
435
+ end
436
+
437
+ end
@@ -0,0 +1,482 @@
1
+ =begin
2
+
3
+ ### sample discount object:
4
+
5
+ id : whatever
6
+ product_ids : []
7
+ count : 123
8
+ needs_verification : true/false
9
+ discount_percentage :
10
+ discount_amount :
11
+ origin_cart_id : whatever
12
+ pending_verification : [cart_id => date_time]
13
+ used_by : [cart_id => date/time]
14
+
15
+ other_fields will be added from owner_concern.
16
+
17
+ *if both percentage and amount are present, then amount will be used.
18
+
19
+ *when a payment is made => check if cart fully paid => show option to create coupons,enter discount amount/percentage,enter needs verification or not => if yes => create a discount_object with those details
20
+
21
+ *now when someone finds this discount object => give link to create a cart directly with it,(there should be an action on cart_item called bulk_create => there will first create the cart items => then redirect_to create_cart => with those cart_items, and also the discount code)
22
+
23
+ *now in prepare_cart =>
24
+ if dicount_code is provided:
25
+
26
+ 1. check that the code id exsits
27
+ 2. check how many have been utilized
28
+ 3. if verification is necessary then send a message to the verifier, or in case the cart is being proxied, then the verification is bypassed => when he updates the discount object as verified(for that user id)
29
+ 4. if verification is not necessary , add the user to the discount object -> as those who used this.
30
+
31
+ *now if no verification is needed or after verification incorporate the discount_amount in the calculation of the cart_price.
32
+
33
+ *show the modified cart price.
34
+
35
+ *let him make a payment, he can make with amount as 0, with cash. gateway payment is disabled if pending balance is 0.
36
+
37
+ *the payment is instantly accepted if pending_balance is zero.
38
+
39
+ =end
40
+
41
+ module Auth::Concerns::Shopping::DiscountConcern
42
+
43
+ extend ActiveSupport::Concern
44
+
45
+ include Auth::Concerns::ChiefModelConcern
46
+ include Auth::Concerns::OwnerConcern
47
+
48
+ included do
49
+
50
+ ####################################################
51
+ ##
52
+ ## FIELDS
53
+ ##
54
+ ####################################################
55
+
56
+ ## the product ids that this discount object can contain.
57
+ field :product_ids, type: Array, default: []
58
+
59
+ ## whether this discount object needs verification by the creator of the cart mentioned below, default is false
60
+ field :requires_verification, type: Boolean, default: false
61
+
62
+ ## the total number of times this discount object can be used.
63
+ field :count, type: Integer
64
+
65
+ ## the amount in plain float that this discount object provides
66
+ field :discount_amount, type: Float, default: 0.0
67
+
68
+ ## the amount in percentage terms for discount, will be applied to the cart price.
69
+ field :discount_percentage, type: Float, default: 0.0
70
+
71
+ ## the original cart on which this discount object was created from.
72
+ field :cart_id, type: String
73
+
74
+ ## the cart is internally set.
75
+ attr_accessor :cart
76
+
77
+ field :verified, type: Array, default:[]
78
+
79
+ field :pending, type: Array, default: []
80
+
81
+ field :declined, type: Array, default: []
82
+
83
+ ## the hash of user ids who have used this discoutn code
84
+ ## key => [String] user id
85
+ ## value => [Integer] number of times used.
86
+ field :used_by_users, type: Array, default: []
87
+
88
+
89
+ ## these attributes are used in the update action , to add the ids that should be marked as verified or declined.
90
+
91
+ attr_accessor :add_verified_ids
92
+
93
+ attr_accessor :add_declined_ids
94
+
95
+ #########################################################
96
+ ##
97
+ ## VALIDATIONS
98
+ ##
99
+ #########################################################
100
+
101
+ validate :cart_exists, :unless => :admin_and_cart_id_absent
102
+
103
+ validate :one_discount_object_per_cart, if: Proc.new{|a| a.cart_id }
104
+
105
+ validate :cart_has_multiples_of_all_items, if: Proc.new{|a| a.cart_id }
106
+
107
+ validate :cart_can_create_discount_coupons, if: Proc.new { |a| a.cart_id }
108
+
109
+ validate :user_can_create_discount_coupons
110
+
111
+ validates :discount_percentage, numericality: { greater_than_or_equal_to: 0.0, less_than_or_equal_to: 100.0 }, if: Proc.new {|a| a.discount_percentage_changed?}
112
+
113
+ validates :discount_amount, numericality: {greater_than_or_equal_to: 0.0}, if: Proc.new {|a| a.discount_amount_changed?}
114
+
115
+ validate :discount_percentage_permitted, if: Proc.new {|a| a.discount_percentage_changed? && !a.admin_and_cart_id_absent}
116
+
117
+
118
+ ## SHOULD BE TESTED.
119
+ ## the maximum discount amount is not validated in case its an admin and the cart id is not provided
120
+ validate :maximum_discount_amount, if: Proc.new {|a| (a.discount_amount_changed? || a.discount_percentage_changed?) && a.cart_id}
121
+
122
+ ## does not validate for product ids if the user is admin, and the cart is not present.
123
+ validates :product_ids, presence: true, if: Proc.new{|a| a.cart_id}
124
+
125
+ ## validates for count irrespective.
126
+ validates :count, presence: true
127
+
128
+ #########################################################
129
+ ##
130
+ ##
131
+ ## CALLBACKS
132
+ ##
133
+ ##
134
+ #########################################################
135
+
136
+ before_validation do |document|
137
+
138
+ document.set_cart
139
+
140
+ if document.new_record?
141
+
142
+ if document.cart
143
+ ## assign the products internally.
144
+ document.product_ids = document.cart.cart_items.map{|citem| citem = citem.product_id}
145
+
146
+ ## assign count
147
+ document.count = document.cart.cart_items.first.quantity
148
+ else
149
+ ## whatever was sent in the params.
150
+ ## the count param is permitted only if the user is an admin.
151
+ end
152
+
153
+ end
154
+
155
+ ## if either the discount amount or percentage is nil, set it to 0.
156
+
157
+ document.discount_percentage = 0 if document.discount_percentage.nil?
158
+
159
+ document.discount_amount = 0 if document.discount_amount.nil?
160
+
161
+ ## what is the maximum permissible amount?
162
+
163
+
164
+ ## give the add verified and declined ids, default values.
165
+
166
+ document.add_verified_ids ||= []
167
+ document.add_declined_ids ||= []
168
+
169
+
170
+
171
+ document.pending = document.pending - ([document.add_declined_ids + document.add_verified_ids].flatten)
172
+
173
+ document.verified = document.verified + document.add_verified_ids
174
+
175
+ document.declined = document.declined + document.add_declined_ids
176
+
177
+ end
178
+
179
+
180
+ ## all discounts are public to be searched.
181
+ before_save do |document|
182
+ self.public = "yes"
183
+ end
184
+
185
+
186
+
187
+ end
188
+
189
+ module ClassMethods
190
+
191
+
192
+
193
+
194
+
195
+
196
+ def find_discounts(options)
197
+ conditions = {:resource_id => nil}
198
+ conditions[:resource_id] = options[:resource].id.to_s if options[:resource]
199
+ Auth.configuration.discount_class.constantize.where(conditions)
200
+ end
201
+
202
+
203
+
204
+
205
+ ## @called_from : payment_concern.rb
206
+ ## @param[String] payment_id
207
+ ## @return[BSON::Document] the document after the update or nil, in case nothing was updated.
208
+ def add_pending_discount(payment_id,discount_object_id)
209
+ Auth.configuration.discount_class.constantize.
210
+ where({
211
+ "$and" => [
212
+ {
213
+ "verified" => {
214
+ "$ne" => payment_id
215
+ }
216
+ },
217
+ {
218
+ "pending" => {
219
+ "$ne" => payment_id
220
+ }
221
+ },
222
+ {
223
+ "declined" => {
224
+ "$ne" => payment_id
225
+ }
226
+ },
227
+ {
228
+ "_id" => BSON::ObjectId(discount_object_id)
229
+ }
230
+ ]
231
+ })
232
+ .find_one_and_update(
233
+ {
234
+ "$push" => {
235
+ :pending => payment_id
236
+ }
237
+ },
238
+ {
239
+ :return_document => :after
240
+ }
241
+ )
242
+ end
243
+
244
+ ## @called_from : payment_concern.rb
245
+ ## @param[String] payment_id : the id of the payment
246
+ ## @param[String] discount_object_id : the id of the discount object
247
+ ## @return[Integer] payment_status: returns the status that should be set for the payment.
248
+ ## @working: this def will match a discount object with the provided, id, and then filter the resulting fields to include any of the three arrays "pending","verified" or "declined" as long as they contain the payment id. It will return a payment_status that is to be set for the payment, based on teh result. If it finds that none of the arrays contain the payment id, then it will do a find and update to add the payment_id to the pending_array.
249
+
250
+ def get_payment_status(payment,discount_object_id)
251
+
252
+
253
+
254
+ results = Auth.configuration.discount_class.constantize.collection.aggregate([
255
+
256
+ {
257
+ "$match" => {
258
+ "_id" => BSON::ObjectId(discount_object_id)
259
+ }
260
+ },
261
+ {
262
+ "$project" => {
263
+ "verified" => {
264
+ "$filter" => {
265
+ "input" => "$verified",
266
+ "as" => "verified",
267
+ "cond" => {
268
+ "$eq" =>
269
+ [ "$$verified", payment.id.to_s
270
+ ]
271
+ }
272
+ }
273
+ },
274
+ "pending" => {
275
+ "$filter" => {
276
+ "input" => "$pending",
277
+ "as" => "pending",
278
+ "cond" => {
279
+ "$eq" =>
280
+ [ "$$pending", payment.id.to_s
281
+ ]
282
+ }
283
+ }
284
+ },
285
+ "declined" => {
286
+ "$filter" => {
287
+ "input" => "$declined",
288
+ "as" => "declined",
289
+ "cond" => {
290
+ "$eq" =>
291
+ [ "$$declined", payment.id.to_s
292
+ ]
293
+ }
294
+ }
295
+ }
296
+ }
297
+ }
298
+
299
+ ])
300
+
301
+ results_as_mongoid_docs = []
302
+
303
+ results.each do |r|
304
+ results_as_mongoid_docs << Mongoid::Factory.from_db(Auth.configuration.discount_class.constantize,r)
305
+ end
306
+
307
+ if results_as_mongoid_docs.empty?
308
+ ## this discont object does not exist
309
+ ## return 0
310
+ puts "------------------------there was no such discount object-----------------------------"
311
+ 0
312
+ elsif !results_as_mongoid_docs[0].verified.empty?
313
+ ## it has been verified
314
+ ## so return 1
315
+ puts "it has been verified"
316
+ 1
317
+ elsif !results_as_mongoid_docs[0].declined.empty?
318
+ ## it has been declined
319
+ ## so return 0
320
+ puts "it has been declined"
321
+ 0
322
+ elsif !results_as_mongoid_docs[0].pending.empty?
323
+ ## it has not yet been acted on
324
+ ## so return nil
325
+ puts "it is still pending."
326
+ nil
327
+ else
328
+ ## it has to still be added
329
+ ## so in this case also the payment status will remain nil
330
+ ## but this has to indicate that it should be still added.
331
+ ## execute a find_and_update, where the payment id is not present in any of the three arrays, and then add it to the pending array.
332
+ puts "came to add pending discount."
333
+ doc_after = self.add_pending_discount(payment.id.to_s,discount_object_id)
334
+ return 0 unless doc_after
335
+ return nil
336
+ end
337
+
338
+ end
339
+
340
+
341
+ ## @called_from : payment_concern.rb
342
+ ## decrements the count by 1
343
+ ## if enforce_single_use is passed as false, a given user can utilize the discount any number of times.
344
+ ## checks that the count of the discount_object is greater than one before doing this.
345
+ ## returns the updated document after the update is complete.
346
+ ## if the document returned afterwards is nil, then it means that the payment_status will be set as failed.
347
+ ## otherwise, set the payment_status as 1.
348
+ def use_discount(discount,payment,enforce_single_use = true)
349
+
350
+ ## so we can check here if the cart has any items pending, before running this.
351
+ ## so we can only use the discount if all cart items are accepted
352
+ if discount.cart_id
353
+ discount.cart_can_create_discount_coupons
354
+ end
355
+
356
+ if discount.errors.full_messages.empty?
357
+
358
+ query_hash = {
359
+ :_id => discount.id.to_s,
360
+ :pending => {"$ne" => payment.id.to_s},
361
+ :declined => {"$ne" => payment.id.to_s},
362
+ :count => {"$gte" => 1}
363
+ }
364
+ if enforce_single_use == true
365
+ query_hash[:used_by_users => {"$ne" => payment.resource_id.to_s}]
366
+ end
367
+ updated_doc = Auth.configuration.discount_class.constantize.where(query_hash).find_one_and_update({
368
+ "$inc" => {
369
+ :count => -1
370
+ },
371
+ "$push" => {
372
+ :used_by_users => payment.resource_id.to_s
373
+ }
374
+ },
375
+ {
376
+ :return_document => :after
377
+ }
378
+ )
379
+
380
+ return 0 if updated_doc.nil?
381
+ return 1
382
+
383
+ else
384
+ return 0
385
+ end
386
+
387
+ end
388
+
389
+
390
+
391
+ end
392
+
393
+ #######################################################
394
+ ##
395
+ ##
396
+ ## CALLBACK METHODS.
397
+ ##
398
+ ##
399
+ #######################################################
400
+
401
+ def set_cart
402
+ begin
403
+
404
+ if self.cart_id
405
+
406
+ self.cart = Auth.configuration.cart_class.constantize.find(self.cart_id)
407
+
408
+
409
+ self.cart.prepare_cart
410
+
411
+ end
412
+
413
+ rescue => e
414
+ puts e.to_s
415
+ end
416
+ end
417
+
418
+ #######################################################
419
+ ##
420
+ ##
421
+ ## VALIDATION METHODS.
422
+ ##
423
+ ##
424
+ #######################################################
425
+
426
+ def one_discount_object_per_cart
427
+ discount_coupons_with_cart =
428
+ Auth.configuration.discount_class.constantize.where(:cart_id => self.cart_id.to_s)
429
+
430
+ count = self.new_record? ? 0 : 1
431
+
432
+ self.errors.add(:cart,"you can only create one discount coupon per cart") if discount_coupons_with_cart.size > count
433
+
434
+ end
435
+
436
+
437
+ def cart_exists
438
+ self.errors.add(:cart,"the cart does not exist") unless self.cart
439
+ end
440
+
441
+ ## this should only be if a cart id is provided.
442
+ def cart_can_create_discount_coupons
443
+ set_cart unless self.cart
444
+ self.errors.add(:cart, "you cannot create discount coupons on this cart") unless cart.can_create_discount_coupons?
445
+ end
446
+
447
+
448
+ def user_can_create_discount_coupons
449
+ self.errors.add(:cart,"you cannot create discount coupons") unless get_resource.can_create_discount_coupons?
450
+ end
451
+
452
+
453
+ def cart_has_multiples_of_all_items
454
+ self.errors.add(:cart,"the cart must have equal numbers of all items") if self.cart.cart_items.select{|c| c.quantity != self.count}.size > 0
455
+ end
456
+
457
+
458
+ def discount_percentage_permitted
459
+ self.errors.add(:discount_percentage,"you cannot set a discount percentage") if self.discount_percentage > 0
460
+ end
461
+
462
+
463
+ def maximum_discount_amount
464
+ ## cannot exceed the sum of all cart items prices, we mean one multiple of the cart item prices.
465
+ self.errors.add(:discount_amount,"the discount amount cannot exceed:") if self.discount_amount > (self.cart.cart_items.map{|c| c = c.price}.inject(:+))
466
+ end
467
+
468
+
469
+
470
+ ## returns true if:
471
+ ## 1. the user is an admin
472
+ ## 2. there is no cart id.
473
+ def admin_and_cart_id_absent
474
+ #puts "signed in resource is:"
475
+ #puts signed_in_resource.to_s
476
+ #puts "is it an admin?"
477
+ #puts signed_in_resource.is_admin?
478
+ #puts "cart id is nil: #{cart_id.nil?}"
479
+ signed_in_resource.is_admin? && cart_id.nil?
480
+ end
481
+
482
+ end