Subversion Repositories SmartDukaan

Rev

Rev 14946 | Rev 15877 | 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
'''
14854 amit.gupta 6
from bs4 import BeautifulSoup
13569 amit.gupta 7
from bson.binary import Binary
13680 amit.gupta 8
from datetime import datetime, date, timedelta
13569 amit.gupta 9
from dtr import main
13576 amit.gupta 10
from dtr.dao import AffiliateInfo, Order, SubOrder
14398 amit.gupta 11
from dtr.main import getBrowserObject, ScrapeException, getStore, ParseException, \
12
    Store as MStore, ungzipResponse, tprint
14415 amit.gupta 13
from dtr.storage import Mongo
15350 amit.gupta 14
from dtr.storage.Mongo import getImgSrc, getDealRank
14758 amit.gupta 15
from dtr.utils.utils import fetchResponseUsingProxy
13662 amit.gupta 16
from pprint import pprint
13569 amit.gupta 17
from pymongo import MongoClient
15350 amit.gupta 18
from urlparse import urlparse, parse_qs
13569 amit.gupta 19
import json
20
import pymongo
21
import re
14443 amit.gupta 22
import time
13662 amit.gupta 23
import traceback
13569 amit.gupta 24
import urllib
13603 amit.gupta 25
 
13721 amit.gupta 26
USERNAME='profittill2@gmail.com'
13569 amit.gupta 27
PASSWORD='spice@2020'
28
AFFILIATE_URL='http://affiliate.snapdeal.com'
29
POST_URL='https://api-p03.hasoffers.com/v3/Affiliate_Report.json'
30
ORDER_TRACK_URL='https://m.snapdeal.com/orderSummary'
31
CONFIG_URL='http://affiliate.snapdeal.com/publisher/js/config.php'
32
 
13662 amit.gupta 33
class Store(MStore):
13569 amit.gupta 34
 
35
    '''
36
    This is to map order statuses of our system to order statuses of snapdeal.
37
    And our statuses will change accordingly.
38
 
39
    '''
40
    OrderStatusMap = {
14861 amit.gupta 41
                      MStore.ORDER_PLACED : ['in progress', 'pending for verification', 'not available', 'in process', 'processing', 'processed'],
14678 amit.gupta 42
                      MStore.ORDER_DELIVERED : ['delivered'],
14861 amit.gupta 43
                      MStore.ORDER_SHIPPED : ['in transit', 'dispatched'],
14946 amit.gupta 44
                      MStore.ORDER_CANCELLED : ['closed for vendor reallocation', 'cancelled', 'product returned by courier', 'returned', 'n/a', 'courier returned']
13569 amit.gupta 45
                      }
13662 amit.gupta 46
 
47
    CONF_CB_AMOUNT = MStore.CONF_CB_DISCOUNTED_PRICE
13569 amit.gupta 48
    def __init__(self,store_id):
49
        super(Store, self).__init__(store_id)
50
 
51
    def getName(self):
52
        return "snapdeal"
53
 
54
    def scrapeAffiliate(self, startDate=None, endDate=None):
55
        br = getBrowserObject()
56
        br.open(AFFILIATE_URL)
57
        br.select_form(nr=0)
58
        br.form['data[User][password]'] = PASSWORD 
59
        br.form['data[User][email]'] = USERNAME
60
        br.submit()
61
        response = br.open(CONFIG_URL)
62
 
13680 amit.gupta 63
        token =  re.findall('"session_token":"(.*?)"', ungzipResponse(response), re.IGNORECASE)[0]
14145 amit.gupta 64
        print token
13569 amit.gupta 65
        allOffers = self._getAllOffers(br, token)
14443 amit.gupta 66
        self._saveToAffiliate(allOffers)
13569 amit.gupta 67
 
13662 amit.gupta 68
    def _setLastSaleDate(self, saleDate):
13680 amit.gupta 69
        self.db.lastSaleDtate.update({'storeId':self.store_id}, {'$set':{'saleDate':saleDate}})
13569 amit.gupta 70
 
13662 amit.gupta 71
 
72
 
73
    def _getLastSaleDate(self,):
74
        lastDaySaleObj = self.db.lastDaySale.find_one({"storeId":self.store_id})
75
        if lastDaySaleObj is None:
76
            return datetime.min
77
 
14854 amit.gupta 78
 
79
 
80
    def _parseB(self, orderId, subTagId, userId, page, orderSuccessUrl):
81
        soup = BeautifulSoup(page)
82
 
83
        orderDetailContainerDivs = soup.body.find("div", {'class':'cardLayoutWrap'}).findAll('div', recursive=False)
84
        orderDetailDiv = orderDetailContainerDivs.pop(0)
85
        paymentDetailDiv  = orderDetailContainerDivs.pop(0)
86
        subOrders = orderDetailContainerDivs
87
 
88
        placedOn = orderDetailDiv.span.text.split(':')[1].strip()
89
        merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
90
        merchantOrder.placedOn = placedOn
91
        merchantOrder.merchantOrderId = parse_qs(urlparse(orderSuccessUrl).query)['order'][0]
92
 
93
        paymentDivs = paymentDetailDiv.findAll('div', recursive=False)
94
        paymentDivs.pop(0)
95
        for orderTr in paymentDivs:
96
            orderTrString = str(orderTr)
97
            if "Total Amount Paid" in orderTrString:
98
                amountPaid = orderTr.div.find('div', {'class':'detailBlock'}).text.strip()
99
                merchantOrder.paidAmount = int(re.findall(r'\d+', amountPaid)[0])
100
            elif "Total Amount" in orderTrString:
101
                merchantOrder.totalAmount = re.findall(r'\d+', orderTrString)[0]
102
            elif "Delivery Charges" in orderTrString:
103
                merchantOrder.deliveryCharges = re.findall(r'\d+', orderTrString)[0]
104
            elif "Discount Applied" in orderTrString:
105
                merchantOrder.discountApplied = re.findall(r'\d+', orderTrString)[0]
106
            elif "Offer Discount" in orderTrString:
107
                merchantOrder.discountApplied = re.findall(r'\d+', orderTrString)[0]
108
 
109
        merchantSubOrders = []
110
        for subOrderElement in subOrders:
14883 amit.gupta 111
            subOrder = self.parseSubOrderB(subOrderElement, placedOn)
112
            if subOrder is not None:
15350 amit.gupta 113
                dealRank = getDealRank(subOrder.productCode, self.store_id, merchantOrder.userId)
114
                subOrder.dealRank = dealRank.get('rank')
115
                subOrder.rankDesc = dealRank.get('description')
14883 amit.gupta 116
                merchantSubOrders.append(subOrder)
14854 amit.gupta 117
        merchantOrder.subOrders = merchantSubOrders
118
        return merchantOrder
119
 
13760 amit.gupta 120
    def _parse(self, orderId, subTagId, userId, page, orderSuccessUrl):
13662 amit.gupta 121
 
13760 amit.gupta 122
        #page=page.decode("utf-8")
14854 amit.gupta 123
        soup = BeautifulSoup(page)
13760 amit.gupta 124
        #orderHead = soup.find(name, attrs, recursive, text)
125
        sections = soup.findAll("section")
126
 
127
        #print sections
128
 
129
        order = sections[1]
130
        orderTrs = order.findAll("tr")
131
 
132
        placedOn = str(orderTrs[0].findAll("td")[1].text)
133
 
134
        #Pop two section elements
135
        sections.pop(0) 
136
        sections.pop(0)
137
        subOrders = sections
138
 
139
 
140
        merchantSubOrders = []
141
 
142
        merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
14447 amit.gupta 143
        merchantOrder.placedOn = placedOn
14023 amit.gupta 144
        merchantOrder.merchantOrderId = re.findall(r'\d+', str(soup.find("div", {"class":"deals_heading"})))[1]
13760 amit.gupta 145
        for orderTr in orderTrs:
146
            orderTrString = str(orderTr)
147
            if "Total Amount" in orderTrString:
148
                merchantOrder.totalAmount = re.findall(r'\d+', orderTrString)[0]
149
            elif "Delivery Charges" in orderTrString:
150
                merchantOrder.deliveryCharges = re.findall(r'\d+', orderTrString)[0]
151
            elif "Discount Applied" in orderTrString:
152
                merchantOrder.discountApplied = re.findall(r'\d+', orderTrString)[0]
153
            elif "Paid Amount" in orderTrString:
154
                merchantOrder.paidAmount = re.findall(r'\d+', orderTrString)[0]
155
 
156
        for subOrderElement in subOrders:
13809 amit.gupta 157
            subOrders = self.parseSubOrder(subOrderElement, placedOn)                           
158
            merchantSubOrders.extend(subOrders)   
13760 amit.gupta 159
 
160
        merchantOrder.subOrders = merchantSubOrders
161
        return merchantOrder
162
 
163
    def parseSubOrder(self, subOrderElement, placedOn):
13809 amit.gupta 164
        subOrders = []
13760 amit.gupta 165
        productUrl = str(subOrderElement.find("a")['href'])
166
        subTable = subOrderElement.find("table", {"class":"lrPad"})
167
        subTrs = subTable.findAll("tr")
168
        unitPrice=None
14458 amit.gupta 169
        offerDiscount = 0
13760 amit.gupta 170
        deliveryCharges = None
171
        amountPaid = None
14458 amit.gupta 172
        amount = 0
14473 amit.gupta 173
        sdCash = 0
174
        unitPrice = 0
13760 amit.gupta 175
        for subTr in subTrs:
176
            subTrString = str(subTr)
177
            if "Unit Price" in subTrString:
14473 amit.gupta 178
                unitPrice = int(re.findall(r'\d+', subTrString)[0])
13760 amit.gupta 179
            if "Quantity" in subTrString:
14458 amit.gupta 180
                qty = int(re.findall(r'\d+', subTrString)[0])
13760 amit.gupta 181
            elif "Offer Discount" in subTrString:
14458 amit.gupta 182
                offerDiscount +=   int(re.findall(r'\d+', subTrString)[0])
14861 amit.gupta 183
            elif "SD Cash" in subTrString:
14473 amit.gupta 184
                sdCash =   int(re.findall(r'\d+', subTrString)[0])
13760 amit.gupta 185
            elif "Delivery Charges" in subTrString:
14473 amit.gupta 186
                deliveryCharges =   int(re.findall(r'\d+', subTrString)[0])
13760 amit.gupta 187
            elif "Subtotal" in subTrString:
188
                if int(qty) > 0:
14459 amit.gupta 189
                    amountPaid =   int(re.findall(r'\d+', subTrString)[0])/qty
13760 amit.gupta 190
                else:
14459 amit.gupta 191
                    amountPaid =   0
14458 amit.gupta 192
        if qty>0:
14473 amit.gupta 193
            amount = unitPrice - offerDiscount - sdCash
194
            amount = 0 if amount < 0 else amount
13760 amit.gupta 195
 
14459 amit.gupta 196
        div1 = subOrderElement.find("div", {"class": "blk lrPad subordrs"})
197
        if div1 is None:
13760 amit.gupta 198
            raise ParseException("subOrder", "Could not Parse suborders for Snapdeal")
199
 
14459 amit.gupta 200
        for strDiv in str(div1).split("<div class=\"seperator\"></div>"):
201
            div = BeautifulSoup(strDiv)
13760 amit.gupta 202
            productTitle = str(subOrderElement.find("a").text)
203
            productUrl = "http://m.snapdeal.com/" + productUrl 
204
            subOrder = SubOrder(productTitle, productUrl, placedOn, amountPaid)
205
 
206
            subOrder.amountPaid = amountPaid
207
            subOrder.deliveryCharges = deliveryCharges
208
            subOrder.offerDiscount = offerDiscount
13809 amit.gupta 209
            subOrder.unitPrice = int(unitPrice)
13760 amit.gupta 210
            subOrder.productCode = re.findall(r'\d+$', productUrl)[0]
14415 amit.gupta 211
            subOrder.imgUrl = Mongo.getImgSrc(subOrder.productCode, self.store_id).get('thumbnail')
14458 amit.gupta 212
            cashbackStatus = Store.CB_NA
213
            cashbackAmount = 0
214
            percentage = 0
215
            if amount > 0:
216
                (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amount)
14473 amit.gupta 217
                if cashbackAmount > 0:
14476 amit.gupta 218
                    cashbackStatus = Store.CB_PENDING
13760 amit.gupta 219
            subOrder.cashBackStatus = cashbackStatus
220
            subOrder.cashBackAmount = cashbackAmount
14458 amit.gupta 221
            subOrder.cashBackPercentage = percentage
13760 amit.gupta 222
 
223
 
224
            trackAnchor = div.find("a")   
225
            if trackAnchor is not None:
226
                subOrder.tracingkUrl = str(trackAnchor['href'])
227
 
228
            divStr = str(div)
229
            divStr = divStr.replace("\n","").replace("\t", "")
230
 
231
            for line in divStr.split("<br />"):
232
                if "Suborder ID" in line:
233
                    subOrder.merchantSubOrderId = re.findall(r'\d+', line)[0]   
234
                elif "Status" in line:
14402 amit.gupta 235
                    print line
13760 amit.gupta 236
                    subOrder.detailedStatus = re.findall('>(.*?)</span>', line, re.IGNORECASE)[0]
237
                elif "Est. Shipping Date" in line:
238
                    subOrder.estimatedShippingDate = line.split(":")[1].strip()
239
                elif "Est. Delivery Date" in line:
240
                    subOrder.estimatedDeliveryDate = line.split(":")[1].strip()
241
                elif "Courier Name" in line:
242
                    subOrder.courierName = line.split(":")[1].strip()
243
                elif "Tracking No" in line:
244
                    subOrder.trackingNumber = line.split(":")[1].strip()
13809 amit.gupta 245
            subOrders.append(subOrder)
246
        return subOrders
13760 amit.gupta 247
 
14854 amit.gupta 248
    def parseSubOrderB(self, subOrderElement, placedOn):
249
        subOrders = []
250
        prodDivs = subOrderElement.findAll('div', recursive=False)
251
        prodDetailDiv = prodDivs[1].findAll('div', recursive=False)
252
 
253
        offerDiscount = 0
254
        deliveryCharges = None
255
        amountPaid = 0
256
        sdCash = 0
257
        unitPrice = 0
258
 
259
        paymentDivs = prodDivs[2].findAll('div', recursive=False)
260
        for paymentDiv in paymentDivs:
261
            strPaymentDiv = str(paymentDiv)
262
            if "Unit Price" in strPaymentDiv:
14883 amit.gupta 263
                try:
264
                    unitPrice = int(re.findall(r'\d+', strPaymentDiv)[0])
265
                except:
266
                    return None
14872 amit.gupta 267
            elif "Offer Discount" in strPaymentDiv:
268
                offerDiscount += int(re.findall(r'\d+', strPaymentDiv)[0])
269
            elif "Discount" in strPaymentDiv:
270
                offerDiscount += int(re.findall(r'\d+', strPaymentDiv)[0])
14861 amit.gupta 271
            elif "SD Cash" in strPaymentDiv:
14854 amit.gupta 272
                sdCash =   int(re.findall(r'\d+', strPaymentDiv)[0])
273
            elif "Delivery Charges" in strPaymentDiv:
274
                deliveryCharges =   int(re.findall(r'\d+', strPaymentDiv)[0])
275
            elif "Subtotal" in strPaymentDiv:
276
                amountPaid =   int(re.findall(r'\d+', paymentDiv.find('div', {'class':'itemPriceDetail'}).text)[0])
277
 
278
        amount = unitPrice - offerDiscount - sdCash
279
 
280
        imgDiv = prodDetailDiv[0]
281
        otherDiv = prodDetailDiv[1]
282
        productTitle = otherDiv.find('div',{'class':'orderName'}).text.strip()
283
 
284
        productUrl = imgDiv.a['href']
285
        subOrder = SubOrder(productTitle, productUrl, placedOn, amountPaid)
14863 amit.gupta 286
        subOrder.merchantSubOrderId = prodDivs[0].text.split(':')[1].strip()
14854 amit.gupta 287
        subOrder.detailedStatus = otherDiv.find('div',{'class':'orderStatus'}).span.text.strip()
288
        deliveryStatus = otherDiv.find('div',{'class':'orderDelivery'})
289
        if deliveryStatus is not None:
290
            delString = deliveryStatus.text.strip()
291
            arr = delString.split(':')
292
            if "On" in arr[0]:
293
                subOrder.deliveredOn = arr[1].strip()
294
            elif "Exp. Delivery by" in arr[0]:
295
                subOrder.estimatedDeliveryDate = arr[1].strip()
296
            else:
297
                subOrder.estimatedShippingDate = arr[1].strip()
298
 
299
        subOrder.imgUrl = imgDiv.a.img['src']
300
        subOrder.productCode = re.findall(r'\d+$', productUrl)[0]
301
        subOrder.deliveryCharges = deliveryCharges
302
        subOrder.offerDiscount = offerDiscount
303
        subOrder.unitPrice = int(unitPrice)
304
        cashbackStatus = Store.CB_NA
305
        cashbackAmount = 0
306
        percentage = 0
307
        if amountPaid > 0:
308
            (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amount)
309
            if cashbackAmount > 0:
310
                cashbackStatus = Store.CB_PENDING
311
        subOrder.cashBackStatus = cashbackStatus
312
        subOrder.cashBackAmount = cashbackAmount
313
        subOrder.cashBackPercentage = percentage
314
 
315
 
316
        courierDet = subOrderElement.find('div', {'class':'courierDetail'})
317
        if courierDet is not None:
318
            subOrder.courierName = courierDet.span.text.strip()
319
        trackingDet = subOrderElement.find('div', {'class':'trackingNo'})
320
        if trackingDet is not None:
321
            subOrder.trackingUrl = trackingDet.span.a['href']
322
            subOrder.trackingNumber = trackingDet.span.a.text.strip()
323
 
324
        subOrders.append(subOrder)
325
        return subOrder
326
 
13576 amit.gupta 327
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
13760 amit.gupta 328
                    #print merchantOrder
13796 amit.gupta 329
        resp = {}
13582 amit.gupta 330
        try:
331
            br = getBrowserObject()
332
            url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', orderSuccessUrl,re.IGNORECASE)[0]
13791 amit.gupta 333
            page = br.open(url)
334
            page = ungzipResponse(page)
14854 amit.gupta 335
            try:
336
                merchantOrder = self._parseB(orderId, subTagId, userId, page, orderSuccessUrl)
337
            except:
14861 amit.gupta 338
                traceback.print_exc()
14854 amit.gupta 339
                merchantOrder = self._parse(orderId, subTagId, userId, page, orderSuccessUrl)
340
 
14312 amit.gupta 341
            merchantOrder.orderTrackingUrl = url
342
 
343
            if self._saveToOrder(todict(merchantOrder)):
344
                resp['result'] = 'ORDER_CREATED'
345
            else:
346
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
347
 
13796 amit.gupta 348
            return resp
13582 amit.gupta 349
        except:
350
            print "Error occurred"
13603 amit.gupta 351
            traceback.print_exc()
14312 amit.gupta 352
            resp['result'] = 'ORDER_NOT_CREATED'
13796 amit.gupta 353
            return resp
13781 amit.gupta 354
 
13569 amit.gupta 355
 
356
        #soup = BeautifulSoup(rawHtml,convertEntities=BeautifulSoup.HTML_ENTITIES)
357
        #soup.find(name, attrs, recursive, text)
13576 amit.gupta 358
 
359
    def _getStatusFromDetailedStatus(self, detailedStatus):
360
        for key, value in Store.OrderStatusMap.iteritems():
14678 amit.gupta 361
            if detailedStatus.lower() in value:
13576 amit.gupta 362
                return key
14675 amit.gupta 363
        print "Detailed Status need to be mapped", detailedStatus, self.store_id
14861 amit.gupta 364
        return None
13569 amit.gupta 365
 
13610 amit.gupta 366
 
13569 amit.gupta 367
    def scrapeStoreOrders(self,):
13760 amit.gupta 368
        #collectionMap = {'palcedOn':1}
13576 amit.gupta 369
        orders = self._getActiveOrders()
370
        for order in orders:
14696 amit.gupta 371
            print "Order", self.store_name, order['orderId']
14398 amit.gupta 372
            try:
373
                url = ORDER_TRACK_URL + re.findall('.*(\?.*?)$', order['orderSuccessUrl'],re.IGNORECASE)[0]
14758 amit.gupta 374
                page = fetchResponseUsingProxy(url)
14398 amit.gupta 375
                #page=page.decode("utf-8")
14861 amit.gupta 376
                soup = BeautifulSoup(page)
377
                try:
378
                    self.tryBParsing(order, soup)
379
                except:
380
                    traceback.print_exc()
381
                    sections = soup.findAll("section")
382
                    orderEl = sections[1]
383
                    orderTrs = orderEl.findAll("tr")
384
 
385
                    placedOn = str(orderTrs[0].findAll("td")[1].text)
386
                    sections.pop(0)
387
                    sections.pop(0)
388
 
389
                    subOrders = sections
390
                    bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
391
                    closed = True
392
                    for subOrderElement in subOrders:
393
                        div1 = subOrderElement.findAll("div", {"class": "blk lrPad subordrs"})
394
                        if len(div1)<=0:
395
                            raise ParseException("subOrder", "Could not Parse suborders for Snapdeal")
396
                        subOrder = None
397
                        breakFlag = False
398
                        for strDiv in str(div1).split("<div class=\"seperator\"></div>"):
399
                            div = BeautifulSoup(strDiv)
400
                            divStr = str(div)
401
                            divStr = divStr.replace("\n","").replace("\t", "")
402
                            updateMap = {}
403
                            for line in divStr.split("<br />"):
404
                                if "Suborder ID" in line:
405
                                    merchantSubOrderId = re.findall(r'\d+', line)[0]
406
                                    #break if suborder is inactive   
407
                                    subOrder =  self._isSubOrderActive(order, merchantSubOrderId)
408
                                    if subOrder is None:
409
                                        subOrders = self.parseSubOrder(subOrderElement, placedOn)
410
                                        self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict(subOrders)}}})
411
                                        print "Added new suborders to Order id - ", order['orderId']
412
                                        closed = False
413
                                        breakFlag = True
414
                                        break
415
                                    elif subOrder['closed']:
416
                                        breakFlag = True
417
                                        break
418
                                    else: 
419
                                        findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": merchantSubOrderId}
420
                                elif "Status :" in line:
421
                                    detailedStatus = re.findall('>(.*?)</span>', line, re.IGNORECASE)[0]
422
                                    updateMap["subOrders.$.detailedStatus"] = detailedStatus
423
                                    status = self._getStatusFromDetailedStatus(detailedStatus) 
424
                                    closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
425
                                    if status is not None:
426
                                        updateMap["subOrders.$.status"] = status
427
                                    if detailedStatus == 'Closed For Vendor Reallocation':
428
                                        #if it is more than 6hours mark closed.
429
                                        closeAt = subOrder.get("closeAt") 
430
                                        if closeAt is None:
431
                                            closeAt = datetime.now() + timedelta(hours=6)
432
                                            updateMap["subOrders.$.closeAt"] = datetime.strftime(closeAt,"%Y-%m-%d %H:%M:%S")
433
                                        else:
434
                                            closeAt = datetime.strptime(closeAt,"%Y-%m-%d %H:%M:%S")
435
                                            if datetime.now() > closeAt:
436
                                                closedStatus = True
437
 
438
 
439
                                    if closedStatus:
440
                                        #if status is closed then change the paybackStatus accordingly
441
                                        updateMap["subOrders.$.closed"] = True
442
                                        if status == Store.ORDER_DELIVERED:
443
                                            if subOrder.get("cashBackStatus") == Store.CB_PENDING:
444
                                                updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
445
                                        elif status == Store.ORDER_CANCELLED:
446
                                            if subOrder.get("cashBackStatus") == Store.CB_PENDING:
447
                                                updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
448
 
14398 amit.gupta 449
                                    else:
14861 amit.gupta 450
                                        closed = False
451
                                elif "Est. Shipping Date" in line:
452
                                    estimatedShippingDate = line.split(":")[1].strip()
453
                                    updateMap["subOrders.$.estimatedShippingDate"] = estimatedShippingDate
454
                                elif "Est. Delivery Date" in line:
455
                                    estimatedDeliveryDate = line.split(":")[1].strip()
456
                                    updateMap["subOrders.$.estimatedDeliveryDate"] = estimatedDeliveryDate
457
                                elif "Courier Name" in line:
458
                                    courierName = line.split(":")[1].strip()
459
                                    updateMap["subOrders.$.courierName"] = courierName
460
                                elif "Tracking No" in line:
461
                                    trackingNumber = line.split(":")[1].strip()
462
                                    updateMap["subOrders.$.trackingNumber"] = trackingNumber
463
 
464
                            if breakFlag:
465
                                continue
466
 
467
                            bulk.find(findMap).update({'$set' : updateMap})
468
                        bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
469
                    result = bulk.execute()
470
                    tprint(result)
14398 amit.gupta 471
            except:
14847 amit.gupta 472
                tprint("Could not update " + str(order['orderId']) + "For store " + self.getName())
14692 amit.gupta 473
                self.db.merchantOrder.update({"orderId":order['orderId']}, {"$set":{"parseError":True}})
14398 amit.gupta 474
                traceback.print_exc()                
13576 amit.gupta 475
 
14854 amit.gupta 476
    def tryBParsing(self, order, soup):
477
        orderDetailContainerDivs = soup.body.find("div", {'class':'cardLayoutWrap'}).findAll('div', recursive=False)
478
        orderDetailDiv = orderDetailContainerDivs.pop(0)
479
        placedOn = orderDetailDiv.span.text.split(':')[1].strip()
480
 
481
        orderDetailContainerDivs.pop(0)
482
 
483
        subOrders = orderDetailContainerDivs
484
        bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
485
        closed = True
486
        for subOrderElement in subOrders:
487
            prodDivs = subOrderElement.findAll('div', recursive=False)
488
            merchantSubOrderId = prodDivs[0].text.split(':')[1].strip()
489
            subOrder = None
14861 amit.gupta 490
            subOrder =  self._isSubOrderActive(order, merchantSubOrderId)
491
            if subOrder is None:
14864 amit.gupta 492
                try:
14883 amit.gupta 493
                    subOrder = self.parseSubOrderB(subOrderElement, placedOn)
494
                    if subOrder is None:
495
                        continue
496
                    self.db.merchantOrder.update({"orderId":order['orderId']},{'$push':{"subOrders":{"$each":todict([subOrder])}}})
14864 amit.gupta 497
                    print "Added new suborders to Order id - ", order['orderId']
498
                    closed = False
499
                except:
500
                    pass
14861 amit.gupta 501
                continue
502
            elif subOrder['closed']:
503
                continue
504
            else: 
14864 amit.gupta 505
                prodDetailDiv = prodDivs[1].findAll('div', recursive=False)
506
                otherDiv = prodDetailDiv[1]
507
                trackBlock = subOrderElement.find('div',{'class':'trackingDetailsBlock'})
14861 amit.gupta 508
                findMap = {"orderId": order['orderId'], "subOrders.merchantSubOrderId": merchantSubOrderId}
509
                updateMap = {}
510
                detailedStatus = otherDiv.find('div',{'class':'orderStatus'}).span.text.strip()
511
                updateMap["subOrders.$.detailedStatus"] = detailedStatus
512
                status = self._getStatusFromDetailedStatus(detailedStatus) 
513
                closedStatus = status in [Store.ORDER_DELIVERED, Store.ORDER_CANCELLED]
514
                if status is not None:
14854 amit.gupta 515
                    updateMap["subOrders.$.status"] = status
14864 amit.gupta 516
                if 'A New Order Placed With A Different Seller' in str(trackBlock):
14861 amit.gupta 517
                    #if it is more than 6hours mark closed.
518
                    closeAt = subOrder.get("closeAt") 
519
                    if closeAt is None:
520
                        closeAt = datetime.now() + timedelta(hours=6)
521
                        updateMap["subOrders.$.closeAt"] = datetime.strftime(closeAt,"%Y-%m-%d %H:%M:%S")
14854 amit.gupta 522
                    else:
14861 amit.gupta 523
                        closeAt = datetime.strptime(closeAt,"%Y-%m-%d %H:%M:%S")
524
                        if datetime.now() > closeAt:
525
                            closedStatus = True
14864 amit.gupta 526
                            updateMap["subOrders.$.status"] = Store.ORDER_CANCELLED
14861 amit.gupta 527
 
528
 
529
                if closedStatus:
530
                    #if status is closed then change the paybackStatus accordingly
531
                    updateMap["subOrders.$.closed"] = True
532
                    if status == Store.ORDER_DELIVERED:
533
                        if subOrder.get("cashBackStatus") == Store.CB_PENDING:
534
                            updateMap["subOrders.$.cashBackStatus"] = Store.CB_APPROVED
535
                    elif status == Store.ORDER_CANCELLED:
536
                        if subOrder.get("cashBackStatus") == Store.CB_PENDING:
537
                            updateMap["subOrders.$.cashBackStatus"] = Store.CB_CANCELLED
538
 
539
                else:
540
                    closed = False
14854 amit.gupta 541
 
14861 amit.gupta 542
                deliveryStatus = otherDiv.find('div',{'class':'orderDelivery'})
543
                if deliveryStatus is not None:
544
                    delString = deliveryStatus.text.strip()
545
                    arr = delString.split(':')    
546
                    if "On" in arr[0]:
547
                        updateMap['subOrders.$.deliveredOn'] = arr[1].strip()
548
                    elif "Exp. Delivery by" in arr[0]:
549
                        updateMap['subOrders.$.estimatedDeliveryDate'] = arr[1].strip()
550
                    else:
551
                        updateMap['subOrders.$.estimatedShippingDate'] = arr[1].strip()
552
                courierDet = subOrderElement.find('div', {'class':'courierDetail'})
553
                if courierDet is not None:
554
                    updateMap['subOrders.$.courierName'] = courierDet.span.text.strip()
555
                trackingDet = subOrderElement.find('div', {'class':'trackingNo'})
556
                if trackingDet is not None:
557
                    updateMap['subOrders.$.trackingUrl'] = trackingDet.span.a['href']
558
                    updateMap['subOrders.$.trackingNumber'] = trackingDet.span.a.text.strip()                    
14854 amit.gupta 559
            bulk.find(findMap).update({'$set' : updateMap})
560
        bulk.find({'orderId': order['orderId']}).update({'$set':{'closed': closed,"parseError":False}})
561
        result = bulk.execute()
562
        tprint(result)
563
 
13576 amit.gupta 564
 
13569 amit.gupta 565
    def _saveToAffiliate(self, offers):
13576 amit.gupta 566
        collection = self.db.snapdealOrderAffiliateInfo
14443 amit.gupta 567
        mcollection = self.db.merchantOrder
568
        for offer in offers:
569
            offer = self.covertToObj(offer)
570
            collection.update({"adId":offer.adId, "saleAmount":offer.saleAmount, "payOut":offer.payOut},{"$set":todict(offer)}, upsert=True)
14446 amit.gupta 571
            mcollection.update({"subTagId":offer.subTagId, "storeId":self.store_id, "subOrders.missingAff":True}, {"$set":{"subOrders.$.missingAff":False}})
13569 amit.gupta 572
 
573
 
574
    def _getAllOffers(self, br, token):
575
        allOffers = []
576
        nextPage = 1  
577
        while True:
578
            data = getPostData(token, nextPage)
579
            response = br.open(POST_URL, data)
13680 amit.gupta 580
            rmap = json.loads(ungzipResponse(response))
13569 amit.gupta 581
            if rmap is not None:
582
                rmap = rmap['response']
14492 amit.gupta 583
                print rmap
13569 amit.gupta 584
                if rmap is not None and len(rmap['errors'])==0:
585
                    allOffers += rmap['data']['data']
586
            nextPage += 1
587
            if rmap['data']['pageCount']<nextPage:
588
                break
589
 
590
        return allOffers
591
 
592
    def covertToObj(self,offer):
593
        offerData = offer['Stat']
594
        offer1 = AffiliateInfo(offerData['affiliate_info1'], self.store_id, offerData['conversion_status'], offerData['ad_id'], 
14576 amit.gupta 595
                              offerData['datetime'], int(float(offerData['payout'])), offer['Offer']['name'], offerData['ip'], int(float(offerData['conversion_sale_amount'])))
14443 amit.gupta 596
        offer1.saleTime = int(time.mktime(datetime.strptime(offer1.saleDate, "%Y-%m-%d %H:%M:%S").timetuple()))
13569 amit.gupta 597
        return offer1
598
def getPostData(token, page = 1, limit= 20, startDate=None, endDate=None):
13680 amit.gupta 599
    endDate=date.today() + timedelta(days=1)
600
    startDate=endDate - timedelta(days=31)
13569 amit.gupta 601
 
602
    parameters = (
603
        ("page",str(page)),
604
        ("limit",str(limit)),
605
        ("fields[]","Stat.offer_id"),
606
        ("fields[]","Stat.datetime"),
607
        ("fields[]","Offer.name"),
608
        ("fields[]","Stat.conversion_status"),
609
        ("fields[]","Stat.conversion_sale_amount"),
610
        ("fields[]","Stat.payout"),
611
        ("fields[]","Stat.ip"),
612
        ("fields[]","Stat.ad_id"),
613
        ("fields[]","Stat.affiliate_info1"),
614
        ("sort[Stat.datetime]","desc"),
615
        ("filters[Stat.date][conditional]","BETWEEN"),
616
        ("filters[Stat.date][values][]",startDate.strftime('%Y-%m-%d')),
617
        ("filters[Stat.date][values][]",endDate.strftime('%Y-%m-%d')),
618
        ("data_start",startDate.strftime('%Y-%m-%d')),
619
        ("data_end",endDate.strftime('%Y-%m-%d')),
620
        ("Method","getConversions"),
621
        ("NetworkId","jasper"),
622
        ("SessionToken",token),
623
    )
624
    #Encode the parameters
625
    return urllib.urlencode(parameters)
626
 
627
def main():
14458 amit.gupta 628
    #print todict([1,2,"3"])
14402 amit.gupta 629
    store = getStore(3)
15350 amit.gupta 630
    store.parseOrderRawHtml(3322211, "3232311", 2, "32311243", "https://m.snapdeal.com/purchaseMobileComplete?code=926317148e560dbbe07f3326332662ec&order=6139907711")
14883 amit.gupta 631
    #store.scrapeStoreOrders()
13662 amit.gupta 632
    #store._isSubOrderActive(8, "5970688907")
14653 amit.gupta 633
    #store.scrapeAffiliate()
14758 amit.gupta 634
    #store.scrapeStoreOrders()
13569 amit.gupta 635
 
636
 
14459 amit.gupta 637
 
13576 amit.gupta 638
def todict(obj, classkey=None):
639
    if isinstance(obj, dict):
640
        data = {}
641
        for (k, v) in obj.items():
642
            data[k] = todict(v, classkey)
643
        return data
644
    elif hasattr(obj, "_ast"):
645
        return todict(obj._ast())
646
    elif hasattr(obj, "__iter__"):
647
        return [todict(v, classkey) for v in obj]
648
    elif hasattr(obj, "__dict__"):
649
        data = dict([(key, todict(value, classkey)) 
650
            for key, value in obj.__dict__.iteritems() 
651
            if not callable(value) and not key.startswith('_')])
652
        if classkey is not None and hasattr(obj, "__class__"):
653
            data[classkey] = obj.__class__.__name__
654
        return data
655
    else:
656
        return obj
14239 amit.gupta 657
 
658
if __name__ == '__main__':
659
    main()