trex-model 1.5.20__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.

Files changed (64) hide show
  1. {trex-model-1.5.20 → trex-model-1.5.21}/PKG-INFO +1 -1
  2. {trex-model-1.5.20 → trex-model-1.5.21}/setup.py +1 -1
  3. {trex-model-1.5.20 → trex-model-1.5.21}/trex_model.egg-info/PKG-INFO +1 -1
  4. {trex-model-1.5.20 → trex-model-1.5.21}/trex_model.egg-info/SOURCES.txt +1 -0
  5. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/customer_model_helpers.py +160 -27
  6. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/helper/reward_transaction_helper.py +196 -175
  7. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/merchant_models.py +19 -7
  8. trex-model-1.5.21/trexmodel/models/datastore/merchant_promotion_models.py +50 -0
  9. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/program_models.py +25 -1
  10. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/reward_models.py +34 -11
  11. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/system_models.py +23 -0
  12. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/transaction_models.py +16 -4
  13. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/user_models.py +1 -1
  14. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/merchant_helpers.py +5 -0
  15. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/program_conf.py +4 -0
  16. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/utils/model/model_util.py +1 -0
  17. {trex-model-1.5.20 → trex-model-1.5.21}/LICENSE +0 -0
  18. {trex-model-1.5.20 → trex-model-1.5.21}/MANIFEST.in +0 -0
  19. {trex-model-1.5.20 → trex-model-1.5.21}/README.md +0 -0
  20. {trex-model-1.5.20 → trex-model-1.5.21}/setup.cfg +0 -0
  21. {trex-model-1.5.20 → trex-model-1.5.21}/trex_model.egg-info/dependency_links.txt +0 -0
  22. {trex-model-1.5.20 → trex-model-1.5.21}/trex_model.egg-info/requires.txt +0 -0
  23. {trex-model-1.5.20 → trex-model-1.5.21}/trex_model.egg-info/top_level.txt +0 -0
  24. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/__init__.py +0 -0
  25. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/conf.py +0 -0
  26. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/__init__.py +0 -0
  27. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/__init__.py +0 -0
  28. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/admin_models.py +0 -0
  29. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/analytic_models.py +0 -0
  30. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/app_models.py +0 -0
  31. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/coporate_models.py +0 -0
  32. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/customer_models.py +0 -0
  33. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/fb_subsriber_models.py +0 -0
  34. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/helper/__init__.py +0 -0
  35. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/helper/reward_model_helpers.py +0 -0
  36. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/import_models.py +0 -0
  37. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/inventory_model.py +0 -0
  38. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/loyalty_models.py +0 -0
  39. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/lucky_draw_models.py +0 -0
  40. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/marketing_models.py +0 -0
  41. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/membership_models.py +0 -0
  42. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/message_model_helper.py +0 -0
  43. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/message_models.py +0 -0
  44. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/model_decorators.py +0 -0
  45. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/ndb_models.py +0 -0
  46. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/pos_models.py +0 -0
  47. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/prepaid_models.py +0 -0
  48. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/product_models.py +0 -0
  49. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/rating_models.py +0 -0
  50. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/recruit_models.py +0 -0
  51. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/redeem_models.py +0 -0
  52. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/redemption_catalogue_models.py +0 -0
  53. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/referral_program_model.py +0 -0
  54. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/spending_base_program_model.py +0 -0
  55. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/task_models.py +0 -0
  56. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/test_models.py +0 -0
  57. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/datastore/voucher_models.py +0 -0
  58. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/model_decorator.py +0 -0
  59. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/models/prepaid_helpers.py +0 -0
  60. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/pos_conf.py +0 -0
  61. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/utils/__init__.py +0 -0
  62. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/utils/gcloud/__init__.py +0 -0
  63. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/utils/gcloud/datastore_util.py +0 -0
  64. {trex-model-1.5.20 → trex-model-1.5.21}/trexmodel/utils/model/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: trex-model
3
- Version: 1.5.20
3
+ Version: 1.5.21
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.5.20',
6
+ version='1.5.21',
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.5.20
3
+ Version: 1.5.21
4
4
  Summary: TRex database module package
5
5
  Home-page: https://bitbucket.org/lokjac/trex-model
6
6
  Author: Jack Lok
@@ -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
@@ -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
- latest_expiry_date = datetime.strptime(new_reward_details.get('expiry_date'), '%d-%m-%Y').date()
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
- new_latest_expiry_date = latest_expiry_date
36
- reward_balance = reward_amount - used_reward_amount
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' : new_latest_expiry_date.strftime('%d-%m-%Y'),
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
- if reward_summary_by_reward_format is None:
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
- existing_latest_expiry_date = reward_summary_by_reward_format.get('latest_expiry_date')
73
- existing_latest_expiry_date = datetime.strptime(existing_latest_expiry_date, '%d-%m-%Y').date()
74
-
75
- new_latest_expiry_date = latest_expiry_date
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
- reward_source_list = reward_summary_by_reward_format.get('sources') or []
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['sources'] = reward_source_list
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] = reward_summary_by_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')