trex-model 1.2.7__tar.gz → 1.2.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 (59) hide show
  1. {trex-model-1.2.7/trex_model.egg-info → trex-model-1.2.9}/PKG-INFO +1 -1
  2. {trex-model-1.2.7 → trex-model-1.2.9}/setup.py +1 -1
  3. {trex-model-1.2.7 → trex-model-1.2.9/trex_model.egg-info}/PKG-INFO +1 -1
  4. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/customer_models.py +23 -7
  5. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/membership_models.py +2 -1
  6. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/merchant_models.py +62 -5
  7. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/product_models.py +4 -0
  8. trex-model-1.2.9/trexmodel/models/datastore/redemption_catalogue_models.py +373 -0
  9. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/voucher_models.py +9 -3
  10. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/program_conf.py +26 -5
  11. trex-model-1.2.7/trexmodel/models/datastore/redemption_catalogue_models.py +0 -22
  12. {trex-model-1.2.7 → trex-model-1.2.9}/LICENSE +0 -0
  13. {trex-model-1.2.7 → trex-model-1.2.9}/MANIFEST.in +0 -0
  14. {trex-model-1.2.7 → trex-model-1.2.9}/README.md +0 -0
  15. {trex-model-1.2.7 → trex-model-1.2.9}/setup.cfg +0 -0
  16. {trex-model-1.2.7 → trex-model-1.2.9}/trex_model.egg-info/SOURCES.txt +0 -0
  17. {trex-model-1.2.7 → trex-model-1.2.9}/trex_model.egg-info/dependency_links.txt +0 -0
  18. {trex-model-1.2.7 → trex-model-1.2.9}/trex_model.egg-info/requires.txt +0 -0
  19. {trex-model-1.2.7 → trex-model-1.2.9}/trex_model.egg-info/top_level.txt +0 -0
  20. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/__init__.py +0 -0
  21. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/conf.py +0 -0
  22. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/__init__.py +0 -0
  23. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/__init__.py +0 -0
  24. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/admin_models.py +0 -0
  25. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/analytic_models.py +0 -0
  26. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/app_models.py +0 -0
  27. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/coporate_models.py +0 -0
  28. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/customer_model_helpers.py +0 -0
  29. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/fb_subsriber_models.py +0 -0
  30. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/import_models.py +0 -0
  31. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/inventory_model.py +0 -0
  32. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/loyalty_models.py +0 -0
  33. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/lucky_draw_models.py +0 -0
  34. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/message_model_helper.py +0 -0
  35. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/message_models.py +0 -0
  36. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/model_decorators.py +0 -0
  37. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/ndb_models.py +0 -0
  38. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/pos_models.py +0 -0
  39. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/prepaid_models.py +0 -0
  40. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/program_models.py +0 -0
  41. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/rating_models.py +0 -0
  42. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/redeem_models.py +0 -0
  43. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/reward_model_helpers.py +0 -0
  44. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/reward_models.py +0 -0
  45. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/spending_base_program_model.py +0 -0
  46. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/system_models.py +0 -0
  47. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/task_models.py +0 -0
  48. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/test_models.py +0 -0
  49. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/transaction_models.py +0 -0
  50. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/datastore/user_models.py +0 -0
  51. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/merchant_helpers.py +0 -0
  52. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/model_decorator.py +0 -0
  53. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/models/prepaid_helpers.py +0 -0
  54. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/pos_conf.py +0 -0
  55. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/utils/__init__.py +0 -0
  56. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/utils/gcloud/__init__.py +0 -0
  57. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/utils/gcloud/datastore_util.py +0 -0
  58. {trex-model-1.2.7 → trex-model-1.2.9}/trexmodel/utils/model/__init__.py +0 -0
  59. {trex-model-1.2.7 → trex-model-1.2.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.2.7
3
+ Version: 1.2.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.2.7',
6
+ version='1.2.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.2.7
3
+ Version: 1.2.9
4
4
  Summary: TRex database module package
5
5
  Home-page: https://bitbucket.org/lokjac/trex-model
6
6
  Author: Jack Lok
@@ -76,7 +76,10 @@ class Customer(BaseNModel, DictModel, FullTextSearchable):
76
76
  'tags_list', 'memberships_list', 'registered_merchant_acct', 'entitled_membership_reward_summary',
77
77
  'reward_summary', 'entitled_voucher_summary', 'prepaid_summary', 'kpi_summary', 'entitled_lucky_draw_ticket_summary',
78
78
  'entitled_birthday_reward_summary', 'tier_membership_key',
79
- 'registered_outlet_key', 'registered_merchant_acct_key', 'registered_datetime', 'modified_datetime']
79
+ 'registered_outlet_key', 'registered_merchant_acct_key', 'registered_datetime', 'modified_datetime',
80
+
81
+
82
+ ]
80
83
 
81
84
  @property
82
85
  def is_any_entitled_voucher_active(self):
@@ -91,15 +94,10 @@ class Customer(BaseNModel, DictModel, FullTextSearchable):
91
94
 
92
95
  return False
93
96
 
94
- @property
95
- def registered_user_acct_key(self):
96
- #return self.user_acct.urlsafe().decode('utf-8')
97
- return self.key.parent().urlsafe().decode('utf-8')
98
-
99
97
  @property
100
98
  def registered_user_acct(self):
101
99
  #return User.fetch(self.user_acct.urlsafe())
102
- return User.fetch(self.key.parent().urlsafe())
100
+ return User.get_by_reference_code(self.reference_code)
103
101
 
104
102
  @property
105
103
  def registered_merchant_acct(self):
@@ -120,6 +118,15 @@ class Customer(BaseNModel, DictModel, FullTextSearchable):
120
118
  if self.outlet:
121
119
  return self.outlet.urlsafe().decode("utf-8")
122
120
 
121
+ @property
122
+ def merchant_memberships_list(self):
123
+ _memberships_list = []
124
+ for key in self.memberships_list:
125
+ merchant_membership = MerchantMembership.fetch(key)
126
+ _memberships_list.append(merchant_membership)
127
+
128
+ return _memberships_list
129
+
123
130
  @property
124
131
  def tier_membership_key(self):
125
132
  if self.tier_membership:
@@ -448,6 +455,15 @@ class Customer(BaseNModel, DictModel, FullTextSearchable):
448
455
 
449
456
  return (search_results, total_count, next_cursor)
450
457
 
458
+ @staticmethod
459
+ def update_all_from_user_acct(user_acct):
460
+ customers_list = Customer.list_by_user_account(user_acct)
461
+ if customers_list:
462
+ logger.info('Found customer %d account', len(customers_list))
463
+ for c in customers_list:
464
+ c.update_from_user_acct(user_acct)
465
+
466
+
451
467
  def update_from_user_acct(self, user_acct):
452
468
 
453
469
  self.name = user_acct.name
@@ -27,6 +27,7 @@ class MembershipBase(BaseNModel, DictModel):
27
27
 
28
28
  label = ndb.StringProperty(required=True)
29
29
  desc = ndb.StringProperty(required=False)
30
+ terms_and_conditions = ndb.StringProperty(required=False)
30
31
 
31
32
  expiration_type = ndb.StringProperty(required=True)
32
33
  expiration_value = ndb.IntegerProperty(required=False)
@@ -43,7 +44,7 @@ class MembershipBase(BaseNModel, DictModel):
43
44
  modified_by = ndb.KeyProperty(name="modified_by", kind=MerchantUser)
44
45
  modified_by_username = ndb.StringProperty(required=False)
45
46
 
46
- dict_properties = ['label', 'desc', 'expiration_type', 'expiration_value', 'created_datetime', 'modified_datetime']
47
+ dict_properties = ['label', 'desc', 'terms_and_conditions', 'expiration_type', 'expiration_value', 'created_datetime', 'modified_datetime']
47
48
 
48
49
  @property
49
50
  def merchant_acct(self):
@@ -65,10 +65,12 @@ class MerchantAcct(MerchantMin):
65
65
  account_plan = ndb.JsonProperty()
66
66
  outlet_count = ndb.IntegerProperty(default=0)
67
67
 
68
- published_program_configuration = ndb.JsonProperty()
69
- published_voucher_configuration = ndb.JsonProperty()
70
- membership_configuration = ndb.JsonProperty()
71
- tier_membership_configuration = ndb.JsonProperty()
68
+ published_program_configuration = ndb.JsonProperty()
69
+ published_voucher_configuration = ndb.JsonProperty()
70
+ published_redemption_catalogue_configuration = ndb.JsonProperty()
71
+
72
+ membership_configuration = ndb.JsonProperty()
73
+ tier_membership_configuration = ndb.JsonProperty()
72
74
 
73
75
  reward_naming_configuration = ndb.JsonProperty()
74
76
 
@@ -89,6 +91,7 @@ class MerchantAcct(MerchantMin):
89
91
  'tier_membership_configuration', 'prepaid_configuration', 'lucky_draw_configuration', 'product_modifier_configuration',
90
92
  'dashboard_stat_figure', 'program_settings', 'is_tier_membership_configured', 'website',
91
93
  'product_package', 'loyalty_package','account_plan','outlet_count', 'outlet_limit',
94
+ 'published_redemption_catalogue_configuration',
92
95
  ]
93
96
 
94
97
 
@@ -477,7 +480,33 @@ class MerchantAcct(MerchantMin):
477
480
  self.lucky_draw_configuration['programs'] = existing_lucky_draw_list
478
481
  self.lucky_draw_configuration['count'] = len(existing_lucky_draw_list)
479
482
 
480
- self.put()
483
+ self.put()
484
+
485
+ def update_published_redemption_catalogue(self, catalogue_configuration):
486
+ if is_empty(self.published_redemption_catalogue_configuration):
487
+ self.published_redemption_catalogue_configuration = {
488
+ 'catalogues' :[catalogue_configuration],
489
+ 'count' : 1,
490
+ }
491
+
492
+ else:
493
+ existing_catalogue_list = self.published_redemption_catalogue_configuration.get('catalogues')
494
+
495
+ catalogue_key = catalogue_configuration.get('catalogue_key')
496
+
497
+ index = 0
498
+ for v in existing_catalogue_list:
499
+ if v.get('catalogue_key') == catalogue_key:
500
+ existing_catalogue_list.pop(index)
501
+
502
+ index = index+1
503
+
504
+ existing_catalogue_list.append(catalogue_configuration)
505
+
506
+ self.published_redemption_catalogue_configuration['catalogues'] = existing_catalogue_list
507
+ self.published_redemption_catalogue_configuration['count'] = len(existing_catalogue_list)
508
+
509
+ self.put()
481
510
 
482
511
  def update_lucky_draw_program_settings(self, lucky_draw_program_settings):
483
512
  logger.debug('update_lucky_draw_program_settings debug: lucky_draw_program_settings = %s', lucky_draw_program_settings)
@@ -645,6 +674,34 @@ class MerchantAcct(MerchantMin):
645
674
 
646
675
  self.put()
647
676
 
677
+ def remove_redeption_catalogue(self, catalogue_key):
678
+ existing_catalogues_list = self.published_redemption_catalogue_configuration['catalogues']
679
+
680
+ new_catalogues_list = []
681
+ for catalogue in existing_catalogues_list:
682
+ if catalogue.get('catalogue_key') != catalogue_key:
683
+ new_catalogues_list.append(catalogue)
684
+
685
+
686
+ self.published_redemption_catalogue_configuration['catalogues'] = new_catalogues_list
687
+ self.published_redemption_catalogue_configuration['count'] = len(new_catalogues_list)
688
+
689
+ self.put()
690
+
691
+ def remove_archieve_redemption_catalogue(self, archieve_redemption_catalogue_key):
692
+ existing_catalogues_list = self.published_redemption_catalogue_configuration['catalogues']
693
+
694
+ new_catalogues_list = []
695
+ for catalogue in existing_catalogues_list:
696
+ if catalogue.get('catalogue_key') != archieve_redemption_catalogue_key:
697
+ new_catalogues_list.append(catalogue)
698
+
699
+
700
+ self.published_redemption_catalogue_configuration['catalogues'] = new_catalogues_list
701
+ self.published_redemption_catalogue_configuration['count'] = len(new_catalogues_list)
702
+
703
+ self.put()
704
+
648
705
  def remove_archieve_basic_membership(self, archieve_membership_key):
649
706
  self.flush_dirty_membership_configuration()
650
707
  existing_memberships_list = self.membership_configuration['memberships']
@@ -413,6 +413,10 @@ class Product(ProductBase, FullTextSearchable):
413
413
 
414
414
  dict_properties = ['product_sku', 'product_name', 'category_key', 'price', 'cost', 'product_desc', 'barcode', 'pos_settings', 'tax_details', 'product_modifier']
415
415
 
416
+ @property
417
+ def product_default_image(self):
418
+ return self.pos_settings.get('representation_settings').get('image_url')
419
+
416
420
  def setting_details_for_pos(self, merchant_acct):
417
421
  modifier_keys_list = self.product_modifier
418
422
  modifier_setting_list_for_pos = []
@@ -0,0 +1,373 @@
1
+ '''
2
+ Created on 25 Sep 2023
3
+
4
+ @author: jacklok
5
+ '''
6
+ import logging
7
+ from trexmodel.models.datastore.ndb_models import BaseNModel, DictModel
8
+ from google.cloud import ndb
9
+ from datetime import datetime
10
+ import trexmodel.conf as model_conf
11
+ from trexmodel import program_conf
12
+ from trexmodel.models.datastore.merchant_models import MerchantUser,\
13
+ MerchantAcct
14
+ from trexlib.utils.string_util import is_not_empty, is_empty
15
+ from trexmodel.models.datastore.model_decorators import model_transactional
16
+
17
+ logger = logging.getLogger('model')
18
+
19
+ class RedemptionCatalogue(BaseNModel, DictModel):
20
+ #merchant_acct = ndb.KeyProperty(name="merchant_acct", kind=MerchantAcct)
21
+ label = ndb.StringProperty(required=True)
22
+ desc = ndb.StringProperty(required=False)
23
+ redeem_reward_format = ndb.StringProperty(required=True, choices=set(program_conf.REDEEM_REWARD_FORMAT_GROUP))
24
+ completed_status = ndb.StringProperty(required=True, choices=set(program_conf.REDEMPTION_CATALOGUE_STATUS))
25
+ start_date = ndb.DateProperty(required=True)
26
+ end_date = ndb.DateProperty(required=True)
27
+ created_datetime = ndb.DateTimeProperty(required=True, auto_now_add=True)
28
+ modified_datetime = ndb.DateTimeProperty(required=True, auto_now=True)
29
+
30
+ published_datetime = ndb.DateTimeProperty(required=False)
31
+ archived_datetime = ndb.DateTimeProperty(required=False)
32
+
33
+ catalogue_settings = ndb.JsonProperty(required=True)
34
+
35
+ created_by = ndb.KeyProperty(name="created_by", kind=MerchantUser)
36
+ created_by_username = ndb.StringProperty(required=False)
37
+ modified_by = ndb.KeyProperty(name="modified_by", kind=MerchantUser)
38
+ modified_by_username = ndb.StringProperty(required=False)
39
+
40
+ enabled = ndb.BooleanProperty(required=True, default=True)
41
+ archived = ndb.BooleanProperty(required=True, default=False)
42
+
43
+ image_storage_filename = ndb.StringProperty(required=False)
44
+ image_public_url = ndb.StringProperty(required=False)
45
+
46
+ dict_properties = [
47
+ "label","desc","completed_status","start_date","end_date","created_datetime",
48
+ "redeem_reward_format","catalogue_settings", "image_storage_filename", "image_public_url",
49
+ "exclusive_tags_list", "exclusive_memberships_list", "exclusive_tier_memberships_list",
50
+ "completed_prograss_in_percentage","completed_status_index", "catalogue_items",
51
+ "is_enabled", "is_disabled", "is_archived", "is_published",
52
+ ]
53
+
54
+ @property
55
+ def is_enabled(self):
56
+ return self.enabled
57
+
58
+ @property
59
+ def is_disabled(self):
60
+ return self.enabled==False
61
+
62
+ @property
63
+ def is_archived(self):
64
+ return self.archived
65
+
66
+ @property
67
+ def is_published(self):
68
+ return self.completed_status == program_conf.PROGRAM_STATUS_PUBLISH
69
+
70
+ @property
71
+ def merchant_acct(self):
72
+ return MerchantAcct.fetch(self.key.parent().urlsafe())
73
+
74
+ @property
75
+ def exclusive_tags_list(self):
76
+ if self.catalogue_settings.get('exclusivity') and self.catalogue_settings.get('exclusivity').get('tags'):
77
+ return self.catalogue_settings.get('exclusivity').get('tags') or []
78
+
79
+ @property
80
+ def exclusive_memberships_list(self):
81
+ if self.catalogue_settings.get('exclusivity') and self.catalogue_settings.get('exclusivity').get('memberships'):
82
+ return self.catalogue_settings.get('exclusivity').get('memberships') or []
83
+
84
+ @property
85
+ def exclusive_tier_memberships_list(self):
86
+ if self.catalogue_settings.get('exclusivity') and self.catalogue_settings.get('exclusivity').get('tier_memberships'):
87
+ return self.catalogue_settings.get('exclusivity').get('tier_memberships') or []
88
+
89
+ @property
90
+ def catalogue_items(self):
91
+ return self.catalogue_settings.get('items') or []
92
+
93
+ @property
94
+ def completed_prograss_in_percentage(self):
95
+ return program_conf.redemption_catalogue_completed_progress_percentage(self.completed_status)
96
+
97
+ @property
98
+ def completed_status_index(self):
99
+ return program_conf.get_redemption_catalogue_completed_status_index(self.completed_status)
100
+
101
+ @staticmethod
102
+ def create(merchant_acct, label=None, desc=None, start_date=None, end_date=None, redeem_reward_format=None, created_by=None):
103
+
104
+ created_by_username = None
105
+ if is_not_empty(created_by):
106
+ if isinstance(created_by, MerchantUser):
107
+ created_by_username = created_by.username
108
+
109
+ redemption_catalogue = RedemptionCatalogue(
110
+ parent = merchant_acct.create_ndb_key(),
111
+ label = label,
112
+ desc = desc,
113
+ start_date = start_date,
114
+ end_date = end_date,
115
+ redeem_reward_format= redeem_reward_format,
116
+ created_by = created_by.create_ndb_key(),
117
+ created_by_username = created_by_username,
118
+ completed_status = program_conf.REDEMPTION_CATALOGUE_STATUS_DEFINED_CATALOGUE,
119
+ catalogue_settings = {},
120
+ )
121
+
122
+ redemption_catalogue.put()
123
+
124
+ return redemption_catalogue
125
+
126
+ @staticmethod
127
+ def update(redemption_catalogue, label=None, desc=None, start_date=None, end_date=None, redeem_reward_format=None, modified_by=None):
128
+
129
+ modified_by_username = None
130
+ if is_not_empty(modified_by):
131
+ if isinstance(modified_by, MerchantUser):
132
+ modified_by_username = modified_by.username
133
+
134
+ redemption_catalogue.label = label
135
+ redemption_catalogue.desc = desc
136
+ redemption_catalogue.start_date = start_date
137
+ redemption_catalogue.end_date = end_date
138
+ redemption_catalogue.redeem_reward_format = redeem_reward_format
139
+ redemption_catalogue.completed_status = program_conf.REDEMPTION_CATALOGUE_STATUS_DEFINED_CATALOGUE
140
+
141
+ redemption_catalogue.modified_by = modified_by.create_ndb_key()
142
+ redemption_catalogue.modified_by_username = modified_by_username
143
+
144
+ redemption_catalogue.put()
145
+
146
+ return redemption_catalogue
147
+
148
+
149
+ def remove_redemption_catalogue_item(self, voucher_index, modified_by=None):
150
+ modified_by_username = None
151
+ if is_not_empty(modified_by):
152
+ if isinstance(modified_by, MerchantUser):
153
+ modified_by_username = modified_by.username
154
+
155
+
156
+ catalogue_settings = self.catalogue_settings
157
+
158
+ items = catalogue_settings.get('items')
159
+ if is_not_empty(items):
160
+ items = [item for item in items if item.get('voucher_index') != voucher_index]
161
+
162
+ catalogue_settings['items'] = items
163
+
164
+ self.catalogue_settings = catalogue_settings
165
+
166
+ self.modified_by = modified_by.create_ndb_key()
167
+ self.modified_by_username = modified_by_username
168
+
169
+ self.put()
170
+
171
+ def update_redemption_catalogue_image(self, image_public_url=None, image_storage_filename=None, modified_by=None):
172
+
173
+ modified_by_username = None
174
+
175
+ if is_not_empty(modified_by):
176
+ if isinstance(modified_by, MerchantUser):
177
+ modified_by_username = modified_by.username
178
+
179
+ self.image_public_url = image_public_url
180
+ self.image_storage_filename = image_storage_filename
181
+
182
+ self.modified_by = modified_by.create_ndb_key()
183
+ self.modified_by_username = modified_by_username
184
+
185
+ self.completed_status = program_conf.REDEMPTION_CATALOGUE_STATUS_UPLOAD_MATERIAL
186
+ self.put()
187
+
188
+ def completed_redemption_catalogue_image_status(self, modified_by=None, default_redemption_catalogue_image=None):
189
+ modified_by_username = None
190
+
191
+ if is_not_empty(modified_by):
192
+ if isinstance(modified_by, MerchantUser):
193
+ modified_by_username = modified_by.username
194
+
195
+
196
+ if is_empty(self.image_public_url):
197
+ self.image_public_url = default_redemption_catalogue_image
198
+
199
+ self.modified_by = modified_by.create_ndb_key()
200
+ self.modified_by_username = modified_by_username
201
+ self.completed_status = program_conf.REDEMPTION_CATALOGUE_STATUS_UPLOAD_MATERIAL
202
+ self.put()
203
+
204
+ def add_redemption_catalogue_item(self, item_settings, modified_by=None):
205
+ modified_by_username = None
206
+ if is_not_empty(modified_by):
207
+ if isinstance(modified_by, MerchantUser):
208
+ modified_by_username = modified_by.username
209
+
210
+
211
+ catalogue_settings = self.catalogue_settings
212
+
213
+ items = catalogue_settings.get('items')
214
+ if items is None:
215
+ items = []
216
+
217
+ items.append(item_settings)
218
+
219
+ catalogue_settings['items'] = items
220
+
221
+ self.catalogue_settings = catalogue_settings
222
+
223
+ self.modified_by = modified_by.create_ndb_key()
224
+ self.modified_by_username = modified_by_username
225
+
226
+ self.put()
227
+
228
+ @model_transactional(desc="update_redemption_catalogue_exclusivity")
229
+ def update_redemption_catalogue_exclusivity(self, exclusivity_configuration, modified_by=None):
230
+ modified_by_username = None
231
+ if is_not_empty(modified_by):
232
+ if isinstance(modified_by, MerchantUser):
233
+ modified_by_username = modified_by.username
234
+
235
+
236
+ catalogue_settings = self.catalogue_settings
237
+ catalogue_settings['exclusivity'] = exclusivity_configuration
238
+
239
+ self.catalogue_settings = catalogue_settings
240
+
241
+ self.modified_by = modified_by.create_ndb_key()
242
+ self.modified_by_username = modified_by_username
243
+
244
+ self.completed_status = program_conf.REDEMPTION_CATALOGUE_STATUS_DEFINE_EXCLUSIVITY
245
+
246
+ self.put()
247
+
248
+
249
+ @model_transactional(desc="complete_adding_redemption_catalogue_item")
250
+ def complete_adding_redemption_catalogue_item(self, modified_by=None):
251
+ modified_by_username = None
252
+ if is_not_empty(modified_by):
253
+ if isinstance(modified_by, MerchantUser):
254
+ modified_by_username = modified_by.username
255
+
256
+ self.completed_status = program_conf.REDEMPTION_CATALOGUE_STATUS_DEFINE_ITEM
257
+ self.modified_by = modified_by.create_ndb_key()
258
+ self.modified_by_username = modified_by_username
259
+
260
+ self.put()
261
+
262
+
263
+ @model_transactional(desc="publish_redemption_catalogue")
264
+ def publish_redemption_catalogue(self, modified_by=None):
265
+ modified_by_username = None
266
+ if is_not_empty(modified_by):
267
+ if isinstance(modified_by, MerchantUser):
268
+ modified_by_username = modified_by.username
269
+ self.modified_by = modified_by.create_ndb_key()
270
+
271
+ self.completed_status = program_conf.REDEMPTION_CATALOGUE_STATUS_PUBLISH
272
+ self.published_datetime = datetime.utcnow()
273
+
274
+ self.modified_by_username = modified_by_username
275
+ self.put()
276
+
277
+ catalogue_configuration = self.to_configuration()
278
+
279
+ logger.debug('catalogue_configuration=%s', catalogue_configuration)
280
+
281
+ merchant_acct = self.merchant_acct
282
+ merchant_acct.update_published_redemption_catalogue(catalogue_configuration)
283
+
284
+ @model_transactional(desc="enable redemption catalogue")
285
+ def enable(self, modified_by=None):
286
+ self.enabled = True
287
+
288
+ modified_by_username = None
289
+
290
+ if is_not_empty(modified_by):
291
+ if isinstance(modified_by, MerchantUser):
292
+ modified_by_username = modified_by.username
293
+
294
+ self.modified_by = modified_by.create_ndb_key()
295
+ self.modified_by_username = modified_by_username
296
+
297
+ self.put()
298
+
299
+ if self.is_published:
300
+ merchant_acct = self.merchant_acct
301
+ merchant_acct.update_published_redemption_catalogue(self.to_configuration())
302
+
303
+
304
+
305
+
306
+ @model_transactional(desc="disable redemption catalogue")
307
+ def disable(self, modified_by=None):
308
+ self.enabled = False
309
+
310
+ modified_by_username = None
311
+
312
+ if is_not_empty(modified_by):
313
+ if isinstance(modified_by, MerchantUser):
314
+ modified_by_username = modified_by.username
315
+ self.modified_by = modified_by.create_ndb_key()
316
+
317
+ self.modified_by_username = modified_by_username
318
+
319
+ self.put()
320
+
321
+ merchant_acct = self.merchant_acct
322
+ merchant_acct.remove_redeption_catalogue(self.key_in_str)
323
+
324
+ @model_transactional(desc="archive redemption catal0gue")
325
+ def archive(self, modified_by=None):
326
+ self.archived = True
327
+
328
+ modified_by_username = None
329
+
330
+ if is_not_empty(modified_by):
331
+ if isinstance(modified_by, MerchantUser):
332
+ modified_by_username = modified_by.username
333
+ self.modified_by = modified_by.create_ndb_key()
334
+
335
+ self.modified_by_username = modified_by_username
336
+ self.archived_datetime = datetime.utcnow()
337
+ self.put()
338
+
339
+ merchant_acct = self.merchant_acct
340
+ merchant_acct.remove_redeption_catalogue(self.key_in_str)
341
+
342
+ def to_configuration(self):
343
+ catalogue_configuration = {
344
+ 'merchant_acct_key' : self.parent_key,
345
+ 'catalogue_key' : self.key_in_str,
346
+ 'label' : self.label,
347
+ 'desc' : self.desc,
348
+ 'redeem_reward_format' : self.redeem_reward_format,
349
+ 'start_date' : self.start_date.strftime('%d-%m-%Y'),
350
+ 'end_date' : self.end_date.strftime('%d-%m-%Y'),
351
+ 'items' : self.catalogue_settings.get('items'),
352
+ 'exclusivity' : self.catalogue_settings.get('exclusivity'),
353
+ }
354
+
355
+ return catalogue_configuration
356
+
357
+ @staticmethod
358
+ @model_transactional(desc="archive_redemption_catalogue")
359
+ def archive_redemption_catalogue(redemption_catalogue):
360
+ redemption_catalogue.archived = True
361
+ redemption_catalogue.archived_datetime = datetime.now()
362
+ redemption_catalogue.put()
363
+
364
+ merchant_acct = redemption_catalogue.merchant_acct
365
+ merchant_acct.remove_archieve_redemption_catalogue(redemption_catalogue.key_in_str)
366
+
367
+ @staticmethod
368
+ def list_by_merchant_account(merchant_acct):
369
+ return RedemptionCatalogue.query(ndb.AND(RedemptionCatalogue.archived!=True), ancestor=merchant_acct.create_ndb_key()).fetch(limit=model_conf.MAX_FETCH_RECORD)
370
+
371
+ @staticmethod
372
+ def list_archived_by_merchant_account(merchant_acct):
373
+ return RedemptionCatalogue.query(ndb.AND(RedemptionCatalogue.archived==True), ancestor=merchant_acct.create_ndb_key()).fetch(limit=model_conf.MAX_FETCH_RECORD)
@@ -46,7 +46,6 @@ class VoucherBase(BaseNModel, DictModel):
46
46
  modified_by = ndb.KeyProperty(name="modified_by", kind=MerchantUser)
47
47
  modified_by_username = ndb.StringProperty(required=False)
48
48
 
49
- published = ndb.BooleanProperty(default=False)
50
49
  archived = ndb.BooleanProperty(default=False)
51
50
  image_storage_filename = ndb.StringProperty(required=False)
52
51
  image_public_url = ndb.StringProperty(required=False)
@@ -263,7 +262,7 @@ class MerchantVoucher(VoucherBase):
263
262
  return merchant_voucher
264
263
 
265
264
  @staticmethod
266
- def update_voucher_configuration_data(merchant_voucher, configuration=None, modified_by=None):
265
+ def update_voucher_configuration_data(merchant_voucher, configuration=None, modified_by=None, image_public_url=None):
267
266
 
268
267
  modified_by_username = None
269
268
 
@@ -275,6 +274,8 @@ class MerchantVoucher(VoucherBase):
275
274
  merchant_voucher.completed_status = program_conf.VOUCHER_STATUS_CONFIGURATION
276
275
  merchant_voucher.modified_by = modified_by.create_ndb_key()
277
276
  merchant_voucher.modified_by_username = modified_by_username
277
+ if image_public_url:
278
+ merchant_voucher.image_public_url = image_public_url
278
279
 
279
280
  merchant_voucher.put()
280
281
 
@@ -343,7 +344,12 @@ class MerchantVoucher(VoucherBase):
343
344
 
344
345
  @staticmethod
345
346
  def list_by_merchant_account(merchant_acct):
346
- return MerchantVoucher.query(ndb.AND(MerchantVoucher.archived!=True), ancestor=merchant_acct.create_ndb_key()).fetch(limit=model_conf.MAX_FETCH_RECORD)
347
+ vouchers_list = MerchantVoucher.query(ndb.AND(MerchantVoucher.completed_status==program_conf.VOUCHER_STATUS_PUBLISH), ancestor=merchant_acct.create_ndb_key()).fetch(limit=model_conf.MAX_FETCH_RECORD)
348
+ final_list = []
349
+ for v in vouchers_list:
350
+ if v.archived==False:
351
+ final_list.append(v)
352
+ return final_list
347
353
 
348
354
  @staticmethod
349
355
  def list_archived_by_merchant_account(merchant_acct):
@@ -167,6 +167,8 @@ REWARD_FORMAT_DISCOUNT = 'discount'
167
167
  REWARD_FORMAT_PREPAID = 'prepaid'
168
168
  REWARD_FORMAT_MESSAGE = 'message'
169
169
 
170
+ REDEEM_REWARD_FORMAT_GROUP = (REWARD_FORMAT_POINT, REWARD_FORMAT_STAMP)
171
+
170
172
  REWARD_FORMAT_MAP = {
171
173
  REWARD_FORMAT_POINT: 'points',
172
174
  REWARD_FORMAT_STAMP: 'stamp',
@@ -265,14 +267,27 @@ ALL_PROGRAM_STATUS = (PROGRAM_STATUS_PROGRAM_BASE,
265
267
  PROGRAM_STATUS_PUBLISH
266
268
  )
267
269
 
268
- REDEMPTION_CATALOGUE_STATUS = (PROGRAM_STATUS_PROGRAM_BASE,
269
- PROGRAM_STATUS_DEFINE_ITEM,
270
- PROGRAM_STATUS_EXCLUSIVITY,
271
- PROGRAM_STATUS_PUBLISH
270
+ REDEMPTION_CATALOGUE_STATUS_DEFINED_CATALOGUE = 'define_catalogue'
271
+ REDEMPTION_CATALOGUE_STATUS_DEFINE_ITEM = 'define_item'
272
+ REDEMPTION_CATALOGUE_STATUS_UPLOAD_MATERIAL = 'upload_material'
273
+ REDEMPTION_CATALOGUE_STATUS_DEFINE_EXCLUSIVITY = 'define_exclusivity'
274
+ REDEMPTION_CATALOGUE_STATUS_REVIEW = 'review'
275
+ REDEMPTION_CATALOGUE_STATUS_PUBLISH = 'published'
276
+
277
+
278
+ REDEMPTION_CATALOGUE_STATUS = (
279
+ REDEMPTION_CATALOGUE_STATUS_DEFINED_CATALOGUE,
280
+ REDEMPTION_CATALOGUE_STATUS_DEFINE_ITEM,
281
+ REDEMPTION_CATALOGUE_STATUS_UPLOAD_MATERIAL,
282
+ REDEMPTION_CATALOGUE_STATUS_DEFINE_EXCLUSIVITY,
283
+ REDEMPTION_CATALOGUE_STATUS_REVIEW,
284
+ REDEMPTION_CATALOGUE_STATUS_PUBLISH
272
285
  )
273
286
 
274
287
 
275
288
 
289
+
290
+
276
291
  PROGRAM_SCHEDULE_TYPE_DAILY = 'daily'
277
292
  PROGRAM_SCHEDULE_TYPE_MONTH_START = 'month_start'
278
293
  PROGRAM_SCHEDULE_TYPE_WEEKEND = 'weekend'
@@ -418,6 +433,9 @@ def get_tier_reward_program_completed_status_index(completed_status):
418
433
  def get_lucky_draw_program_completed_status_index(completed_status):
419
434
  return LUCKY_DRAW_PROGRAM_STATUS.index(completed_status)
420
435
 
436
+ def get_redemption_catalogue_completed_status_index(completed_status):
437
+ return REDEMPTION_CATALOGUE_STATUS.index(completed_status)
438
+
421
439
  def is_program_current_status_reach(checking_status, completed_status):
422
440
  completed_status_index = get_program_completed_status_index(completed_status)
423
441
  checking_status_index = get_program_completed_status_index(checking_status)
@@ -516,4 +534,7 @@ def lucky_draw_program_completed_progress_percentage(completed_status):
516
534
  print('lucky_draw_program_completed_progress_percentage: completed_status_index(%s)=%s'% (completed_status,completed_status_index))
517
535
  return int((completed_status_index+1)/len(LUCKY_DRAW_PROGRAM_STATUS) * 100)
518
536
 
519
-
537
+ def redemption_catalogue_completed_progress_percentage(completed_status):
538
+ completed_status_index = get_redemption_catalogue_completed_status_index(completed_status)
539
+ print('redemption_catalogue_completed_progress_percentage: completed_status_index(%s)=%s'% (completed_status,completed_status_index))
540
+ return int((completed_status_index+1)/len(REDEMPTION_CATALOGUE_STATUS) * 100)
@@ -1,22 +0,0 @@
1
- '''
2
- Created on 25 Sep 2023
3
-
4
- @author: jacklok
5
- '''
6
- import logging
7
- from trexmodel.models.datastore.ndb_models import BaseNModel, DictModel
8
- from google.cloud import ndb
9
- from datetime import datetime
10
- import trexmodel.conf as model_conf
11
- from trexmodel import program_conf
12
-
13
- logger = logging.getLogger('model')
14
-
15
- class RedemptionCatalogue(BaseNModel, DictModel):
16
- label = ndb.StringProperty(required=True)
17
- desc = ndb.StringProperty(required=False)
18
- completed_status = ndb.StringProperty(required=True, choices=set(program_conf.REDEMPTION_CATALOGUE_STATUS))
19
- start_date = ndb.DateProperty(required=True)
20
- end_date = ndb.DateProperty(required=True)
21
-
22
-
File without changes
File without changes
File without changes
File without changes
File without changes