Subversion Repositories SmartDukaan

Rev

Rev 21331 | Go to most recent revision | 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
21321 amit.gupta 257
            self._getStatusFromDetailedStatus(subOrder.detailedStatus)
17395 amit.gupta 258
            if not update:
259
                amount = subOrder.amount if hasattr(subOrder, 'amount') else subOrder.amountPaid
18156 amit.gupta 260
                cashbackAmount, cashbackPercent = self.getCashbackAmount(subOrder.productCode, amount/subOrder.quantity)
17395 amit.gupta 261
                cashbackStatus = Store.CB_PENDING
262
                if cashbackAmount <= 0:
263
                    cashbackStatus = Store.CB_NA
18156 amit.gupta 264
                subOrder.cashBackAmount = cashbackAmount*subOrder.quantity
17395 amit.gupta 265
                subOrder.cashBackPercentage = cashbackPercent
266
                subOrder.cashBackStatus = cashbackStatus      
267
                dealRank = getDealRank(subOrder.productCode, self.store_id, order.userId)
268
                subOrder.dealRank = dealRank.get('rank')
269
                subOrder.rankDesc = dealRank.get('description')
270
                subOrder.maxNlc = dealRank.get('maxNlc')
271
                subOrder.minNlc = dealRank.get('minNlc')
272
                subOrder.db = dealRank.get('dp')
273
                subOrder.itemStatus = dealRank.get('status')
274
            subOrder.closed = subOrder.status in [Store.ORDER_CANCELLED, Store.ORDER_DELIVERED]
16371 amit.gupta 275
            closed = closed and subOrder.closed
17395 amit.gupta 276
            if subOrder.cashBackStatus!=Store.CB_NA:
277
                subOrder.cashBackStatus = Store.CB_PENDING
278
                if subOrder.status == self.ORDER_CANCELLED:
279
                    subOrder.cashBackStatus = Store.CB_CANCELLED 
280
                elif subOrder.status == self.ORDER_DELIVERED:
281
                    subOrder.cashBackStatus = Store.CB_APPROVED
16371 amit.gupta 282
        order.closed = closed
283
 
14618 amit.gupta 284
def settlePayBack(runtype='dry'):
14663 amit.gupta 285
    userAmountMap = {}
286
    searchMapList = []
14666 amit.gupta 287
    for mo in client.Dtr.merchantOrder.find({"subOrders.cashBackStatus":Store.CB_APPROVED}):
14663 amit.gupta 288
        userId = mo.get("userId")
14664 amit.gupta 289
        if   mo.get('subOrders') is not None:
14663 amit.gupta 290
            for so in mo['subOrders']:
14666 amit.gupta 291
                if so.get('cashBackStatus') == Store.CB_APPROVED:
14663 amit.gupta 292
                    searchMapList.append({"orderId":mo.get("orderId"), "subOrders.merchantSubOrderId":so.get("merchantSubOrderId")})
293
                    if not userAmountMap.has_key(userId):
294
                        userAmountMap[userId] = so.get('cashBackAmount')
295
                    else:
296
                        userAmountMap[userId] += so.get('cashBackAmount')
297
                    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"))
298
                else:  
299
                    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"))
300
    for searchMap in searchMapList:
301
        print "%s\t%s"%(searchMap.get('orderId'),searchMap.get('subOrders.merchantSubOrderId'))
14664 amit.gupta 302
    for key,val in userAmountMap.iteritems():
303
        print "%s\t%s"%(key,val)
14663 amit.gupta 304
    if (runtype=='live'):
14666 amit.gupta 305
        bulk = client.Dtr.merchantOrder.initialize_ordered_bulk_op()
14663 amit.gupta 306
        if len(searchMapList) == 0:
14618 amit.gupta 307
            return
14666 amit.gupta 308
        for searchMap in searchMapList:
309
            bulk.find(searchMap).update({'$set' : {'subOrders.$.cashBackStatus':Store.CB_CREDIT_IN_PROCESS}})
310
        bulk.execute()
14663 amit.gupta 311
 
13927 amit.gupta 312
        datetimeNow = datetime.now() 
313
        batchId = int(time.mktime(datetimeNow.timetuple()))
314
        if refundToWallet(batchId, userAmountMap):
14666 amit.gupta 315
            bulk = client.Dtr.merchantOrder.initialize_ordered_bulk_op()
316
            for searchMap in searchMapList:
317
                bulk.find(searchMap).update({'$set' : {'subOrders.$.cashBackStatus':Store.CB_CREDITED, "subOrders.$.batchId":batchId}})
318
            print bulk.execute()
17234 amit.gupta 319
            sum=0
320
            creditedSubOrders=0
321
            message = []
14666 amit.gupta 322
            for key, value in userAmountMap.iteritems():
17234 amit.gupta 323
                sum += value
324
                creditedSubOrders += 1
16736 amit.gupta 325
                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})
326
                client.Dtr.user.update({"userId":key}, {"$inc": { "credited": value, utils.CREDIT_TYPE_ORDER:value}}, upsert=True)
17234 amit.gupta 327
            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 328
            utils.sendmail(['amit.gupta@shop2020.in', 'rajneesh.arora@saholic.com','khushal.bhatia@saholic.com'], "".join(message), 'Cashback for Order Credited Successfully')
13952 amit.gupta 329
            tprint("PayBack Settled")
14666 amit.gupta 330
        else:
331
            tprint("Error Occurred while running batch. Rolling Back")
332
            bulk = client.Dtr.merchantOrder.initialize_ordered_bulk_op()
333
            for searchMap in searchMapList:
334
                bulk.find(searchMap).update({'$set' : {'subOrders.$.cashBackStatus':Store.CB_APPROVED}})
335
            bulk.execute()
14663 amit.gupta 336
 
337
 
338
def settlePayBack1(runtype='dry'):
339
        approvedUserMap = {}
340
        pendingUserMap = {}
341
        creditedToWalletUserMap = {}
342
        #client.Dtr.merchantOrder.update({'subOrders.cashBackStatus':Store.CB_APPROVED},{'$set':{'subOrders.$.cashBackStatus':Store.CB_CREDIT_IN_PROCESS}}, multi=True)    
343
        for mo in client.Dtr.merchantOrder.find({"subOrders.cashBackStatus":Store.CB_CREDITED}):
344
            userId = mo.get("userId")
345
            for so in mo['subOrders']:
346
                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"))
347
 
348
        for refund in client.Dtr.refund.find():
349
            print "%s\t%s\t%s\t%s"%(refund.get("userId") ,refund.get("timestamp") ,refund.get("userAmount"), refund.get("batch"))
350
 
351
 
13927 amit.gupta 352
def refundToWallet(batchId, userAmountMap):
19568 manas 353
    #base64string = base64.encodestring('%s:%s' % ("dtr", "dtr18Feb2015")).replace('\n', '')
13927 amit.gupta 354
    batchUpdateMap = {}
355
    try :
356
        saholicUserAmountMap = {}
357
        for key, value in userAmountMap.iteritems():
19568 manas 358
            #userLookupRequest = urllib2.Request(USER_LOOKUP_URL %(key), headers=headers)
359
            #userLookupRequest.add_header("Authorization", "Basic %s" % base64string)
13927 amit.gupta 360
            try:
19568 manas 361
                #response = urllib2.urlopen(userLookupRequest).read()
362
                #saholicUserId = json.loads(response)['account_key']
363
                saholicUserId = userLookUpForSaholicId(key)
364
                if saholicUserId is not 'User Not present in profitmandi':
365
                    saholicUserAmountMap[saholicUserId] = value
366
                else:
367
                    raise Exception('User Not present in dtr')
13927 amit.gupta 368
            except:
19553 manas 369
                traceback.print_exc()
13934 amit.gupta 370
                tprint("Could not fetch saholic id for user : " + str(key))
13927 amit.gupta 371
                continue
13939 amit.gupta 372
        if len(saholicUserAmountMap) > 0:
373
            batchUpdateMap['userAmount'] = json.dumps(saholicUserAmountMap)
374
            batchUpdateMap['batchId'] = batchId
375
            request = urllib2.Request(WALLET_CREDIT_URL, headers=headers)
376
            data = urllib.urlencode(batchUpdateMap)
377
            response = urllib2.urlopen(request, data)
378
            return json.loads(response.read())['response']['credited']
379
        else:
380
            tprint("Nothing to Refund")
381
            return False
13927 amit.gupta 382
    except:
383
        traceback.print_exc()
384
        tprint("Could not batch refund")
385
        return False
13868 amit.gupta 386
 
13662 amit.gupta 387
def main():
14618 amit.gupta 388
#    client = MongoClient('mongodb://root:ecip$dtrMay2014@dtr:27017/')
389
#    s = Store(1)
390
#    orders = s.db.Dtr.find({"subOrders.imgUrl":{"$exists":1}}, {"merchantOrderId":1, "subOrders.productCode":1,"subOrders.imgUrl":1,"_id": 0})
391
#    db = client.Dtr
392
#    for order in orders:
393
#        for subOrder in order.get("subOrders"):
394
#            #db.merchantOrder.update({"merchantOrderId":order.getMerchantOrderId,"subOrders.imgUrl":{"$exists":0}, "subOrders.productCode":subOrder.get("productCode")}, {"$set":{"subOrders.$.imgUrl":subOrder.get("imgUrl")}})
395
#            db.merchantOrder.findOne()
14663 amit.gupta 396
    settlePayBack('dry')        
13569 amit.gupta 397
 
398
 
13868 amit.gupta 399
###
400
#Settlement process is suposed to be a batch and run weekly
401
#It is should be running on first hour of mondays. As cron should
402
# Maintain a batch id.
403
 
21268 amit.gupta 404
agentDefault = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11'
405
def getBrowserObject(agent = agentDefault):
13569 amit.gupta 406
    import cookielib
407
    br = mechanize.Browser(factory=mechanize.RobustFactory())
408
    cj = cookielib.LWPCookieJar()
409
    br.set_cookiejar(cj)
410
    br.set_handle_equiv(True)
411
    br.set_handle_redirect(True)
412
    br.set_handle_referer(True)
413
    br.set_handle_robots(False)
414
    br.set_debug_http(False)
415
    br.set_debug_redirects(False)
416
    br.set_debug_responses(False)
417
 
418
    br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
419
 
21268 amit.gupta 420
    br.addheaders = [('User-Agent', agent),
13569 amit.gupta 421
                     ('Accept', 'text/html,application/xhtml+xml,application/json,application/xml;q=0.9,*/*;q=0.8'),
422
                     ('Accept-Encoding', 'gzip,deflate,sdch'),                  
423
                     ('Accept-Language', 'en-US,en;q=0.8'),                     
424
                     ('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.3')]
13677 amit.gupta 425
    return br
16371 amit.gupta 426
def todict(obj, classkey=None):
427
    if isinstance(obj, dict):
428
        data = {}
429
        for (k, v) in obj.items():
430
            data[k] = todict(v, classkey)
431
        return data
432
    elif hasattr(obj, "_ast"):
433
        return todict(obj._ast())
434
    elif hasattr(obj, "__iter__"):
435
        return [todict(v, classkey) for v in obj]
436
    elif hasattr(obj, "__dict__"):
437
        data = dict([(key, todict(value, classkey)) 
438
            for key, value in obj.__dict__.iteritems() 
439
            if not callable(value) and not key.startswith('_')])
440
        if classkey is not None and hasattr(obj, "__class__"):
441
            data[classkey] = obj.__class__.__name__
442
        return data
443
    else:
444
        return obj
20615 amit.gupta 445
 
446
def manualCredit(runtype='dry'):
447
    #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}
448
    userAmountMap={}
449
    for key,val in userAmountMap.iteritems():
450
        print "%s\t%s"%(key,val)
451
    if (runtype=='live'):
452
        datetimeNow = datetime.now() 
453
        batchId = int(time.mktime(datetimeNow.timetuple()))
454
        if refundToWallet(batchId, userAmountMap):
455
            sum=0
456
            creditedSubOrders=0
457
            message = []
458
            for key, value in userAmountMap.iteritems():
459
                sum += value
460
                creditedSubOrders += 1
461
                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})
462
                client.Dtr.user.update({"userId":key}, {"$inc": { "credited": value, utils.CREDIT_TYPE_ORDER:value}}, upsert=True)
463
            message.append("<b>Batch Id - %d</b><br><b>Total Amount Credited - %d</b><br><b>Total SubOrders Credited- %d</b>"%(batchId,sum, creditedSubOrders))
464
            utils.sendmail(['amit.gupta@shop2020.in', 'rajneesh.arora@saholic.com','khushal.bhatia@saholic.com'], "".join(message), 'Cashback for Order Credited Successfully')
465
            tprint("PayBack Settled")
466
        else:
467
            tprint("Error Occurred while running batch. Rolling Back")
13677 amit.gupta 468
 
13690 amit.gupta 469
def ungzipResponse(r):
470
    headers = r.info()
17388 amit.gupta 471
    if headers.get('Content-Encoding')=='gzip':
13690 amit.gupta 472
        import gzip
473
        gz = gzip.GzipFile(fileobj=r, mode='rb')
474
        html = gz.read()
475
        gz.close()
17388 amit.gupta 476
    else:
477
        html = r.read() 
478
 
479
    return html
13724 amit.gupta 480
 
481
def tprint(*msg):
13927 amit.gupta 482
    print datetime.now(), "-", msg
13939 amit.gupta 483
 
484
if __name__ == '__main__':
14848 amit.gupta 485
    main()
486