| 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()
|