trex-model 1.5.19__tar.gz → 1.5.21__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.19 → trex-model-1.5.21}/PKG-INFO +1 -1
- {trex-model-1.5.19 → trex-model-1.5.21}/setup.py +1 -1
- {trex-model-1.5.19 → trex-model-1.5.21}/trex_model.egg-info/PKG-INFO +1 -1
- {trex-model-1.5.19 → trex-model-1.5.21}/trex_model.egg-info/SOURCES.txt +1 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/customer_model_helpers.py +160 -27
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/helper/reward_transaction_helper.py +196 -175
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/merchant_models.py +19 -7
- trex-model-1.5.21/trexmodel/models/datastore/merchant_promotion_models.py +50 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/program_models.py +25 -1
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/rating_models.py +5 -1
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/reward_models.py +34 -11
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/system_models.py +23 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/transaction_models.py +16 -4
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/user_models.py +1 -1
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/merchant_helpers.py +5 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/program_conf.py +4 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/utils/model/model_util.py +1 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/LICENSE +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/MANIFEST.in +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/README.md +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/setup.cfg +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trex_model.egg-info/dependency_links.txt +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trex_model.egg-info/requires.txt +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trex_model.egg-info/top_level.txt +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/__init__.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/conf.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/__init__.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/__init__.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/admin_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/analytic_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/app_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/coporate_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/customer_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/fb_subsriber_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/helper/__init__.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/helper/reward_model_helpers.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/import_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/inventory_model.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/loyalty_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/lucky_draw_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/marketing_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/membership_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/message_model_helper.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/message_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/model_decorators.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/ndb_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/pos_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/prepaid_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/product_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/recruit_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/redeem_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/redemption_catalogue_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/referral_program_model.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/spending_base_program_model.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/task_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/test_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/voucher_models.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/model_decorator.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/prepaid_helpers.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/pos_conf.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/utils/__init__.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/utils/gcloud/__init__.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/utils/gcloud/datastore_util.py +0 -0
- {trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/utils/model/__init__.py +0 -0
|
@@ -31,6 +31,7 @@ trexmodel/models/datastore/lucky_draw_models.py
|
|
|
31
31
|
trexmodel/models/datastore/marketing_models.py
|
|
32
32
|
trexmodel/models/datastore/membership_models.py
|
|
33
33
|
trexmodel/models/datastore/merchant_models.py
|
|
34
|
+
trexmodel/models/datastore/merchant_promotion_models.py
|
|
34
35
|
trexmodel/models/datastore/message_model_helper.py
|
|
35
36
|
trexmodel/models/datastore/message_models.py
|
|
36
37
|
trexmodel/models/datastore/model_decorators.py
|
{trex-model-1.5.19 → trex-model-1.5.21}/trexmodel/models/datastore/customer_model_helpers.py
RENAMED
|
@@ -4,14 +4,70 @@ Created on 29 Apr 2021
|
|
|
4
4
|
@author: jacklok
|
|
5
5
|
'''
|
|
6
6
|
from trexlib.utils.string_util import is_empty, is_not_empty
|
|
7
|
-
from datetime import datetime
|
|
7
|
+
from datetime import datetime, timedelta
|
|
8
8
|
from dateutil.relativedelta import relativedelta
|
|
9
9
|
import logging
|
|
10
|
+
from trexconf.program_conf import REWARD_FORMAT_STAMP, REWARD_FORMAT_POINT
|
|
10
11
|
|
|
11
12
|
logger = logging.getLogger('helper')
|
|
12
13
|
#logger = logging.getLogger('debug')
|
|
13
14
|
|
|
14
15
|
|
|
16
|
+
'''
|
|
17
|
+
def update_customer_nearest_expiry_stamp_reward_summary(customer, start_datetime, end_datetime):
|
|
18
|
+
nearest_expiry_details = {
|
|
19
|
+
'expiry_date': start_datetime.date()
|
|
20
|
+
}
|
|
21
|
+
transactions_list = []
|
|
22
|
+
total_stamp_balance = .0
|
|
23
|
+
today = datetime.utcnow().date()
|
|
24
|
+
|
|
25
|
+
(result, next_cursor) = CustomerStampReward.list_by_valid_with_cursor(customer, limit=100, start_datetime=start_datetime, end_datetime=end_datetime)
|
|
26
|
+
logger.debug('next_cursor=%s', next_cursor)
|
|
27
|
+
logger.debug('transaction count=%s', len(result))
|
|
28
|
+
|
|
29
|
+
while is_not_empty(next_cursor):
|
|
30
|
+
|
|
31
|
+
if result:
|
|
32
|
+
(nearest_expiry_details, transactions_list, total_stamp_balance) = __update_customer_nearest_expiry_reward_summary(result, nearest_expiry_details, transactions_list)
|
|
33
|
+
|
|
34
|
+
(result, next_cursor) = CustomerStampReward.list_by_valid_with_cursor(customer, limit=100, start_cursor=next_cursor, start_datetime=start_datetime, end_datetime=end_datetime)
|
|
35
|
+
|
|
36
|
+
logger.debug('result=%s, type of is %s', result, type(result))
|
|
37
|
+
logger.debug('next_cursor=%s, type of is %s', next_cursor, type(next_cursor))
|
|
38
|
+
|
|
39
|
+
if result:
|
|
40
|
+
(nearest_expiry_details, transactions_list, total_stamp_balance) = __update_customer_nearest_expiry_reward_summary(result, nearest_expiry_details, transactions_list)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def __update_customer_nearest_expiry_reward_summary(result, nearest_expiry_details, transactions_list, total_reward_balance):
|
|
45
|
+
|
|
46
|
+
for r in result:
|
|
47
|
+
reward_balance = r.reward_balance
|
|
48
|
+
transaction_reward_summary = r.to_reward_summary()
|
|
49
|
+
customer_reward_summary = update_reward_summary_with_new_reward(nearest_expiry_details)
|
|
50
|
+
|
|
51
|
+
total_reward_balance +=reward_balance
|
|
52
|
+
|
|
53
|
+
transactions_list.append({
|
|
54
|
+
'transaction_id' : r.transaction_id,
|
|
55
|
+
'reward_balance' : reward_balance,
|
|
56
|
+
'expiry_date' : datetime.strftime(r.expiry_date, '%d-%m-%Y'),
|
|
57
|
+
'transact_datetime' : datetime.strftime(r.rewarded_datetime, '%d-%m-%Y %H:%M:%s'),
|
|
58
|
+
'reward_format' : r.reward_format,
|
|
59
|
+
'is_expired' : r.expiry_date<today,
|
|
60
|
+
})
|
|
61
|
+
return (customer_reward_summary, transactions_list, total_reward_balance)
|
|
62
|
+
|
|
63
|
+
def update_nearest_expiry_reward_summary(customer, reward_format):
|
|
64
|
+
if reward_format==REWARD_FORMAT_POINT:
|
|
65
|
+
pass
|
|
66
|
+
elif reward_format==REWARD_FORMAT_STAMP:
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
'''
|
|
70
|
+
|
|
15
71
|
'''
|
|
16
72
|
Customer Reward Summary format is
|
|
17
73
|
{
|
|
@@ -24,31 +80,54 @@ Customer Reward Summary format is
|
|
|
24
80
|
|
|
25
81
|
'''
|
|
26
82
|
''' --------------- Start: Update reward summary for point and stamp--------------'''
|
|
27
|
-
def update_reward_summary_with_new_reward(existing_reward_summary, new_reward_details):
|
|
83
|
+
def update_reward_summary_with_new_reward(existing_reward_summary, new_reward_details, checking_date=None, max_days_ahead=1800, n_latest_nearest_expiry_entries=10):
|
|
28
84
|
reward_format = new_reward_details.get('reward_format')
|
|
29
85
|
reward_amount = new_reward_details.get('amount')
|
|
30
86
|
used_reward_amount = new_reward_details.get('used_amount')
|
|
87
|
+
reward_balance = reward_amount - used_reward_amount
|
|
88
|
+
new_reward_amount = .0
|
|
89
|
+
rewarded_date = datetime.strptime(new_reward_details.get('rewarded_date'), '%d-%m-%Y').date()
|
|
90
|
+
|
|
31
91
|
program_key = new_reward_details.get('program_key')
|
|
32
92
|
is_reach_reward_limit = new_reward_details.get('is_reach_reward_limit')
|
|
33
|
-
|
|
93
|
+
checking_date = checking_date if checking_date is not None else datetime.today().date()
|
|
94
|
+
new_reward_expiry_date = datetime.strptime(new_reward_details.get('expiry_date'), '%d-%m-%Y').date()
|
|
95
|
+
last_rewarded_date = new_reward_details.get('last_rewarded_date')
|
|
96
|
+
last_rewarded_date = datetime.strptime(last_rewarded_date, '%d-%m-%Y').date() if last_rewarded_date else rewarded_date
|
|
97
|
+
|
|
98
|
+
if new_reward_expiry_date<=checking_date:
|
|
99
|
+
return
|
|
100
|
+
|
|
101
|
+
latest_expiry_date = new_reward_expiry_date
|
|
34
102
|
existing_latest_expiry_date = None
|
|
35
|
-
|
|
36
|
-
|
|
103
|
+
nearest_expiry_date = None
|
|
104
|
+
|
|
105
|
+
|
|
37
106
|
|
|
38
107
|
logger.debug('reward_amount=%s', reward_amount)
|
|
39
108
|
logger.debug('used_reward_amount=%s', used_reward_amount)
|
|
40
109
|
logger.debug('reward_balance=%s', reward_balance)
|
|
41
110
|
|
|
111
|
+
logger.debug('checking_date=%s', checking_date)
|
|
112
|
+
|
|
42
113
|
if reward_balance<0:
|
|
43
114
|
reward_balance=0
|
|
44
115
|
|
|
45
116
|
if is_empty(existing_reward_summary):
|
|
117
|
+
nearest_expiry_date = new_reward_expiry_date
|
|
46
118
|
|
|
47
119
|
existing_reward_summary = {
|
|
48
120
|
reward_format:{
|
|
49
|
-
'latest_expiry_date' :
|
|
121
|
+
'latest_expiry_date' : latest_expiry_date.strftime('%d-%m-%Y'),
|
|
122
|
+
'last_rewarded_date' : last_rewarded_date.strftime('%d-%m-%Y'),
|
|
123
|
+
'checking_date' : checking_date.strftime('%d-%m-%Y'),
|
|
50
124
|
'amount' : reward_balance,
|
|
51
|
-
|
|
125
|
+
'nearest_expiry_list' : [
|
|
126
|
+
{
|
|
127
|
+
'expiry_date' : nearest_expiry_date.strftime('%d-%m-%Y'),
|
|
128
|
+
'amount' : reward_balance,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
52
131
|
'sources' : [
|
|
53
132
|
{
|
|
54
133
|
'amount' : reward_balance,
|
|
@@ -59,30 +138,39 @@ def update_reward_summary_with_new_reward(existing_reward_summary, new_reward_de
|
|
|
59
138
|
}
|
|
60
139
|
|
|
61
140
|
}
|
|
141
|
+
|
|
142
|
+
|
|
62
143
|
else:
|
|
63
|
-
reward_summary_by_reward_format = existing_reward_summary.get(reward_format)
|
|
144
|
+
reward_summary_by_reward_format = existing_reward_summary.get(reward_format,{})
|
|
145
|
+
reward_source_list = reward_summary_by_reward_format.get('sources') or []
|
|
146
|
+
nearest_expiry_list = reward_summary_by_reward_format.get('nearest_expiry_list', [])
|
|
64
147
|
|
|
65
|
-
|
|
66
|
-
reward_summary_by_reward_format = {
|
|
67
|
-
'amount': 0,
|
|
68
|
-
}
|
|
69
|
-
new_latest_expiry_date = latest_expiry_date
|
|
70
|
-
else:
|
|
148
|
+
existing_last_rewarded_date = reward_summary_by_reward_format.get('last_rewarded_date')
|
|
71
149
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
150
|
+
if is_empty(existing_last_rewarded_date):
|
|
151
|
+
existing_last_rewarded_date = last_rewarded_date
|
|
152
|
+
|
|
153
|
+
if rewarded_date>last_rewarded_date:
|
|
154
|
+
last_rewarded_date = rewarded_date
|
|
76
155
|
|
|
77
|
-
if latest_expiry_date > existing_latest_expiry_date:
|
|
78
|
-
new_latest_expiry_date = existing_latest_expiry_date
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
reward_summary_by_reward_format['latest_expiry_date'] = new_latest_expiry_date.strftime('%d-%m-%Y')
|
|
82
|
-
reward_summary_by_reward_format['amount'] = reward_summary_by_reward_format['amount'] + reward_balance
|
|
83
156
|
|
|
84
|
-
|
|
157
|
+
if is_not_empty(nearest_expiry_list):
|
|
158
|
+
nearest_expiry_list = __remove_expired_reward(nearest_expiry_list, checking_date)
|
|
159
|
+
|
|
160
|
+
new_record = {
|
|
161
|
+
'amount' : reward_balance,
|
|
162
|
+
'expiry_date' : datetime.strftime(new_reward_expiry_date, '%d-%m-%Y')
|
|
163
|
+
}
|
|
164
|
+
#nearest_expiry_list = __add_record_or_update_if_within_max_day_range(nearest_expiry_list, new_record, today_date, max_days_ahead)
|
|
165
|
+
|
|
166
|
+
__add_record_or_update_if_within_max_day_range(nearest_expiry_list, new_record, checking_date, max_days_ahead)
|
|
167
|
+
|
|
168
|
+
nearest_expiry_list = __maintain_latest_n_entries(nearest_expiry_list, n_latest_nearest_expiry_entries)
|
|
169
|
+
|
|
170
|
+
nearest_expiry_list = sorted(nearest_expiry_list, key=lambda x: __string_to_date(x['expiry_date']))
|
|
171
|
+
|
|
85
172
|
found_program_reward_source = False
|
|
173
|
+
|
|
86
174
|
for reward_source in reward_source_list:
|
|
87
175
|
existing_reward_source_program_key = reward_source.get('program_key')
|
|
88
176
|
if existing_reward_source_program_key== program_key:
|
|
@@ -102,12 +190,57 @@ def update_reward_summary_with_new_reward(existing_reward_summary, new_reward_de
|
|
|
102
190
|
}
|
|
103
191
|
)
|
|
104
192
|
|
|
105
|
-
reward_summary_by_reward_format
|
|
193
|
+
if is_empty(reward_summary_by_reward_format):
|
|
194
|
+
new_reward_amount = reward_balance
|
|
195
|
+
|
|
196
|
+
else:
|
|
197
|
+
|
|
198
|
+
existing_latest_expiry_date = reward_summary_by_reward_format.get('latest_expiry_date')
|
|
199
|
+
existing_latest_expiry_date = datetime.strptime(existing_latest_expiry_date, '%d-%m-%Y').date()
|
|
200
|
+
existing_reward_amount = reward_summary_by_reward_format.get('amount', .0)
|
|
201
|
+
new_reward_amount = existing_reward_amount + reward_balance
|
|
202
|
+
|
|
203
|
+
if existing_latest_expiry_date > latest_expiry_date:
|
|
204
|
+
latest_expiry_date = existing_latest_expiry_date
|
|
205
|
+
|
|
206
|
+
reward_summary_by_reward_format = {
|
|
207
|
+
'amount' : new_reward_amount,
|
|
208
|
+
'latest_expiry_date' : latest_expiry_date.strftime('%d-%m-%Y'),
|
|
209
|
+
'last_rewarded_date' : last_rewarded_date.strftime('%d-%m-%Y'),
|
|
210
|
+
'checking_date' : checking_date.strftime('%d-%m-%Y'),
|
|
211
|
+
'nearest_expiry_list' : nearest_expiry_list or [],
|
|
212
|
+
'sources' : reward_source_list,
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
106
217
|
|
|
107
|
-
existing_reward_summary[reward_format]
|
|
218
|
+
existing_reward_summary[reward_format] = reward_summary_by_reward_format
|
|
108
219
|
|
|
109
220
|
return existing_reward_summary
|
|
110
221
|
|
|
222
|
+
def __string_to_date(date_str):
|
|
223
|
+
return datetime.strptime(date_str, '%d-%m-%Y').date()
|
|
224
|
+
|
|
225
|
+
def __remove_expired_reward(data, current_date):
|
|
226
|
+
return [record for record in data if __string_to_date(record['expiry_date']) >= current_date]
|
|
227
|
+
|
|
228
|
+
def __add_record_or_update_if_within_max_day_range(data_list, new_record, current_date, max_days_ahead):
|
|
229
|
+
expiry_date = __string_to_date(new_record['expiry_date'])
|
|
230
|
+
if current_date <= expiry_date <= current_date + timedelta(days=max_days_ahead):
|
|
231
|
+
for record in data_list:
|
|
232
|
+
if record['expiry_date'] == new_record['expiry_date']:
|
|
233
|
+
record['amount'] += new_record['amount']
|
|
234
|
+
break
|
|
235
|
+
else:
|
|
236
|
+
data_list.append(new_record)
|
|
237
|
+
else:
|
|
238
|
+
logger.debug(f"Record with expiry date {new_record['expiry_date']} is out of the allowed range and was not added.")
|
|
239
|
+
|
|
240
|
+
def __maintain_latest_n_entries(data, n):
|
|
241
|
+
data.sort(key=lambda x: __string_to_date(x['expiry_date']), reverse=True)
|
|
242
|
+
return data[:n]
|
|
243
|
+
|
|
111
244
|
def update_reward_summary_with_reverted_reward(existing_reward_summary, reverting_reward_details):
|
|
112
245
|
reward_summary = existing_reward_summary
|
|
113
246
|
reward_format = reverting_reward_details.get('reward_format')
|