Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
14220 amit.gupta 1
'''
2
Created on Jan 15, 2015
3
 
4
@author: amit
5
'''
6
from BeautifulSoup import BeautifulSoup
7
from bson.binary import Binary
8
from datetime import datetime, date, timedelta
9
from dtr import main
10
from dtr.config import PythonPropertyReader
11
from dtr.dao import AffiliateInfo, Order, SubOrder
12
from dtr.main import getBrowserObject, ScrapeException, getStore, ParseException, \
13
    Store as MStore, ungzipResponse, tprint
14
from pprint import pprint
15
from pymongo import MongoClient
16
import json
17
import pymongo
18
import re
19
import traceback
20
import urllib
21
import urllib2
22
 
14222 amit.gupta 23
ORDERSTATUS  = {"PAYMENT_PENDING" : 0,
24
"PAYMENT_FAILED" : 1,
25
"COD_VERIFICATION_PENDING" : 2,
26
"SUBMITTED_FOR_PROCESSING" : 3,
27
"ACCEPTED" : 4,
28
"INVENTORY_LOW" : 5,
29
"REJECTED" : 6,
30
"BILLED" : 7,
31
"PAYMENT_FLAGGED" : 8,
32
"SHIPPED_FROM_WH" : 9,
33
"SHIPPED_TO_LOGST" : 10,
34
"PAYMENT_FLAGGED_DENIED" : 11,
35
"DELIVERY_SUCCESS" : 12,
36
"CANCEL_REQUEST_RECEIVED" : 13,
37
"CANCEL_REQUEST_CONFIRMED" : 14,
38
"CANCELLED_ON_CUSTOMER_REQUEST" : 15,
39
"SHIPPED_TO_DESTINATION_CITY" : 16,
40
"REACHED_DESTINATION_CITY" : 17,
41
"COD_VERIFICATION_FAILED" : 18,
42
"FAILED" : 19,
43
"RTO_IN_TRANSIT" : 20,
44
"RTO_RECEIVED_PRESTINE" : 21,
45
"DOA_PICKUP_REQUEST_RAISED" : 22,
46
"DOA_PICKUP_CONFIRMED" : 23,
47
"DOA_RETURN_IN_TRANSIT" : 24,
48
"DOA_RECEIVED_PRESTINE" : 25,
49
"DOA_CERT_INVALID" : 26,
50
"DOA_CERT_VALID" : 27,
51
"RTO_RESHIPPED" : 28,
52
"DOA_INVALID_RESHIPPED" : 29,
53
"DOA_VALID_RESHIPPED" : 30,
54
"RTO_REFUNDED" : 31,
55
"DOA_VALID_REFUNDED" : 32,
56
"DOA_INVALID_REFUNDED" : 33,
57
"CANCELLED_DUE_TO_LOW_INVENTORY" : 34,
58
"LOW_INV_PO_RAISED" : 35,
59
"LOW_INV_REVERSAL_IN_PROCESS" : 36,
60
"LOW_INV_NOT_AVAILABLE_AT_HOTSPOT" : 37,
61
"LOW_INV_PO_RAISED_TIMEOUT" : 38,
62
"LOW_INV_REVERSAL_TIMEOUT" : 39,
63
"FIRST_DELIVERY_ATTEMPT_MADE" : 40,
64
"CAPTURE_IN_PROCESS" : 41,
65
"DOA_REQUEST_RECEIVED" : 42,
66
"DOA_REQUEST_AUTHORIZED" : 43,
67
"DOA_PICKUP_DENIED" : 44,
68
"DOA_RECEIVED_DAMAGED" : 45,
69
"DOA_LOST_IN_TRANSIT" : 46,
70
"DOA_RESHIPPED_RCVD_DAMAGED" : 47,
71
"DOA_REFUNDED_RCVD_DAMAGED" : 48,
72
"DOA_RESHIPPED_LOST_IN_TRANSIT" : 49,
73
"DOA_REFUNDED_LOST_IN_TRANSIT" : 50,
74
"RTO_RECEIVED_DAMAGED" : 51,
75
"RTO_LOST_IN_TRANSIT" : 52,
76
"RTO_DAMAGED_RESHIPPED" : 53,
77
"RTO_DAMAGED_REFUNDED" : 54,
78
"RTO_LOST_IN_TRANSIT_RESHIPPED" : 55,
79
"RTO_LOST_IN_TRANSIT_REFUNDED" : 56,
80
"RTO_INVENTORY_REVERSED" : 57,
81
"RET_REQUEST_RECEIVED" : 58,
82
"RET_REQUEST_AUTHORIZED" : 59,
83
"RET_PICKUP_REQUEST_RAISED" : 60,
84
"RET_PICKUP_DENIED" : 61,
85
"RET_PICKUP_CONFIRMED" : 62,
86
"RET_RETURN_IN_TRANSIT" : 63,
87
"RET_RECEIVED_PRESTINE" : 64,
88
"RET_RECEIVED_DAMAGED" : 65,
89
"RET_LOST_IN_TRANSIT" : 66,
90
"RET_PRODUCT_USABLE" : 67,
91
"RET_PRODUCT_UNUSABLE" : 68,
92
"RET_PRODUCT_USABLE_RESHIPPED" : 69,
93
"RET_PRODUCT_USABLE_REFUNDED" : 70,
94
"RET_PRODUCT_UNUSABLE_RESHIPPED" : 71,
95
"RET_PRODUCT_UNUSABLE_REFUNDED" : 72,
96
"RET_RESHIPPED_RCVD_DAMAGED" : 73,
97
"RET_REFUNDED_RCVD_DAMAGED" : 74,
98
"RET_RESHIPPED_LOST_IN_TRANSIT" : 75,
99
"RET_REFUNDED_LOST_IN_TRANSIT" : 76,
100
"LOST_IN_TRANSIT" : 77,
101
"LOST_IN_TRANSIT_RESHIPPED" : 78,
102
"LOST_IN_TRANSIT_REFUNDED" : 79,
103
"DELIVERED_AT_STORE" : 80,
104
"RECEIVED_AT_STORE" : 81}
14220 amit.gupta 105
headers = { 
106
           'User-agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
107
            'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',      
108
            'Accept-Language' : 'en-US,en;q=0.8',                     
109
            'Accept-Charset' : 'ISO-8859-1,utf-8;q=0.7,*;q=0.3'
110
        }
111
SAHOLIC_ORDER_URL=PythonPropertyReader.getConfig('SAHOLIC_ORDER_URL')
112
class Store(MStore):
113
    '''
114
    This is to map order statuses of our system to order statuses of snapdeal.
115
    And our statuses will change accordingly.
116
 
117
    '''
118
    OrderStatusMap = {
119
                      MStore.ORDER_PLACED : [2,3,4,5,6,7,8,13],
120
                      MStore.ORDER_DELIVERED : [12],
121
                      MStore.ORDER_SHIPPED : [9,10,16,17,20,21,81,80],
122
                      MStore.ORDER_CANCELLED : [6,11,14,15,18,19,31,28,53,54,55,56]
123
                      }
124
 
125
 
126
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
14227 amit.gupta 127
        resp = {}
14220 amit.gupta 128
        paymentId = int(re.findall(r'=(.*)?','http://www.saholic.com/pay-success?paymentId=1528903')[0])
129
        orderRequest = urllib2.Request(SAHOLIC_ORDER_URL %(paymentId), headers=headers)
130
        try:
131
            response = urllib2.urlopen(orderRequest).read()
132
            response = json.loads(response)['response']
133
            payment = response['payment']
134
            orders = response['orders']
14228 amit.gupta 135
            items = response['itemsMap']
14220 amit.gupta 136
            orders[0]
137
            merchantOrder = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
138
            merchantOrder.merchantOrderId = payment['merchantTxnId']
139
            merchantOrder.createdOn = datetime.strftime(datetime.fromtimestamp(orders[0]['created_timestamp']/1000),"%d %B %Y")
140
            merchantOrder.paidAmount = payment['amount']
141
 
142
            subOrders = []
143
            for o in orders:
144
                lineitem = o['lineitems'][0]
145
 
14234 amit.gupta 146
                item = items[str(lineitem['item_id'])]
14220 amit.gupta 147
                brand = lineitem.get('brand')
148
                modelNumber = lineitem.get('model_number')
149
                modelName = lineitem.get('model_name')
150
                color = lineitem.get('color')
151
                productTitle = brand + (" " + modelName if modelName else "") + (" "  + modelNumber if modelNumber is not None else "") + ("(" + color +")" if color else "")
14236 amit.gupta 152
                amountPaid = o['total_amount']- o['gvAmount']
153
                subOrder = SubOrder(productTitle, None, merchantOrder.createdOn, amountPaid)
14220 amit.gupta 154
 
155
                subOrder.merchantSubOrderId = o['id']
156
                subOrder.estimatedDeliveryDate = datetime.strftime(datetime.fromtimestamp(o['promised_delivery_time']/1000),"%d %B %Y")
157
                subOrder.imgUrl = item['imgUrl'] 
14221 amit.gupta 158
                subOrder.productUrl = "http://m.saholic.com/" + item['url']
14222 amit.gupta 159
                subOrder.detailedStatus = o['statusDescription']
14236 amit.gupta 160
                (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amountPaid)
161
                cashbackStatus = Store.CB_PENDING
162
                if cashbackAmount <= 0:
163
                    cashbackStatus = Store.CB_NA
164
                subOrder.cashBackStatus = cashbackStatus
165
                subOrder.cashBackAmount = cashbackAmount
166
                if percentage > 0:
167
                    subOrder.cashBackPercentage = percentage
14220 amit.gupta 168
                subOrders.append(subOrder)
169
 
170
            merchantOrder.subOrders = subOrders
14235 amit.gupta 171
            self._saveToOrder(todict(merchantOrder))
14227 amit.gupta 172
            resp['result'] = 'ORDER_CREATED'
14220 amit.gupta 173
        except:
174
            tprint("Could not fetch saholic id for user : " + str(userId))
14227 amit.gupta 175
            traceback.print_exc()
176
            resp['result'] = 'PARSE_ERROR'
177
        return resp
14220 amit.gupta 178
 
179
    def _getStatusFromDetailedStatus(self, detailedStatus):
180
        for key, value in Store.OrderStatusMap.iteritems():
181
            if detailedStatus in value:
182
                return key
183
            print "Detailed Status need to be mapped"
184
        raise ParseException("_getStatusFromDetailedStatus", "Found new order status" + detailedStatus)
185
 
186
 
187
    def scrapeStoreOrders(self,):
188
        pass
189
 
190
    def _saveToAffiliate(self, offers):
191
        if offers is None or len(offers)==0:
192
            print "no affiliate have been pushed"
193
            return
194
        collection = self.db.snapdealOrderAffiliateInfo
195
        try:
196
            collection.insert(offers,continue_on_error=True)
197
        except pymongo.errors.DuplicateKeyError as e:
198
            print e.details
199
 
200
 
201
    def covertToObj(self,offer):
202
        offerData = offer['Stat']
203
        offer1 = AffiliateInfo(offerData['affiliate_info1'], self.store_id, offerData['conversion_status'], offerData['ad_id'], 
204
                              offerData['datetime'], offerData['payout'], offer['Offer']['name'], offerData['ip'], offerData['conversion_sale_amount'])
205
 
206
        return offer1
207
def getPostData(token, page = 1, limit= 20, startDate=None, endDate=None):
208
    endDate=date.today() + timedelta(days=1)
209
    startDate=endDate - timedelta(days=31)
210
 
211
    parameters = (
212
        ("page",str(page)),
213
        ("limit",str(limit)),
214
        ("fields[]","Stat.offer_id"),
215
        ("fields[]","Stat.datetime"),
216
        ("fields[]","Offer.name"),
217
        ("fields[]","Stat.conversion_status"),
218
        ("fields[]","Stat.conversion_sale_amount"),
219
        ("fields[]","Stat.payout"),
220
        ("fields[]","Stat.ip"),
221
        ("fields[]","Stat.ad_id"),
222
        ("fields[]","Stat.affiliate_info1"),
223
        ("sort[Stat.datetime]","desc"),
224
        ("filters[Stat.date][conditional]","BETWEEN"),
225
        ("filters[Stat.date][values][]",startDate.strftime('%Y-%m-%d')),
226
        ("filters[Stat.date][values][]",endDate.strftime('%Y-%m-%d')),
227
        ("data_start",startDate.strftime('%Y-%m-%d')),
228
        ("data_end",endDate.strftime('%Y-%m-%d')),
229
        ("Method","getConversions"),
230
        ("NetworkId","jasper"),
231
        ("SessionToken",token),
232
    )
233
    #Encode the parameters
234
    return urllib.urlencode(parameters)
235
 
236
def main():
237
 
238
    store = getStore(3)
239
    #store.scrapeStoreOrders()
240
    #store._isSubOrderActive(8, "5970688907")
241
    #store.scrapeAffiliate()
242
    store.parseOrderRawHtml(12345, "subtagId", 122323,  "html", 'http://www.saholic.com/pay-success?paymentId=1528903')
243
 
244
 
245
if __name__ == '__main__':
246
    main()
247
 
248
def todict(obj, classkey=None):
249
    if isinstance(obj, dict):
250
        data = {}
251
        for (k, v) in obj.items():
252
            data[k] = todict(v, classkey)
253
        return data
254
    elif hasattr(obj, "_ast"):
255
        return todict(obj._ast())
256
    elif hasattr(obj, "__iter__"):
257
        return [todict(v, classkey) for v in obj]
258
    elif hasattr(obj, "__dict__"):
259
        data = dict([(key, todict(value, classkey)) 
260
            for key, value in obj.__dict__.iteritems() 
261
            if not callable(value) and not key.startswith('_')])
262
        if classkey is not None and hasattr(obj, "__class__"):
263
            data[classkey] = obj.__class__.__name__
264
        return data
265
    else:
266
        return obj