trex-model 1.3.7__tar.gz → 1.3.9__tar.gz

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.

Potentially problematic release.


This version of trex-model might be problematic. Click here for more details.

Files changed (61) hide show
  1. {trex-model-1.3.7/trex_model.egg-info → trex-model-1.3.9}/PKG-INFO +1 -1
  2. {trex-model-1.3.7 → trex-model-1.3.9}/setup.py +1 -1
  3. {trex-model-1.3.7 → trex-model-1.3.9/trex_model.egg-info}/PKG-INFO +1 -1
  4. {trex-model-1.3.7 → trex-model-1.3.9}/trex_model.egg-info/SOURCES.txt +1 -0
  5. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/lucky_draw_models.py +7 -3
  6. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/merchant_models.py +210 -8
  7. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/program_models.py +9 -8
  8. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/recruit_models.py +3 -1
  9. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/redemption_catalogue_models.py +2 -2
  10. trex-model-1.3.9/trexmodel/models/datastore/referral_program_model.py +370 -0
  11. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/program_conf.py +56 -4
  12. {trex-model-1.3.7 → trex-model-1.3.9}/LICENSE +0 -0
  13. {trex-model-1.3.7 → trex-model-1.3.9}/MANIFEST.in +0 -0
  14. {trex-model-1.3.7 → trex-model-1.3.9}/README.md +0 -0
  15. {trex-model-1.3.7 → trex-model-1.3.9}/setup.cfg +0 -0
  16. {trex-model-1.3.7 → trex-model-1.3.9}/trex_model.egg-info/dependency_links.txt +0 -0
  17. {trex-model-1.3.7 → trex-model-1.3.9}/trex_model.egg-info/requires.txt +0 -0
  18. {trex-model-1.3.7 → trex-model-1.3.9}/trex_model.egg-info/top_level.txt +0 -0
  19. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/__init__.py +0 -0
  20. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/conf.py +0 -0
  21. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/__init__.py +0 -0
  22. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/__init__.py +0 -0
  23. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/admin_models.py +0 -0
  24. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/analytic_models.py +0 -0
  25. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/app_models.py +0 -0
  26. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/coporate_models.py +0 -0
  27. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/customer_model_helpers.py +0 -0
  28. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/customer_models.py +0 -0
  29. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/fb_subsriber_models.py +0 -0
  30. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/import_models.py +0 -0
  31. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/inventory_model.py +0 -0
  32. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/loyalty_models.py +0 -0
  33. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/marketing_models.py +0 -0
  34. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/membership_models.py +0 -0
  35. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/message_model_helper.py +0 -0
  36. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/message_models.py +0 -0
  37. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/model_decorators.py +0 -0
  38. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/ndb_models.py +0 -0
  39. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/pos_models.py +0 -0
  40. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/prepaid_models.py +0 -0
  41. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/product_models.py +0 -0
  42. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/rating_models.py +0 -0
  43. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/redeem_models.py +0 -0
  44. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/reward_model_helpers.py +0 -0
  45. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/reward_models.py +0 -0
  46. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/spending_base_program_model.py +0 -0
  47. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/system_models.py +0 -0
  48. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/task_models.py +0 -0
  49. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/test_models.py +0 -0
  50. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/transaction_models.py +0 -0
  51. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/user_models.py +0 -0
  52. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/datastore/voucher_models.py +0 -0
  53. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/merchant_helpers.py +0 -0
  54. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/model_decorator.py +0 -0
  55. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/models/prepaid_helpers.py +0 -0
  56. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/pos_conf.py +0 -0
  57. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/utils/__init__.py +0 -0
  58. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/utils/gcloud/__init__.py +0 -0
  59. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/utils/gcloud/datastore_util.py +0 -0
  60. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/utils/model/__init__.py +0 -0
  61. {trex-model-1.3.7 → trex-model-1.3.9}/trexmodel/utils/model/model_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: trex-model
3
- Version: 1.3.7
3
+ Version: 1.3.9
4
4
  Summary: TRex database module package
5
5
  Home-page: https://bitbucket.org/lokjac/trex-model
6
6
  Author: Jack Lok
@@ -3,7 +3,7 @@ with open("README.md", "r") as fh:
3
3
  long_description = fh.read()
4
4
  setuptools.setup(
5
5
  name='trex-model',
6
- version='1.3.7',
6
+ version='1.3.9',
7
7
  author="Jack Lok",
8
8
  author_email="sglok77@gmail.com",
9
9
  description="TRex database module package",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: trex-model
3
- Version: 1.3.7
3
+ Version: 1.3.9
4
4
  Summary: TRex database module package
5
5
  Home-page: https://bitbucket.org/lokjac/trex-model
6
6
  Author: Jack Lok
@@ -43,6 +43,7 @@ trexmodel/models/datastore/rating_models.py
43
43
  trexmodel/models/datastore/recruit_models.py
44
44
  trexmodel/models/datastore/redeem_models.py
45
45
  trexmodel/models/datastore/redemption_catalogue_models.py
46
+ trexmodel/models/datastore/referral_program_model.py
46
47
  trexmodel/models/datastore/reward_model_helpers.py
47
48
  trexmodel/models/datastore/reward_models.py
48
49
  trexmodel/models/datastore/spending_base_program_model.py
@@ -58,9 +58,9 @@ class LuckyDrawProgram(LuckyDrawBase):
58
58
  'created_datetime', 'modified_datetime','archived_datetime', 'completed_status',
59
59
  'condition_settings', 'exclusivity_settings', 'prize_settings',
60
60
  'exclusive_tags_list', 'exclusive_memberships_list', 'exclusive_tier_memberships_list',
61
- 'created_by_username', 'modified_by_username', 'completed_prograss_in_percentage',
61
+ 'created_by_username', 'modified_by_username', 'completed_progress_in_percentage',
62
62
  'is_published', 'is_enabled','is_disabled', 'totalPrizePossibility',
63
- 'image_storage_filename', 'image_public_url', 'test_result',
63
+ 'image_storage_filename', 'image_public_url', 'test_result', 'is_expired',
64
64
  ]
65
65
 
66
66
 
@@ -95,6 +95,10 @@ class LuckyDrawProgram(LuckyDrawBase):
95
95
  def is_disabled(self):
96
96
  return self.enabled==False
97
97
 
98
+ @property
99
+ def is_expired(self):
100
+ return self.end_date<datetime.now().date()
101
+
98
102
  @property
99
103
  def is_archived(self):
100
104
  return self.archived
@@ -119,7 +123,7 @@ class LuckyDrawProgram(LuckyDrawBase):
119
123
  return ','.join(self.exclusivity_settings.get('tier_memberships')) or ''
120
124
 
121
125
  @property
122
- def completed_prograss_in_percentage(self):
126
+ def completed_progress_in_percentage(self):
123
127
  return program_conf.lucky_draw_program_completed_progress_percentage(self.completed_status)
124
128
 
125
129
  @property
@@ -67,30 +67,32 @@ class MerchantAcct(MerchantMin):
67
67
  outlet_count = ndb.IntegerProperty(default=0)
68
68
 
69
69
  published_program_configuration = ndb.JsonProperty()
70
+ published_referral_program_configuration = ndb.JsonProperty()
70
71
  published_voucher_configuration = ndb.JsonProperty()
71
72
  published_redemption_catalogue_configuration = ndb.JsonProperty()
72
73
 
73
74
  membership_configuration = ndb.JsonProperty()
74
75
  tier_membership_configuration = ndb.JsonProperty()
75
76
 
76
- reward_naming_configuration = ndb.JsonProperty()
77
+ reward_naming_configuration = ndb.JsonProperty()
77
78
 
78
- prepaid_configuration = ndb.JsonProperty()
79
+ prepaid_configuration = ndb.JsonProperty()
79
80
 
80
- lucky_draw_configuration = ndb.JsonProperty(required=False)
81
+ lucky_draw_configuration = ndb.JsonProperty(required=False)
81
82
 
82
- product_modifier_configuration = ndb.JsonProperty()
83
+ product_modifier_configuration = ndb.JsonProperty()
83
84
 
84
- program_settings = ndb.JsonProperty()
85
+ program_settings = ndb.JsonProperty()
85
86
 
86
- stat_figure_update_interval_in_minutes = conf.MERCHANT_STAT_FIGURE_UPDATE_INTERVAL_IN_MINUTES
87
- stat_figure_update_datetime_format = '%d-%m-%Y %H:%M:%S'
87
+ stat_figure_update_interval_in_minutes = conf.MERCHANT_STAT_FIGURE_UPDATE_INTERVAL_IN_MINUTES
88
+ stat_figure_update_datetime_format = '%d-%m-%Y %H:%M:%S'
88
89
 
89
90
  dict_properties = ['company_name', 'brand_name', 'contact_name', 'business_reg_no', 'mobile_phone',
90
91
  'office_phone', 'fax_phone', 'email', 'account_code', 'country',
91
92
  'registered_datetime', 'modified_datetime', 'plan_start_date', 'plan_end_date', 'currency_code',
92
93
  'timezone',
93
- 'published_program_configuration', 'published_voucher_configuration', 'membership_configuration',
94
+ 'published_program_configuration', 'published_referral_program_configuration',
95
+ 'published_voucher_configuration', 'membership_configuration',
94
96
  'tier_membership_configuration', 'prepaid_configuration', 'lucky_draw_configuration', 'product_modifier_configuration',
95
97
  'dashboard_stat_figure', 'program_settings', 'is_tier_membership_configured', 'website',
96
98
  'product_package', 'loyalty_package','account_plan','outlet_count', 'outlet_limit',
@@ -213,6 +215,47 @@ class MerchantAcct(MerchantMin):
213
215
  if self.lucky_draw_configuration.get('settings'):
214
216
  return self.lucky_draw_configuration['settings']['ticket_image_url']
215
217
 
218
+ @property
219
+ def referrer_promote_title(self):
220
+ if is_not_empty(self.program_settings):
221
+ if self.program_settings.get('referral_program'):
222
+ return self.program_settings.get('referral_program').get('referrer_promote_title', '')
223
+ return ''
224
+
225
+ @property
226
+ def referee_promote_title(self):
227
+ if is_not_empty(self.program_settings):
228
+ if self.program_settings.get('referral_program'):
229
+ return self.program_settings.get('referral_program').get('referee_promote_title', '')
230
+ return ''
231
+
232
+ @property
233
+ def referrer_promote_desc(self):
234
+ if is_not_empty(self.program_settings):
235
+ if self.program_settings.get('referral_program'):
236
+ return self.program_settings.get('referral_program').get('referrer_promote_desc', '')
237
+ return ''
238
+
239
+ @property
240
+ def referee_promote_desc(self):
241
+ if is_not_empty(self.program_settings):
242
+ if self.program_settings.get('referral_program'):
243
+ return self.program_settings.get('referral_program').get('referee_promote_desc', '')
244
+ return ''
245
+
246
+ @property
247
+ def referrer_promote_image(self):
248
+ if is_not_empty(self.program_settings):
249
+ if self.program_settings.get('referral_program'):
250
+ return self.program_settings.get('referral_program').get('referrer_promote_image')
251
+
252
+ @property
253
+ def referee_promote_image(self):
254
+ if is_not_empty(self.program_settings):
255
+ if self.program_settings.get('referral_program'):
256
+ return self.program_settings.get('referral_program').get('referee_promote_image')
257
+
258
+
216
259
  @staticmethod
217
260
  def default_program_settings():
218
261
  return {
@@ -222,7 +265,104 @@ class MerchantAcct(MerchantMin):
222
265
  'membership_renew_late_day' : 30,
223
266
 
224
267
  }
268
+
269
+ def update_referrer_program_promote_text(self,
270
+ promote_title=None,
271
+ promote_desc=None,
272
+ modified_by=None):
273
+ modified_by_username = None
274
+
275
+ if is_not_empty(modified_by):
276
+ if isinstance(modified_by, MerchantUser):
277
+ modified_by_username = modified_by.username
278
+
279
+ if is_empty(self.program_settings):
280
+ self.program_settings = {
281
+ 'referral_program':{}
282
+ }
283
+ else:
284
+ if is_empty(self.program_settings.get('referral_program')):
285
+ self.program_settings['referral_program'] = {}
286
+
287
+ self.modified_by = modified_by.create_ndb_key()
288
+ self.modified_by_username = modified_by_username
289
+
290
+ self.program_settings['referral_program']['referrer_promote_title'] = promote_title
291
+ self.program_settings['referral_program']['referrer_promote_desc'] = promote_desc
292
+ self.put()
293
+
294
+ def update_referee_program_promote_text(self,
295
+ promote_title=None,
296
+ promote_desc=None,
297
+ modified_by=None):
298
+ modified_by_username = None
299
+
300
+ if is_not_empty(modified_by):
301
+ if isinstance(modified_by, MerchantUser):
302
+ modified_by_username = modified_by.username
303
+
304
+ if is_empty(self.program_settings):
305
+ self.program_settings = {
306
+ 'referral_program':{}
307
+ }
308
+ else:
309
+ if is_empty(self.program_settings.get('referral_program')):
310
+ self.program_settings['referral_program'] = {}
225
311
 
312
+ self.modified_by = modified_by.create_ndb_key()
313
+ self.modified_by_username = modified_by_username
314
+
315
+ self.program_settings['referral_program']['referee_promote_title'] = promote_title
316
+ self.program_settings['referral_program']['referee_promote_desc'] = promote_desc
317
+ self.put()
318
+
319
+ def upload_referrer_program_promote_image(self, image_public_url=None, image_storage_filename=None, modified_by=None):
320
+
321
+ modified_by_username = None
322
+
323
+ if is_not_empty(modified_by):
324
+ if isinstance(modified_by, MerchantUser):
325
+ modified_by_username = modified_by.username
326
+
327
+ if is_empty(self.program_settings):
328
+ self.program_settings = {
329
+ 'referral_program':{}
330
+ }
331
+ else:
332
+ if is_empty(self.program_settings.get('referral_program')):
333
+ self.program_settings['referral_program'] = {}
334
+
335
+ self.program_settings['referral_program']['referrer_promote_image'] = image_public_url
336
+ self.program_settings['referral_program']['referrer_promote_image_filename'] = image_storage_filename
337
+
338
+ self.modified_by = modified_by.create_ndb_key()
339
+ self.modified_by_username = modified_by_username
340
+
341
+ self.put()
342
+
343
+ def upload_referee_program_promote_image(self, image_public_url=None, image_storage_filename=None, modified_by=None):
344
+
345
+ modified_by_username = None
346
+
347
+ if is_not_empty(modified_by):
348
+ if isinstance(modified_by, MerchantUser):
349
+ modified_by_username = modified_by.username
350
+
351
+ if is_empty(self.program_settings):
352
+ self.program_settings = {
353
+ 'referral_program':{}
354
+ }
355
+ else:
356
+ if is_empty(self.program_settings.get('referral_program')):
357
+ self.program_settings['referral_program'] = {}
358
+
359
+ self.program_settings['referral_program']['referee_promote_image'] = image_public_url
360
+ self.program_settings['referral_program']['referee_promote_image_filename'] = image_storage_filename
361
+
362
+ self.modified_by = modified_by.create_ndb_key()
363
+ self.modified_by_username = modified_by_username
364
+
365
+ self.put()
226
366
 
227
367
  @staticmethod
228
368
  def update_details(merchant_acct, company_name=None, brand_name=None, business_reg_no=None, contact_name=None,
@@ -408,6 +548,32 @@ class MerchantAcct(MerchantMin):
408
548
 
409
549
  self.put()
410
550
 
551
+ def update_published_referral_program(self, program_configuration):
552
+ if is_empty(self.published_referral_program_configuration):
553
+ self.published_referral_program_configuration = {
554
+ 'programs' :[program_configuration],
555
+ 'count' : 1,
556
+ }
557
+
558
+ else:
559
+ self.flush_dirty_program_configuration()
560
+ existing_programs_list = self.published_referral_program_configuration.get('programs')
561
+
562
+ program_key = program_configuration.get('program_key')
563
+ index = 0
564
+ for p in existing_programs_list:
565
+ if p.get('program_key') == program_key:
566
+ existing_programs_list.pop(index)
567
+
568
+ index = index+1
569
+
570
+ existing_programs_list.append(program_configuration)
571
+
572
+ self.published_referral_program_configuration['programs'] = existing_programs_list
573
+ self.published_referral_program_configuration['count'] = len(existing_programs_list)
574
+
575
+ self.put()
576
+
411
577
  def add_voucher(self, voucher_configuration):
412
578
  if is_empty(self.published_voucher_configuration):
413
579
  self.published_voucher_configuration = {
@@ -678,6 +844,42 @@ class MerchantAcct(MerchantMin):
678
844
 
679
845
  self.put()
680
846
 
847
+ def remove_program_from_published_referral_program_configuration(self, program_key_to_remove):
848
+
849
+ logger.debug('remove_program_from_published_referral_program_configuration: program_key_to_remove=%s', program_key_to_remove)
850
+
851
+ #self.flush_dirty_program_configuration()
852
+ existing_programs_list = self.published_referral_program_configuration['programs']
853
+ program_count = len(existing_programs_list)
854
+
855
+ logger.debug('program_count before remove=%s', program_count)
856
+
857
+ index = 0
858
+
859
+ for program in existing_programs_list:
860
+
861
+ logger.debug('program_key=%s', program.get('program_key'))
862
+
863
+ is_same_program_key = program.get('program_key') == program_key_to_remove
864
+
865
+ logger.debug('is_same_program_key=%s', is_same_program_key)
866
+
867
+ if is_same_program_key:
868
+ existing_programs_list.pop(index)
869
+
870
+ logger.debug('Found program to be remove')
871
+
872
+ index = index+1
873
+
874
+ program_count = len(existing_programs_list)
875
+
876
+ logger.debug('program_count after remove=%s', program_count)
877
+
878
+ self.published_referral_program_configuration['programs'] = existing_programs_list
879
+ self.published_referral_program_configuration['count'] = program_count
880
+
881
+ self.put()
882
+
681
883
 
682
884
 
683
885
  def remove_redeption_catalogue(self, catalogue_key):
@@ -252,10 +252,11 @@ class BaseProgram(BaseNModel, DictModel):
252
252
 
253
253
  program.put()
254
254
 
255
- merchant_acct = program.merchant_acct
256
- merchant_acct.remove_program_from_published_program_configuration(program.key_in_str)
257
-
258
- cls.__remove_schedule_program(program)
255
+ if program.is_published:
256
+ merchant_acct = program.merchant_acct
257
+ merchant_acct.remove_program_from_published_program_configuration(program.key_in_str)
258
+
259
+ cls.__remove_schedule_program(program)
259
260
 
260
261
  def to_configuration(self):
261
262
  program_configuration = {
@@ -279,7 +280,7 @@ class BaseProgram(BaseNModel, DictModel):
279
280
  class BasicRewardProgram(BaseProgram):
280
281
 
281
282
  @property
282
- def completed_prograss_in_percentage(self):
283
+ def completed_progress_in_percentage(self):
283
284
 
284
285
  return program_conf.program_completed_progress_percentage(self.completed_status, self.loyalty_package)
285
286
 
@@ -560,7 +561,7 @@ class BasicRewardProgram(BaseProgram):
560
561
  class MerchantProgram(BasicRewardProgram):
561
562
  dict_properties = ['reward_base', 'giveaway_method', 'reward_format', 'completed_status', 'start_date', 'end_date', 'label','desc', 'program_settings',
562
563
  'created_datetime', 'modified_datetime', 'enabled','completed_status','is_enabled', 'is_disabled', 'is_review_state',
563
- 'is_published', 'archived', 'is_reward_amount_required', 'completed_prograss_in_percentage', 'completed_status_index',
564
+ 'is_published', 'archived', 'is_reward_amount_required', 'completed_progress_in_percentage', 'completed_status_index',
564
565
  'exclusive_tags_list', 'exclusive_memberships_list', 'exclusive_tier_memberships_list',
565
566
  'is_recurring_scheme',
566
567
  'expiration_type', 'expiration_date', 'expiration_value', 'is_expiration_date_type',
@@ -661,13 +662,13 @@ class MerchantTierRewardProgram(MerchantProgram):
661
662
 
662
663
  dict_properties = ['completed_status', 'start_date', 'end_date', 'label', 'desc', 'program_settings', 'reward_format',
663
664
  'created_datetime', 'modified_datetime', 'enabled','completed_status','is_enabled', 'is_disabled', 'is_review_state',
664
- 'is_published', 'archived', 'completed_prograss_in_percentage', 'completed_status_index',
665
+ 'is_published', 'archived', 'completed_progress_in_percentage', 'completed_status_index',
665
666
  'exclusive_tags_list', 'exclusive_memberships_list', 'exclusive_tier_memberships_list',
666
667
  'is_tier_recycle', 'is_show_progress', 'max_unlock_tier_count_per_trax',
667
668
  'created_by_username', 'modified_by_username', 'loyalty_package']
668
669
 
669
670
  @property
670
- def completed_prograss_in_percentage(self):
671
+ def completed_progress_in_percentage(self):
671
672
  return program_conf.tier_reward_program_completed_progress_percentage(self.completed_status)
672
673
 
673
674
  @property
@@ -27,12 +27,13 @@ class CoFounderRecruit(RecruitBase):
27
27
  founding_details = ndb.TextProperty(required=False)
28
28
  employment_time = ndb.TextProperty(required=True)
29
29
  skill = ndb.TextProperty(required=True)
30
+ other_skill = ndb.TextProperty(required=True)
30
31
  linkedin_profile = ndb.TextProperty(required=True)
31
32
 
32
33
 
33
34
  @staticmethod
34
35
  def create(name=None, mobile_phone=None, email=None, address=None, involved_in_founding=False,
35
- founding_details=None, employment_time=None, skill=None, linkedin_profile=None):
36
+ founding_details=None, employment_time=None, skill=None, other_skill=None, linkedin_profile=None):
36
37
  CoFounderRecruit(
37
38
  name = name,
38
39
  mobile_phone = mobile_phone,
@@ -42,6 +43,7 @@ class CoFounderRecruit(RecruitBase):
42
43
  founding_details = founding_details,
43
44
  employment_time = employment_time,
44
45
  skill = skill,
46
+ other_skill = other_skill,
45
47
  linkedin_profile = linkedin_profile,
46
48
  ).put()
47
49
 
@@ -49,7 +49,7 @@ class RedemptionCatalogue(BaseNModel, DictModel):
49
49
  "label","desc","completed_status","start_date","end_date","created_datetime",
50
50
  "redeem_reward_format","catalogue_settings", "image_storage_filename", "image_public_url",
51
51
  "exclusive_tags_list", "exclusive_memberships_list", "exclusive_tier_memberships_list",
52
- "completed_prograss_in_percentage","completed_status_index", "catalogue_items",
52
+ "completed_progress_in_percentage","completed_status_index", "catalogue_items",
53
53
  "is_enabled", "is_disabled", "is_archived", "is_published", "loyalty_package",
54
54
  ]
55
55
 
@@ -93,7 +93,7 @@ class RedemptionCatalogue(BaseNModel, DictModel):
93
93
  return self.catalogue_settings.get('items') or []
94
94
 
95
95
  @property
96
- def completed_prograss_in_percentage(self):
96
+ def completed_progress_in_percentage(self):
97
97
  return program_conf.redemption_catalogue_completed_progress_percentage(self.completed_status, self.loyalty_package)
98
98
 
99
99
  @property
@@ -0,0 +1,370 @@
1
+ '''
2
+ Created on 8 Apr 2024
3
+
4
+ @author: jacklok
5
+ '''
6
+
7
+ from google.cloud import ndb
8
+ from trexmodel.models.datastore.ndb_models import BaseNModel, DictModel
9
+ import trexmodel.conf as model_conf
10
+ from trexlib.utils.string_util import is_not_empty, random_string, is_empty
11
+ from trexmodel.models.datastore.merchant_models import MerchantAcct, Outlet,\
12
+ MerchantUser
13
+ from trexmodel.models.datastore.coporate_models import CorporateAcct
14
+ import logging
15
+ from trexmodel import conf, program_conf
16
+ from datetime import datetime
17
+ from trexmodel.models.datastore.model_decorators import model_transactional
18
+ from trexlib.utils.common.common_util import sort_list, sort_dict_list
19
+ from builtins import staticmethod
20
+
21
+
22
+
23
+ #logger = logging.getLogger('model')
24
+ logger = logging.getLogger('debug')
25
+
26
+ class BaseProgram(BaseNModel, DictModel):
27
+ completed_status = ndb.StringProperty(required=True, choices=set(program_conf.REFERRAL_PROGRAM_STATUS))
28
+ #reward_format = ndb.StringProperty(required=False, choices=set(program_conf.REWARD_FORMAT_SET))
29
+ start_date = ndb.DateProperty(required=True)
30
+ end_date = ndb.DateProperty(required=True)
31
+
32
+ label = ndb.StringProperty(required=False)
33
+ desc = ndb.StringProperty(required=False)
34
+
35
+ promote_title = ndb.StringProperty(required=False)
36
+ promote_desc = ndb.StringProperty(required=False)
37
+
38
+ program_settings = ndb.JsonProperty(required=True)
39
+ created_datetime = ndb.DateTimeProperty(required=True, auto_now_add=True)
40
+ modified_datetime = ndb.DateTimeProperty(required=True, auto_now=True)
41
+ published_datetime = ndb.DateTimeProperty(required=False)
42
+ archived_datetime = ndb.DateTimeProperty(required=False)
43
+ remarks = ndb.StringProperty(required=False)
44
+
45
+ created_by = ndb.KeyProperty(name="created_by", kind=MerchantUser)
46
+ created_by_username = ndb.StringProperty(required=False)
47
+ modified_by = ndb.KeyProperty(name="modified_by", kind=MerchantUser)
48
+ modified_by_username = ndb.StringProperty(required=False)
49
+
50
+ enabled = ndb.BooleanProperty(default=True)
51
+ archived = ndb.BooleanProperty(default=False)
52
+
53
+ image_storage_filename = ndb.StringProperty(required=False)
54
+ image_public_url = ndb.StringProperty(required=False)
55
+
56
+ program_code = ndb.StringProperty(required=False)
57
+
58
+ loyalty_package = ndb.StringProperty(required=False, default=program_conf.LOYALTY_PACKAGE_SCALE)
59
+
60
+ @property
61
+ def is_enabled(self):
62
+ return self.enabled
63
+
64
+ @property
65
+ def is_disabled(self):
66
+ return self.enabled==False
67
+
68
+ @property
69
+ def is_archived(self):
70
+ return self.archived
71
+
72
+ @property
73
+ def is_published(self):
74
+ return self.completed_status == program_conf.PROGRAM_STATUS_PUBLISH
75
+
76
+ @property
77
+ def is_review_state(self):
78
+ return program_conf.is_existing_referral_program_status_final_state(self.completed_status)
79
+
80
+ @classmethod
81
+ @model_transactional(desc="publish_program")
82
+ def publish_program(cls, program):
83
+ program.completed_status = program_conf.PROGRAM_STATUS_PUBLISH
84
+ program.published_datetime = datetime.now()
85
+ program.put()
86
+
87
+ merchant_acct = program.merchant_acct_entity
88
+ merchant_acct.update_published_referral_program(program.to_configuration())
89
+
90
+ @classmethod
91
+ @model_transactional(desc="archive_program")
92
+ def archive_program(cls, program):
93
+ program.archived = True
94
+ program.archived_datetime = datetime.now()
95
+ program.put()
96
+
97
+ merchant_acct = program.merchant_acct_entity
98
+ merchant_acct.remove_program_from_published_referral_program_configuration(program.key_in_str)
99
+
100
+
101
+ @classmethod
102
+ @model_transactional(desc="enable program")
103
+ def enable(cls, program, modified_by=None):
104
+ program.enabled = True
105
+
106
+ modified_by_username = None
107
+
108
+ if is_not_empty(modified_by):
109
+ if isinstance(modified_by, MerchantUser):
110
+ modified_by_username = modified_by.username
111
+
112
+ program.modified_by = modified_by.create_ndb_key()
113
+ program.modified_by_username = modified_by_username
114
+
115
+ if program.is_published:
116
+ merchant_acct = program.merchant_acct_entity
117
+ merchant_acct.update_published_referral_program(program.to_configuration())
118
+
119
+ program.put()
120
+
121
+ @classmethod
122
+ @model_transactional(desc="disable program")
123
+ def disable(cls, program, modified_by=None):
124
+ program.enabled = False
125
+
126
+ modified_by_username = None
127
+
128
+ if is_not_empty(modified_by):
129
+ if isinstance(modified_by, MerchantUser):
130
+ modified_by_username = modified_by.username
131
+ program.modified_by = modified_by.create_ndb_key()
132
+
133
+ program.modified_by_username = modified_by_username
134
+
135
+ program.put()
136
+
137
+ if program.is_published:
138
+ merchant_acct = program.merchant_acct_entity
139
+ merchant_acct.remove_program_from_published_referral_program_configuration(program.key_in_str)
140
+
141
+ @property
142
+ def merchant_acct_entity(self):
143
+ return MerchantAcct.fetch(self.key.parent().urlsafe())
144
+
145
+ def to_configuration(self):
146
+ program_configuration = {
147
+ 'merchant_acct_key' : self.parent_key,
148
+ 'program_key' : self.key_in_str,
149
+ 'label' : self.label,
150
+ 'desc' : self.desc,
151
+ 'start_date' : self.start_date.strftime('%d-%m-%Y'),
152
+ 'end_date' : self.end_date.strftime('%d-%m-%Y'),
153
+ 'promote_title' : self.promote_title,
154
+ 'promote_desc' : self.promote_desc,
155
+ 'promote_image_link' : self.image_public_url,
156
+ 'program_settings' : self.program_settings,
157
+ 'is_published' : self.is_published,
158
+ }
159
+
160
+ return program_configuration
161
+
162
+ class MerchantReferralProgram(BaseProgram):
163
+ dict_properties = [
164
+ 'completed_status', 'start_date', 'end_date', 'label','desc',
165
+ 'program_settings',
166
+ 'created_datetime', 'modified_datetime', 'enabled',
167
+ 'archived_datetime',
168
+ 'is_enabled', 'is_disabled', 'is_review_state',
169
+ 'is_published', 'archived', 'completed_progress_in_percentage',
170
+ 'completed_status_index',
171
+ 'promote_title', 'promote_desc', 'promote_image_link',
172
+ 'remarks', 'loyalty_package', 'image_storage_filename', 'image_public_url',
173
+ 'created_by_username', 'modified_by_username']
174
+
175
+
176
+ @property
177
+ def promote_image_link(self):
178
+ return self.image_public_url
179
+
180
+ @property
181
+ def completed_progress_in_percentage(self):
182
+ return program_conf.referral_program_completed_progress_percentage(self.completed_status)
183
+
184
+ @property
185
+ def completed_status_index(self):
186
+ return program_conf.get_referral_program_completed_status_index(self.completed_status)
187
+
188
+ @staticmethod
189
+ def create(merchant_acct, label=None,
190
+ desc=None, start_date=None, end_date=None, created_by=None,
191
+ default_promote_image = None,
192
+ loyalty_package = program_conf.LOYALTY_PACKAGE_SCALE,
193
+ ):
194
+
195
+ created_by_username = None
196
+ if is_not_empty(created_by):
197
+ if isinstance(created_by, MerchantUser):
198
+ created_by_username = created_by.username
199
+
200
+ program_settings = {
201
+ }
202
+
203
+
204
+
205
+ merchant_program = MerchantReferralProgram(
206
+ parent = merchant_acct.create_ndb_key(),
207
+ label = label,
208
+ #reward_format = reward_format,
209
+ desc = desc,
210
+ start_date = start_date,
211
+ end_date = end_date,
212
+ created_by = created_by.create_ndb_key(),
213
+ created_by_username = created_by_username,
214
+ completed_status = program_conf.PROGRAM_STATUS_PROGRAM_BASE,
215
+ program_settings = program_settings,
216
+ loyalty_package = loyalty_package,
217
+ image_public_url = default_promote_image,
218
+ )
219
+
220
+ merchant_program.put()
221
+ return merchant_program
222
+
223
+ @staticmethod
224
+ def update_program_base_data(program, label=None,
225
+ desc=None,start_date=None, end_date=None, modified_by=None,
226
+ default_promote_image = None,
227
+ loyalty_package=program_conf.LOYALTY_PACKAGE_LITE,
228
+ ):
229
+
230
+ modified_by_username = None
231
+
232
+ if is_not_empty(modified_by):
233
+ if isinstance(modified_by, MerchantUser):
234
+ modified_by_username = modified_by.username
235
+
236
+ program_settings = program.program_settings or {}
237
+
238
+
239
+ program.label = label
240
+ program.desc = desc
241
+ #program.reward_format = reward_format
242
+ program.start_date = start_date
243
+ program.end_date = end_date
244
+ program.modified_by = modified_by.create_ndb_key()
245
+ program.modified_by_username = modified_by_username
246
+ program.completed_status = program_conf.PROGRAM_STATUS_PROGRAM_BASE
247
+ program.program_settings = program_settings
248
+ program.loyalty_package = loyalty_package
249
+ program.image_public_url = default_promote_image
250
+
251
+
252
+ program.put()
253
+
254
+ return program
255
+
256
+ @staticmethod
257
+ def define_referrer_reward(program, modified_by=None):
258
+
259
+ modified_by_username = None
260
+
261
+ if is_not_empty(modified_by):
262
+ if isinstance(modified_by, MerchantUser):
263
+ modified_by_username = modified_by.username
264
+
265
+ program.modified_by = modified_by.create_ndb_key()
266
+ program.modified_by_username = modified_by_username
267
+ program.completed_status = program_conf.PROGRAM_STATUS_DEFINE_REFERRER_REWARD
268
+
269
+
270
+ program.put()
271
+
272
+ return program
273
+
274
+ @staticmethod
275
+ def define_referee_reward(program, modified_by=None):
276
+
277
+ modified_by_username = None
278
+
279
+ if is_not_empty(modified_by):
280
+ if isinstance(modified_by, MerchantUser):
281
+ modified_by_username = modified_by.username
282
+
283
+ program.modified_by = modified_by.create_ndb_key()
284
+ program.modified_by_username = modified_by_username
285
+ program.completed_status = program_conf.PROGRAM_STATUS_DEFINE_REFEREE_REWARD
286
+
287
+
288
+ program.put()
289
+
290
+ return program
291
+
292
+ @staticmethod
293
+ def __add_program_reward(program, point_configuration, modified_by=None, target_reward_items_naming='referrer_reward_items'):
294
+ modified_by_username = None
295
+
296
+ rewards_list = None
297
+
298
+ if is_not_empty(modified_by):
299
+ if isinstance(modified_by, MerchantUser):
300
+ modified_by_username = modified_by.username
301
+
302
+ if program.program_settings is None:
303
+ rewards_list = []
304
+ program_settings = {}
305
+
306
+ else:
307
+ program_settings = program.program_settings
308
+ rewards_list = program_settings.get(target_reward_items_naming) or []
309
+
310
+
311
+ rewards_list.append(point_configuration)
312
+ logger.debug('rewards_list=%s', rewards_list)
313
+ program_settings[target_reward_items_naming] = rewards_list
314
+
315
+ program.modified_by = modified_by.create_ndb_key()
316
+ program.modified_by_username = modified_by_username
317
+ program.program_settings = program_settings
318
+
319
+ program.put()
320
+
321
+ return program
322
+
323
+ @staticmethod
324
+ def __remove_program_reward(program, voucher_index, modified_by=None, target_reward_items_naming='referrer_reward_items'):
325
+ if is_not_empty(modified_by):
326
+ if isinstance(modified_by, MerchantUser):
327
+ modified_by_username = modified_by.username
328
+
329
+ program_settings = program.program_settings
330
+ existing_rewards_list = program_settings.get(target_reward_items_naming) or []
331
+ new_rewards_list = []
332
+ for reward in existing_rewards_list:
333
+ if reward.get('reward_index') !=voucher_index:
334
+ new_rewards_list.append(reward)
335
+
336
+ program_settings[target_reward_items_naming] = new_rewards_list
337
+
338
+ program.modified_by = modified_by.create_ndb_key()
339
+ program.modified_by_username = modified_by_username
340
+ program.program_settings = program_settings
341
+
342
+ program.put()
343
+
344
+ @staticmethod
345
+ def add_referrer_program_reward(program, reward_configuration, modified_by=None):
346
+ return MerchantReferralProgram.__add_program_reward(program, reward_configuration, modified_by=modified_by, target_reward_items_naming='referrer_reward_items')
347
+
348
+ @staticmethod
349
+ def add_referee_program_reward(program, reward_configuration, modified_by=None):
350
+ return MerchantReferralProgram.__add_program_reward(program, reward_configuration, modified_by=modified_by, target_reward_items_naming='referee_reward_items')
351
+
352
+ @staticmethod
353
+ def remove_referrer_program_reward(program, reward_index, modified_by=None):
354
+ MerchantReferralProgram.__remove_program_reward(program, reward_index, modified_by=modified_by, target_reward_items_naming='referrer_reward_items')
355
+
356
+ @staticmethod
357
+ def remove_referee_program_reward(program, reward_index, modified_by=None):
358
+ MerchantReferralProgram.__remove_program_reward(program, reward_index, modified_by=modified_by, target_reward_items_naming='referee_reward_items')
359
+
360
+ @staticmethod
361
+ def list_by_merchant_account(merchant_acct):
362
+ return MerchantReferralProgram.query(ndb.AND(MerchantReferralProgram.archived!=True), ancestor=merchant_acct.create_ndb_key()).fetch(limit=model_conf.MAX_FETCH_RECORD)
363
+
364
+ @staticmethod
365
+ def list_archived_by_merchant_account(merchant_acct):
366
+ return MerchantReferralProgram.query(ndb.AND(MerchantReferralProgram.archived==True), ancestor=merchant_acct.create_ndb_key()).fetch(limit=model_conf.MAX_FETCH_RECORD)
367
+
368
+
369
+
370
+
@@ -43,6 +43,7 @@ FEATURE_CODE_TIER_REWARD_PROGRAM = 'tier_reward'
43
43
  FEATURE_CODE_REWARDING_PROGRAM = 'rewarding'
44
44
  FEATURE_CODE_REDEMPTION_PROGRAM = 'redemption'
45
45
  FEATURE_CODE_LUCKY_DRAW_PROGRAM = 'lucky_draw'
46
+ FEATURE_CODE_REFERRAL_PROGRAM = 'referral'
46
47
 
47
48
  PRODUCT_CODE_POINT_OF_SALES = 'pos'
48
49
  PRODUCT_CODE_LOYALTY = 'loyalty'
@@ -114,7 +115,7 @@ PACKAGE_FEATURE_PROGRAM_MAP = {
114
115
  FEATURE_CODE_REWARDING_PROGRAM,
115
116
  FEATURE_CODE_REDEMPTION_PROGRAM,
116
117
  FEATURE_CODE_LUCKY_DRAW_PROGRAM,
117
-
118
+ FEATURE_CODE_REFERRAL_PROGRAM,
118
119
  ],
119
120
 
120
121
  }
@@ -197,12 +198,17 @@ PROGRAM_STATUS_DEFINE_TIER = 'define_program_tier'
197
198
  PROGRAM_STATUS_DEFINE_REWARD = 'define_reward'
198
199
  PROGRAM_STATUS_DEFINE_CONDITION = 'define_condition'
199
200
  PROGRAM_STATUS_UPLOAD_TICKET_IMAGE = 'upload_material'
201
+ PROGRAM_STATUS_UPLOAD_MATERIAL = 'upload_material'
200
202
  PROGRAM_STATUS_DEFINE_PRIZE = 'define_prize'
201
203
  PROGRAM_STATUS_DEFINE_PRIZE_POSSIBILITY = 'define_prize_possibility'
202
204
  PROGRAM_STATUS_EXCLUSIVITY = 'exclusivity'
203
205
  PROGRAM_STATUS_REVIEW = 'review'
204
206
  PROGRAM_STATUS_PUBLISH = 'published'
205
207
  PROGRAM_STATUS_DEFINE_ITEM = 'define_item'
208
+ PROGRAM_STATUS_DEFINE_PROMOTE_TEXT = 'define_promote_text'
209
+
210
+ PROGRAM_STATUS_DEFINE_REFERRER_REWARD = 'define_program_referrer_reward'
211
+ PROGRAM_STATUS_DEFINE_REFEREE_REWARD = 'define_program_referee_reward'
206
212
 
207
213
  ACTION_AFTER_UNLOCK_TIER_NO_ACTION = 'no_action'
208
214
  ACTION_AFTER_UNLOCK_TIER_CONSUME_REWARD = 'consume_reward'
@@ -243,6 +249,14 @@ BASIC_REWARD_PROGRAM_STATUS = [PROGRAM_STATUS_PROGRAM_B
243
249
  PROGRAM_STATUS_PUBLISH
244
250
  ]
245
251
 
252
+ REFERRAL_REWARD_PROGRAM_STATUS = [PROGRAM_STATUS_PROGRAM_BASE,
253
+ PROGRAM_STATUS_DEFINE_REFERRER_REWARD,
254
+ PROGRAM_STATUS_DEFINE_REFEREE_REWARD,
255
+ PROGRAM_STATUS_REVIEW,
256
+ PROGRAM_STATUS_PUBLISH
257
+ ]
258
+
259
+
246
260
  LITE_BASIC_REWARD_PROGRAM_STATUS = [PROGRAM_STATUS_PROGRAM_BASE,
247
261
  PROGRAM_STATUS_REWARD_SCHEME,
248
262
  PROGRAM_STATUS_REVIEW,
@@ -260,10 +274,19 @@ TIER_REWARD_PROGRAM_STATUS = [PROGRAM_STATUS_PROGRAM_BA
260
274
  LUCKY_DRAW_PROGRAM_STATUS = [
261
275
  PROGRAM_STATUS_PROGRAM_BASE,
262
276
  #PROGRAM_STATUS_DEFINE_CONDITION,
263
- PROGRAM_STATUS_UPLOAD_TICKET_IMAGE,
264
- PROGRAM_STATUS_DEFINE_PRIZE,
277
+ PROGRAM_STATUS_DEFINE_PRIZE,
265
278
  PROGRAM_STATUS_DEFINE_PRIZE_POSSIBILITY,
266
279
  PROGRAM_STATUS_EXCLUSIVITY,
280
+ PROGRAM_STATUS_UPLOAD_TICKET_IMAGE,
281
+ PROGRAM_STATUS_PUBLISH,
282
+ ]
283
+
284
+ REFERRAL_PROGRAM_STATUS = [PROGRAM_STATUS_PROGRAM_BASE,
285
+ PROGRAM_STATUS_DEFINE_REFERRER_REWARD,
286
+ PROGRAM_STATUS_DEFINE_REFEREE_REWARD,
287
+ #PROGRAM_STATUS_DEFINE_PROMOTE_TEXT,
288
+ #PROGRAM_STATUS_UPLOAD_MATERIAL,
289
+ #PROGRAM_STATUS_REVIEW,
267
290
  PROGRAM_STATUS_PUBLISH,
268
291
  ]
269
292
 
@@ -273,7 +296,7 @@ ALL_PROGRAM_STATUS = (PROGRAM_STATUS_PROGRAM_BASE,
273
296
  PROGRAM_STATUS_DEFINE_REWARD,
274
297
  PROGRAM_STATUS_EXCLUSIVITY,
275
298
  PROGRAM_STATUS_REVIEW,
276
- PROGRAM_STATUS_PUBLISH
299
+ PROGRAM_STATUS_PUBLISH,
277
300
  )
278
301
 
279
302
  REDEMPTION_CATALOGUE_STATUS_DEFINED_CATALOGUE = 'define_catalogue'
@@ -368,6 +391,7 @@ REWARD_EXPIRATION_TYPE_AFTER_YEAR = 'year'
368
391
  REWARD_EXPIRATION_TYPE_AFTER_MONTH = 'month'
369
392
  REWARD_EXPIRATION_TYPE_AFTER_WEEK = 'week'
370
393
  REWARD_EXPIRATION_TYPE_AFTER_DAY = 'day'
394
+ REWARD_EXPIRATION_TYPE_END_OF_MONTH = 'eom'
371
395
 
372
396
  FIRST_DAY_OF_MONTH = 'month_start'
373
397
  ON_DOB_DATE = 'dob_date'
@@ -451,6 +475,9 @@ def get_lucky_draw_program_completed_status_index(completed_status):
451
475
  def get_redemption_catalogue_completed_status_index(completed_status):
452
476
  return REDEMPTION_CATALOGUE_STATUS.index(completed_status)
453
477
 
478
+ def get_referral_program_completed_status_index(completed_status):
479
+ return REFERRAL_PROGRAM_STATUS.index(completed_status)
480
+
454
481
  def is_program_current_status_reach(checking_status, completed_status):
455
482
  completed_status_index = get_program_completed_status_index(completed_status)
456
483
  checking_status_index = get_program_completed_status_index(checking_status)
@@ -460,6 +487,15 @@ def is_program_current_status_reach(checking_status, completed_status):
460
487
 
461
488
  return checking_status_index<=completed_status_index+1
462
489
 
490
+ def is_referral_program_current_status_reach(checking_status, completed_status):
491
+ completed_status_index = get_referral_program_completed_status_index(completed_status)
492
+ checking_status_index = get_referral_program_completed_status_index(checking_status)
493
+
494
+ print('completed_status_index=%s'%completed_status_index)
495
+ print('checking_status_index=%s'%checking_status_index)
496
+
497
+ return checking_status_index<=completed_status_index+1
498
+
463
499
  def is_voucher_current_status_reach(checking_status, completed_status):
464
500
  completed_status_index = get_voucher_completed_status_index(completed_status)
465
501
  checking_status_index = get_voucher_completed_status_index(checking_status)
@@ -494,6 +530,12 @@ def is_valid_to_update_program_status(checking_status, completed_status):
494
530
 
495
531
  return checking_status_index<=completed_status_index+1
496
532
 
533
+ def is_valid_to_update_referral_program_status(checking_status, completed_status):
534
+ completed_status_index = get_referral_program_completed_status_index(completed_status)
535
+ checking_status_index = get_referral_program_completed_status_index(checking_status)
536
+
537
+ return checking_status_index<=completed_status_index+1
538
+
497
539
  def is_valid_to_update_voucher_status(checking_status, completed_status):
498
540
  completed_status_index = get_voucher_completed_status_index(completed_status)
499
541
  checking_status_index = get_voucher_completed_status_index(checking_status)
@@ -524,6 +566,11 @@ def is_existing_program_status_final_state(completed_status):
524
566
 
525
567
  return completed_status_index==len(BASIC_REWARD_PROGRAM_STATUS)-1
526
568
 
569
+ def is_existing_referral_program_status_final_state(completed_status):
570
+ completed_status_index = get_referral_program_completed_status_index(completed_status)
571
+
572
+ return completed_status_index==len(BASIC_REWARD_PROGRAM_STATUS)-1
573
+
527
574
  def is_existing_tier_reward_program_status_final_state(completed_status):
528
575
  completed_status_index = get_tier_reward_program_completed_status_index(completed_status)
529
576
 
@@ -559,3 +606,8 @@ def redemption_catalogue_completed_progress_percentage(completed_status, loyalty
559
606
  return int((completed_status_index+1)/len(LITE_REDEMPTION_CATALOGUE_STATUS) * 100)
560
607
  else:
561
608
  return int((completed_status_index+1)/len(REDEMPTION_CATALOGUE_STATUS) * 100)
609
+
610
+ def referral_program_completed_progress_percentage(completed_status):
611
+ completed_status_index = get_referral_program_completed_status_index(completed_status)
612
+ print('referral_program_completed_progress_percentage: completed_status_index(%s)=%s'% (completed_status,completed_status_index))
613
+ return int((completed_status_index+1)/len(REFERRAL_PROGRAM_STATUS) * 100)
File without changes
File without changes
File without changes
File without changes
File without changes