Subversion Repositories SmartDukaan

Rev

Rev 16378 | Rev 16383 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

'''
Created on Apr 12, 2015

@author: amit
'''
from bs4 import BeautifulSoup
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.sources.amazon import readSSh
from dtr.utils.utils import fetchResponseUsingProxy
from pymongo.mongo_client import MongoClient
from datetime import datetime, timedelta
import json
import traceback
from elixir import *

from dtr.storage.DataService import paytm_coupon_usages

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']
                      
                      }
    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):
        orders = self.db.merchantOrder.find({"storeId":1, "closed":False, "subOrders":{"$elemMatch":{"closed":False, "trackingUrl":{"$exists":True}}}})
        for merchantOrder in orders:
            executeBulk = False
            try:
                bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
                closed = True
                map1 = {}
                for subOrder in merchantOrder.get("subOrders"):
                    if subOrder.get("closed"):
                        continue
                    elif subOrder.get("trackingUrl") is None:
                        closed = False
                        continue
                    executeBulk = True
                    findMap = {"orderId":merchantOrder.get("orderId"), "subOrders.merchantSubOrderId":subOrder.get("merchantSubOrderId")} 
                    trackingUrl = subOrder.get("trackingUrl")
                    if not map1.has_key(trackingUrl):
                        map1[trackingUrl] = self.parseTrackingUrl(trackingUrl)
                    newOrder = map1.get(trackingUrl)
                    updateMap = self.getUpdateMap(newOrder, subOrder.get('cashBackStatus'))
                    print findMap, "\n", updateMap
                    bulk.find(findMap).update({'$set' : updateMap})
                    closed = closed and newOrder['closed']
                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()
        
    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("https://paytm.com/shop/orderdetail/%s?actions=1&channel=web&version=2"%(order.get("merchantOrderId")))
        return missingOrderUrls

    def trackOrdersForUser(self, userId, url, rawHtml):
        executeBulk = False
        ordermap = json.loads(rawHtml).get("order")
        merchantOrderId = str(ordermap.get("id"))
        merchantOrder = self.db.merchantOrder.findOne({"merchantOrderId":merchantOrderId})
        bulk = self.db.merchantOrder.initialize_ordered_bulk_op()
        closed=True
        for item in ordermap.get("items"):
            merchantSubOrderId = item.get("id")
            for subOrder in merchantOrder.get("subOrders"):
                if not subOrder.get("closed"):
                    if merchantSubOrderId == subOrder.get("merchantSubOrderId") and item.get("status_text") != subOrder.get("detailedStatus"):
                        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
                    
        
    def parseOrderRawHtml(self, orderId, subTagId, userId, rawHtml, orderSuccessUrl):
        try:
            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 = ordermap.get("date") + " "+ ordermap.get("time") 
            order.requireDetail = False
            order.status = 'success'
            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") - paytmcashback 
                detailedStatus = item.get("status_text")
                status = self._getStatusFromDetailedStatus(detailedStatus)
                if status == None:
                    status = MStore.ORDER_PLACED
                subOrder = SubOrder(item.get("title"), item.get("product").get(""), ordermap.get("date"), amountPaid, status, item.get("quantity"))
                subOrder.imgUrl = product.get("thumbnail")
                subOrder.detailedStatus = detailedStatus
                subOrder.productUrl = shareUrl
                subOrder.productCode = product.get("url").split("?")[0].split("/")[-1]
                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)
            if coupon_code:
                usage = paytm_coupon_usages()
                usage.cashback = total_cashback
                usage.coupon = coupon_code
                usage.user_id = userId
                usage.order_id = orderId
                session.commit()
            self.populateDerivedFields(order)
            if self._saveToOrder(todict(order)):
                resp['result'] = 'ORDER_CREATED'
            else:
                resp['result'] = 'ORDER_ALREADY_CREATED_IGNORED'
        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)
    #store.scrapeStoreOrders()
    #store.parseOrderRawHtml(312119, 'SUB1', 14, readSSh("/home/amit/paytm.json"), "someurl")
    print store.getTrackingUrls(14)
    
if __name__ == '__main__':
    main()