Subversion Repositories SmartDukaan

Rev

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