Subversion Repositories SmartDukaan

Rev

Rev 18573 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
14811 amit.gupta 1
'''
2
Created on Apr 12, 2015
3
 
4
@author: amit
5
'''
6
from bs4 import BeautifulSoup
16391 amit.gupta 7
from datetime import datetime, timedelta
14811 amit.gupta 8
from dtr import main
16371 amit.gupta 9
from dtr.dao import Order, SubOrder
14811 amit.gupta 10
from dtr.main import getBrowserObject, getStore, ParseException, ungzipResponse, \
16371 amit.gupta 11
    Store as MStore, sourceMap, tprint, todict
16974 amit.gupta 12
from dtr.storage.DataService import paytm_coupon_usages, paytm_coupon_non_usages, \
13
    Feedbacks, Users
18384 amit.gupta 14
from dtr.storage.Mongo import getDealRank
16561 amit.gupta 15
from dtr.utils.utils import fetchResponseUsingProxy, find_between, readSSh
16391 amit.gupta 16
from elixir import *
14811 amit.gupta 17
from pymongo.mongo_client import MongoClient
16371 amit.gupta 18
import json
16391 amit.gupta 19
import os
16371 amit.gupta 20
import traceback
14811 amit.gupta 21
 
16489 amit.gupta 22
ORDER_DETAIL_API_URL = 'https://paytm.com/shop/orderdetail/%s?actions=1&channel=web&version=2'
23
ORDER_DETAIL_URL = "https://paytm.com/myorders/%s"
16974 amit.gupta 24
ORDER_TEMPLATE="Merchant Order Id - %s, Created On - %s"
25
SUBORDER_TEMPLATE="\n\t\t %d %s at rate %d"
14811 amit.gupta 26
class Store(MStore):
27
    OrderStatusMap = {
16382 amit.gupta 28
                      main.Store.ORDER_PLACED : ['in process', 'ready to be shipped', 'order recieved', 'order received', 'pending confirmation', 'waiting for courier pickup'],
16283 amit.gupta 29
                      main.Store.ORDER_DELIVERED : ['delivered'],
16371 amit.gupta 30
                      main.Store.ORDER_SHIPPED : ['in transit', 'shipped'],
16489 amit.gupta 31
                      main.Store.ORDER_CANCELLED : ['failed', 'payment failed', 'cancelled']                      
14811 amit.gupta 32
                      }
16489 amit.gupta 33
 
14811 amit.gupta 34
    def __init__(self,store_id):
35
        client = MongoClient('mongodb://localhost:27017/')
36
        self.db = client.dtr
37
        super(Store, self).__init__(store_id)
38
 
39
    def saveOrder(self, merchantOrder):
40
        MStore.saveOrder(self, merchantOrder)
16371 amit.gupta 41
 
42
    def parseTrackingUrl(self, trackingUrl):
43
        subOrder = {}
44
        page = fetchResponseUsingProxy(trackingUrl)
45
        soup = BeautifulSoup(page)
46
        subOrder['detailedStatus'] = soup.h1.text
47
        subOrder['status'] = self._getStatusFromDetailedStatus(subOrder['detailedStatus'])
14811 amit.gupta 48
 
16371 amit.gupta 49
 
14811 amit.gupta 50
    def scrapeStoreOrders(self):
16473 amit.gupta 51
        pass
14811 amit.gupta 52
 
16371 amit.gupta 53
    def getTrackingUrls(self, userId):
54
        missingOrderUrls = []
55
        #missingOrders = self._getMissingOrders({'userId':userId})
56
        #for missingOrder in missingOrders:
57
        #    missingOrderUrls.append(ORDER_REDIRECT_URL%(missingOrder['merchantOrderId']))
16382 amit.gupta 58
        orders = self._getActiveOrders({'userId':userId, "subOrders.trackingUrl":{"$exists":False} }, {"merchantOrderId":1})
16371 amit.gupta 59
        for order in orders:
16382 amit.gupta 60
            print order
16489 amit.gupta 61
            missingOrderUrls.append({"url":ORDER_DETAIL_API_URL%(order.get("merchantOrderId")), "referer":ORDER_DETAIL_URL%order.get("merchantOrderId")}  )
16382 amit.gupta 62
        return missingOrderUrls
16371 amit.gupta 63
 
64
    def trackOrdersForUser(self, userId, url, rawHtml):
16434 amit.gupta 65
        merchantOrderId = find_between(url, "https://paytm.com/shop/orderdetail/","?actions=1&channel=web&version=2")
16391 amit.gupta 66
        directory = "/PaytmTrack/User" + str(userId)
67
        if not os.path.exists(directory):
68
            os.makedirs(directory)
69
 
16382 amit.gupta 70
        executeBulk = False
16391 amit.gupta 71
        filename = directory + "/" + merchantOrderId + "-" +  datetime.strftime(datetime.now(), '%d-%m:%H:%M:%S')   
72
        f = open(filename,'w')
73
        f.write(rawHtml) # python will convert \n to os.linesep
16421 amit.gupta 74
        f.close() # you can omit in most cases as the destructor will call if
16433 amit.gupta 75
        rawHtml = "".join(["{", find_between(rawHtml,">{", "}</pre>"), "}"])
16440 amit.gupta 76
        merchantOrder = self.db.merchantOrder.find_one({"merchantOrderId":merchantOrderId, "storeId":self.store_id})
16435 amit.gupta 77
        print rawHtml
16421 amit.gupta 78
        if rawHtml == "":
16427 amit.gupta 79
            tprint("Could not update " + str(merchantOrder['orderId']) + " For store " + self.getName())
80
            self.db.merchantOrder.update({"orderId":merchantOrder['orderId']}, {"$set":{"parseError":True}})
16421 amit.gupta 81
            raise    
82
        ordermap = json.loads(rawHtml).get("order")
16388 amit.gupta 83
        try:
84
            bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
85
            closed=True
86
            for item in ordermap.get("items"):
16389 amit.gupta 87
                merchantSubOrderId = str(item.get("id"))
16388 amit.gupta 88
                for subOrder in merchantOrder.get("subOrders"):
89
                    if not subOrder.get("closed"):
16435 amit.gupta 90
                        if merchantSubOrderId == subOrder.get("merchantSubOrderId"):
16388 amit.gupta 91
                            executeBulk = True
92
                            findMap = {"orderId":merchantOrder.get("orderId"), "subOrders.merchantSubOrderId":subOrder.get("merchantSubOrderId")}
93
                            newSub = {}
94
                            detailedStatus = item.get("status_text")
95
                            newSub['detailedStatus'] = detailedStatus
96
                            status  = self._getStatusFromDetailedStatus(detailedStatus)
97
                            newSub['status'] = status if status else subOrder.get("status")  
98
                            updateMap = self.getUpdateMap(newSub, subOrder.get("cashBackStatus"))
99
                            bulk.find(findMap).update({'$set' : updateMap})
100
                            closed = closed and newSub['closed']
101
                            break
102
                        else:
103
                            continue
104
            if executeBulk:
16387 amit.gupta 105
                bulk.find({"orderId":merchantOrder.get("orderId")}).update({"$set":{"closed":closed, "parseError":False}})
106
                bulk.execute()
16388 amit.gupta 107
        except:
16427 amit.gupta 108
            tprint("Could not update " + str(merchantOrder['orderId']) + " For store " + self.getName())
109
            self.db.merchantOrder.update({"orderId":merchantOrder['orderId']}, {"$set":{"parseError":True}})
110
            traceback.print_exc()
111
            raise
16371 amit.gupta 112
 
16283 amit.gupta 113
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
16626 amit.gupta 114
        rawHtml1 = rawHtml
16421 amit.gupta 115
        #Expected is json
16437 amit.gupta 116
        rawHtml = "".join(["{", find_between(rawHtml,">{", "}</pre>"), "}"])
117
        if rawHtml != "": 
16421 amit.gupta 118
            try:
119
                resp = {}
20163 naman 120
                if rawHtml == '{}':
121
#                     print "Rawhtml" , rawHtml
122
                    resp['result'] = 'ORDER_NOT_CREATED_KNOWN'
123
                    return resp
16421 amit.gupta 124
                #orderSuccessUrl = "https://paytm.com/shop/orderdetail/1155961075?actions=1&channel=web&version=2"
125
                ordermap = json.loads(rawHtml).get("order")
126
                if not ordermap.get("need_shipping"):
127
                    resp['result'] = 'RECHARGE_ORDER_IGNORED'
128
                    return resp
129
                elif ordermap.get("payment_status") == "PROCESSING":
130
                    resp['result'] = 'PAYMENT_PENDING_IGNORED'
131
                    return resp
132
                order = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
133
                order.deliveryCharges = ordermap.get("shipping_charges") - ordermap.get("shipping_discount")
134
                order.merchantOrderId = str(ordermap.get("id"))  
135
                order.discountApplied = ordermap.get("discount_amount")
136
                order.paidAmount = ordermap.get("grandtotal")
137
                order.placedOn = datetime.strftime(getISTDate(ordermap.get("created_at")),"%d-%m-%Y %H:%M:%S") 
138
                order.requireDetail = False
139
                order.status = 'success'
16489 amit.gupta 140
                order.orderTrackingUrl = ORDER_DETAIL_URL%(order.merchantOrderId)
16421 amit.gupta 141
                order.totalAmount = ordermap.get("subtotal")
142
                subOrders = []
143
                order.subOrders = subOrders
144
                coupon_code = None
145
                total_cashback = 0
146
                for item in ordermap.get("items"):
147
                    product = item.get("product")
148
                    shareUrl = product.get("seourl").replace("catalog.paytm.com/v1", "paytm.com/shop")
149
                    paytmcashback = 0
150
                    if item.get("promo_code"):
151
                        coupon_code = item.get("promo_code")
152
                        for s in item.get("promo_text").split(): 
153
                            if s.isdigit():
154
                                paytmcashback = int(s)
155
                                total_cashback += paytmcashback
156
                                break
16489 amit.gupta 157
                    amountPaid = item.get("subtotal") 
16421 amit.gupta 158
                    detailedStatus = item.get("status_text")
159
                    status = self._getStatusFromDetailedStatus(detailedStatus)
160
                    if status == None:
161
                        status = MStore.ORDER_PLACED
16447 amit.gupta 162
                    subOrder = SubOrder(item.get("title"), shareUrl, order.placedOn, amountPaid, status, item.get("quantity"))
18384 amit.gupta 163
                    subOrder.productCode = product.get("url").split("?")[0].split("/")[-1]
18573 manas 164
                    dealRank = getDealRank(subOrder.productCode, self.store_id, userId)
18384 amit.gupta 165
                    subOrder.dealRank = dealRank.get('rank')
166
                    subOrder.rankDesc = dealRank.get('description')
167
                    subOrder.maxNlc = dealRank.get('maxNlc')
168
                    subOrder.minNlc = dealRank.get('minNlc')
169
                    subOrder.db = dealRank.get('dp')
170
                    subOrder.itemStatus = dealRank.get('status')
16489 amit.gupta 171
                    subOrder.offerDiscount =  paytmcashback
16421 amit.gupta 172
                    subOrder.imgUrl = product.get("thumbnail")
173
                    subOrder.detailedStatus = detailedStatus
174
                    subOrder.merchantSubOrderId = str(item.get("id"))
175
                    if status == MStore.ORDER_PLACED: 
176
                        if item.get("status_flow")[1].get("date"):
177
                            subOrder.estimatedShippingDate = datetime.strftime(getISTDate(item.get("status_flow")[1].get("date")), "%d %b")
178
                        if item.get("status_flow")[2].get("date"):
179
                            subOrder.estimatedDeliveryDate = datetime.strftime(getISTDate(item.get("status_flow")[2].get("date")), "%d %b")
180
                    else:
181
                        subOrder.closed = False
182
                    subOrders.append(subOrder)
183
                self.populateDerivedFields(order)
184
                if self._saveToOrder(todict(order)):
16974 amit.gupta 185
                    try:
186
                        if coupon_code:
187
                            usage = paytm_coupon_usages()
188
                            usage.cashback = total_cashback
189
                            usage.coupon = coupon_code
190
                            usage.user_id = userId
191
                            usage.order_id = orderId
192
                        else:
193
                            user = session.query(Users).filter_by(id=userId).first()
194
                            ticket = Feedbacks()
195
                            ticket.user_id = userId
196
                            ticket.email = user.email 
197
                            ticket.subject = "User created Order without Applying coupon"
17086 amit.gupta 198
                            ticket.created = datetime.now()
16974 amit.gupta 199
                            s1 =ORDER_TEMPLATE%(order.merchantOrderId, order.createdOn)
200
                            subs = []
201
                            for subOrder in order.subOrders:
202
                                subs.append(SUBORDER_TEMPLATE%(subOrder.quantity, subOrder.productTitle, subOrder.amountPaid))
203
                            subs.insert(0,s1)
204
                            ticket.message = "".join(subs)
205
                            session.commit()
17086 amit.gupta 206
                    except:
207
                        traceback.print_exc()
16974 amit.gupta 208
                    finally:
16926 amit.gupta 209
                        session.close()
16421 amit.gupta 210
                    resp['result'] = 'ORDER_CREATED'
16382 amit.gupta 211
                else:
16421 amit.gupta 212
                    resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
213
            except:
18573 manas 214
                traceback.print_exc()
16421 amit.gupta 215
                resp['result'] = 'ORDER_NOT_CREATED'
216
 
217
        else:
16626 amit.gupta 218
            try:
219
                soup = BeautifulSoup(rawHtml1)
220
                if soup.h2.text == 'Web page not available':
221
                    resp['result'] = 'WEB_PAGE_NOT_AVAILABLE'
222
            except:
223
                resp['result'] = 'ORDER_NOT_CREATED'
16421 amit.gupta 224
        return resp
16382 amit.gupta 225
 
16371 amit.gupta 226
    def _getStatusFromDetailedStatus(self, detailedStatus):
227
        for key, value in Store.OrderStatusMap.iteritems():
228
            if detailedStatus.lower() in value:
229
                return key
16375 amit.gupta 230
        print "Detailed Status-", detailedStatus,  "need to be mapped for Store-", self.store_name
16371 amit.gupta 231
        return None
232
def getISTDate(tzString):
233
    tzDate = datetime.strptime(tzString, "%Y-%m-%dT%H:%M:%S.%fZ") 
234
    tzDate = tzDate + timedelta(0,19800)
235
    return tzDate
236
 
14811 amit.gupta 237
def main():
238
    store = getStore(6)
20163 naman 239
    print store.parseOrderRawHtml(140284, '796881_SHA61467477927', 26050, readSSh("/home/manish/paytm.html"), 'https://paytm.com/shop/summary/1857113078')
16283 amit.gupta 240
    #store.scrapeStoreOrders()
17086 amit.gupta 241
    #store.trackOrdersForUser(2, "https://paytm.com/shop/orderdetail/1168545614?actions=1&channel=web&version=2", readSSh("/home/amit/p.html"))
16383 amit.gupta 242
    #print store.getTrackingUrls(14)
14811 amit.gupta 243
 
244
if __name__ == '__main__':
245
    main()