trex-model 1.5.24__tar.gz → 1.5.26__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.5.24 → trex-model-1.5.26}/PKG-INFO +1 -1
- {trex-model-1.5.24 → trex-model-1.5.26}/setup.py +1 -1
- {trex-model-1.5.24 → trex-model-1.5.26}/trex_model.egg-info/PKG-INFO +1 -1
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/customer_models.py +17 -3
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/marketing_models.py +24 -1
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/membership_models.py +18 -16
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/merchant_models.py +1 -1
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/ndb_models.py +31 -1
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/rating_models.py +34 -8
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/redeem_models.py +16 -4
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/redemption_catalogue_models.py +26 -1
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/transaction_models.py +7 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/voucher_models.py +9 -10
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/merchant_helpers.py +3 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/LICENSE +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/MANIFEST.in +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/README.md +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/setup.cfg +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trex_model.egg-info/SOURCES.txt +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trex_model.egg-info/dependency_links.txt +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trex_model.egg-info/requires.txt +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trex_model.egg-info/top_level.txt +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/__init__.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/conf.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/__init__.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/__init__.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/admin_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/analytic_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/app_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/coporate_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/customer_model_helpers.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/fb_subsriber_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/helper/__init__.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/helper/reward_model_helpers.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/helper/reward_transaction_helper.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/import_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/inventory_model.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/loyalty_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/lucky_draw_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/merchant_promotion_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/message_model_helper.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/message_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/model_decorators.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/pos_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/prepaid_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/product_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/program_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/recruit_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/referral_program_model.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/reward_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/spending_base_program_model.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/system_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/task_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/test_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/user_models.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/model_decorator.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/prepaid_helpers.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/pos_conf.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/program_conf.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/utils/__init__.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/utils/gcloud/__init__.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/utils/gcloud/datastore_util.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/utils/model/__init__.py +0 -0
- {trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/utils/model/model_util.py +0 -0
|
@@ -314,7 +314,21 @@ class Customer(BaseNModel, DictModel, FullTextSearchable):
|
|
|
314
314
|
password=None, reference_code=None,
|
|
315
315
|
is_email_verified=False, is_mobile_phone_verified=False):
|
|
316
316
|
|
|
317
|
-
|
|
317
|
+
if is_not_empty(email):
|
|
318
|
+
checking_user = User.get_by_email(email)
|
|
319
|
+
elif is_not_empty(mobile_phone):
|
|
320
|
+
checking_user = User.get_by_email(mobile_phone)
|
|
321
|
+
|
|
322
|
+
if checking_user is not None:
|
|
323
|
+
created_user = checking_user
|
|
324
|
+
created_user.name = name
|
|
325
|
+
created_user.email = email
|
|
326
|
+
created_user.mobile_phone = mobile_phone
|
|
327
|
+
created_user.gender = gender
|
|
328
|
+
created_user.password = password
|
|
329
|
+
created_user.birth_date = birth_date
|
|
330
|
+
else:
|
|
331
|
+
created_user = User.create(name=name, email=email, mobile_phone=mobile_phone,
|
|
318
332
|
gender=gender, birth_date=birth_date,
|
|
319
333
|
password=password, reference_code=reference_code,
|
|
320
334
|
is_email_verified=is_email_verified,
|
|
@@ -910,11 +924,11 @@ class CustomerMembership(BaseNModel, DictModel):
|
|
|
910
924
|
|
|
911
925
|
|
|
912
926
|
@staticmethod
|
|
913
|
-
def create(customer, merchant_membership, entitled_datetime=None, assigned_outlet=None, assigned_by=None):
|
|
927
|
+
def create(customer, merchant_membership, entitled_datetime=None, assigned_outlet=None, assigned_by=None, number_of_year=None):
|
|
914
928
|
if entitled_datetime is None:
|
|
915
929
|
entitled_datetime = datetime.utcnow()
|
|
916
930
|
|
|
917
|
-
expiry_date = merchant_membership.calc_expiry_date(start_date=entitled_datetime)
|
|
931
|
+
expiry_date = merchant_membership.calc_expiry_date(start_date=entitled_datetime, number_of_year=number_of_year)
|
|
918
932
|
logger.debug('expiry_date=%s', expiry_date)
|
|
919
933
|
merchant_acct = merchant_membership.merchant_acct
|
|
920
934
|
customer_membership = CustomerMembership(
|
|
@@ -14,6 +14,7 @@ import trexmodel.conf as model_conf
|
|
|
14
14
|
import logging
|
|
15
15
|
from _datetime import timedelta
|
|
16
16
|
from trexconf.program_conf import MERCHANT_NEWS_STATUS_PUBLISH
|
|
17
|
+
from trexconf.conf import MERCHANT_NEWS_BASE_URL
|
|
17
18
|
|
|
18
19
|
logger = logging.getLogger('model')
|
|
19
20
|
|
|
@@ -223,6 +224,22 @@ class MarketingImage(BaseNModel, DictModel):
|
|
|
223
224
|
|
|
224
225
|
return image_file
|
|
225
226
|
|
|
227
|
+
@staticmethod
|
|
228
|
+
def create_upload_file(image_label, image_file_storage_filename, public_url, merchant_acct, image_file_type=None):
|
|
229
|
+
logger.debug('image_file_type=%s', image_file_type)
|
|
230
|
+
|
|
231
|
+
image_file = MarketingImage(
|
|
232
|
+
parent = merchant_acct.create_ndb_key(),
|
|
233
|
+
image_label = image_label,
|
|
234
|
+
image_file_public_url = public_url,
|
|
235
|
+
image_file_storage_filename = image_file_storage_filename,
|
|
236
|
+
image_file_type = image_file_type,
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
image_file.put()
|
|
240
|
+
|
|
241
|
+
return image_file
|
|
242
|
+
|
|
226
243
|
@staticmethod
|
|
227
244
|
def remove_file(image_file, bucket):
|
|
228
245
|
|
|
@@ -313,7 +330,8 @@ class MerchantNewsFile(BaseNModel, DictModel):
|
|
|
313
330
|
|
|
314
331
|
|
|
315
332
|
dict_properties = ['image_url', 'completed_progress_in_percentage','is_published', 'is_enabled',
|
|
316
|
-
'label', 'desc', 'news_text', 'start_date', 'end_date', 'enabled', 'is_archived',
|
|
333
|
+
'label', 'desc', 'news_text', 'start_date', 'end_date', 'enabled', 'is_archived',
|
|
334
|
+
'news_public_url',
|
|
317
335
|
'completed_status']
|
|
318
336
|
|
|
319
337
|
@property
|
|
@@ -326,6 +344,10 @@ class MerchantNewsFile(BaseNModel, DictModel):
|
|
|
326
344
|
return self.news_file_public_url
|
|
327
345
|
else:
|
|
328
346
|
return conf.MERCHANT_NEWS_DEFAULT_IMAGE
|
|
347
|
+
|
|
348
|
+
@property
|
|
349
|
+
def news_public_url(self):
|
|
350
|
+
return '%s/merchant/marketing/news/%s/show' % (MERCHANT_NEWS_BASE_URL, self.key_in_str)
|
|
329
351
|
|
|
330
352
|
@property
|
|
331
353
|
def completed_progress_in_percentage(self):
|
|
@@ -480,6 +502,7 @@ class MerchantNewsFile(BaseNModel, DictModel):
|
|
|
480
502
|
'content' : self.news_text,
|
|
481
503
|
'start_datetime' : self.start_date.strftime('%d-%m-%Y %H:%M:%S'),
|
|
482
504
|
'end_datetime' : self.end_date.strftime('%d-%m-%Y %H:%M:%S'),
|
|
505
|
+
'news_public_url' : self.news_public_url,
|
|
483
506
|
}
|
|
484
507
|
|
|
485
508
|
def publish(self, published_by=None):
|
|
@@ -67,29 +67,31 @@ class MembershipBase(BaseNModel, DictModel):
|
|
|
67
67
|
def list_by_merchant_acct(cls, merchant_acct, is_archived=False):
|
|
68
68
|
return cls.query(ndb.AND(MerchantMembership.archived == is_archived), ancestor=merchant_acct.create_ndb_key()).fetch(limit=model_conf.MAX_FETCH_RECORD)
|
|
69
69
|
|
|
70
|
-
def calc_expiry_date(self, start_date=None):
|
|
70
|
+
def calc_expiry_date(self, start_date=None, number_of_year=None):
|
|
71
71
|
|
|
72
72
|
if start_date is None:
|
|
73
73
|
start_date = datetime.utcnow()
|
|
74
74
|
|
|
75
75
|
logger.debug('start_date=%s', start_date)
|
|
76
76
|
logger.debug('self.expiration_type=%s', self.expiration_type)
|
|
77
|
+
if is_not_empty(number_of_year) and isinstance(number_of_year, int):
|
|
78
|
+
return start_date + relativedelta(years=number_of_year)
|
|
79
|
+
else:
|
|
80
|
+
if self.expiration_type == program_conf.MEMBERSHIP_EXPIRATION_TYPE_AFTER_YEAR:
|
|
81
|
+
return start_date + relativedelta(years=self.expiration_value)
|
|
82
|
+
|
|
83
|
+
elif self.expiration_type == program_conf.MEMBERSHIP_EXPIRATION_TYPE_AFTER_MONTH:
|
|
84
|
+
return start_date + relativedelta(months=self.expiration_value)
|
|
77
85
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
elif self.expiration_type == program_conf.MEMBERSHIP_EXPIRATION_TYPE_AFTER_DAY:
|
|
88
|
-
return start_date + relativedelta(days=self.expiration_value)
|
|
89
|
-
|
|
90
|
-
else:
|
|
91
|
-
#for no expiration
|
|
92
|
-
return datetime.max
|
|
86
|
+
elif self.expiration_type == program_conf.MEMBERSHIP_EXPIRATION_TYPE_AFTER_WEEK:
|
|
87
|
+
return start_date + relativedelta(weeks=self.expiration_value)
|
|
88
|
+
|
|
89
|
+
elif self.expiration_type == program_conf.MEMBERSHIP_EXPIRATION_TYPE_AFTER_DAY:
|
|
90
|
+
return start_date + relativedelta(days=self.expiration_value)
|
|
91
|
+
|
|
92
|
+
else:
|
|
93
|
+
#for no expiration
|
|
94
|
+
return datetime.max
|
|
93
95
|
|
|
94
96
|
@classmethod
|
|
95
97
|
def upload_membership_card_image(cls, membership, uploading_file, merchant_acct, bucket, modified_by=None):
|
|
@@ -1442,7 +1442,7 @@ class Outlet(BusinessEntity, FullTextSearchable):
|
|
|
1442
1442
|
|
|
1443
1443
|
@property
|
|
1444
1444
|
def merchant_acct_key(self):
|
|
1445
|
-
return self.key.parent().urlsafe()
|
|
1445
|
+
return self.key.parent().urlsafe().decode('utf-8')
|
|
1446
1446
|
|
|
1447
1447
|
@property
|
|
1448
1448
|
def outlet_key(self):
|
|
@@ -17,7 +17,33 @@ from trexconf import conf as lib_conf
|
|
|
17
17
|
from trexconf import conf as model_conf
|
|
18
18
|
from google.cloud.datastore.helpers import GeoPoint
|
|
19
19
|
|
|
20
|
-
logger = logging.getLogger('model')
|
|
20
|
+
#logger = logging.getLogger('model')
|
|
21
|
+
logger = logging.getLogger('target_debug')
|
|
22
|
+
|
|
23
|
+
def clone_entity(entity, parent=None, **extra_args):
|
|
24
|
+
"""
|
|
25
|
+
Clone an NDB entity and return the clone.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
entity: The NDB entity to be cloned.
|
|
29
|
+
extra_args: Additional properties to override in the cloned entity.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
A new instance of the entity's class with copied properties.
|
|
33
|
+
"""
|
|
34
|
+
klass = entity.__class__
|
|
35
|
+
props = {}
|
|
36
|
+
|
|
37
|
+
for prop_name, prop in klass._properties.items():
|
|
38
|
+
logger.debug('clone prop_name=%s', prop_name)
|
|
39
|
+
if not isinstance(prop, ndb.ComputedProperty):
|
|
40
|
+
props[prop_name] = getattr(entity, prop_name)
|
|
41
|
+
|
|
42
|
+
props.update(extra_args)
|
|
43
|
+
if parent:
|
|
44
|
+
return klass(parent=parent, **props)
|
|
45
|
+
else:
|
|
46
|
+
return klass(**props)
|
|
21
47
|
|
|
22
48
|
def convert_to_serializable_value(val, none_as_empty_string=False, gmt=0,
|
|
23
49
|
datetime_format=lib_conf.DEFAULT_DATETIME_FORMAT,
|
|
@@ -223,6 +249,10 @@ class NDBModel(object):
|
|
|
223
249
|
def create_ndb_key(self):
|
|
224
250
|
return ndb.Key(flat=self.key.flat())
|
|
225
251
|
|
|
252
|
+
def clone(self, parent=None, **overrides):
|
|
253
|
+
return clone_entity(self, parent=parent, **overrides)
|
|
254
|
+
|
|
255
|
+
|
|
226
256
|
class BaseNModel(DictModel, NDBModel):
|
|
227
257
|
|
|
228
258
|
saved = False
|
|
@@ -10,9 +10,10 @@ from trexmodel.models.datastore.user_models import User
|
|
|
10
10
|
from trexconf import conf
|
|
11
11
|
from datetime import datetime, timedelta
|
|
12
12
|
import logging
|
|
13
|
-
from trexmodel.models.datastore.transaction_models import
|
|
13
|
+
from trexmodel.models.datastore.transaction_models import CustomerTransaction
|
|
14
14
|
|
|
15
|
-
logger = logging.getLogger('model')
|
|
15
|
+
#logger = logging.getLogger('model')
|
|
16
|
+
logger = logging.getLogger('target_debug')
|
|
16
17
|
|
|
17
18
|
class RatingBase(BaseNModel, DictModel):
|
|
18
19
|
user_acct = ndb.KeyProperty(name="user_acct", kind=User)
|
|
@@ -95,6 +96,24 @@ class OutletRating(RatingBase):
|
|
|
95
96
|
|
|
96
97
|
|
|
97
98
|
outlet_rating.put()
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def update(user_acct, outlet, service_rating=.5, ambience_rating=.5, food_rating=.5, value_rating=.5):
|
|
102
|
+
|
|
103
|
+
outlet_rating = OutletRating.get_user_rating_by_outlet(user_acct, outlet)
|
|
104
|
+
if outlet_rating:
|
|
105
|
+
outlet_rating.previous_service_rating = outlet_rating.service_rating
|
|
106
|
+
outlet_rating.previous_ambience_rating = outlet_rating.ambience_rating
|
|
107
|
+
outlet_rating.previous_food_rating = outlet_rating.food_rating
|
|
108
|
+
outlet_rating.previous_value_rating = outlet_rating.value_rating
|
|
109
|
+
|
|
110
|
+
outlet_rating.service_rating = service_rating
|
|
111
|
+
outlet_rating.ambience_rating = ambience_rating
|
|
112
|
+
outlet_rating.food_rating = food_rating
|
|
113
|
+
outlet_rating.value_rating = value_rating
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
outlet_rating.put()
|
|
98
117
|
|
|
99
118
|
@staticmethod
|
|
100
119
|
def __calculate_rating(rating_list):
|
|
@@ -146,18 +165,25 @@ class TransactionRating(RatingBase):
|
|
|
146
165
|
remarks = ndb.StringProperty(required=False)
|
|
147
166
|
created_datetime = ndb.DateTimeProperty(required=True, auto_now_add=True)
|
|
148
167
|
|
|
149
|
-
dict_properties = ['transaction_id','service_rating', 'ambience_rating', 'food_rating','value_rating',
|
|
168
|
+
dict_properties = ['transaction_id','service_rating', 'ambience_rating', 'food_rating','value_rating', 'remarks',
|
|
150
169
|
]
|
|
151
170
|
|
|
152
171
|
@staticmethod
|
|
153
172
|
def create(user_acct, transaction_id, service_rating=.5, ambience_rating=.5, food_rating=.5, value_rating=.5,
|
|
154
173
|
remarks=None, for_testing=False):
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
174
|
+
customer_transaction = CustomerTransaction.get_by_transaction_id(transaction_id)
|
|
175
|
+
|
|
176
|
+
logger.info('customer_transaction=%s', customer_transaction)
|
|
177
|
+
logger.info('for_testing=%s', for_testing)
|
|
178
|
+
|
|
179
|
+
if customer_transaction is not None:
|
|
180
|
+
outlet = customer_transaction.transact_outlet_entity
|
|
181
|
+
merchant_acct = customer_transaction.transact_merchant_acct
|
|
182
|
+
|
|
160
183
|
transaction_rating = TransactionRating.get_by_transaction_id(transaction_id)
|
|
184
|
+
|
|
185
|
+
logger.info('transaction_rating=%s', transaction_rating)
|
|
186
|
+
|
|
161
187
|
if transaction_rating is None:
|
|
162
188
|
transaction_rating = TransactionRating(
|
|
163
189
|
user_acct = user_acct.create_ndb_key(),
|
|
@@ -151,6 +151,11 @@ class CustomerRedemption(BaseNModel, DictModel):
|
|
|
151
151
|
def redeemed_outlet_details(self):
|
|
152
152
|
if self.redeemed_outlet:
|
|
153
153
|
return Outlet.fetch(self.redeemed_outlet_key)
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def redeemed_outlet_name(self):
|
|
157
|
+
if self.redeemed_outlet_details:
|
|
158
|
+
return self.redeemed_outlet_details.name
|
|
154
159
|
|
|
155
160
|
@property
|
|
156
161
|
def redeemed_customer_key(self):
|
|
@@ -246,10 +251,17 @@ class CustomerRedemption(BaseNModel, DictModel):
|
|
|
246
251
|
return CustomerRedemption.query(ndb.AND(CustomerRedemption.status==status), ancestor=customer.create_ndb_key()).fetch(limit=limit)
|
|
247
252
|
|
|
248
253
|
@staticmethod
|
|
249
|
-
def list_customer_redemption(customer_acct, offset=0, limit=conf.PAGINATION_SIZE, start_cursor=None, return_with_cursor=False):
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
254
|
+
def list_customer_redemption(customer_acct, offset=0, limit=conf.PAGINATION_SIZE, start_cursor=None, return_with_cursor=False, reverse_order=True, keys_only=False):
|
|
255
|
+
if keys_only:
|
|
256
|
+
query = CustomerRedemption.query(ancestor = customer_acct.create_ndb_key())
|
|
257
|
+
return CustomerRedemption.list_all_with_condition_query(query, offset=offset, limit=limit, keys_only=True)
|
|
258
|
+
else:
|
|
259
|
+
if reverse_order:
|
|
260
|
+
query = CustomerRedemption.query(ancestor = customer_acct.create_ndb_key()).order(-CustomerRedemption.redeemed_datetime)
|
|
261
|
+
else:
|
|
262
|
+
query = CustomerRedemption.query(ancestor = customer_acct.create_ndb_key()).order(CustomerRedemption.redeemed_datetime)
|
|
263
|
+
|
|
264
|
+
return CustomerRedemption.list_all_with_condition_query(query, offset=offset, limit=limit, start_cursor=start_cursor, return_with_cursor=return_with_cursor)
|
|
253
265
|
|
|
254
266
|
@staticmethod
|
|
255
267
|
def list_by_outlet(redeemed_outlet, offset=0, limit=conf.PAGINATION_SIZE, start_cursor=None, return_with_cursor=False):
|
{trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/redemption_catalogue_models.py
RENAMED
|
@@ -12,6 +12,8 @@ from trexmodel.models.datastore.merchant_models import MerchantUser,\
|
|
|
12
12
|
MerchantAcct
|
|
13
13
|
from trexlib.utils.string_util import is_not_empty, is_empty
|
|
14
14
|
from trexmodel.models.datastore.model_decorators import model_transactional
|
|
15
|
+
from trexconf.program_conf import REDEMPTION_CATALOGUE_STATUS_DEFINED_CATALOGUE,\
|
|
16
|
+
REDEMPTION_CATALOGUE_STATUS_NEW
|
|
15
17
|
|
|
16
18
|
logger = logging.getLogger('model')
|
|
17
19
|
|
|
@@ -49,7 +51,7 @@ class RedemptionCatalogue(BaseNModel, DictModel):
|
|
|
49
51
|
"redeem_reward_format","catalogue_settings", "image_storage_filename", "image_public_url",
|
|
50
52
|
"exclusive_tags_list", "exclusive_memberships_list", "exclusive_tier_memberships_list",
|
|
51
53
|
"completed_progress_in_percentage","completed_status_index", "catalogue_items",
|
|
52
|
-
"is_enabled", "is_disabled", "is_archived", "is_published", "loyalty_package",
|
|
54
|
+
"is_enabled", "is_disabled", "is_archived", "is_published", "loyalty_package", "is_expired",
|
|
53
55
|
]
|
|
54
56
|
|
|
55
57
|
@property
|
|
@@ -64,6 +66,10 @@ class RedemptionCatalogue(BaseNModel, DictModel):
|
|
|
64
66
|
def is_archived(self):
|
|
65
67
|
return self.archived
|
|
66
68
|
|
|
69
|
+
@property
|
|
70
|
+
def is_expired(self):
|
|
71
|
+
return self.end_date<datetime.today().date()
|
|
72
|
+
|
|
67
73
|
@property
|
|
68
74
|
def is_published(self):
|
|
69
75
|
return self.completed_status == program_conf.PROGRAM_STATUS_PUBLISH
|
|
@@ -157,6 +163,25 @@ class RedemptionCatalogue(BaseNModel, DictModel):
|
|
|
157
163
|
return redemption_catalogue
|
|
158
164
|
|
|
159
165
|
|
|
166
|
+
def clone(self, created_by=None, **overrides):
|
|
167
|
+
created_datetime = datetime.utcnow();
|
|
168
|
+
overrides.setdefault('created_datetime', created_datetime)
|
|
169
|
+
overrides.setdefault('modified_datetime', created_datetime)
|
|
170
|
+
overrides.setdefault('published_datetime', None)
|
|
171
|
+
overrides.setdefault('archived_datetime', None)
|
|
172
|
+
overrides.setdefault('completed_status', REDEMPTION_CATALOGUE_STATUS_NEW)
|
|
173
|
+
|
|
174
|
+
created_by_username = None
|
|
175
|
+
if is_not_empty(created_by):
|
|
176
|
+
if isinstance(created_by, MerchantUser):
|
|
177
|
+
created_by_username = created_by.username
|
|
178
|
+
|
|
179
|
+
overrides.setdefault('created_by', created_by.create_ndb_key())
|
|
180
|
+
overrides.setdefault('created_by_username', created_by_username)
|
|
181
|
+
|
|
182
|
+
new_cloned = super().clone(parent=self.key.parent(), **overrides)
|
|
183
|
+
return new_cloned
|
|
184
|
+
|
|
160
185
|
def remove_redemption_catalogue_item(self, voucher_index, modified_by=None):
|
|
161
186
|
modified_by_username = None
|
|
162
187
|
if is_not_empty(modified_by):
|
|
@@ -266,6 +266,13 @@ class CustomerTransaction(SalesTransaction):
|
|
|
266
266
|
if self.transact_outlet:
|
|
267
267
|
return Outlet.fetch(self.transact_outlet.urlsafe())
|
|
268
268
|
|
|
269
|
+
@property
|
|
270
|
+
def transact_outlet_name(self):
|
|
271
|
+
outlet = self.transact_outlet_details
|
|
272
|
+
if outlet:
|
|
273
|
+
return self.transact_outlet_details.name
|
|
274
|
+
else:
|
|
275
|
+
return ''
|
|
269
276
|
|
|
270
277
|
@property
|
|
271
278
|
def purchased_merchant_membership_key(self):
|
|
@@ -385,6 +385,14 @@ class MerchantVoucher(VoucherBase):
|
|
|
385
385
|
final_list.append(v)
|
|
386
386
|
return final_list
|
|
387
387
|
|
|
388
|
+
@staticmethod
|
|
389
|
+
def list_latest_by_merchant_account(merchant_acct):
|
|
390
|
+
vouchers_list = MerchantVoucher.query(ndb.AND(MerchantVoucher.archived==False), ancestor=merchant_acct.create_ndb_key()).fetch(limit=model_conf.MAX_FETCH_RECORD)
|
|
391
|
+
final_list = []
|
|
392
|
+
for v in vouchers_list:
|
|
393
|
+
final_list.append(v)
|
|
394
|
+
return final_list
|
|
395
|
+
|
|
388
396
|
@staticmethod
|
|
389
397
|
def list_archived_by_merchant_account(merchant_acct):
|
|
390
398
|
return MerchantVoucher.query(ndb.AND(MerchantVoucher.archived==True), ancestor=merchant_acct.create_ndb_key()).fetch(limit=model_conf.MAX_FETCH_RECORD)
|
|
@@ -393,16 +401,7 @@ class MerchantVoucher(VoucherBase):
|
|
|
393
401
|
def list_published_by_merchant_account(merchant_acct):
|
|
394
402
|
return 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)
|
|
395
403
|
|
|
396
|
-
|
|
397
|
-
def list_latest_by_merchant_account(merchant_acct):
|
|
398
|
-
published_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)
|
|
399
|
-
|
|
400
|
-
filtered_out_archived_vouchers_list = []
|
|
401
|
-
for voucher in published_vouchers_list:
|
|
402
|
-
if voucher.archived==False:
|
|
403
|
-
filtered_out_archived_vouchers_list.append(voucher)
|
|
404
|
-
|
|
405
|
-
return filtered_out_archived_vouchers_list
|
|
404
|
+
|
|
406
405
|
|
|
407
406
|
class BrandVouhcer(VoucherBase):
|
|
408
407
|
#merchant_acct = ndb.KeyProperty(name="merchant_acct", kind=MerchantAcct)
|
|
@@ -45,6 +45,9 @@ def construct_merchant_acct_info(merchant_acct):
|
|
|
45
45
|
|
|
46
46
|
if merchant_acct.published_news_configuration:
|
|
47
47
|
merchant_news_list = merchant_acct.published_news_configuration['news']
|
|
48
|
+
|
|
49
|
+
for news in merchant_news_list:
|
|
50
|
+
logger.debug('news public url=%s', news.get('news_public_url'))
|
|
48
51
|
|
|
49
52
|
published_redemption_catalogue_configuration = merchant_acct.published_redemption_catalogue_configuration
|
|
50
53
|
catalogues_list = []
|
|
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.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/customer_model_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/helper/reward_model_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/merchant_promotion_models.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
|
{trex-model-1.5.24 → trex-model-1.5.26}/trexmodel/models/datastore/referral_program_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{trex-model-1.5.24 → trex-model-1.5.26}/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
|