Subversion Repositories SmartDukaan

Rev

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