trex-model 1.2.8__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.
- {trex-model-1.2.8/trex_model.egg-info → trex-model-1.2.9}/PKG-INFO +1 -1
- {trex-model-1.2.8 → trex-model-1.2.9}/setup.py +1 -1
- {trex-model-1.2.8 → trex-model-1.2.9/trex_model.egg-info}/PKG-INFO +1 -1
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/customer_models.py +14 -7
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/membership_models.py +2 -1
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/merchant_models.py +62 -5
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/product_models.py +4 -0
- trex-model-1.2.9/trexmodel/models/datastore/redemption_catalogue_models.py +373 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/voucher_models.py +9 -3
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/program_conf.py +26 -5
- trex-model-1.2.8/trexmodel/models/datastore/redemption_catalogue_models.py +0 -22
- {trex-model-1.2.8 → trex-model-1.2.9}/LICENSE +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/MANIFEST.in +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/README.md +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/setup.cfg +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trex_model.egg-info/SOURCES.txt +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trex_model.egg-info/dependency_links.txt +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trex_model.egg-info/requires.txt +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trex_model.egg-info/top_level.txt +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/__init__.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/conf.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/__init__.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/__init__.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/admin_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/analytic_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/app_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/coporate_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/customer_model_helpers.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/fb_subsriber_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/import_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/inventory_model.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/loyalty_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/lucky_draw_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/message_model_helper.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/message_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/model_decorators.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/ndb_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/pos_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/prepaid_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/program_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/rating_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/redeem_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/reward_model_helpers.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/reward_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/spending_base_program_model.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/system_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/task_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/test_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/transaction_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/user_models.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/merchant_helpers.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/model_decorator.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/prepaid_helpers.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/pos_conf.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/utils/__init__.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/utils/gcloud/__init__.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/utils/gcloud/datastore_util.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/utils/model/__init__.py +0 -0
- {trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/utils/model/model_util.py +0 -0
|
@@ -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.
|
|
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:
|
|
@@ -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
|
|
69
|
-
published_voucher_configuration
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
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
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{trex-model-1.2.8 → trex-model-1.2.9}/trexmodel/models/datastore/spending_base_program_model.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|