Subversion Repositories SmartDukaan

Rev

Rev 6433 | Rev 6497 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1976 varun.gupt 1
'''
2
Created on May 24, 2010
3
@author: Varun Gupta
4
'''
5
from shop2020.clients.UserClient import UserClient
3133 rajveer 6
from shop2020.clients.CatalogClient import CatalogClient
1976 varun.gupt 7
from shop2020.thriftpy.model.v1.user.ttypes import PromotionException
8
from shop2020.model.v1.user.impl import Dataservice
5469 rajveer 9
from shop2020.model.v1.user.impl.Dataservice import Promotion, Coupon, PromotionTracker,\
10
    RechargeVoucher
1976 varun.gupt 11
from shop2020.utils.Utils import to_py_date
6250 amit.gupta 12
import uuid
1976 varun.gupt 13
 
14
from elixir import session
2389 varun.gupt 15
import datetime, traceback
6250 amit.gupta 16
from string import Template
6433 anupam.sin 17
from shop2020.model.v1.user.impl.PromotionRuleDataUtilities import get_coupon_usage_count, get_coupon_usage_count_by_user
1976 varun.gupt 18
 
3187 rajveer 19
def initialize(dbname = 'user', db_hostname="localhost"):
20
    Dataservice.initialize(dbname, db_hostname)
1976 varun.gupt 21
 
22
def create_promotion(name, rule_execution_src, start_on, end_on):
23
    promotion = Promotion()
24
    promotion.name = name
25
    promotion.rule_execution_src = rule_execution_src
26
    promotion.start_on = to_py_date(start_on)
27
    promotion.end_on = to_py_date(end_on)
28
    promotion.created_on = datetime.datetime.now()
29
    session.commit()
30
 
31
def get_all_promotions():
32
    return Promotion.query.all()
33
 
34
def generate_coupons_for_promotion(promotion_id, coupon_code):
35
    promotion = Promotion.get_by(id = promotion_id)
36
 
37
    coupon = Coupon()
38
    coupon.promotion = promotion
39
    coupon.coupon_code = coupon_code
40
    coupon.arguments = ""
41
    session.commit()
42
 
6355 amit.gupta 43
def create_coupon(promotionId, endOn, email, amount, isCod, usage):
6367 amit.gupta 44
    if promotionId not in (26,27):
45
        raise PromotionException(101, 'Only promotion ids 26 and 27 are expected')
6250 amit.gupta 46
    promotion = Promotion.get_by(id = promotionId)
47
    if promotion:     
48
        coupon_code = uuid.uuid4().hex[:10]
49
        coupon = Coupon.get_by(coupon_code = coupon_code)
50
        while coupon is not None:
51
            coupon_code = uuid.uuid4().hex[:10]
52
            coupon = Coupon.get_by(coupon_code = coupon_code)
6355 amit.gupta 53
        s=Template('{"emails":["$email"],"discount":$amount,"usage_limit_for_user":$usage,"endOn":$endOn, "isCod":$isCod}')
6250 amit.gupta 54
        coupon = Coupon()
55
        coupon.promotion = promotion
56
        coupon.coupon_code = coupon_code
6355 amit.gupta 57
        coupon.arguments = s.substitute(email=email, amount=amount, usage=usage, endOn=endOn, isCod=isCod)
6250 amit.gupta 58
        session.commit()
59
        return coupon_code
60
    else:
61
        raise PromotionException(101, 'Could not find Promotion for id' + str(promotionId))
6301 amit.gupta 62
 
63
def get_coupon(coupon_code):
64
    return Coupon.get_by(coupon_code = coupon_code)
6250 amit.gupta 65
 
6433 anupam.sin 66
def apply_recharge_coupon(coupon_code, total_amount, user_id):
67
    coupon = Coupon.get_by(coupon_code = coupon_code)
68
    discount = 0
69
 
70
    if coupon:
71
 
72
        args = eval(coupon.arguments) if coupon.arguments is not None else {}
73
 
6443 anupam.sin 74
        if 'percent' in args :
75
            percentDiscount = args['percent']
76
        else :
77
            return {0 : 'Currently this coupon is unavailable'}
78
 
6433 anupam.sin 79
        if 'minDiscountableVal' in args and total_amount < int(args['minDiscountableVal']):
80
            return {0:'This coupon is valid for recharges equal to or more than Rs.' + (args['minDiscountableVal'])}
81
 
82
        if 'couponType' in args and (args['couponType']) == 'RECHARGE':
6443 anupam.sin 83
            discount = round(total_amount * percentDiscount)
6433 anupam.sin 84
        else :
85
            return {0:'Invalid Coupon'}
86
 
87
        todate = datetime.datetime.now()
88
        if 'endOn' in args and todate > to_py_date(args['endOn']) :
89
            return {0:'This coupon is expired.'}
90
 
91
        if 'startHour' in args :
92
            startHour = int(args['startHour'])
93
        else :
94
            return {0 : 'Currently this coupon is unavailable'}
95
 
96
        if 'startMinute' in args :
97
            startMinute = int(args['startMinute'])
98
        else :
99
            return {0 : 'Currently this coupon is unavailable'}
100
 
101
        if 'endHour' in args :
102
            endHour = int(args['endHour'])
103
        else :
104
            return {0 : 'Currently this coupon is unavailable'}
105
 
106
        if 'endMinute' in args :
107
            endMinute = int(args['endMinute'])
108
        else :
109
            return {0 : 'Currently this coupon is unavailable'}
110
 
111
        now = datetime.datetime.now()
112
        curtime = datetime.time(now.hour, now.minute, now.second)
113
        starttime = datetime.time(startHour, startMinute, 0)
114
        endtime = datetime.time(endHour, endMinute, 0)
115
        if (curtime < starttime or curtime > endtime):
116
            return {0:'Currently this coupon is unavailable'}
117
 
6443 anupam.sin 118
        if 'userLimit' in args :
119
            userLimit = args['userLimit']
120
        else :
121
            return {0 : 'Currently this coupon is unavailable'}
122
 
6433 anupam.sin 123
        count_coupon_usage_by_user = get_coupon_usage_count_by_user(coupon_code, user_id)
6443 anupam.sin 124
        if count_coupon_usage_by_user >= userLimit:
125
            return {0:'This coupon is applicable only ' + str(userLimit) + ' times per user'}
6433 anupam.sin 126
 
6443 anupam.sin 127
        if 'globalLimit' in args :
128
            globalLimit = args['globalLimit']
129
        else :
130
            return {0 : 'Currently this coupon is unavailable'}
131
 
6433 anupam.sin 132
        count_coupon_usage = get_coupon_usage_count(coupon_code)
6443 anupam.sin 133
        if count_coupon_usage >= globalLimit:
6433 anupam.sin 134
            return {0:'This promotion is over.'}
135
 
136
        if 'maxDiscount' in args and discount > int(args['maxDiscount']):
137
            return {int(args['maxDiscount']):"Coupon Applied"}
138
 
139
        return {discount:'Coupon Applied'}
140
    else:
141
        return {0:'Invalid Coupon'}
142
 
1976 varun.gupt 143
def apply_coupon(coupon_code, cart_id):
144
    coupon = Coupon.get_by(coupon_code = coupon_code)
145
 
146
    if coupon:
6011 rajveer 147
        todate = datetime.datetime.now()
148
        if not (coupon.promotion.start_on <=  todate and coupon.promotion.end_on >= todate):
6433 anupam.sin 149
            raise PromotionException(101, 'Promotion has expired')
6011 rajveer 150
 
1976 varun.gupt 151
        user_client = UserClient().get_client()
152
        cart = user_client.getCart(cart_id)
3554 varun.gupt 153
 
2389 varun.gupt 154
        coupon_module = coupon.promotion.rule_execution_src.strip()
155
 
156
        try:
3554 varun.gupt 157
            user_client.deleteDiscountsFromCart(cart_id)
2389 varun.gupt 158
            imported_coupon_module = __import__("shop2020.model.v1.user.promotionrules", globals(), locals(), [coupon_module])
159
            rule = eval("imported_coupon_module." + coupon_module)
2466 varun.gupt 160
 
161
            args = eval(coupon.arguments) if coupon.arguments is not None else {}
162
 
3554 varun.gupt 163
            updated_cart, discounts = rule.execute(cart, coupon_code, args)
164
 
165
            if discounts and len(discounts) > 0:    user_client.saveDiscounts(discounts)
166
 
2389 varun.gupt 167
            user_client.applyCouponToCart(cart_id, coupon_code, updated_cart.totalPrice, updated_cart.discountedPrice)
3554 varun.gupt 168
 
2389 varun.gupt 169
            return updated_cart
170
 
171
        except ImportError as e:
172
            traceback.print_stack()
173
            #TODO: Better message
174
            raise PromotionException(100, 'Internal error occurred.')
1976 varun.gupt 175
    else:
176
        print 'Invalid Coupon Code'
177
        raise PromotionException(101, 'Invalid Coupon Code')
178
 
179
def track_coupon_usage(coupon_code, transaction_id, user_id):
180
    promotion_tracker = PromotionTracker()
181
    promotion_tracker.coupon_code = coupon_code
182
    promotion_tracker.transaction_id = transaction_id
183
    promotion_tracker.user_id = user_id
184
    promotion_tracker.applied_on = datetime.datetime.now()
185
    session.commit()
186
 
3386 varun.gupt 187
def get_active_coupons():
188
    return Coupon.query.all()
189
 
190
def get_successful_payment_count_for_coupon(coupon_code):
191
    return PromotionTracker.query.filter_by(coupon_code = coupon_code).count()
192
 
193
def get_rule_doc_string(rule_name):
194
    imported_coupon_module = __import__("shop2020.model.v1.user.promotionrules", globals(), locals(), [rule_name])
195
    rule = eval("imported_coupon_module." + rule_name)
196
    return rule.__doc__
4189 varun.gupt 197
 
1976 varun.gupt 198
def close_session():
199
    if session.is_active:
3376 rajveer 200
        session.close()
4189 varun.gupt 201
 
3376 rajveer 202
def is_alive():
203
    try:
204
        session.query(Promotion.id).limit(1).one()
205
        return True
206
    except:
4189 varun.gupt 207
        return False
208
 
4494 varun.gupt 209
def get_discounts_for_entity(entity_id):
210
    catalog_client = CatalogClient().get_client()
211
    items = catalog_client.getItemsByCatalogId(entity_id)
212
 
213
    discount_finder = ItemDiscountFinder()
214
    discounts = discount_finder.getCouponsAndDiscountsOnItem(items[0])
215
 
216
    if len(discounts) > 0:
217
        return {discounts[0][0]: discounts[0][1]}
218
    else:
219
        return {}
220
 
4189 varun.gupt 221
def get_item_discount_map(item_ids):
222
 
223
    discount_finder = ItemDiscountFinder()
224
    item_coupons_discounts = []
225
 
226
    catalog_client = CatalogClient().get_client()
227
 
228
    for item_id in item_ids:
229
        item = catalog_client.getItem(item_id)
230
 
231
        discounts = discount_finder.getCouponsAndDiscountsOnItem(item)
232
 
233
        for discount in discounts:
234
            item_coupons_discounts.append((item_id, discount[0], discount[1]))
235
            break
236
 
237
    return item_coupons_discounts
238
 
5469 rajveer 239
def add_voucher(t_voucher):
240
    voucher = RechargeVoucher()
241
    voucher.available = True
242
    voucher.amount = t_voucher.amount
243
    voucher.voucherCode = t_voucher.voucherCode
244
    voucher.voucherType = t_voucher.voucherType
245
    if t_voucher.issuedOn:
246
        voucher.issuedOn = to_py_date(t_voucher.issuedOn)
247
    if t_voucher.expiredOn:
248
        voucher.expiredOn = to_py_date(t_voucher.expiredOn)
249
    session.commit()
250
 
251
def assign_voucher(userId, userEmail, voucherType, amount):
252
    voucher = RechargeVoucher.query.filter_by(voucherType = voucherType, amount = amount, available = True).first()
253
    if not voucher:
254
        raise PromotionException(501, 'Voucher of this type is not available.')
255
    voucher.userId = userId
256
    voucher.available = False
257
    voucher.issuedOn = datetime.datetime.now()
258
    voucher.email = userEmail
259
    session.commit()
260
    return voucher
261
 
262
def mark_voucher_as_redeemed(voucherCode, redeemedOn):
263
    voucher = RechargeVoucher.query.filter_by(voucherCode = voucherCode).first()
264
    voucher.redeemedOn = to_py_date(redeemedOn)
265
    voucher.redeemed = True
266
    session.commit()
267
    return True
268
 
4189 varun.gupt 269
class ItemDiscountFinder:
270
 
271
    def __init__(self):
272
        self.coupon_modules = {}
273
        coupons = get_active_coupons()
274
 
275
        for coupon in coupons:
5996 amit.gupta 276
            if coupon.coupon_code not in ('SAHOLIC4RS', 'SAndroid', 'SAHOLIC4MJ', 'SAHOLIC4SS', 'SJunglee'):
4189 varun.gupt 277
                coupon_rule = coupon.promotion.rule_execution_src.strip()
278
 
279
                imported_coupon_module = __import__("shop2020.model.v1.user.promotionrules", globals(), locals(), [coupon_rule])
280
                self.coupon_modules[coupon.coupon_code] = eval("imported_coupon_module." + coupon_rule)
281
 
282
    def getCouponsAndDiscountsOnItem(self, item):
283
        discounts = []
284
 
285
        for coupon_code, coupon_rule_module in self.coupon_modules.iteritems():
286
 
287
            discount = coupon_rule_module.getDiscountOnItem(item)
288
 
289
            if discount is not None:
290
                discounts.append((coupon_code, discount))
291
 
292
        return discounts