Subversion Repositories SmartDukaan

Rev

Rev 14236 | Rev 14246 | 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 = {}
14237 amit.gupta 128
        paymentId = int(re.findall(r'=(.*)?',orderSuccessUrl)[0])
14220 amit.gupta 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)
14237 amit.gupta 154
                subOrder.merchantSubOrderId = str(o['id'])
155
                subOrder.orderDetailUrl = "http://m.saholic.com/order/" + subOrder.merchantSubOrderId 
14220 amit.gupta 156
 
157
                subOrder.estimatedDeliveryDate = datetime.strftime(datetime.fromtimestamp(o['promised_delivery_time']/1000),"%d %B %Y")
158
                subOrder.imgUrl = item['imgUrl'] 
14221 amit.gupta 159
                subOrder.productUrl = "http://m.saholic.com/" + item['url']
14222 amit.gupta 160
                subOrder.detailedStatus = o['statusDescription']
14236 amit.gupta 161
                (cashbackAmount, percentage) = self.getCashbackAmount(subOrder.productCode, amountPaid)
162
                cashbackStatus = Store.CB_PENDING
163
                if cashbackAmount <= 0:
164
                    cashbackStatus = Store.CB_NA
165
                subOrder.cashBackStatus = cashbackStatus
166
                subOrder.cashBackAmount = cashbackAmount
167
                if percentage > 0:
168
                    subOrder.cashBackPercentage = percentage
14220 amit.gupta 169
                subOrders.append(subOrder)
170
 
171
            merchantOrder.subOrders = subOrders
14235 amit.gupta 172
            self._saveToOrder(todict(merchantOrder))
14227 amit.gupta 173
            resp['result'] = 'ORDER_CREATED'
14220 amit.gupta 174
        except:
175
            tprint("Could not fetch saholic id for user : " + str(userId))
14227 amit.gupta 176
            traceback.print_exc()
177
            resp['result'] = 'PARSE_ERROR'
178
        return resp
14220 amit.gupta 179
 
180
    def _getStatusFromDetailedStatus(self, detailedStatus):
181
        for key, value in Store.OrderStatusMap.iteritems():
182
            if detailedStatus in value:
183
                return key
184
            print "Detailed Status need to be mapped"
185
        raise ParseException("_getStatusFromDetailedStatus", "Found new order status" + detailedStatus)
186
 
187
 
188
    def scrapeStoreOrders(self,):
189
        pass
190
 
191
    def _saveToAffiliate(self, offers):
192
        if offers is None or len(offers)==0:
193
            print "no affiliate have been pushed"
194
            return
195
        collection = self.db.snapdealOrderAffiliateInfo
196
        try:
197
            collection.insert(offers,continue_on_error=True)
198
        except pymongo.errors.DuplicateKeyError as e:
199
            print e.details
200
 
201
 
202
    def covertToObj(self,offer):
203
        offerData = offer['Stat']
204
        offer1 = AffiliateInfo(offerData['affiliate_info1'], self.store_id, offerData['conversion_status'], offerData['ad_id'], 
205
                              offerData['datetime'], offerData['payout'], offer['Offer']['name'], offerData['ip'], offerData['conversion_sale_amount'])
206
 
207
        return offer1
208
def getPostData(token, page = 1, limit= 20, startDate=None, endDate=None):
209
    endDate=date.today() + timedelta(days=1)
210
    startDate=endDate - timedelta(days=31)
211
 
212
    parameters = (
213
        ("page",str(page)),
214
        ("limit",str(limit)),
215
        ("fields[]","Stat.offer_id"),
216
        ("fields[]","Stat.datetime"),
217
        ("fields[]","Offer.name"),
218
        ("fields[]","Stat.conversion_status"),
219
        ("fields[]","Stat.conversion_sale_amount"),
220
        ("fields[]","Stat.payout"),
221
        ("fields[]","Stat.ip"),
222
        ("fields[]","Stat.ad_id"),
223
        ("fields[]","Stat.affiliate_info1"),
224
        ("sort[Stat.datetime]","desc"),
225
        ("filters[Stat.date][conditional]","BETWEEN"),
226
        ("filters[Stat.date][values][]",startDate.strftime('%Y-%m-%d')),
227
        ("filters[Stat.date][values][]",endDate.strftime('%Y-%m-%d')),
228
        ("data_start",startDate.strftime('%Y-%m-%d')),
229
        ("data_end",endDate.strftime('%Y-%m-%d')),
230
        ("Method","getConversions"),
231
        ("NetworkId","jasper"),
232
        ("SessionToken",token),
233
    )
234
    #Encode the parameters
235
    return urllib.urlencode(parameters)
236
 
237
def main():
238
 
239
    store = getStore(3)
240
    #store.scrapeStoreOrders()
241
    #store._isSubOrderActive(8, "5970688907")
242
    #store.scrapeAffiliate()
243
    store.parseOrderRawHtml(12345, "subtagId", 122323,  "html", 'http://www.saholic.com/pay-success?paymentId=1528903')
244
 
245
 
246
if __name__ == '__main__':
247
    main()
248
 
249
def todict(obj, classkey=None):
250
    if isinstance(obj, dict):
251
        data = {}
252
        for (k, v) in obj.items():
253
            data[k] = todict(v, classkey)
254
        return data
255
    elif hasattr(obj, "_ast"):
256
        return todict(obj._ast())
257
    elif hasattr(obj, "__iter__"):
258
        return [todict(v, classkey) for v in obj]
259
    elif hasattr(obj, "__dict__"):
260
        data = dict([(key, todict(value, classkey)) 
261
            for key, value in obj.__dict__.iteritems() 
262
            if not callable(value) and not key.startswith('_')])
263
        if classkey is not None and hasattr(obj, "__class__"):
264
            data[classkey] = obj.__class__.__name__
265
        return data
266
    else:
267
        return obj