Subversion Repositories SmartDukaan

Rev

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

from suds.client import Client
from shop2020.clients.TransactionClient import TransactionClient
from datetime import datetime, time, timedelta
import traceback
import re

raclient = None
user_profile = None
shipperMap = {}

DEBUG=True

acc_url="http://netconnect.bluedart.com/Ver1.7/ShippingAPI/WayBill/WayBillGeneration.svc?wsdl"
LOGIN_ID ="FA316326"
LICENCE_KEY="131f6cfe91591bcc9de7032bb1ed6d13"
API_VERSION="1.3"
API_TYPE="S"
AREA="ALL"

xstr = lambda s: s or ""

class __BluedartAWBResponse:
    def __init__(self, awbNo, destArea, destLocation):
        self.awbNo = awbNo
        self.destArea = destArea
        self.destLocation = destLocation

def get_client():
    global raclient
    if raclient is None:
        raclient = Client(acc_url, timeout=70)
        return raclient
    else:
        return raclient

def get_profile():
    global user_profile
    if user_profile is None:
        profile = get_client().factory.create('ns0:UserProfile')
        profile.Api_type = API_TYPE
        profile.Area = AREA 
        profile.LicenceKey = LICENCE_KEY
        profile.LoginID = LOGIN_ID
        profile.Version = API_VERSION
        user_profile = profile
    return user_profile

def get_shipper_object(warehouse_id):
    global shipperMap
    if shipperMap.has_key(warehouse_id):
        return shipperMap.get(warehouse_id)
    else:
        tc = TransactionClient().get_client()
        info = tc.getBuyerByWarehouse(warehouse_id)
        if info is None:
            raise RuntimeError("Buyer address mapping is None")
        ship = get_client().factory.create('ns2:Shipper')
        ship.CustomerAddress1 = info.buyerAddress.address[:30]
        ship.CustomerAddress2 = info.buyerAddress.address[30:60]
        ship.CustomerAddress3 = info.buyerAddress.address[60:90]
        ship.CustomerCode = "316326"
        ship.CustomerMobile = info.buyerAddress.contact_number
        ship.VendorCode="AMPFAR"
        ship.OriginArea = "FAR"
        ship.CustomerPincode = info.buyerAddress.pin
        info.organisationName = info.organisationName+" "
        temp_org = info.organisationName.split(" ")
        ship.Sender = (xstr(temp_org[0])+" "+xstr(temp_org[1])).strip()
        ship.CustomerName = ship.Sender
        ship.CustomerTelephone= info.buyerAddress.contact_number 
        shipperMap[warehouse_id] = ship
    return shipperMap.get(warehouse_id)

def create_commodity_obj(orders_list, cd, ser):
    SpecialInstruction = ""
    it=0
    for order in orders_list:
        it+=1
        temp = xstr(order.lineitems[0].brand)+" "+xstr(order.lineitems[0].model_name)+" "+xstr(order.lineitems[0].model_number)+" "+xstr(order.lineitems[0].color)+"-"+str(order.lineitems[0].quantity)
        SpecialInstruction+=temp
        if len(orders_list) == it:
            pass
        else:
            SpecialInstruction+=","
            
    SpecialInstruction = re.sub(' +',' ',SpecialInstruction)
    ser.SpecialInstruction = SpecialInstruction[:50]
    cd.CommodityDetail1 = SpecialInstruction[:30]
    cd.CommodityDetail2 = SpecialInstruction[30:60]
    cd.CommodityDetail3 = SpecialInstruction[60:90]
    ser.Commodity = cd
    return ser
        
def clean_address(order, consignee):
    address_string = xstr(order.customer_address1)+" "+xstr(order.customer_address2)
    address_string = re.sub(",",' ',address_string)
    add_string = re.sub(' +',' ',address_string)
    c_1, idx = sub_address(address_string, 0, 30)
    c_2, idx = sub_address(address_string, idx, idx+30)
    c_3, idx = sub_address(address_string, idx, len(add_string))
    consignee.ConsigneeAddress1 = c_1.strip()
    consignee.ConsigneeAddress2 = c_2.strip()
    consignee.ConsigneeAddress3 = (c_3 +" "+order.customer_city).strip()
    return consignee
        

def sub_address(add_str, previous_loc, final_loc):
    sub = add_str[previous_loc:final_loc]
    max_idx = sub.rfind(" ")
    if max_idx==-1:
        return sub, len(sub)
    if max_idx == (final_loc-1):
        return sub, final_loc-1
    return sub[: max_idx], max_idx+previous_loc

def get_shipment_details(logisticsTxnId):
    tc = TransactionClient().get_client()
    shipment_cost_detail = tc.getCostDetailForLogisticsTxnId(logisticsTxnId)
    return shipment_cost_detail
    

def generate_awb(orders_list):
    try:
        if not isinstance(orders_list, list) or not orders_list:
            raise ValueError("Expecting list of orders")
        consignee = get_client().factory.create('ns2:Consignee')
        consignee = clean_address(orders_list[0], consignee)
        consignee.ConsigneeAttention = orders_list[0].customer_name
        consignee.ConsigneeMobile = orders_list[0].customer_mobilenumber
        consignee.ConsigneeName = orders_list[0].customer_name
        consignee.ConsigneePincode = orders_list[0].customer_pincode
        consignee.ConsigneeTelephone = orders_list[0].customer_mobilenumber
        ser = get_client().factory.create('ns2:Services')
        productType = get_client().factory.create('ns1:ProductType')
        actual_weight = 0.0
        collectable_amount = 0.0
        declared_value = 0.0
        isCod = orders_list[0].cod
        for order in orders_list:
            line_item = order.lineitems[0]
            actual_weight += line_item.total_weight
            collectable_amount += order.net_payable_amount
            declared_value += order.total_amount
        ser.ActualWeight = actual_weight
        ser.CreditReferenceNo = orders_list[0].logisticsTransactionId
        ser.DeclaredValue = declared_value 
        ser.ProductCode = "A"
        ser.ProductType = productType.Dutiables
        ser.PieceCount = 1
        now_time = datetime.now().time()
        if now_time <= time(19,00):
            ser.PickupDate = datetime.today().strftime('%Y-%m-%d')
        else:
            ser.PickupDate = (datetime.now()+timedelta(days=1)).strftime('%Y-%m-%d')
        ser.PickupTime="1900"
        ser.IsReversePickup = False
        ser.PDFOutputNotRequired = True
        ser.RegisterPickup = False
        if isCod and collectable_amount > 0:
            ser.CollectableAmount = collectable_amount 
            ser.SubProductCode = "C"
        else:
            ser.SubProductCode = "P"
        wbg = get_client().factory.create('ns2:WayBillGenerationRequest')
        
        d= get_client().factory.create('ns2:Dimension')
        shipment_cost = get_shipment_details(orders_list[0].logisticsTransactionId)
        if shipment_cost is None or shipment_cost.packageDimensions is None:
            raise RuntimeError("Package dim. is none")
        t_dimensions = shipment_cost.packageDimensions.split("X")
        if len(t_dimensions)!=3:
            raise RuntimeError("Package dim. is not valid")
        d.Count=1
        d.Length = float(t_dimensions[0].strip())
        d.Breadth = float(t_dimensions[1].strip())
        d.Height = float(t_dimensions[2].strip())
        ser.Dimensions.Dimension=[d]
        
        cd = get_client().factory.create('ns2:Commodity')
        
        ser = create_commodity_obj(orders_list, cd, ser)
        
        wbg.Consignee = consignee
        wbg.Services = ser
        wbg.Shipper = get_shipper_object(orders_list[0].warehouse_id)
        
        response = get_client().service.GenerateWayBill(wbg, get_profile())
        if response.AWBNo is None:
            raise RuntimeError("AWB generated is empty")
        else:
            bluedartResponse = __BluedartAWBResponse(str(response.AWBNo),str(response.DestinationArea),str(response.DestinationLocation))
            return bluedartResponse
    finally:
        if DEBUG:
            print get_client().last_sent()
            print get_client().last_received()

def main():
    print generate_awb([])
    
    

if __name__ == '__main__':
    main()