Subversion Repositories SmartDukaan

Rev

Rev 21332 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
13569 amit.gupta 1
'''
2
Created on Jan 15, 2015
3
 
4
@author: amit
5
'''
14618 amit.gupta 6
from datetime import datetime, timedelta
15078 amit.gupta 7
from dtr.config import PythonPropertyReader
19577 manas 8
from dtr.storage.Mongo import getDealRank, userLookUpForSaholicId
14618 amit.gupta 9
from dtr.storage.Mysql import getOrdersAfterDate1, getOrdersAfterDate
13868 amit.gupta 10
from pprint import pprint
13569 amit.gupta 11
from pymongo.mongo_client import MongoClient
14413 amit.gupta 12
import base64
13569 amit.gupta 13
import importlib
13662 amit.gupta 14
import json
15
import math
13569 amit.gupta 16
import mechanize
14413 amit.gupta 17
import time
13631 amit.gupta 18
import traceback
13662 amit.gupta 19
import urllib
20
import urllib2
16736 amit.gupta 21
from dtr.utils import utils 
17013 manish.sha 22
sourceMap = {1:"amazon", 2:"flipkart", 3:"snapdeal", 4:"spice", 5:"shopclues", 6:"paytm", 7:"homeshop18"}
13662 amit.gupta 23
headers = { 
24
           'User-agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
25
            'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',      
26
            'Accept-Language' : 'en-US,en;q=0.8',                     
27
            'Accept-Charset' : 'ISO-8859-1,utf-8;q=0.7,*;q=0.3'
28
        }
14145 amit.gupta 29
CASHBACK_URL = PythonPropertyReader.getConfig('CASHBACK_URL')
30
USER_LOOKUP_URL = PythonPropertyReader.getConfig('USER_LOOKUP_URL')
31
WALLET_CREDIT_URL = PythonPropertyReader.getConfig('WALLET_CREDIT_URL')
13569 amit.gupta 32
 
33
def getStore(source_id):
34
    #module = sourceMap[source_id]
35
    store = Store(source_id)
13631 amit.gupta 36
    try:
37
        module = importlib.import_module("dtr.sources." + sourceMap[source_id])
38
        store = getattr(module, "Store")(source_id)
39
        return store
40
    except:
13781 amit.gupta 41
        traceback.print_exc()
13631 amit.gupta 42
        return None
13569 amit.gupta 43
 
44
class ScrapeException(Exception):
45
    """Exception raised for errors in the input.
46
 
47
    Attributes:
48
        expr -- input expression in which the error occurred
49
        msg  -- explanation of the error
50
    """
51
 
52
    def __init__(self, expr, msg):
53
        self.expr = expr
54
        self.msg = msg
55
 
56
class ParseException(Exception):
57
    """Exception raised for errors in the input.
58
 
59
    Attributes:
60
        expr -- input expression in which the error occurred
61
        msg  -- explanation of the error
62
    """
63
 
64
    def __init__(self, expr, msg):
65
        self.expr = expr
66
        self.msg = msg
67
 
13677 amit.gupta 68
client = MongoClient('mongodb://localhost:27017/') 
69
 
13569 amit.gupta 70
class Store(object):
71
 
72
    ORDER_PLACED = 'Order Placed'
73
    ORDER_DELIVERED = 'Delivered'
74
    ORDER_SHIPPED = 'Shipped' #Lets see if we can make use of it
75
    ORDER_CANCELLED = 'Cancelled'
76
 
13662 amit.gupta 77
    CB_INIT = 'Waiting Confirmation'
13610 amit.gupta 78
    CB_PENDING = 'Pending'
13955 amit.gupta 79
    CB_CREDIT_IN_PROCESS = 'Credit in process'
13610 amit.gupta 80
    CB_CREDITED = 'Credited to wallet'
81
    CB_NA = 'Not Applicable'
82
    CB_APPROVED = 'Approved'
14618 amit.gupta 83
    CB_REJECTED = 'Rejected'
84
    CB_ONHOLD = 'On hold'
13610 amit.gupta 85
    CB_CANCELLED = 'Cancelled'
13569 amit.gupta 86
 
13662 amit.gupta 87
    CONF_CB_SELLING_PRICE = 0
88
    CONF_CB_DISCOUNTED_PRICE = 1
13610 amit.gupta 89
 
13569 amit.gupta 90
    def __init__(self, store_id):
13662 amit.gupta 91
        self.db = client.Dtr
18156 amit.gupta 92
        self.catalogdb = client.Catalog
13569 amit.gupta 93
        self.store_id = store_id
13576 amit.gupta 94
        self.store_name = sourceMap[store_id]
13569 amit.gupta 95
 
13662 amit.gupta 96
    '''
97
    To Settle payback for respective stores.
98
    Also ensures that settlement happens only for approved orders
99
    '''
13569 amit.gupta 100
 
101
    def getName(self):
102
        raise NotImplementedError
103
 
104
    def scrapeAffiliate(self, startDate=None, endDate=None):
105
        raise NotImplementedError
106
 
16390 amit.gupta 107
    def getTrackingUrls(self, userId):
108
        raise NotImplementedError
109
 
110
 
13569 amit.gupta 111
    def saveToAffiliate(self, offers):
112
        raise NotImplementedError
113
 
16371 amit.gupta 114
    def getUpdateMap(self, subOrder, cashBackStatus):
14624 amit.gupta 115
        updateMap = {}
116
        closed = False
117
        for (key,value) in subOrder.iteritems():
118
            if key=="status":
119
                if value==Store.ORDER_CANCELLED:
120
                    closed = True
121
                    updateMap['subOrders.$.closed'] = True
16371 amit.gupta 122
                    if cashBackStatus == Store.CB_PENDING:
14624 amit.gupta 123
                        updateMap['subOrders.$.cashBackStatus'] = Store.CB_CANCELLED
124
                if value==Store.ORDER_DELIVERED:
125
                    closed = True
126
                    updateMap['subOrders.$.closed'] = True
16371 amit.gupta 127
                    if cashBackStatus == Store.CB_PENDING:
14624 amit.gupta 128
                        updateMap['subOrders.$.cashBackStatus'] = Store.CB_APPROVED
129
            updateMap['subOrders.$.' + key] = value
130
        subOrder['closed'] = closed
131
        return updateMap
132
 
14618 amit.gupta 133
    def saveOrder(self, merchantOrder):
134
        #merchantOrder = Order()
135
        #merchantOrder.status
136
        #mercha
137
        pass
138
 
139
 
13569 amit.gupta 140
    def scrapeStoreOrders(self,):
141
        raise NotImplementedError
13610 amit.gupta 142
 
14618 amit.gupta 143
    def updateSubOrder(self, subOrder):
144
        pass
145
        #if subOrder.get
146
 
13690 amit.gupta 147
    def _saveToOrder(self, order):
148
        collection = self.db.merchantOrder
149
        try:
17388 amit.gupta 150
            print "************************************************************************"
151
            print "order"
152
            print order
153
            print "************************************************************************"
13690 amit.gupta 154
            order = collection.insert(order)
14273 amit.gupta 155
            return True 
13690 amit.gupta 156
        except Exception as e:
14273 amit.gupta 157
            return False
14081 amit.gupta 158
 
159
    def _updateToOrder(self, order):
160
        collection = self.db.merchantOrder
161
        try:
14959 amit.gupta 162
            print "************************************************************************"
163
            print "order"
164
            print order
165
            print "************************************************************************"
14081 amit.gupta 166
            collection.update({"orderId":order['orderId']},{"$set":order}, upsert = True)
167
            #merchantOder 
168
        except Exception as e:
169
            traceback.print_exc()
13662 amit.gupta 170
 
171
    def getCashbackAmount(self, productCode, amount):
13995 amit.gupta 172
        alagvar = CASHBACK_URL % (productCode,self.store_id)
13662 amit.gupta 173
        filehandle = urllib2.Request(alagvar,headers=headers)
174
        x= urllib2.urlopen(filehandle)
17179 amit.gupta 175
        cashBack = json.loads(str(x.read()))
176
        if len(cashBack)==0:
13721 amit.gupta 177
            return (0,0)
13662 amit.gupta 178
        else:
17179 amit.gupta 179
            maxCashBack = cashBack.get('maxCashBack') 
180
            if maxCashBack:
181
                if cashBack.get('cash_back_type') ==1 and (float(cashBack.get('cash_back'))*amount)/100 > maxCashBack:
182
                    cashBack['cash_back'] = cashBack['maxCashBack']
183
                    return (cashBack['cash_back'], 0)
184
                elif cashBack.get('cash_back_type') ==2 and cashBack.get('cash_back') > cashBack.get('maxCashBack'):
185
                    cashBack['cash_back'] = cashBack['maxCashBack']
186
                    return (cashBack['cash_back'], 0)
187
                else:
188
                    pass
19525 amit.gupta 189
            if cashBack['cash_back_type'] == 1:
17179 amit.gupta 190
                return (math.floor((amount * cashBack['cash_back'])/100), cashBack['cash_back'])
13662 amit.gupta 191
            else:
17179 amit.gupta 192
                return (cashBack['cash_back'], 0)
13721 amit.gupta 193
 
13662 amit.gupta 194
 
13569 amit.gupta 195
    '''
196
    Parses the order for specific store
197
 
198
    order id, total amount, created on(now() if could not parse
199
    suborder id, title, quantity, unit price, expected delivery date,
200
    status (default would be Order placed)
201
 
202
    once products are identified, each suborder can then be updated
203
    with respective cashback.
204
 
205
    Possible fields to display for Not yet delivered orders are 
206
    Product/Quantity/Amount/Store/CashbackAmount/OrderDate/ExpectedDelivery/OrderStaus/DetailedStatus/CashbackStatus
207
    No need to show cancelled orders.
13610 amit.gupta 208
    CashbackStatus - NotApplicable/Pending/Approved/Cancelled/CreditedToWallet
13569 amit.gupta 209
    OrderStatus - Placed/Cancelled/Delivered
210
    '''
13576 amit.gupta 211
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
13569 amit.gupta 212
 
213
        pass
214
 
13721 amit.gupta 215
    def _updateOrdersPayBackStatus(self, searchMap, updateMap):
13781 amit.gupta 216
        searchMap['subOrders.missingAff'] = False
217
        updateMap['subOrders.$.missingAff'] = True
13927 amit.gupta 218
        self.db.merchantOrder.update(searchMap, { '$set': updateMap }, multi=True)
13721 amit.gupta 219
 
13781 amit.gupta 220
    def _getActiveOrders(self, searchMap={}, collectionMap={}):
13721 amit.gupta 221
        collection = self.db.merchantOrder
17234 amit.gupta 222
        searchMap = dict(searchMap.items()+ {"subOrders.closed": False, "storeId" : self.store_id}.items()) 
17395 amit.gupta 223
        #collectionMap =  dict(collectionMap.items() + {"orderSuccessUrl":1, "orderId":1,"subOrders":1, "placedOn":1, "orderTracking"}.items())
224
        stores = collection.find(searchMap)
13721 amit.gupta 225
        return [store for store in stores]
226
 
14081 amit.gupta 227
    def _getMissingOrders(self,searchMap={}):
228
        collection = self.db.merchantOrder
14948 amit.gupta 229
        searchMap = dict(searchMap.items()+ {"requireDetail":True, "storeId":self.store_id}.items()) 
14081 amit.gupta 230
        orders = collection.find(searchMap)
231
        return list(orders)
232
 
233
 
13721 amit.gupta 234
    def _isSubOrderActive(self,order, merchantSubOrderId):
235
        subOrders = order.get("subOrders")
14867 amit.gupta 236
        if subOrders is None:
237
            return None
13721 amit.gupta 238
        for subOrder in subOrders:
239
            if merchantSubOrderId == subOrder.get("merchantSubOrderId"):
240
                return subOrder
241
        return None
21331 amit.gupta 242
 
243
    def _isSubOrderActive1(self,order, merchantSubOrderId):
244
        subOrders = order.subOrders
245
        if subOrders is None:
246
            return None
247
        for subOrder in subOrders:
21332 amit.gupta 248
            if merchantSubOrderId == subOrder.merchantSubOrderId:
21331 amit.gupta 249
                return subOrder
250
        return None
14663 amit.gupta 251
 
17395 amit.gupta 252
    def populateDerivedFields(self, order, update=False):
16371 amit.gupta 253
        closed=True
254
        for subOrder in order.subOrders:
255
            if subOrder.closed:
256
                continue
21774 amit.gupta 257
            if not subOrder.status:
258
                subOrder.status = self._getStatusFromDetailedStatus(subOrder.detailedStatus)
17395 amit.gupta 259
            if not update:
260
                amount = subOrder.amount if hasattr(subOrder, 'amount') else subOrder.amountPaid
18156 amit.gupta 261
                cashbackAmount, cashbackPercent = self.getCashbackAmount(subOrder.productCode, amount/subOrder.quantity)
17395 amit.gupta 262
                cashbackStatus = Store.CB_PENDING
263
                if cashbackAmount <= 0:
264
                    cashbackStatus = Store.CB_NA
18156 amit.gupta 265
                subOrder.cashBackAmount = cashbackAmount*subOrder.quantity
17395 amit.gupta 266
                subOrder.cashBackPercentage = cashbackPercent
267
                subOrder.cashBackStatus = cashbackStatus      
268
                dealRank = getDealRank(subOrder.productCode, self.store_id, order.userId)
269
                subOrder.dealRank = dealRank.get('rank')
270
                subOrder.rankDesc = dealRank.get('description')
271
                subOrder.maxNlc = dealRank.get('maxNlc')
272
                subOrder.minNlc = dealRank.get('minNlc')
273
                subOrder.db = dealRank.get('dp')
274
                subOrder.itemStatus = dealRank.get('status')
275
            subOrder.closed = subOrder.status in [Store.ORDER_CANCELLED, Store.ORDER_DELIVERED]
16371 amit.gupta 276
            closed = closed and subOrder.closed
17395 amit.gupta 277
            if subOrder.cashBackStatus!=Store.CB_NA:
278
                subOrder.cashBackStatus = Store.CB_PENDING
279
                if subOrder.status == self.ORDER_CANCELLED:
280
                    subOrder.cashBackStatus = Store.CB_CANCELLED 
281
                elif subOrder.status == self.ORDER_DELIVERED:
282
                    subOrder.cashBackStatus = Store.CB_APPROVED
16371 amit.gupta 283
        order.closed = closed
284
 
14618 amit.gupta 285
def settlePayBack(runtype='dry'):
14663 amit.gupta 286
    userAmountMap = {}
287
    searchMapList = []
14666 amit.gupta 288
    for mo in client.Dtr.merchantOrder.find({"subOrders.cashBackStatus":Store.CB_APPROVED}):
14663 amit.gupta 289
        userId = mo.get("userId")
14664 amit.gupta 290
        if   mo.get('subOrders') is not None:
14663 amit.gupta 291
            for so in mo['subOrders']:
14666 amit.gupta 292
                if so.get('cashBackStatus') == Store.CB_APPROVED:
14663 amit.gupta 293
                    searchMapList.append({"orderId":mo.get("orderId"), "subOrders.merchantSubOrderId":so.get("merchantSubOrderId")})
294
                    if not userAmountMap.has_key(userId):
295
                        userAmountMap[userId] = so.get('cashBackAmount')
296
                    else:
297
                        userAmountMap[userId] += so.get('cashBackAmount')
298
                    print "%s\t%s\t%s\t%s\t%s\t%s\t%s"%(userId, mo.get("orderId"), so.get("merchantSubOrderId"),so.get("productTitle") ,so.get("cashBackStatus"), so.get("cashBackAmount"), so.get("batchId"))
299
                else:  
300
                    print "%s\t%s\t%s\t%s\t%s\t%s\t%s"%(userId, mo.get("orderId"), so.get("merchantSubOrderId"),so.get("productTitle") ,so.get("cashBackStatus"), so.get("cashBackAmount"), so.get("batchId"))
301
    for searchMap in searchMapList:
302
        print "%s\t%s"%(searchMap.get('orderId'),searchMap.get('subOrders.merchantSubOrderId'))
14664 amit.gupta 303
    for key,val in userAmountMap.iteritems():
304
        print "%s\t%s"%(key,val)
14663 amit.gupta 305
    if (runtype=='live'):
14666 amit.gupta 306
        bulk = client.Dtr.merchantOrder.initialize_ordered_bulk_op()
14663 amit.gupta 307
        if len(searchMapList) == 0:
14618 amit.gupta 308
            return
14666 amit.gupta 309
        for searchMap in searchMapList:
310
            bulk.find(searchMap).update({'$set' : {'subOrders.$.cashBackStatus':Store.CB_CREDIT_IN_PROCESS}})
311
        bulk.execute()
14663 amit.gupta 312
 
13927 amit.gupta 313
        datetimeNow = datetime.now() 
314
        batchId = int(time.mktime(datetimeNow.timetuple()))
315
        if refundToWallet(batchId, userAmountMap):
14666 amit.gupta 316
            bulk = client.Dtr.merchantOrder.initialize_ordered_bulk_op()
317
            for searchMap in searchMapList:
318
                bulk.find(searchMap).update({'$set' : {'subOrders.$.cashBackStatus':Store.CB_CREDITED, "subOrders.$.batchId":batchId}})
319
            print bulk.execute()
17234 amit.gupta 320
            sum=0
321
            creditedSubOrders=0
322
            message = []
14666 amit.gupta 323
            for key, value in userAmountMap.iteritems():
17234 amit.gupta 324
                sum += value
325
                creditedSubOrders += 1
16736 amit.gupta 326
                client.Dtr.refund.insert({"userId": key, "batch":batchId, "userAmount":value, "timestamp":datetime.strftime(datetimeNow,"%Y-%m-%d %H:%M:%S"), "type":utils.CREDIT_TYPE_ORDER})
327
                client.Dtr.user.update({"userId":key}, {"$inc": { "credited": value, utils.CREDIT_TYPE_ORDER:value}}, upsert=True)
17234 amit.gupta 328
            message.append("<b>Batch Id - %d</b><br><b>Total Amount Credited - %d</b><br><b>Total SubOrders Credited- %d</b>"%(batchId,sum, creditedSubOrders))
20172 aman.kumar 329
            utils.sendmail(['amit.gupta@shop2020.in', 'rajneesh.arora@saholic.com','khushal.bhatia@saholic.com'], "".join(message), 'Cashback for Order Credited Successfully')
13952 amit.gupta 330
            tprint("PayBack Settled")
14666 amit.gupta 331
        else:
332
            tprint("Error Occurred while running batch. Rolling Back")
333
            bulk = client.Dtr.merchantOrder.initialize_ordered_bulk_op()
334
            for searchMap in searchMapList:
335
                bulk.find(searchMap).update({'$set' : {'subOrders.$.cashBackStatus':Store.CB_APPROVED}})
336
            bulk.execute()
14663 amit.gupta 337
 
338
 
339
def settlePayBack1(runtype='dry'):
340
        approvedUserMap = {}
341
        pendingUserMap = {}
342
        creditedToWalletUserMap = {}
343
        #client.Dtr.merchantOrder.update({'subOrders.cashBackStatus':Store.CB_APPROVED},{'$set':{'subOrders.$.cashBackStatus':Store.CB_CREDIT_IN_PROCESS}}, multi=True)    
344
        for mo in client.Dtr.merchantOrder.find({"subOrders.cashBackStatus":Store.CB_CREDITED}):
345
            userId = mo.get("userId")
346
            for so in mo['subOrders']:
347
                print "%s\t%s\t%s\t%s\t%s\t%s\t%s"%(userId, mo.get("orderId"), so.get("merchantSubOrderId"),so.get("productTitle") ,so.get("cashBackStatus"), so.get("cashBackAmount"), so.get("batchId"))
348
 
349
        for refund in client.Dtr.refund.find():
350
            print "%s\t%s\t%s\t%s"%(refund.get("userId") ,refund.get("timestamp") ,refund.get("userAmount"), refund.get("batch"))
351
 
352
 
13927 amit.gupta 353
def refundToWallet(batchId, userAmountMap):
19568 manas 354
    #base64string = base64.encodestring('%s:%s' % ("dtr", "dtr18Feb2015")).replace('\n', '')
13927 amit.gupta 355
    batchUpdateMap = {}
356
    try :
357
        saholicUserAmountMap = {}
358
        for key, value in userAmountMap.iteritems():
19568 manas 359
            #userLookupRequest = urllib2.Request(USER_LOOKUP_URL %(key), headers=headers)
360
            #userLookupRequest.add_header("Authorization", "Basic %s" % base64string)
13927 amit.gupta 361
            try:
19568 manas 362
                #response = urllib2.urlopen(userLookupRequest).read()
363
                #saholicUserId = json.loads(response)['account_key']
364
                saholicUserId = userLookUpForSaholicId(key)
365
                if saholicUserId is not 'User Not present in profitmandi':
366
                    saholicUserAmountMap[saholicUserId] = value
367
                else:
368
                    raise Exception('User Not present in dtr')
13927 amit.gupta 369
            except:
19553 manas 370
                traceback.print_exc()
13934 amit.gupta 371
                tprint("Could not fetch saholic id for user : " + str(key))
13927 amit.gupta 372
                continue
13939 amit.gupta 373
        if len(saholicUserAmountMap) > 0:
374
            batchUpdateMap['userAmount'] = json.dumps(saholicUserAmountMap)
375
            batchUpdateMap['batchId'] = batchId
376
            request = urllib2.Request(WALLET_CREDIT_URL, headers=headers)
377
            data = urllib.urlencode(batchUpdateMap)
378
            response = urllib2.urlopen(request, data)
379
            return json.loads(response.read())['response']['credited']
380
        else:
381
            tprint("Nothing to Refund")
382
            return False
13927 amit.gupta 383
    except:
384
        traceback.print_exc()
385
        tprint("Could not batch refund")
386
        return False
13868 amit.gupta 387
 
13662 amit.gupta 388
def main():
14618 amit.gupta 389
#    client = MongoClient('mongodb://root:ecip$dtrMay2014@dtr:27017/')
390
#    s = Store(1)
391
#    orders = s.db.Dtr.find({"subOrders.imgUrl":{"$exists":1}}, {"merchantOrderId":1, "subOrders.productCode":1,"subOrders.imgUrl":1,"_id": 0})
392
#    db = client.Dtr
393
#    for order in orders:
394
#        for subOrder in order.get("subOrders"):
395
#            #db.merchantOrder.update({"merchantOrderId":order.getMerchantOrderId,"subOrders.imgUrl":{"$exists":0}, "subOrders.productCode":subOrder.get("productCode")}, {"$set":{"subOrders.$.imgUrl":subOrder.get("imgUrl")}})
396
#            db.merchantOrder.findOne()
14663 amit.gupta 397
    settlePayBack('dry')        
13569 amit.gupta 398
 
399
 
13868 amit.gupta 400
###
401
#Settlement process is suposed to be a batch and run weekly
402
#It is should be running on first hour of mondays. As cron should
403
# Maintain a batch id.
404
 
21268 amit.gupta 405
agentDefault = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11'
406
def getBrowserObject(agent = agentDefault):
13569 amit.gupta 407
    import cookielib
408
    br = mechanize.Browser(factory=mechanize.RobustFactory())
409
    cj = cookielib.LWPCookieJar()
410
    br.set_cookiejar(cj)
411
    br.set_handle_equiv(True)
412
    br.set_handle_redirect(True)
413
    br.set_handle_referer(True)
414
    br.set_handle_robots(False)
415
    br.set_debug_http(False)
416
    br.set_debug_redirects(False)
417
    br.set_debug_responses(False)
418
 
419
    br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
420
 
21268 amit.gupta 421
    br.addheaders = [('User-Agent', agent),
13569 amit.gupta 422
                     ('Accept', 'text/html,application/xhtml+xml,application/json,application/xml;q=0.9,*/*;q=0.8'),
423
                     ('Accept-Encoding', 'gzip,deflate,sdch'),                  
424
                     ('Accept-Language', 'en-US,en;q=0.8'),                     
425
                     ('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.3')]
13677 amit.gupta 426
    return br
16371 amit.gupta 427
def todict(obj, classkey=None):
428
    if isinstance(obj, dict):
429
        data = {}
430
        for (k, v) in obj.items():
431
            data[k] = todict(v, classkey)
432
        return data
433
    elif hasattr(obj, "_ast"):
434
        return todict(obj._ast())
435
    elif hasattr(obj, "__iter__"):
436
        return [todict(v, classkey) for v in obj]
437
    elif hasattr(obj, "__dict__"):
438
        data = dict([(key, todict(value, classkey)) 
439
            for key, value in obj.__dict__.iteritems() 
440
            if not callable(value) and not key.startswith('_')])
441
        if classkey is not None and hasattr(obj, "__class__"):
442
            data[classkey] = obj.__class__.__name__
443
        return data
444
    else:
445
        return obj
20615 amit.gupta 446
 
447
def manualCredit(runtype='dry'):
448
    #userAmountMap = {19964:8,7144:9,20274:12,25978:24,29914:24,28026:48,6409:48,2482:49,21852:52,2261:56,8109:57,23372:57,5772:82,29467:82,19612:82,7447:125,15898:126,11701:136,29483:138,20001:162,7070:164,11628:166,5222:250,14074:363,17378:369,7764:684,30153:996}
449
    userAmountMap={}
450
    for key,val in userAmountMap.iteritems():
451
        print "%s\t%s"%(key,val)
452
    if (runtype=='live'):
453
        datetimeNow = datetime.now() 
454
        batchId = int(time.mktime(datetimeNow.timetuple()))
455
        if refundToWallet(batchId, userAmountMap):
456
            sum=0
457
            creditedSubOrders=0
458
            message = []
459
            for key, value in userAmountMap.iteritems():
460
                sum += value
461
                creditedSubOrders += 1
462
                client.Dtr.refund.insert({"userId": key, "batch":batchId, "userAmount":value, "timestamp":datetime.strftime(datetimeNow,"%Y-%m-%d %H:%M:%S"), "type":utils.CREDIT_TYPE_ORDER})
463
                client.Dtr.user.update({"userId":key}, {"$inc": { "credited": value, utils.CREDIT_TYPE_ORDER:value}}, upsert=True)
464
            message.append("<b>Batch Id - %d</b><br><b>Total Amount Credited - %d</b><br><b>Total SubOrders Credited- %d</b>"%(batchId,sum, creditedSubOrders))
465
            utils.sendmail(['amit.gupta@shop2020.in', 'rajneesh.arora@saholic.com','khushal.bhatia@saholic.com'], "".join(message), 'Cashback for Order Credited Successfully')
466
            tprint("PayBack Settled")
467
        else:
468
            tprint("Error Occurred while running batch. Rolling Back")
13677 amit.gupta 469
 
13690 amit.gupta 470
def ungzipResponse(r):
471
    headers = r.info()
17388 amit.gupta 472
    if headers.get('Content-Encoding')=='gzip':
13690 amit.gupta 473
        import gzip
474
        gz = gzip.GzipFile(fileobj=r, mode='rb')
475
        html = gz.read()
476
        gz.close()
17388 amit.gupta 477
    else:
478
        html = r.read() 
479
 
480
    return html
13724 amit.gupta 481
 
482
def tprint(*msg):
13927 amit.gupta 483
    print datetime.now(), "-", msg
13939 amit.gupta 484
 
485
if __name__ == '__main__':
14848 amit.gupta 486
    main()
487