usman 0.3.26 → 0.3.27

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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/usman/api/v1/docs_controller.rb +85 -6
  3. data/app/controllers/usman/api/v1/profile_controller.rb +5 -10
  4. data/app/controllers/usman/api/v1/registrations_controller.rb +136 -38
  5. data/app/models/device.rb +36 -2
  6. data/app/models/registration.rb +24 -2
  7. data/app/models/user.rb +24 -2
  8. data/app/views/usman/api/v1/docs/change_number/_neg_case_1.html.erb +30 -0
  9. data/app/views/usman/api/v1/docs/change_number/_neg_case_2.html.erb +30 -0
  10. data/app/views/usman/api/v1/docs/change_number/_neg_case_3.html.erb +40 -0
  11. data/app/views/usman/api/v1/docs/change_number/_neg_case_4.html.erb +42 -0
  12. data/app/views/usman/api/v1/docs/change_number/_neg_case_5.html.erb +40 -0
  13. data/app/views/usman/api/v1/docs/change_number/_neg_case_6.html.erb +40 -0
  14. data/app/views/usman/api/v1/docs/change_number/_neg_case_7.html.erb +38 -0
  15. data/app/views/usman/api/v1/docs/change_number/_pos_case_1.html.erb +37 -0
  16. data/app/views/usman/api/v1/docs/delete_account/_neg_case_1.html.erb +30 -0
  17. data/app/views/usman/api/v1/docs/delete_account/_neg_case_2.html.erb +30 -0
  18. data/app/views/usman/api/v1/docs/delete_account/_pos_case_1.html.erb +29 -0
  19. data/app/views/usman/api/v1/docs/send_otp_to_change_number/_neg_case_1.html.erb +30 -0
  20. data/app/views/usman/api/v1/docs/send_otp_to_change_number/_neg_case_2.html.erb +30 -0
  21. data/app/views/usman/api/v1/docs/send_otp_to_change_number/_neg_case_3.html.erb +35 -0
  22. data/app/views/usman/api/v1/docs/send_otp_to_change_number/_neg_case_4.html.erb +33 -0
  23. data/app/views/usman/api/v1/docs/send_otp_to_change_number/_pos_case_1.html.erb +32 -0
  24. data/app/views/usman/api/v1/docs/{single_contacts → single_contact}/_neg_case_1.html.erb +0 -0
  25. data/app/views/usman/api/v1/docs/{single_contacts → single_contact}/_pos_case_1.html.erb +0 -0
  26. data/config/locales/usman/api.ar.yml +58 -29
  27. data/config/locales/usman/api.en.yml +34 -28
  28. data/config/routes.rb +10 -1
  29. data/lib/usman/version.rb +1 -1
  30. data/spec/dummy/spec/factories/user.rb +4 -0
  31. metadata +22 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7af4414597edcc1c594ec129f781c08b1e065cf9
4
- data.tar.gz: 3fc75080e583e8690c928c59dc9631bd2790b720
3
+ metadata.gz: f92a7c718aee50ad9013355ee1a2cc4893dd7f71
4
+ data.tar.gz: 73cbf7609e77b3069772e09614c00cb36abaee49
5
5
  SHA512:
6
- metadata.gz: 6978436bb08a879e2083d2c6d942bbaffe3f6beb04139f6a9650beb7c32effbaa9ca9b691ac336a4c0c39aac99346216fed4d8a3bd9f652b9145d16c04b9b2db
7
- data.tar.gz: 171ec6ec396622040719344ff329c983a56468cc916a50d4f480f1a5f58cdd048f0eb7170a6e3e0165e77e60424ec84aeea59c5849703947569e8e5281d714cf
6
+ metadata.gz: da3684674e7e8442ca3d7b4116c17c0f57d2a681d5e31b57c87964b035f2a30ac53fd5bdc6133fcfb2fe03097d6aac55362b2d5dc27c32c4abc869b994080bde
7
+ data.tar.gz: ae26db23e9f3eff5b5b3169a9e9a3533e586f366574648cc86cb93daf2fe2c340f7bc9c5a8e8648a21173959f1e34796f2b5458e19ebe19f807137952929e2d8
@@ -207,7 +207,6 @@ module Usman
207
207
  render 'kuppayam/api/docs/show'
208
208
  end
209
209
 
210
-
211
210
  def contacts_sync
212
211
  set_title("Sync Contacts")
213
212
  @request_type = "POST"
@@ -278,8 +277,8 @@ module Usman
278
277
  render 'kuppayam/api/docs/show'
279
278
  end
280
279
 
281
- def single_contacts
282
- set_title("Single Contacts")
280
+ def single_contact
281
+ set_title("Single Contact")
283
282
  @request_type = "GET"
284
283
  @end_point = "/api/v1/contacts/:id"
285
284
  @description = <<-eos
@@ -296,7 +295,7 @@ module Usman
296
295
  @example_path = "usman/api/v1/docs/"
297
296
  @examples = ["pos_case_1", "neg_case_1"]
298
297
 
299
- set_nav("docs/usman/single_contacts")
298
+ set_nav("docs/usman/single_contact")
300
299
 
301
300
  render 'kuppayam/api/docs/show'
302
301
  end
@@ -375,6 +374,83 @@ module Usman
375
374
  render 'kuppayam/api/docs/show'
376
375
  end
377
376
 
377
+ def send_otp_to_change_number
378
+ set_title("Resend OTP API")
379
+ @request_type = "POST"
380
+ @end_point = "/api/v1/send_otp_to_change_number"
381
+ @description = <<-eos
382
+ This API will send the OTP as a confirmation to process the request to change the mobile number
383
+ eos
384
+
385
+ @input_headers = {
386
+ "Content-Type" => { value: "application/json", description: "The MIME media type for JSON text is application/json. This is to make sure that a valid json is returned. The default encoding is UTF-8. " }
387
+ }
388
+
389
+ @input_params = {
390
+ uuid: { mandatory: true, description: "Universal Unique Identifier. iOS or Android will give you this programatically.", example: "", default: "" }
391
+ }
392
+
393
+ @example_path = "usman/api/v1/docs/"
394
+ @examples = ["pos_case_1", "neg_case_1", "neg_case_2", "neg_case_3", "neg_case_4"]
395
+
396
+ set_nav("docs/usman/send_otp_to_change_number")
397
+
398
+ render 'kuppayam/api/docs/show'
399
+ end
400
+
401
+ def change_number
402
+ set_title("Change Number API")
403
+ @request_type = "POST"
404
+ @end_point = "/api/v1/change_number"
405
+ @description = <<-eos
406
+ This API along with the OTP will change the mobile number from old to new.
407
+ eos
408
+
409
+ @input_headers = {
410
+ "Content-Type" => { value: "application/json", description: "The MIME media type for JSON text is application/json. This is to make sure that a valid json is returned. The default encoding is UTF-8. " }
411
+ }
412
+
413
+ @input_params = {
414
+ otp: { mandatory: true, description: "One Time Password you have received via SMS. (Five Digit)", example: "51234", default: "" },
415
+ uuid: { mandatory: true, description: "Universal Unique Identifier. iOS or Android will give you this programatically.", example: "", default: "" },
416
+ old_dialing_prefix: { mandatory: true, description: "International Dialing Prefix for countries", example: "+91", default: "" },
417
+ old_mobile_number: { mandatory: true, description: "Mobile Number without Dialing Prefix", example: "If your mobile number is +971 54 312 9876, pass '543129876' without spaces.", default: "" },
418
+ new_dialing_prefix: { mandatory: true, description: "International Dialing Prefix for countries", example: "+971", default: "" },
419
+ new_mobile_number: { mandatory: true, description: "Mobile Number without Dialing Prefix", example: "If your mobile number is +971 54 312 9876, pass '543129876' without spaces.", default: "" }
420
+ }
421
+
422
+ @example_path = "usman/api/v1/docs/"
423
+ @examples = ["pos_case_1", "neg_case_1", "neg_case_2", "neg_case_3", "neg_case_4", "neg_case_5", "neg_case_6", "neg_case_7"]
424
+
425
+ set_nav("docs/usman/change_number")
426
+
427
+ render 'kuppayam/api/docs/show'
428
+ end
429
+
430
+ def delete_account
431
+ set_title("DELETE ACCOUNT API")
432
+ @request_type = "DELETE"
433
+ @end_point = "/api/v1/delete_account"
434
+ @description = <<-eos
435
+ This API will delete the account from the system and the user will be logged out from all sessions.
436
+ eos
437
+
438
+ @warning = "This is an irreversible action and the user will not be able to login back to this account again"
439
+
440
+ @input_headers = {
441
+ "Content-Type" => { value: "application/json", description: "The MIME media type for JSON text is application/json. This is to make sure that a valid json is returned. The default encoding is UTF-8. " }
442
+ }
443
+
444
+ @input_params = {}
445
+
446
+ @example_path = "usman/api/v1/docs/"
447
+ @examples = ["pos_case_1", "neg_case_1", "neg_case_2"]
448
+
449
+ set_nav("docs/usman/delete_account")
450
+
451
+ render 'kuppayam/api/docs/show'
452
+ end
453
+
378
454
  private
379
455
 
380
456
  def set_nav_items
@@ -388,10 +464,13 @@ module Usman
388
464
  get_profile_info: { nav_class: "docs/usman/get_profile_info", icon_class: "fa-user", url: usman.docs_api_v1_get_profile_info_path, text: "Get Profile Info API"},
389
465
  contacts_sync: { nav_class: "docs/usman/contacts_sync", icon_class: "fa-user", url: usman.docs_api_v1_contacts_sync_path, text: "Contact Syncing"},
390
466
  all_contacts: { nav_class: "docs/usman/all_contacts", icon_class: "fa-user", url: usman.docs_api_v1_all_contacts_path, text: "Get All Contacts"},
391
- single_contacts: { nav_class: "docs/usman/single_contacts", icon_class: "fa-user", url: usman.docs_api_v1_single_contacts_path, text: "Single Contact"},
467
+ single_contact: { nav_class: "docs/usman/single_contact", icon_class: "fa-user", url: usman.docs_api_v1_single_contact_path, text: "Single Contact"},
392
468
  upload_profile_picture_base64: { nav_class: "docs/usman/upload_profile_picture_base64", icon_class: "fa-photo", url: usman.docs_api_v1_upload_profile_picture_base64_path, text: "Upload Profile Picture (Base64)"},
393
469
  upload_profile_picture: { nav_class: "docs/usman/upload_profile_picture", icon_class: "fa-photo", url: usman.docs_api_v1_upload_profile_picture_path, text: "Upload Profile Picture"},
394
- delete_profile_picture: { nav_class: "docs/usman/delete_profile_picture", icon_class: "fa-photo", url: usman.docs_api_v1_delete_profile_picture_path, text: "Remove Profile Picture"}
470
+ delete_profile_picture: { nav_class: "docs/usman/delete_profile_picture", icon_class: "fa-photo", url: usman.docs_api_v1_delete_profile_picture_path, text: "Remove Profile Picture"},
471
+ send_otp_to_change_number: { nav_class: "docs/usman/send_otp_to_change_number", icon_class: "fa-phone", url: usman.docs_api_v1_send_otp_to_change_number_path, text: "Send OTP to Change Number"},
472
+ change_number: { nav_class: "docs/usman/change_number", icon_class: "fa-phone", url: usman.docs_api_v1_change_number_path, text: "Change Number"},
473
+ delete_account: { nav_class: "docs/usman/delete_account", icon_class: "fa-user", url: usman.docs_api_v1_delete_account_path, text: "Delete Account"},
395
474
  }
396
475
  end
397
476
 
@@ -22,17 +22,13 @@ module Usman
22
22
  @user.date_of_birth = permitted_params[:date_of_birth]
23
23
  @user.email = permitted_params[:email]
24
24
 
25
- @country = Country.find_by_id(permitted_params[:country_id])
26
- @city = City.find_by_id(permitted_params[:city_id])
25
+ @user.country = Country.find_by_id(permitted_params[:country_id])
26
+ @user.city = City.find_by_id(permitted_params[:city_id])
27
27
 
28
28
  if @user.valid?
29
29
  @user.save
30
30
  @user.approve!
31
31
  @current_registration.user = @user
32
-
33
- @user.country = @country if @country
34
- @user.city = @city if @city
35
-
36
32
  @current_registration.save
37
33
 
38
34
  # Saving the profile image if passed
@@ -107,13 +103,12 @@ module Usman
107
103
  @country = Country.find_by_id(permitted_params[:country_id])
108
104
  @city = City.find_by_id(permitted_params[:city_id])
109
105
 
106
+ @user.country = @country if @country
107
+ @user.city = @city if @city
108
+
110
109
  if @user.valid?
111
110
  @user.dummy = false
112
111
  @user.save
113
-
114
- @user.country = @country if @country
115
- @user.city = @city if @city
116
-
117
112
  @current_registration.save
118
113
 
119
114
  # Saving the profile image if passed
@@ -3,7 +3,7 @@ module Usman
3
3
  module V1
4
4
  class RegistrationsController < Usman::Api::V1::BaseController
5
5
 
6
- skip_before_action :require_api_token
6
+ skip_before_action :require_api_token, except: [:send_otp_to_change_number, :change_number, :delete_account]
7
7
 
8
8
  def register
9
9
  proc_code = Proc.new do
@@ -34,8 +34,8 @@ module Usman
34
34
  if @device.blocked?
35
35
  @success = false
36
36
  @errors = {
37
- heading: I18n.translate("api.resend_otp.device_blocked.heading"),
38
- message: I18n.translate("api.resend_otp.device_blocked.message"),
37
+ heading: I18n.translate("api.general.device_blocked.heading"),
38
+ message: I18n.translate("api.general.device_blocked.message"),
39
39
  details: {}
40
40
  }
41
41
  else
@@ -59,8 +59,8 @@ module Usman
59
59
  else
60
60
  @success = false
61
61
  @errors = {
62
- heading: I18n.translate("api.resend_otp.device_not_registered.heading"),
63
- message: I18n.translate("api.resend_otp.device_not_registered.message"),
62
+ heading: I18n.translate("api.general.device_not_registered.heading"),
63
+ message: I18n.translate("api.general.device_not_registered.message"),
64
64
  details: {
65
65
  uuid: "is invalid"
66
66
  }
@@ -69,8 +69,8 @@ module Usman
69
69
  else
70
70
  @success = false
71
71
  @errors = {
72
- heading: I18n.translate("api.resend_otp.mobile_number_not_registered.heading"),
73
- message: I18n.translate("api.resend_otp.mobile_number_not_registered.message"),
72
+ heading: I18n.translate("api.general.mobile_number_not_registered.heading"),
73
+ message: I18n.translate("api.general.mobile_number_not_registered.message"),
74
74
  details: {
75
75
  mobile_number: "is invalid"
76
76
  }
@@ -89,8 +89,8 @@ module Usman
89
89
  if @device.blocked?
90
90
  @success = false
91
91
  @errors = {
92
- heading: I18n.translate("api.verify_otp.device_blocked.heading"),
93
- message: I18n.translate("api.verify_otp.device_blocked.message"),
92
+ heading: I18n.translate("api.general.device_blocked.heading"),
93
+ message: I18n.translate("api.general.device_blocked.message"),
94
94
  details: {}
95
95
  }
96
96
  else
@@ -120,8 +120,8 @@ module Usman
120
120
  else
121
121
  @success = false
122
122
  @errors = {
123
- heading: I18n.translate("api.verify_otp.device_not_registered.heading"),
124
- message: I18n.translate("api.verify_otp.device_not_registered.message"),
123
+ heading: I18n.translate("api.general.device_not_registered.heading"),
124
+ message: I18n.translate("api.general.device_not_registered.message"),
125
125
  details: {
126
126
  uuid: "is invalid"
127
127
  }
@@ -130,8 +130,8 @@ module Usman
130
130
  else
131
131
  @success = false
132
132
  @errors = {
133
- heading: I18n.translate("api.verify_otp.mobile_number_not_registered.heading"),
134
- message: I18n.translate("api.verify_otp.mobile_number_not_registered.message"),
133
+ heading: I18n.translate("api.general.mobile_number_not_registered.heading"),
134
+ message: I18n.translate("api.general.mobile_number_not_registered.message"),
135
135
  details: {
136
136
  mobile_number: "is invalid"
137
137
  }
@@ -150,8 +150,8 @@ module Usman
150
150
  if @device.blocked?
151
151
  @success = false
152
152
  @errors = {
153
- heading: I18n.translate("api.accept_tac.device_blocked.heading"),
154
- message: I18n.translate("api.accept_tac.device_blocked.message"),
153
+ heading: I18n.translate("api.general.device_blocked.heading"),
154
+ message: I18n.translate("api.general.device_blocked.message"),
155
155
  details: {}
156
156
  }
157
157
  elsif @device.pending?
@@ -186,8 +186,8 @@ module Usman
186
186
  else
187
187
  @success = false
188
188
  @errors = {
189
- heading: I18n.translate("api.accept_tac.device_not_registered.heading"),
190
- message: I18n.translate("api.accept_tac.device_not_registered.message"),
189
+ heading: I18n.translate("api.general.device_not_registered.heading"),
190
+ message: I18n.translate("api.general.device_not_registered.message"),
191
191
  details: {
192
192
  uuid: "is invalid"
193
193
  }
@@ -196,8 +196,8 @@ module Usman
196
196
  else
197
197
  @success = false
198
198
  @errors = {
199
- heading: I18n.translate("api.verify_otp.mobile_number_not_registered.heading"),
200
- message: I18n.translate("api.verify_otp.mobile_number_not_registered.message"),
199
+ heading: I18n.translate("api.general.mobile_number_not_registered.heading"),
200
+ message: I18n.translate("api.general.mobile_number_not_registered.message"),
201
201
  details: {
202
202
  mobile_number: "is invalid"
203
203
  }
@@ -207,31 +207,131 @@ module Usman
207
207
  render_json_response(proc_code)
208
208
  end
209
209
 
210
- def accept_tac1
210
+ def send_otp_to_change_number
211
211
  proc_code = Proc.new do
212
- @device = Device.where("uuid = ?", params[:uuid]).first
213
- if @device
214
- if @device.blocked?
212
+ if @current_registration
213
+ unless @current_user
215
214
  @success = false
216
215
  @errors = {
217
- heading: I18n.translate("api.mobile_registration.device_blocked.heading"),
218
- message: I18n.translate("api.mobile_registration.device_blocked.message"),
219
- details: {}
216
+ heading: I18n.translate("api.profile.user_does_not_exists.heading"),
217
+ message: I18n.translate("api.profile.user_does_not_exists.message")
220
218
  }
221
219
  else
222
- valid, validation_errors = @device.accept_tac(params[:terms_and_conditions], params[:dialing_prefix], params[:mobile_number])
223
- if valid
220
+ @device = @current_registration.devices.where("uuid = ?", params[:uuid]).first
221
+
222
+ if @device
223
+ if @device.blocked?
224
+ @success = false
225
+ @errors = {
226
+ heading: I18n.translate("api.general.device_blocked.heading"),
227
+ message: I18n.translate("api.general.device_blocked.message"),
228
+ details: {}
229
+ }
230
+ else
231
+ @device.send_otp
232
+ @success = true
233
+ @alert = {
234
+ heading: I18n.translate("api.send_otp_to_change_number.otp_send.heading"),
235
+ message: I18n.translate("api.send_otp_to_change_number.otp_send.message")
236
+ }
237
+ end
238
+ else
239
+ @success = false
240
+ @errors = {
241
+ heading: I18n.translate("api.general.device_not_registered.heading"),
242
+ message: I18n.translate("api.general.device_not_registered.message"),
243
+ }
244
+ end
245
+ end
246
+ else
247
+ @success = false
248
+ @errors = {
249
+ heading: I18n.translate("api.profile.registration_details_missing.heading"),
250
+ message: I18n.translate("api.profile.registration_details_missing.message")
251
+ }
252
+ end
253
+ end
254
+ render_json_response(proc_code)
255
+ end
256
+
257
+ def change_number
258
+ proc_code = Proc.new do
259
+ if @current_registration
260
+ unless @current_user
261
+ @success = false
262
+ @errors = {
263
+ heading: I18n.translate("api.profile.user_does_not_exists.heading"),
264
+ message: I18n.translate("api.profile.user_does_not_exists.message")
265
+ }
266
+ else
267
+ @device = @current_registration.devices.where("uuid = ?", params[:uuid]).first
268
+
269
+ if @device
270
+ if @device.blocked?
271
+ @success = false
272
+ @errors = {
273
+ heading: I18n.translate("api.general.device_blocked.heading"),
274
+ message: I18n.translate("api.general.device_blocked.message"),
275
+ details: {}
276
+ }
277
+ else
278
+ valid, validation_errors = @device.change_number(params[:otp], params[:old_dialing_prefix], params[:old_mobile_number], params[:new_dialing_prefix], params[:new_mobile_number])
279
+ if valid
280
+ @success = true
281
+ @alert = {
282
+ heading: I18n.translate("api.change_number.number_changed.heading"),
283
+ message: I18n.translate("api.change_number.number_changed.message")
284
+ }
285
+ else
286
+ @success = false
287
+ @errors = {
288
+ heading: I18n.translate("api.change_number.number_change_failed.heading"),
289
+ message: I18n.translate("api.change_number.number_change_failed.message"),
290
+ details: validation_errors
291
+ }
292
+ end
293
+
294
+ end
295
+ else
296
+ @success = false
297
+ @errors = {
298
+ heading: I18n.translate("api.general.device_not_registered.heading"),
299
+ message: I18n.translate("api.general.device_not_registered.message"),
300
+ }
301
+ end
302
+ end
303
+ else
304
+ @success = false
305
+ @errors = {
306
+ heading: I18n.translate("api.profile.registration_details_missing.heading"),
307
+ message: I18n.translate("api.profile.registration_details_missing.message")
308
+ }
309
+ end
310
+ end
311
+ render_json_response(proc_code)
312
+ end
313
+
314
+ def delete_account
315
+ proc_code = Proc.new do
316
+ if @current_registration
317
+ unless @current_user
318
+ @success = false
319
+ @errors = {
320
+ heading: I18n.translate("api.profile.user_does_not_exists.heading"),
321
+ message: I18n.translate("api.profile.user_does_not_exists.message")
322
+ }
323
+ else
324
+ if @current_registration.delete!
224
325
  @success = true
225
326
  @alert = {
226
- heading: I18n.translate("api.mobile_registration.tac_accepted.heading"),
227
- message: I18n.translate("api.mobile_registration.tac_accepted.message")
327
+ heading: I18n.translate("api.delete_account.account_deleted.heading"),
328
+ message: I18n.translate("api.delete_account.account_deleted.message")
228
329
  }
229
- @data = { api_token: @device.api_token }
230
330
  else
231
331
  @success = false
232
332
  @errors = {
233
- heading: I18n.translate("api.mobile_registration.tac_not_accepted.heading"),
234
- message: I18n.translate("api.mobile_registration.tac_not_accepted.message"),
333
+ heading: I18n.translate("api.delete_account.account_deletion_failed.heading"),
334
+ message: I18n.translate("api.delete_account.account_deletion_failed.message"),
235
335
  details: validation_errors
236
336
  }
237
337
  end
@@ -239,16 +339,14 @@ module Usman
239
339
  else
240
340
  @success = false
241
341
  @errors = {
242
- heading: I18n.translate("api.general.unexpected_failure.heading"),
243
- message: I18n.translate("api.general.unexpected_failure.message"),
244
- details: {
245
- uuid: "is invalid"
246
- }
342
+ heading: I18n.translate("api.profile.registration_details_missing.heading"),
343
+ message: I18n.translate("api.profile.registration_details_missing.message")
247
344
  }
248
345
  end
249
346
  end
250
347
  render_json_response(proc_code)
251
348
  end
349
+
252
350
  end
253
351
  end
254
352
  end
data/app/models/device.rb CHANGED
@@ -145,7 +145,7 @@ class Device < ApplicationRecord
145
145
 
146
146
  def generate_otp
147
147
  self.otp = rand(10000..99999)
148
- self.otp_sent_at = nil
148
+ self.otp_sent_at = Time.now
149
149
  self.otp_verified_at = nil
150
150
  self.save
151
151
  end
@@ -155,7 +155,7 @@ class Device < ApplicationRecord
155
155
  # Validate OTP and other parameters
156
156
  validation_errors = {}
157
157
 
158
- # TODO - remove 11111 after implementing Twilio
158
+ # TODO - remove 11111
159
159
  validation_errors[:otp] = "doesn't match with our database" unless (self.otp.to_s == otp.to_s or otp.to_s == "11111")
160
160
  validation_errors[:mobile_number] = "doesn't match with our database" unless self.registration.mobile_number.to_s == mobile_number.to_s
161
161
  validation_errors[:dialing_prefix] = "doesn't match with our database" unless self.registration.dialing_prefix.to_s == dialing_prefix.to_s
@@ -225,6 +225,40 @@ class Device < ApplicationRecord
225
225
  return true, {}
226
226
  end
227
227
 
228
+ def change_number(otp, dialing_prefix, mobile_number, new_dialing_prefix, new_mobile_number)
229
+
230
+ # Validate OTP and other parameters
231
+ validation_errors = {}
232
+
233
+ # TODO - remove 11111 after implementing Twilio
234
+ validation_errors[:otp] = "can't be empty" if otp.blank?
235
+
236
+ validation_errors[:otp] = "doesn't match with our database" unless (self.otp.to_s == otp.to_s or otp.to_s == "11111")
237
+ validation_errors[:mobile_number] = "doesn't match with our database" unless self.registration.mobile_number.to_s == mobile_number.to_s
238
+ validation_errors[:dialing_prefix] = "doesn't match with our database" unless self.registration.dialing_prefix.to_s == dialing_prefix.to_s
239
+
240
+ self.registration.dialing_prefix = new_dialing_prefix
241
+ self.registration.mobile_number = new_mobile_number
242
+ self.registration.valid?
243
+ validation_errors[:mobile_number] = self.registration.errors[:mobile_number] unless self.registration.errors[:mobile_number].blank?
244
+ validation_errors[:dialing_prefix] = self.registration.errors[:dialing_prefix] unless self.registration.errors[:dialing_prefix].blank?
245
+
246
+ self.user.phone = new_dialing_prefix + new_mobile_number
247
+ self.user.valid?
248
+ validation_errors[:user_phone] = self.user.errors[:phone] unless self.user.errors[:phone].blank?
249
+
250
+ return false, validation_errors unless validation_errors.empty?
251
+
252
+ self.registration.save
253
+ self.user.save
254
+
255
+ # Clearing the OTP so that next time if he uses the same, it shows error
256
+ self.otp = nil
257
+ self.save
258
+
259
+ return true, {}
260
+ end
261
+
228
262
  def tac_accepted?
229
263
  self.tac_accepted_at.present? && self.tac_accepted_at < Time.now
230
264
  end
@@ -6,17 +6,20 @@ class Registration < ApplicationRecord
6
6
  PENDING = "pending"
7
7
  VERIFIED = "verified"
8
8
  SUSPENDED = "suspended"
9
+ DELETED = "deleted"
9
10
 
10
11
  STATUS = {
11
12
  PENDING => "Pending",
12
13
  VERIFIED => "Verified",
13
- SUSPENDED => "Suspended"
14
+ SUSPENDED => "Suspended",
15
+ DELETED => "Deleted"
14
16
  }
15
17
 
16
18
  STATUS_REVERSE = {
17
19
  "Pending" => PENDING,
18
20
  "Verified" => VERIFIED,
19
- "Suspended" => SUSPENDED
21
+ "Suspended" => SUSPENDED,
22
+ "Deleted" => DELETED
20
23
  }
21
24
 
22
25
  # Associations
@@ -50,6 +53,7 @@ class Registration < ApplicationRecord
50
53
  scope :pending, -> { where(status: PENDING) }
51
54
  scope :verified, -> { where(status: VERIFIED) }
52
55
  scope :suspended, -> { where(status: SUSPENDED) }
56
+ scope :deleted, -> { where(status: DELETED) }
53
57
 
54
58
  # ------------------
55
59
  # Instance Methods
@@ -92,6 +96,14 @@ class Registration < ApplicationRecord
92
96
  (status == SUSPENDED)
93
97
  end
94
98
 
99
+ # * Return true if the user is deleted, else false.
100
+ # == Examples
101
+ # >>> registration.deleted?
102
+ # => true
103
+ def deleted?
104
+ (status == DELETED)
105
+ end
106
+
95
107
  # change the status to :verified
96
108
  # Return the status
97
109
  # == Examples
@@ -122,6 +134,16 @@ class Registration < ApplicationRecord
122
134
  self.user.update_attribute(:status, SUSPENDED) if self.user
123
135
  end
124
136
 
137
+ # change the status to :deleted
138
+ # Return the status
139
+ # == Examples
140
+ # >>> registration.delete!
141
+ # => "deleted"
142
+ def delete!
143
+ self.update_attribute(:status, DELETED)
144
+ self.user.update_attribute(:status, DELETED) if self.user
145
+ end
146
+
125
147
  # Permission Methods
126
148
  # ------------------
127
149
 
data/app/models/user.rb CHANGED
@@ -7,17 +7,20 @@ class User < Usman::ApplicationRecord
7
7
  PENDING = "pending"
8
8
  APPROVED = "approved"
9
9
  SUSPENDED = "suspended"
10
+ DELETED = "deleted"
10
11
 
11
12
  STATUS = {
12
13
  PENDING => "Pending",
13
14
  APPROVED => "Approved",
14
- SUSPENDED => "Suspended"
15
+ SUSPENDED => "Suspended",
16
+ DELETED => "Deleted"
15
17
  }
16
18
 
17
19
  STATUS_REVERSE = {
18
20
  "Pending" => PENDING,
19
21
  "Approved" => APPROVED,
20
- "Suspended" => SUSPENDED
22
+ "Suspended" => SUSPENDED,
23
+ "Deleted" => DELETED
21
24
  }
22
25
 
23
26
  MALE = "male"
@@ -100,6 +103,7 @@ class User < Usman::ApplicationRecord
100
103
  scope :pending, -> { where(status: PENDING) }
101
104
  scope :approved, -> { where(status: APPROVED) }
102
105
  scope :suspended, -> { where(status: SUSPENDED) }
106
+ scope :deleted, -> { where(status: DELETED) }
103
107
 
104
108
  scope :super_admins, -> { where(super_admin: TRUE) }
105
109
  scope :normal_users, -> { where(super_admin: FALSE) }
@@ -177,6 +181,14 @@ class User < Usman::ApplicationRecord
177
181
  (status == SUSPENDED)
178
182
  end
179
183
 
184
+ # * Return true if the user is deleted, else false.
185
+ # == Examples
186
+ # >>> user.deleted?
187
+ # => true
188
+ def deleted?
189
+ (status == DELETED)
190
+ end
191
+
180
192
  # change the status to :pending
181
193
  # Return the status
182
194
  # == Examples
@@ -207,6 +219,16 @@ class User < Usman::ApplicationRecord
207
219
  self.registration.update_attribute(:status, SUSPENDED) if self.registration
208
220
  end
209
221
 
222
+ # change the status to :deleted
223
+ # Return the status
224
+ # == Examples
225
+ # >>> user.delete!
226
+ # => "deleted"
227
+ def delete!
228
+ self.update_attribute(:status, DELETED)
229
+ self.registration.update_attribute(:status, DELETED) if self.registration
230
+ end
231
+
210
232
  # Gender Methods
211
233
  # --------------
212
234
 
@@ -0,0 +1,30 @@
1
+ <%
2
+
3
+ api_title = "Negative Case - 1 - should set proper errors if api token is not present"
4
+
5
+ api_input = <<-eos
6
+ Example:
7
+
8
+ Authorization: nil
9
+ POST #{request.base_url}/api/v1/change_number
10
+ eos
11
+
12
+ api_output = <<-eos
13
+ {
14
+ "success": false,
15
+ "errors": {
16
+ "heading": "Invalid API Token",
17
+ "message": "Use the API Token you have received after accepting the terms and agreement"
18
+ }
19
+ }
20
+ eos
21
+
22
+ %>
23
+
24
+ <%= render partial: "kuppayam/api/docs/example", locals: {
25
+ negative_case: true,
26
+ example_id: "neg_case_1",
27
+ api_title: api_title,
28
+ api_input: api_input,
29
+ api_output: api_output
30
+ } %>