Subversion Repositories SmartDukaan

Rev

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

'''
Created on Apr 12, 2015

@author: amit
'''
from bs4 import BeautifulSoup
from datetime import datetime, timedelta
from dtr import main
from dtr.dao import Order, SubOrder
from dtr.main import getBrowserObject, getStore, ParseException, ungzipResponse, \
    Store as MStore, sourceMap, tprint, todict
from dtr.storage.DataService import paytm_coupon_usages, paytm_coupon_non_usages, \
    Feedbacks, Users
from dtr.storage.Mongo import getDealRank
from dtr.utils.utils import fetchResponseUsingProxy, find_between, readSSh
from elixir import *
from pymongo.mongo_client import MongoClient
import json
import os
import traceback

ORDER_DETAIL_API_URL = 'https://paytm.com/shop/orderdetail/%s?actions=1&channel=web&version=2'
ORDER_DETAIL_URL = "https://paytm.com/myorders/%s"
ORDER_TEMPLATE="Merchant Order Id - %s, Created On - %s"
SUBORDER_TEMPLATE="\n\t\t %d %s at rate %d"
class Store(MStore):
    OrderStatusMap = {
                      main.Store.ORDER_PLACED : ['in process', 'ready to be shipped', 'order recieved', 'order received', 'pending confirmation', 'waiting for courier pickup'],
                      main.Store.ORDER_DELIVERED : ['delivered'],
                      main.Store.ORDER_SHIPPED : ['in transit', 'shipped'],
                      main.Store.ORDER_CANCELLED : ['failed', 'payment failed', 'cancelled']                      
                      }
    
    def __init__(self,store_id):
        client = MongoClient('mongodb://localhost:27017/')
        self.db = client.dtr
        super(Store, self).__init__(store_id)

    def saveOrder(self, merchantOrder):
        MStore.saveOrder(self, merchantOrder)
    
    def parseTrackingUrl(self, trackingUrl):
        subOrder = {}
        page = fetchResponseUsingProxy(trackingUrl)
        soup = BeautifulSoup(page)
        subOrder['detailedStatus'] = soup.h1.text
        subOrder['status'] = self._getStatusFromDetailedStatus(subOrder['detailedStatus'])
        
        
    def scrapeStoreOrders(self):
        pass
        
    def getTrackingUrls(self, userId):
        missingOrderUrls = []
        #missingOrders = self._getMissingOrders({'userId':userId})
        #for missingOrder in missingOrders:
        #    missingOrderUrls.append(ORDER_REDIRECT_URL%(missingOrder['merchantOrderId']))
        orders = self._getActiveOrders({'userId':userId, "subOrders.trackingUrl":{"$exists":False} }, {"merchantOrderId":1})
        for order in orders:
            print order
            missingOrderUrls.append({"url":ORDER_DETAIL_API_URL%(order.get("merchantOrderId")), "referer":ORDER_DETAIL_URL%order.get("merchantOrderId")}  )
        return missingOrderUrls

    def trackOrdersForUser(self, userId, url, rawHtml):
        merchantOrderId = find_between(url, "https://paytm.com/shop/orderdetail/","?actions=1&channel=web&version=2")
        directory = "/PaytmTrack/User" + str(userId)
        if not os.path.exists(directory):
            os.makedirs(directory)
            
        executeBulk = False
        filename = directory + "/" + merchantOrderId + "-" +  datetime.strftime(datetime.now(), '%d-%m:%H:%M:%S')   
        f = open(filename,'w')
        f.write(rawHtml) # python will convert \n to os.linesep
        f.close() # you can omit in most cases as the destructor will call if
        rawHtml = "".join(["{", find_between(rawHtml,">{", "}</pre>"), "}"])
        merchantOrder = self.db.merchantOrder.find_one({"merchantOrderId":merchantOrderId, "storeId":self.store_id})
        print rawHtml
        if rawHtml == "":
            tprint("Could not update " + str(merchantOrder['orderId']) + " For store " + self.getName())
            self.db.merchantOrder.update({"orderId":merchantOrder['orderId']}, {"$set":{"parseError":True}})
            raise    
        ordermap = json.loads(rawHtml).get("order")
        try:
            bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
            closed=True
            for item in ordermap.get("items"):
                merchantSubOrderId = str(item.get("id"))
                for subOrder in merchantOrder.get("subOrders"):
                    if not subOrder.get("closed"):
                        if merchantSubOrderId == subOrder.get("merchantSubOrderId"):
                            executeBulk = True
                            findMap = {"orderId":merchantOrder.get("orderId"), "subOrders.merchantSubOrderId":subOrder.get("merchantSubOrderId")}
                            newSub = {}
                            detailedStatus = item.get("status_text")
                            newSub['detailedStatus'] = detailedStatus
                            status  = self._getStatusFromDetailedStatus(detailedStatus)
                            newSub['status'] = status if status else subOrder.get("status")  
                            updateMap = self.getUpdateMap(newSub, subOrder.get("cashBackStatus"))
                            bulk.find(findMap).update({'$set' : updateMap})
                            closed = closed and newSub['closed']
                            break
                        else:
                            continue
            if executeBulk:
                bulk.find({"orderId":merchantOrder.get("orderId")}).update({"$set":{"closed":closed, "parseError":False}})
                bulk.execute()
        except:
            tprint("Could not update " + str(merchantOrder['orderId']) + " For store " + self.getName())
            self.db.merchantOrder.update({"orderId":merchantOrder['orderId']}, {"$set":{"parseError":True}})
            traceback.print_exc()
            raise
        
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
        rawHtml1 = rawHtml
        #Expected is json
        rawHtml = "".join(["{", find_between(rawHtml,">{", "}</pre>"), "}"])
        if rawHtml != "": 
            try:
                resp = {}
                if rawHtml == '{}':
#                     print "Rawhtml" , rawHtml
                    resp['result'] = 'ORDER_NOT_CREATED_KNOWN'
                    return resp
                #orderSuccessUrl = "https://paytm.com/shop/orderdetail/1155961075?actions=1&channel=web&version=2"
                ordermap = json.loads(rawHtml).get("order")
                if not ordermap.get("need_shipping"):
                    resp['result'] = 'RECHARGE_ORDER_IGNORED'
                    return resp
                elif ordermap.get("payment_status") == "PROCESSING":
                    resp['result'] = 'PAYMENT_PENDING_IGNORED'
                    return resp
                order = Order(orderId, userId, subTagId, self.store_id, orderSuccessUrl)
                order.deliveryCharges = ordermap.get("shipping_charges") - ordermap.get("shipping_discount")
                order.merchantOrderId = str(ordermap.get("id"))  
                order.discountApplied = ordermap.get("discount_amount")
                order.paidAmount = ordermap.get("grandtotal")
                order.placedOn = datetime.strftime(getISTDate(ordermap.get("created_at")),"%d-%m-%Y %H:%M:%S") 
                order.requireDetail = False
                order.status = 'success'
                order.orderTrackingUrl = ORDER_DETAIL_URL%(order.merchantOrderId)
                order.totalAmount = ordermap.get("subtotal")
                subOrders = []
                order.subOrders = subOrders
                coupon_code = None
                total_cashback = 0
                for item in ordermap.get("items"):
                    product = item.get("product")
                    shareUrl = product.get("seourl").replace("catalog.paytm.com/v1", "paytm.com/shop")
                    paytmcashback = 0
                    if item.get("promo_code"):
                        coupon_code = item.get("promo_code")
                        for s in item.get("promo_text").split(): 
                            if s.isdigit():
                                paytmcashback = int(s)
                                total_cashback += paytmcashback
                                break
                    amountPaid = item.get("subtotal") 
                    detailedStatus = item.get("status_text")
                    status = self._getStatusFromDetailedStatus(detailedStatus)
                    if status == None:
                        status = MStore.ORDER_PLACED
                    subOrder = SubOrder(item.get("title"), shareUrl, order.placedOn, amountPaid, status, item.get("quantity"))
                    subOrder.productCode = product.get("url").split("?")[0].split("/")[-1]
                    dealRank = getDealRank(subOrder.productCode, self.store_id, userId)
                    subOrder.dealRank = dealRank.get('rank')
                    subOrder.rankDesc = dealRank.get('description')
                    subOrder.maxNlc = dealRank.get('maxNlc')
                    subOrder.minNlc = dealRank.get('minNlc')
                    subOrder.db = dealRank.get('dp')
                    subOrder.itemStatus = dealRank.get('status')
                    subOrder.offerDiscount =  paytmcashback
                    subOrder.imgUrl = product.get("thumbnail")
                    subOrder.detailedStatus = detailedStatus
                    subOrder.merchantSubOrderId = str(item.get("id"))
                    if status == MStore.ORDER_PLACED: 
                        if item.get("status_flow")[1].get("date"):
                            subOrder.estimatedShippingDate = datetime.strftime(getISTDate(item.get("status_flow")[1].get("date")), "%d %b")
                        if item.get("status_flow")[2].get("date"):
                            subOrder.estimatedDeliveryDate = datetime.strftime(getISTDate(item.get("status_flow")[2].get("date")), "%d %b")
                    else:
                        subOrder.closed = False
                    subOrders.append(subOrder)
                self.populateDerivedFields(order)
                if self._saveToOrder(todict(order)):
                    try:
                        if coupon_code:
                            usage = paytm_coupon_usages()
                            usage.cashback = total_cashback
                            usage.coupon = coupon_code
                            usage.user_id = userId
                            usage.order_id = orderId
                        else:
                            user = session.query(Users).filter_by(id=userId).first()
                            ticket = Feedbacks()
                            ticket.user_id = userId
                            ticket.email = user.email 
                            ticket.subject = "User created Order without Applying coupon"
                            ticket.created = datetime.now()
                            s1 =ORDER_TEMPLATE%(order.merchantOrderId, order.createdOn)
                            subs = []
                            for subOrder in order.subOrders:
                                subs.append(SUBORDER_TEMPLATE%(subOrder.quantity, subOrder.productTitle, subOrder.amountPaid))
                            subs.insert(0,s1)
                            ticket.message = "".join(subs)
                            session.commit()
                    except:
                        traceback.print_exc()
                    finally:
                        session.close()
                    resp['result'] = 'ORDER_CREATED'
                else:
                    resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
            except:
                traceback.print_exc()
                resp['result'] = 'ORDER_NOT_CREATED'
                
        else:
            try:
                soup = BeautifulSoup(rawHtml1)
                if soup.h2.text == 'Web page not available':
                    resp['result'] = 'WEB_PAGE_NOT_AVAILABLE'
            except:
                resp['result'] = 'ORDER_NOT_CREATED'
        return resp
            
    def _getStatusFromDetailedStatus(self, detailedStatus):
        for key, value in Store.OrderStatusMap.iteritems():
            if detailedStatus.lower() in value:
                return key
        print "Detailed Status-", detailedStatus,  "need to be mapped for Store-", self.store_name
        return None
def getISTDate(tzString):
    tzDate = datetime.strptime(tzString, "%Y-%m-%dT%H:%M:%S.%fZ") 
    tzDate = tzDate + timedelta(0,19800)
    return tzDate

def main():
    store = getStore(6)
    print store.parseOrderRawHtml(140284, '796881_SHA61467477927', 26050, readSSh("/home/manish/paytm.html"), 'https://paytm.com/shop/summary/1857113078')
    #store.scrapeStoreOrders()
    #store.trackOrdersForUser(2, "https://paytm.com/shop/orderdetail/1168545614?actions=1&channel=web&version=2", readSSh("/home/amit/p.html"))
    #print store.getTrackingUrls(14)
    
if __name__ == '__main__':
    main()