Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
15509 manish.sha 1
'''
2
Created on Jan 15, 2015
3
 
4
@author: Manish 
5
'''
6
from bs4 import BeautifulSoup
7
from bson.binary import Binary
8
from datetime import datetime, date, timedelta
9
from dtr import main
15791 manish.sha 10
from dtr.dao import AffiliateInfo, Order, SubOrder, ShopCluesAffiliateInfo
15509 manish.sha 11
from dtr.main import getBrowserObject, ScrapeException, getStore, ParseException, \
12
    Store as MStore, ungzipResponse, tprint
13
from dtr.storage import Mongo
14
from dtr.storage.Mongo import getImgSrc
16787 manish.sha 15
from dtr.utils.utils import fetchResponseUsingProxy, PROXY_MESH_GENERAL
15509 manish.sha 16
from pprint import pprint
17
from pymongo import MongoClient
18
import json
19
import pymongo
20
import re
21
import time
22
import traceback
23
import urllib
15791 manish.sha 24
import urllib2
15509 manish.sha 25
from urlparse import urlparse, parse_qs
15791 manish.sha 26
import xml.etree.ElementTree as ET
27
from dtr.storage import MemCache
16097 manish.sha 28
from dtr.storage.Mongo import getDealRank
15509 manish.sha 29
 
15791 manish.sha 30
AFFLIATE_TRASACTIONS_URL = "https://admin.optimisemedia.com/v2/reports/affiliate/leads/leadsummaryexport.aspx?Contact=796881&Country=26&Agency=95&Merchant=420562&Status=-1&Year=%d&Month=%d&Day=%d&EndYear=%d&EndMonth=%d&EndDay=%d&DateType=0&Sort=CompletionDate&Login=1347562DA5E3EFF6FB1561765C47C782&Format=XML&RestrictURL=0"
15509 manish.sha 31
ORDER_TRACK_URL='http://www.shopclues.com/index.php?dispatch=order_lookup.details'
15791 manish.sha 32
ORDER_TRACK_URL_DB='https://sm.shopclues.com/trackOrder?'
15509 manish.sha 33
BASE_URL= 'http://www.shopclues.com'
34
BASE_MURL= 'http://m.shopclues.com'
35
 
36
class Store(MStore):
37
 
38
    '''
39
    This is to map order statuses of our system to order statuses of snapdeal.
40
    And our statuses will change accordingly.
41
 
42
    '''
43
    OrderStatusMap = {
16272 manish.sha 44
                      MStore.ORDER_PLACED : ['payment successful', 'new order - cod confirmation pending', 'processing', 'quality check','on schedule', 'processing - pickup initiated', 'processing - ready to dispatch','processing - procurement delay from merchant','processing - slight procurment delay from merchant','cod order confirmed by customer'],
15509 manish.sha 45
                      MStore.ORDER_DELIVERED : ['delivered', 'complete'],
16254 manish.sha 46
                      MStore.ORDER_SHIPPED : ['in transit', 'dispatched','shipped','order handed to courier','order handed over to courier'],
16370 manish.sha 47
                      MStore.ORDER_CANCELLED : ['payment failed', 'canceled', 'payment declined', 'order on hold - cancellation requested by customer', 'courier returned', 'canceled on customer request', 'canceled by customer','order canceled by customer','canceled - address not shippable','return complete','undelivered - returning to origin']
15509 manish.sha 48
                      }
49
    OrderStatusConfirmationMap= {
15791 manish.sha 50
                                 "P" : "Payment Successful",
51
                                 "D" : "Order Declined",
52
                                 "O" : "New Order - COD confirmation Pending"
15509 manish.sha 53
                                 }
54
 
55
    CONF_CB_AMOUNT = MStore.CONF_CB_DISCOUNTED_PRICE
56
 
16111 manish.sha 57
    def __init__(self,store_id):
58
        super(Store, self).__init__(store_id)
59
 
15791 manish.sha 60
    def convertToObj(self,offer):
16202 manish.sha 61
        orderRef = offer['MerchantRef']
62
        if len(orderRef)>15:
63
            orderRef = orderRef[0:len(orderRef)-10]
16203 manish.sha 64
        offer1 = ShopCluesAffiliateInfo(offer['UID'], offer['TransactionTime'], offer['TransactionId'], orderRef,  orderRef, offer['Merchant'], offer['PID'], offer['Product'], float(str(offer['SR'])), float(str(offer['TransactionValue'])), offer['UKey'], offer['ClickTime'], offer['Status'])
15791 manish.sha 65
        return offer1
66
 
67
    def _saveToAffiliate(self, offers):
68
        collection = self.db.shopcluesOrderAffiliateInfo
69
        mcollection = self.db.merchantOrder
70
        for offerObj in offers:
71
            offer = self.convertToObj(offerObj)
72
            collection.update({"transactionId":offer.transactionId, "subTagId":offer.subTagId, "payOut":offer.payOut},{"$set":todict(offer)}, upsert=True)
73
            mcollection.update({"subTagId":offer.subTagId, "storeId":self.store_id, "subOrders.missingAff":True}, {"$set":{"subOrders.$.missingAff":False}})
74
 
15940 manish.sha 75
    def scrapeAffiliate(self, startDate=datetime.today() - timedelta(days=10), endDate=datetime.today()):
15791 manish.sha 76
        uri = AFFLIATE_TRASACTIONS_URL%(startDate.year,startDate.month,startDate.day,endDate.year,endDate.month,endDate.day)
77
        root = ET.parse(urllib2.urlopen(uri)).getroot()
78
        if len(root)> 0 and len(root[0])> 0:
79
            offers = []
80
            for child in root[0][0]:
81
                offers.append(child.attrib)
82
            self._saveToAffiliate(offers)
83
 
15509 manish.sha 84
    def _setLastSaleDate(self, saleDate):
85
        self.db.lastSaleDtate.update({'storeId':self.store_id}, {'$set':{'saleDate':saleDate}})
86
 
87
    def getName(self):
88
        return "shopclues"    
89
 
90
    def _getLastSaleDate(self,):
91
        lastDaySaleObj = self.db.lastDaySale.find_one({"storeId":self.store_id})
92
        if lastDaySaleObj is None:
93
            return datetime.min
94
 
95
    def _getStatusFromDetailedStatus(self, detailedStatus):
96
        for key, value in Store.OrderStatusMap.iteritems():
97
            if detailedStatus.lower() in value:
98
                return key
99
        print "Detailed Status need to be mapped", detailedStatus, self.store_id
100
        return None
101
 
15791 manish.sha 102
    def _getSingleSubOrderMap(self, orderId, soup, orderObj):
103
        orderStatus = self.OrderStatusConfirmationMap.get(orderObj['0']['status'])
16420 manish.sha 104
        statusTime= str(to_py_date(long(orderObj['0']['timestamp'])))
15509 manish.sha 105
        productDetailsMap = {}
16230 manish.sha 106
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
107
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
15791 manish.sha 108
        firstRow = orderTable.pop(0)
15949 manish.sha 109
        totalColumns = len(firstRow.find_all('th'))
15791 manish.sha 110
        jsonSubOrdersMap = {}
111
        count = 1
112
 
113
        for val in orderObj['0']['items'].values():
114
            newCount = 0
16110 manish.sha 115
            counts = []
15791 manish.sha 116
            for key in jsonSubOrdersMap.keys():
117
                splitKey = key.split('-')
16112 manish.sha 118
                if orderObj['0']['is_parent_order'] == 'N':
119
                    if str(val['order_id']) == splitKey[0]:
120
                        counts.append(int(splitKey[1]))
121
                else:
16420 manish.sha 122
                    if val['child'] is None:
123
                        if str(val['order_id']) == splitKey[0]:
124
                            counts.append(int(splitKey[1]))
125
                    else:
126
                        if str(val['child']) == splitKey[0]:
127
                            counts.append(int(splitKey[1]))
16110 manish.sha 128
 
129
            if len(counts) >0:
130
                newCount = max(counts)
16108 manish.sha 131
            count = newCount +1
16112 manish.sha 132
            if orderObj['0']['is_parent_order'] == 'N':
133
                jsonSubOrdersMap[str(val['order_id'])+'-'+str(count)] = val
134
            else:
16420 manish.sha 135
                if val['child'] is None:
136
                    jsonSubOrdersMap[str(val['order_id'])+'-'+str(count)] = val
137
                else:
138
                    jsonSubOrdersMap[str(val['child'])+'-'+str(count)] = val
15791 manish.sha 139
 
16110 manish.sha 140
 
16275 manish.sha 141
 
15941 manish.sha 142
        print jsonSubOrdersMap.items()
143
 
15791 manish.sha 144
        count = 1
15509 manish.sha 145
        for orderTr in orderTable:
15791 manish.sha 146
            productDetailsSubMap = None
147
            productDetailsSubMap = {}
15509 manish.sha 148
            cols = orderTr.find_all('td')
149
            product_details = cols[0].find_all('a')
150
            #print product_details
151
            productUrl = product_details[0].get('href')
152
            productName = product_details[0].contents[0].strip()
153
            quantity = int(cols[1].text.strip())
15980 manish.sha 154
            sellingPrice = long(cols[2].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 155
            discount = 0
156
            subtotal = 0
157
            if totalColumns == 5:
15949 manish.sha 158
                if cols[3].text.strip()!='-' and 'Rs.' in cols[3].text.strip():
15980 manish.sha 159
                    discount = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 160
                else:
161
                    discount = 0
15980 manish.sha 162
                subtotal = long(cols[4].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 163
            else:
15980 manish.sha 164
                subtotal = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
15509 manish.sha 165
            productDetailsSubMap['productUrl']=BASE_MURL+productUrl
166
            productDetailsSubMap['productName']=productName
15791 manish.sha 167
            productDetailsSubMap['subOrderTrackingUrl']=ORDER_TRACK_URL_DB+'order_id=' +str(orderId)+'&email_id='+ orderObj['0']['email']
15509 manish.sha 168
            productDetailsSubMap['sellingPrice']=sellingPrice
169
            productDetailsSubMap['quantity']=quantity
170
            productDetailsSubMap['discount']=discount
171
            productDetailsSubMap['subtotal']=subtotal
15942 manish.sha 172
            key = str(orderId)+'-'+str(count)
173
            print 'SubOrder Map Key--',key
15791 manish.sha 174
            jsonSubOrderDetails = jsonSubOrdersMap.get(str(orderId)+'-'+str(count))
175
            productCode = jsonSubOrderDetails['product_code']
176
            productImgUrl = jsonSubOrderDetails['images']['image_path'][0]
15509 manish.sha 177
            productDetailsSubMap['productCode']=productCode
178
            productDetailsSubMap['imgUrl']=productImgUrl
179
 
15791 manish.sha 180
            productDetailsSubMap['subOrderStatus']=orderStatus
181
            productDetailsSubMap['subOrderStatusTime']=statusTime
182
            productDetailsMap[str(orderId)+'-'+str(count)]=productDetailsSubMap
183
            count = count +1
15509 manish.sha 184
        return productDetailsMap
185
 
15791 manish.sha 186
    def _getMultiSubOrdersMap(self, orderId, soup, orderObj):
16230 manish.sha 187
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
188
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16105 manish.sha 189
        firstRow = orderTable.pop(0)
15791 manish.sha 190
        #totalColumns = len(firstRow.find_all('td'))
15509 manish.sha 191
        productDetailsMap = {}
15791 manish.sha 192
        '''
193
        jsonSubOrdersMap = {}
194
        for val in orderObj['0']['items'].values():
195
            jsonSubOrdersMap[val['order_id']] = val
196
        '''
197
        existingOrders = []
15509 manish.sha 198
        for orderTr in orderTable:
15791 manish.sha 199
            subOrderDetailsMap = {}
200
 
15509 manish.sha 201
            cols = orderTr.find_all('td')
202
            product_details = cols[0].find_all('a')
203
            #print product_details
204
            subOrderId= product_details[1].contents[0].strip()
15791 manish.sha 205
            if subOrderId in existingOrders:
206
                continue
207
            else:
208
                existingOrders.append(subOrderId)
209
            #productUrl = product_details[0].get('href')
210
            #productName = product_details[0].contents[0].strip()
211
            subOrderTrackingParsingUrl = product_details[1].get('href')
212
            #subOrderTrackingUrl = subOrderTrackingParsingUrl.split('order_lookup.details&')[1]
213
            '''
15509 manish.sha 214
            quantity = int(cols[1].text.strip())
215
            sellingPrice = long(cols[2].text.strip().replace("Rs.",""))
15791 manish.sha 216
            discount = 0
217
            subtotal = 0
218
            if totalColumns == 5:
219
                if cols[3].text.strip()!='-' or 'Rs.' in cols[3].text.strip():
220
                    discount = long(cols[3].text.strip().replace("Rs.",""))
221
                else:
222
                    discount = 0                    
223
                subtotal = long(cols[4].text.strip().replace("Rs.",""))
224
            else:
225
                subtotal = long(cols[3].text.strip().replace("Rs.",""))
15509 manish.sha 226
            productDetailsSubMap['productUrl']=BASE_MURL+productUrl
227
            productDetailsSubMap['productName']=productName
15791 manish.sha 228
            productDetailsSubMap['subOrderTrackingUrl']=ORDER_TRACK_URL_DB+subOrderTrackingUrl
15509 manish.sha 229
            productDetailsSubMap['sellingPrice']=sellingPrice
230
            productDetailsSubMap['quantity']=quantity
231
            productDetailsSubMap['discount']=discount
232
            productDetailsSubMap['subtotal']=subtotal
15791 manish.sha 233
            jsonSubOrderDetails = jsonSubOrdersMap.get(subOrderId)
234
            productCode = jsonSubOrderDetails['product_code']
235
            productImgUrl = jsonSubOrderDetails['images']['image_path'][0]
15509 manish.sha 236
            productDetailsSubMap['productCode']=productCode
237
            productDetailsSubMap['imgUrl']=productImgUrl
15791 manish.sha 238
            '''
16151 manish.sha 239
            orderTrackingPage = fetchResponseUsingProxy(BASE_URL+subOrderTrackingParsingUrl)
240
            orderTrackingPageSoup = BeautifulSoup(orderTrackingPage)
15791 manish.sha 241
            '''
15509 manish.sha 242
            subOrderStatusList = orderTrackingPageSoup.findAll(attrs={'class' : 'price ord_status'})
243
            subOrderStatus = subOrderStatusList[0].contents[0].strip()
244
            subOrderStatusTime= orderTrackingPageSoup.findAll(attrs={'class' : 'sts no_mobile'})[1].contents[2].strip()
245
            productDetailsSubMap['subOrderStatus'] = subOrderStatus
246
            productDetailsSubMap['subOrderStatusTime'] = subOrderStatusTime
247
            productDetailsSubMap['parentOrderId']=orderId
15791 manish.sha 248
            '''
249
 
250
            subOrderDetailsMap = self._getSingleSubOrderMap(subOrderId, orderTrackingPageSoup, orderObj)
15509 manish.sha 251
 
15791 manish.sha 252
            productDetailsMap = dict(productDetailsMap.items()+subOrderDetailsMap.items())
15509 manish.sha 253
 
254
        return productDetailsMap
255
 
256
    def updateCashbackInSubOrders(self, subOrders):
257
        for subOrder in subOrders:
258
            cashbackStatus = Store.CB_NA
259
            cashbackAmount = 0
260
            percentage = 0
261
            amount = subOrder.amountPaid
262
            if amount > 0:
263
                (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amount)
264
                if cashbackAmount > 0:
265
                    cashbackStatus = Store.CB_PENDING
266
            subOrder.cashBackStatus = cashbackStatus
267
            subOrder.cashBackAmount = cashbackAmount
268
            subOrder.cashBackPercentage = percentage
269
        return subOrders
270
 
15947 manish.sha 271
    def _parseOrders(self, orderId, mpOrderId, subTagId, userId, page, orderSuccessUrl, orderObj):
15509 manish.sha 272
        soup = BeautifulSoup(page)
273
        productDetailsMap = {}
274
        paymentFields = soup.findAll(attrs={'class' : 'box_paymentcalculations_row'})
275
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
15948 manish.sha 276
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("\r","").replace("  ","")
15509 manish.sha 277
        ordersubtotal=0
278
        ordercluebucks=0
279
        ordershippingcost=0
280
        ordertotal=0
281
 
282
        for val in paymentFields:
283
            for value in val.contents:
284
                if value is not None:
285
                    if 'div' in str(value).strip():
286
                        if 'Subtotal' in value.text.strip():
15981 manish.sha 287
                            ordersubtotal = long(val.contents[3].text.strip().replace("Rs.","").replace(',',''))
16165 manish.sha 288
                            print 'Order SubTotal:- ',ordersubtotal
15509 manish.sha 289
                        if 'Shipping Cost' in value.text.strip():
15981 manish.sha 290
                            ordershippingcost = long(val.contents[3].text.strip().replace("Rs.","").replace(',',''))
16165 manish.sha 291
                            print 'Shipping Cost:- ',ordershippingcost
15509 manish.sha 292
                        if 'Clue' in value.text.strip():
15981 manish.sha 293
                            ordercluebucks = long(val.contents[3].text.strip().replace("Rs.","").replace(',',''))
16165 manish.sha 294
                            print 'Clue bucks:- ',ordercluebucks
15509 manish.sha 295
                        if 'Total' in value.text.strip():
15791 manish.sha 296
                            ordertotal = val.contents[3].text.strip().replace("Rs.","")
297
                            ordertotal = ordertotal.replace(',','')
16165 manish.sha 298
                            print 'Order Total:- ',ordertotal
15791 manish.sha 299
 
300
        if orderObj['0']['is_parent_order'] == 'N':
15947 manish.sha 301
            productDetailsMap = self._getSingleSubOrderMap(mpOrderId, soup, orderObj)
15509 manish.sha 302
        else:
16420 manish.sha 303
            if orderObj['0']['items'].values()[0]['child'] is None:
304
                productDetailsMap = self._getSingleSubOrderMap(mpOrderId, soup, orderObj)
305
            else:
306
                productDetailsMap = self._getMultiSubOrdersMap(mpOrderId, soup, orderObj)
15509 manish.sha 307
 
15791 manish.sha 308
        merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
15509 manish.sha 309
        merchantOrder.placedOn = placedOn
15791 manish.sha 310
        merchantOrder.merchantOrderId = orderObj['0']['order_id']
15509 manish.sha 311
        merchantOrder.paidAmount = ordertotal
312
        totalOrdersAmount = 0
313
        totalDiscount = 0
314
        subOrders= []
16281 manish.sha 315
        if len(productDetailsMap)==0:
316
            print 'Unable to get Sub Orders for Now:- ',orderObj['0']['order_id']
15509 manish.sha 317
        for key in productDetailsMap:
318
            subOrderDetail = productDetailsMap.get(key)
319
            totalOrdersAmount = totalOrdersAmount  + (subOrderDetail['sellingPrice'] * subOrderDetail['quantity'])
320
            totalDiscount = totalDiscount + (subOrderDetail['discount'] * subOrderDetail['quantity'])
321
            subOrder = SubOrder(subOrderDetail['productName'], subOrderDetail['productUrl'], placedOn, subOrderDetail['subtotal'])
322
            subOrder.merchantSubOrderId = key
323
            subOrder.detailedStatus = subOrderDetail['subOrderStatus']
324
            subOrder.imgUrl = subOrderDetail['imgUrl']
325
            subOrder.offerDiscount = subOrderDetail['discount'] * subOrderDetail['quantity']
326
            subOrder.unitPrice = subOrderDetail['sellingPrice']
327
            subOrder.productCode = subOrderDetail['productCode']
328
            subOrder.amountPaid = subOrderDetail['subtotal']
329
            subOrder.quantity = subOrderDetail['quantity']
15791 manish.sha 330
            subOrder.tracingkUrl = subOrderDetail['subOrderTrackingUrl']
16097 manish.sha 331
            dealRank = getDealRank(subOrder.productCode, self.store_id, merchantOrder.userId)
332
            subOrder.dealRank = dealRank.get('rank')
333
            subOrder.rankDesc = dealRank.get('description')
16283 amit.gupta 334
            subOrder.maxNlc = dealRank.get('maxNlc')
335
            subOrder.minNlc = dealRank.get('minNlc')
336
            subOrder.db = dealRank.get('dp')
337
            subOrder.itemStatus = dealRank.get('status')
15509 manish.sha 338
            subOrders.append(subOrder)
339
        merchantOrder.totalAmount = totalOrdersAmount
340
        merchantOrder.discountApplied = totalDiscount
341
        merchantOrder.deliveryCharges = ordershippingcost
342
        merchantOrder.subOrders = self.updateCashbackInSubOrders(subOrders)
343
 
344
        return merchantOrder
345
 
346
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
347
        resp = {}
348
        try:
15791 manish.sha 349
            rawHtmlSoup = BeautifulSoup(rawHtml)
350
            emailId = None
351
            orderObj = None
352
            merchantOrderId = None
353
            for script in rawHtmlSoup.find_all('script'):
354
                if 'orderConfirmation' in script.text:
16274 manish.sha 355
                    print script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0]
15791 manish.sha 356
                    orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
357
                    if merchantOrderId is None:
358
                        merchantOrderId = orderObj['0']['order_id']
359
                        emailId = orderObj['0']['email']
16197 manish.sha 360
            if orderObj is None or merchantOrderId is None:
16226 manish.sha 361
                orderIdDiv = rawHtmlSoup.body.find("div", {'class':'conf_succes'})
362
                if orderIdDiv is None:
363
                    orderIdArt = rawHtmlSoup.body.find("article", {'class':'white'})
364
                    if orderIdArt is None:
365
                        resp['result'] = 'ORDER_NOT_CREATED_UNKNOWN'
366
                        return resp
367
                    else:
368
                        orderIdDiv= orderIdArt.find('p', recursive=False)
369
                        orderIdVal = str(orderIdDiv.text.split(' : ')[1])
370
                        print "Opening Shopclues Login Page"
371
                        login_url = "https://sm.shopclues.com/login"
372
                        br1 = login(login_url)
373
                        orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+orderIdVal+"&status=P")
374
                        orderDetailPage = ungzipResponse(orderDetailPage)
375
                        rawHtmlSoup = BeautifulSoup(orderDetailPage)
376
                        for script in rawHtmlSoup.find_all('script'):
377
                            if 'orderConfirmation' in script.text:
378
                                orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
379
                                if merchantOrderId is None:
380
                                    merchantOrderId = orderObj['0']['order_id']
381
                                    emailId = orderObj['0']['email']
382
                        logoutpage = br1.open("https://sm.shopclues.com/logout")
383
                        print br1.geturl()
384
                else:
385
                    orderIdDiv= orderIdDiv.find('div', recursive=False)
386
                    orderIdVal = str(orderIdDiv.span.text)
387
                    print "Opening Shopclues Login Page"
388
                    login_url = "https://sm.shopclues.com/login"
389
                    br1 = login(login_url)
390
                    orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+orderIdVal+"&status=P")
391
                    orderDetailPage = ungzipResponse(orderDetailPage)
392
                    rawHtmlSoup = BeautifulSoup(orderDetailPage)
393
                    for script in rawHtmlSoup.find_all('script'):
394
                        if 'orderConfirmation' in script.text:
395
                            orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
396
                            if merchantOrderId is None:
397
                                merchantOrderId = orderObj['0']['order_id']
398
                                emailId = orderObj['0']['email']
399
                    logoutpage = br1.open("https://sm.shopclues.com/logout")
400
                    print br1.geturl()
401
 
16275 manish.sha 402
            if type(orderObj['0']['items']) is list:
403
                print "Opening Shopclues Login Page"
404
                login_url = "https://sm.shopclues.com/login"
405
                br1 = login(login_url)
406
                orderDetailPage = br1.open("https://sm.shopclues.com/orderconfirmation?order_id="+str(merchantOrderId)+"&status=P")
407
                orderDetailPage = ungzipResponse(orderDetailPage)
408
                rawHtmlSoup = BeautifulSoup(orderDetailPage)
409
                for script in rawHtmlSoup.find_all('script'):
410
                    if 'orderConfirmation' in script.text:
411
                        orderObj = json.loads(script.text.strip().split('\n')[0].split('orderConfirmation = ')[1].split(';')[0])
412
                        if merchantOrderId is None:
413
                            merchantOrderId = orderObj['0']['order_id']
414
                            emailId = orderObj['0']['email']
415
                logoutpage = br1.open("https://sm.shopclues.com/logout")
416
                print br1.geturl()
417
 
15509 manish.sha 418
            br = getBrowserObject()
15791 manish.sha 419
            url = ORDER_TRACK_URL +'&order_id=' +str(merchantOrderId)+'&email_id='+ emailId
15509 manish.sha 420
            page = br.open(url)
421
            headers = str(page.info()).split('\n')
422
            page = ungzipResponse(page)
423
            jsonResponse = None
424
            for header in headers:
425
                header = header.split(':')
426
                if header[0] == 'Content-Type' and 'json' in header[1]:
427
                    jsonResponse = json.loads(page)
428
            if jsonResponse is not None:
429
                page = jsonResponse['text']
430
 
16370 manish.sha 431
            merchantOrder = self._parseOrders(orderId, merchantOrderId, subTagId, userId, page, orderSuccessUrl, orderObj) 
15509 manish.sha 432
 
15948 manish.sha 433
            merchantOrder.orderTrackingUrl = ORDER_TRACK_URL_DB + 'order_id=' +str(merchantOrderId)+'&email_id='+ emailId
15509 manish.sha 434
 
435
            if self._saveToOrder(todict(merchantOrder)):
436
                resp['result'] = 'ORDER_CREATED'
437
            else:
438
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
439
 
440
            return resp
441
        except:
442
            print "Error occurred"
443
            traceback.print_exc()
444
            resp['result'] = 'ORDER_NOT_CREATED'
16120 manish.sha 445
            return resp
15509 manish.sha 446
 
15791 manish.sha 447
    def parseSingleSubOrder(self, soup, emailId, subOrderId):
448
        orderStatusList = soup.findAll(attrs={'class' : 'price ord_status'})
449
        subOrderStatus = orderStatusList[0].contents[0].strip()
15509 manish.sha 450
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
16230 manish.sha 451
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("\r","").replace("  ","")
452
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
453
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)    
15791 manish.sha 454
        firstRow = orderTable.pop(0)
15949 manish.sha 455
        totalColumns = len(firstRow.find_all('th'))
15791 manish.sha 456
        subOrders =[]
457
        count =1   
15509 manish.sha 458
        for orderTr in orderTable:
459
            cols = orderTr.find_all('td')
460
            product_details = cols[0].find_all('a')
461
            #print product_details
462
            productUrl = product_details[0].get('href')
463
            productName = product_details[0].contents[0].strip()
464
            quantity = int(cols[1].text.strip())
15980 manish.sha 465
            sellingPrice = long(cols[2].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 466
            discount = 0
467
            subtotal = 0
468
            if totalColumns == 5:
15949 manish.sha 469
                if cols[3].text.strip()!='-' and 'Rs.' in cols[3].text.strip():
15980 manish.sha 470
                    discount = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 471
                else:
472
                    discount = 0
15980 manish.sha 473
                subtotal = long(cols[4].text.strip().replace("Rs.","").replace(',',''))
15791 manish.sha 474
            else:
15980 manish.sha 475
                subtotal = long(cols[3].text.strip().replace("Rs.","").replace(',',''))
16151 manish.sha 476
            productPage = fetchResponseUsingProxy(BASE_MURL+productUrl)
477
            productPageSoup = BeautifulSoup(productPage)
15791 manish.sha 478
            productCode = productPageSoup.find('input', {'type':'hidden'})['value']
15509 manish.sha 479
            allproductImageTags = productPageSoup.findAll(attrs={'class' : 'pd-image'})
480
            productImgUrl = ''
481
            if allproductImageTags is not None and len(allproductImageTags)>0:
482
                productImgUrl= allproductImageTags[0].get('style').split("background:url('")[1].split("')no-repeat center")[0].strip()
483
 
484
            subOrder = SubOrder(productName, productUrl, placedOn, subtotal)
15791 manish.sha 485
            subOrder.merchantSubOrderId = str(subOrderId)+'-'+str(count)
15509 manish.sha 486
            subOrder.detailedStatus = subOrderStatus
487
            subOrder.imgUrl = productImgUrl
488
            subOrder.offerDiscount = discount*quantity
489
            subOrder.unitPrice = sellingPrice
490
            subOrder.productCode = productCode
491
            subOrder.amountPaid = subtotal
492
            subOrder.quantity = quantity
15791 manish.sha 493
            subOrder.tracingkUrl = ORDER_TRACK_URL_DB +  'order_id=' +subOrderId+'&email_id='+ emailId
15509 manish.sha 494
            subOrders.append(subOrder)
15791 manish.sha 495
            count = count +1
15509 manish.sha 496
 
497
        subOrders = self.updateCashbackInSubOrders(subOrders)
15791 manish.sha 498
        return subOrders
15509 manish.sha 499
 
15791 manish.sha 500
    def parseMultiSubOrders(self, soup, emailId):
16230 manish.sha 501
        orderTables = soup.body.findAll("table", {'class':'table product-list'})
502
        orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16145 manish.sha 503
        firstRow = orderTable.pop(0)
15791 manish.sha 504
        '''
505
        totalColumns = len(firstRow.find_all('td'))
506
 
15509 manish.sha 507
        orderDateList = soup.findAll(attrs={'class':'price ord_date'})
15791 manish.sha 508
        placedOn= orderDateList[0].text.strip().replace("\t","").replace("\n","").replace("  ","")
509
        '''    
15509 manish.sha 510
        subOrders = []
15791 manish.sha 511
        existingOrders = []
15509 manish.sha 512
        for orderTr in orderTable:
513
            cols = orderTr.find_all('td')
514
            product_details = cols[0].find_all('a')
515
            #print product_details
516
            subOrderId= product_details[1].contents[0].strip()
15791 manish.sha 517
            if subOrderId in existingOrders:
518
                continue
519
            else:
520
                existingOrders.append(subOrderId)
521
            '''
15509 manish.sha 522
            productUrl = product_details[0].get('href')
523
            productName = product_details[0].contents[0].strip()
15791 manish.sha 524
            '''
525
            subOrderTrackingParsingUrl = product_details[1].get('href')
526
            #subOrderTrackingUrl = subOrderTrackingParsingUrl.split('order_lookup.details&')[1]
527
            '''
15509 manish.sha 528
            quantity = int(cols[1].text.strip())
529
            sellingPrice = long(cols[2].text.strip().replace("Rs.",""))
15791 manish.sha 530
            discount = 0
531
            subtotal = 0
532
            if totalColumns == 5:
533
                if cols[3].text.strip()!='-' or 'Rs.' in cols[3].text.strip():
534
                    discount = long(cols[3].text.strip().replace("Rs.",""))
535
                else:
536
                    discount = 0
537
                subtotal = long(cols[4].text.strip().replace("Rs.",""))
538
            else:
539
                subtotal = long(cols[3].text.strip().replace("Rs.",""))
540
 
15509 manish.sha 541
            br = getBrowserObject()
542
            productPage = br.open(BASE_MURL+productUrl)
543
            productPageHeaders = str(productPage.info()).split('\n')
544
            productPage = ungzipResponse(productPage)
545
            jsonProductResponse = None
546
            for header in productPageHeaders:
547
                header = header.split(':')
548
                if header[0] == 'Content-Type' and 'json' in header[1]:
549
                    jsonProductResponse = json.loads(productPage)
550
            productPageSoup= None
551
            if jsonProductResponse is not None:
552
                productPageSoup = BeautifulSoup(jsonProductResponse['text'])
553
            else:
554
                productPageSoup = BeautifulSoup(productPage)
15791 manish.sha 555
            productCode = productPageSoup.find('input', {'type':'hidden'})['value']
15509 manish.sha 556
            allproductImageTags = productPageSoup.findAll(attrs={'class' : 'pd-image'})
557
            productImgUrl = ''
558
            if allproductImageTags is not None and len(allproductImageTags)>0:
559
                productImgUrl= allproductImageTags[0].get('style').split("background:url('")[1].split("')no-repeat center")[0].strip()
560
            productDetailsSubMap['productCode']=productCode
561
            productDetailsSubMap['imgUrl']=productImgUrl
15791 manish.sha 562
            '''
16151 manish.sha 563
            orderTrackingPage = fetchResponseUsingProxy(BASE_URL+subOrderTrackingParsingUrl)
564
            orderTrackingPageSoup = BeautifulSoup(orderTrackingPage)
15791 manish.sha 565
            subOrdersDetails = self.parseSingleSubOrder(orderTrackingPageSoup, emailId, subOrderId)
566
            subOrders = list(set(subOrders + subOrdersDetails))
15509 manish.sha 567
 
15791 manish.sha 568
        return subOrders
15509 manish.sha 569
 
570
    def scrapeStoreOrders(self,):
571
        #collectionMap = {'palcedOn':1}
572
        searchMap = {}
573
        collectionMap = {"orderTrackingUrl":1}
574
        orders = self._getActiveOrders(searchMap,collectionMap)
575
        for order in orders:
576
            print "Order", self.store_name, order['orderId'], order['orderTrackingUrl']
16138 manish.sha 577
            url = ORDER_TRACK_URL +'&'+ order['orderTrackingUrl'].split('trackOrder?')[1]
16141 manish.sha 578
            print url
16249 manish.sha 579
            page = None
580
            retry = 1
581
            while retry <=3: 
582
                try: 
583
                    page = fetchResponseUsingProxy(url)
584
                    break
585
                except:
16250 manish.sha 586
                    traceback.print_exc()
16249 manish.sha 587
                    retry = retry + 1
588
 
15509 manish.sha 589
            soup = BeautifulSoup(page)
590
            bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
591
            closed = True
16144 manish.sha 592
            orderIdSpan = soup.body.find("span", {'class':'price ord_no'})
593
            if orderIdSpan is not None:
16143 manish.sha 594
                orderStatusList = soup.findAll(attrs={'class' : 'price ord_status'})
595
                if orderStatusList is not None and len(orderStatusList)>0:
596
                    subOrderId = soup.findAll(attrs={'class':'price ord_no'})[0].text.strip()
597
                    orderStatus = orderStatusList[0].contents[0].strip()
16230 manish.sha 598
                    orderTables = soup.body.findAll("table", {'class':'table product-list'})
16229 manish.sha 599
                    orderTable = orderTables[len(orderTables)-1].findAll('tr', recursive=False)
16143 manish.sha 600
                    orderTable.pop(0)
601
                    count = 1
602
                    while count <= len(orderTable):
16160 manish.sha 603
                        subbulk = self.db.merchantOrder.initialize_ordered_bulk_op()
16152 manish.sha 604
                        print 'Sub Order Id', str(subOrderId)+'-'+str(count)
16143 manish.sha 605
                        subOrder =  self._isSubOrderActive(order, str(subOrderId)+'-'+str(count))
606
                        if subOrder is None:
607
                            try:
16787 manish.sha 608
                                print 'Email Id:- '+ str(order['orderTrackingUrl'].split('email_id=')[1])+' and Order Id:- ' + str(subOrderId)
16143 manish.sha 609
                                subOrders = self.parseSingleSubOrder(soup, order['orderTrackingUrl'].split('email_id=')[1], subOrderId)
610
                                for subOrder in subOrders:
611
                                    if subOrder is None:
612
                                        continue
613
                                    self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict([subOrder])}}})
614
                                    print "Added new suborders to Order id - ", order['orderId']
615
                                    closed = False
616
                            except:
16227 manish.sha 617
                                traceback.print_exc()
16143 manish.sha 618
                                pass
16227 manish.sha 619
                            count = count+1
16143 manish.sha 620
                            continue
621
                        elif subOrder['closed']:
16226 manish.sha 622
                            count = count+1
16143 manish.sha 623
                            continue
624
                        else:
16163 manish.sha 625
                            findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": str(subOrderId)+'-'+str(count)}
16143 manish.sha 626
                            updateMap = {}
627
                            updateMap["subOrders.$.detailedStatus"] = orderStatus
628
                            status = self._getStatusFromDetailedStatus(orderStatus) 
629
                            closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
630
                            if status is not None:
631
                                updateMap["subOrders.$.status"] = status
632
                            if closedStatus:
633
                                #if status is closed then change the paybackStatus accordingly
16155 manish.sha 634
                                print 'Order Closed'
16143 manish.sha 635
                                updateMap["subOrders.$.closed"] = True
636
                                if status == Store.ORDER_DELIVERED:
637
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
638
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
639
                                elif status == Store.ORDER_CANCELLED:
640
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
641
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
642
                            else:
15791 manish.sha 643
                                closed = False
16155 manish.sha 644
                                print 'Order not Closed'
16161 manish.sha 645
 
16158 manish.sha 646
                            subbulk.find(findMap).update({'$set' : updateMap})
647
                            subresult = subbulk.execute()
648
                            tprint(subresult)
16164 manish.sha 649
                        count = count +1
16156 manish.sha 650
                    bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
651
                    result = bulk.execute()
652
                    tprint(result)
16143 manish.sha 653
 
654
                else:
655
                    subOrdersList = self.parseMultiSubOrders(soup, order['orderTrackingUrl'].split('email_id=')[1])
656
                    for subOrderObj in subOrdersList:
16159 manish.sha 657
                        subbulk1 = self.db.merchantOrder.initialize_ordered_bulk_op()
16143 manish.sha 658
                        subOrder =  self._isSubOrderActive(order, subOrderObj.merchantSubOrderId)
659
                        if subOrder is None:
660
                            self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict([subOrderObj])}}})
661
                            print "Added new suborders to Order id - ", order['orderId']
662
                            closed = False
663
                            continue
664
                        elif subOrder['closed']:
665
                            continue
15791 manish.sha 666
                        else:
16143 manish.sha 667
                            findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": subOrderId}
668
                            updateMap = {}
669
                            updateMap["subOrders.$.detailedStatus"] = subOrderObj.detailedStatus
670
                            status = self._getStatusFromDetailedStatus(orderStatus) 
671
                            closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
672
                            if status is not None:
673
                                updateMap["subOrders.$.status"] = status
674
                            if closedStatus:
675
                                #if status is closed then change the paybackStatus accordingly
676
                                updateMap["subOrders.$.closed"] = True
677
                                if status == Store.ORDER_DELIVERED:
678
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
679
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
680
                                elif status == Store.ORDER_CANCELLED:
681
                                    if subOrder.get("cashBackStatus") == Store.CB_PENDING:
682
                                        updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
683
                            else:
684
                                closed = False
16159 manish.sha 685
                            subbulk1.find(findMap).update({'$set' : updateMap})
686
                            subresult1 = subbulk1.execute()
687
                            tprint(subresult1)
16156 manish.sha 688
                    bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
689
                    result = bulk.execute()
690
                    tprint(result)
15509 manish.sha 691
            else:
16143 manish.sha 692
                print 'Soup Object not found for this Order', order['orderId'], order['orderTrackingUrl']
693
                continue      
15791 manish.sha 694
 
695
    '''
696
    def getTrackingUrls(self, userId):
697
        missingOrderUrls = ['https://sm.shopclues.com/myaccount','https://sm.shopclues.com/myorders']
698
        return missingOrderUrls
15509 manish.sha 699
 
15791 manish.sha 700
    def parseMyProfileForEmailId(self, userId, url, rawhtml):
701
        profileSoup = BeautifulSoup(rawhtml)
702
        if profileSoup.find('input', {'name':'user_email'}) is not None:
703
            emailId = profileSoup.find('input', {'name':'user_email'})['value']
704
            if emailId is not None and emailId.strip() !='':
705
                mc = MemCache()
706
                mc.set(str(userId), emailId, 600)
707
                return 'EMAIL_SET_SUCCESS'
708
            else:
709
                return 'EMAIL_NOT_FOUND'
710
        else:
711
            return 'EMAIL_NOT_FOUND'
15509 manish.sha 712
 
15791 manish.sha 713
    def parseMyOrdersForEmailId(self, userId, url, rawhtml):
714
        myOrdersPageSoup = BeautifulSoup(rawhtml)
715
        if myOrdersPageSoup.find('a', {'class':'detail'}) is not None:
716
            emailId = myOrdersPageSoup.find('a', {'class':'detail'})['href'].split('&')[1].split('=')[1]
717
            mc = MemCache()
718
            mc.set(str(userId), emailId, 600)
719
            return 'EMAIL_SET_SUCCESS'
720
        else:
721
            return 'EMAIL_NOT_FOUND'
722
    '''        
723
 
16420 manish.sha 724
def to_py_date(java_timestamp):
16424 manish.sha 725
    date = datetime.fromtimestamp(java_timestamp)
16420 manish.sha 726
    return date       
15791 manish.sha 727
 
15509 manish.sha 728
def todict(obj, classkey=None):
729
    if isinstance(obj, dict):
730
        data = {}
731
        for (k, v) in obj.items():
732
            data[k] = todict(v, classkey)
733
        return data
734
    elif hasattr(obj, "_ast"):
735
        return todict(obj._ast())
736
    elif hasattr(obj, "__iter__"):
737
        return [todict(v, classkey) for v in obj]
738
    elif hasattr(obj, "__dict__"):
739
        data = dict([(key, todict(value, classkey)) 
740
            for key, value in obj.__dict__.iteritems() 
741
            if not callable(value) and not key.startswith('_')])
742
        if classkey is not None and hasattr(obj, "__class__"):
743
            data[classkey] = obj.__class__.__name__
744
        return data
745
    else:
16226 manish.sha 746
        return obj
747
 
748
def login(url):
749
    br = getBrowserObject()
16787 manish.sha 750
    br.set_proxies({"http": PROXY_MESH_GENERAL})
16226 manish.sha 751
    br.open(url)
752
    response = br.open(url)
753
    ungzipResponseBr(response, br)
754
    #html = response.read()
755
    #print html
756
    br.select_form(nr=0)
757
    br.form['user'] = "imanthetester@gmail.com"
758
    br.form['password'] = "$Dl8uk"
759
    response = br.submit()
760
    print "********************"
761
    print "Attempting to Login"
762
    print "********************"
763
    #ungzipResponse(response, br)
764
    return br
15791 manish.sha 765
 
16226 manish.sha 766
def ungzipResponseBr(r,b):
767
    headers = r.info()
768
    if headers['Content-Encoding']=='gzip':
769
        import gzip
770
        print "********************"
771
        print "Deflating gzip response"
772
        print "********************"
773
        gz = gzip.GzipFile(fileobj=r, mode='rb')
774
        html = gz.read()
775
        gz.close()
776
        headers["Content-type"] = "text/html; charset=utf-8"
777
        r.set_data( html )
778
        b.set_response(r)    
779
 
15509 manish.sha 780