Subversion Repositories SmartDukaan

Rev

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

#!/usr/bin/python
'''
It processes the following orders:
 1. Orders in DOA_PICKUP_CONFIRMED status : get details of orders that 
     were in DOA_PICKUP_CONFIRMED status from database and 
     calls BlueDart api to know whether they are picked up by BlueDart
     and changes the status to DOA_RETURN_IN_TRANSIT if it is done.
 2. Orders in RET_PICKUP_CONFIRMED status : get details of orders that 
     were in RET_PICKUP_CONFIRMED status from database and 
     calls BlueDart api to know whether they are picked up by BlueDart
     and changes the status to RET_RETURN_IN_TRANSIT if it is done.
 3. Orders in SHIPPED_FROM_WH status: get details of orders that
     were in SHIPPED_FROM_WH status from database and 
     calls BlueDart api to know whether they are picked up by BlueDart
     and changes the status to SHIPPED_TO_LOGST if it is done.
 4. Orders in SHIPPED_TO_LOGST status: get details of orders that
     were in SHIPPED_TO_LOGST status from database and 
     calls BlueDart api to know their status and changes the status accordingly.

It sends out a Pickup mismatch report, Return orders Pickup Mismatch report, Doa Pickup mismatch report,
Undelivered orders report and Returned Orders report to cnc.center@shop2020.in


@author: Manish Sharma
'''
from shop2020.clients.CRMClient import CRMClient
from shop2020.clients.LogisticsClient import LogisticsClient
from shop2020.clients.TransactionClient import TransactionClient
from shop2020.clients.UserClient import UserClient
from shop2020.config.client.ConfigClient import ConfigClient
from LogisticUtils import enqueueMailForFDA
from shop2020.thriftpy.config.ttypes import ConfigException
from shop2020.thriftpy.crm.ttypes import *
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \
    OrderStatus
from shop2020.utils.EmailAttachmentSender import get_attachment_part, mail
from shop2020.utils.Utils import to_py_date
import csv
import datetime
import optparse
import sys
import time
import traceback

if __name__ == '__main__' and __package__ is None:
    import os
    sys.path.insert(0, os.getcwd())
    
defaultUndeliveredAsssigneeId = 47
from_user = 'cnc.center@shop2020.in'
from_pwd = '5h0p2o2o'
to = ['cnc.center@shop2020.in', "amit.sirohi@shop2020.in", "sandeep.sachdeva@shop2020.in", "manoj.kumar@shop2020.in", "rajveer.singh@shop2020.in"]


def process_dao_pickup_orders(provider):
    try:
        doas_tobe_picked_up = fetch_data(provider.id, [OrderStatus.DOA_PICKUP_CONFIRMED])
        doa_pickup_details = read_dao_return_pickup_orders(doas_tobe_picked_up)
        if doa_pickup_details:
            update_picked_doas(provider.id, doa_pickup_details)
    except:
        print "Some issue while processing the orders in DOA_PICKUP_CONFIRMED status"
        traceback.print_exc()

def process_pickup_records(provider):
    try:
        orders_tobe_picked_up = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH])
        pickup_details = read_pickup_orders(orders_tobe_picked_up)
        if pickup_details:
            update_picked_orders(provider.id, pickup_details)
    except:
        print "Some issue while processing the orders in SHIPPED_FROM_WH status"
        traceback.print_exc()
        
def process_return_pickup_orders(provider):
    try:
        returns_tobe_picked_up = fetch_data(provider.id, [OrderStatus.RET_PICKUP_CONFIRMED])
        returns_pickup_details = read_dao_return_pickup_orders(returns_tobe_picked_up)
        if returns_pickup_details:
            update_picked_returns(provider.id, returns_pickup_details)
    except:
        print "Some issue while processing the orders in RET_PICKUP_CONFIRMED status"
        traceback.print_exc()

def process_local_connection_orders(provider):
    try:
        orders_tobe_local_connected = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST])
        local_connected_orders = read_local_connection_orders(orders_tobe_local_connected)
        if local_connected_orders:
            update_local_connected_orders(provider.id, local_connected_orders)
    except:
        print "Some issue while processing the orders for local connection status"
        traceback.print_exc()
        
def process_reached_destination_city_orders(provider):
    try:
        orders_tobe_reached_destination_city = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY])
        destination_city_reached_orders = read_reached_destination_orders(orders_tobe_reached_destination_city)
        if destination_city_reached_orders:
            update_destination_city_reached_orders(provider.id, destination_city_reached_orders)
    except:
        print "Some issue while processing the orders for Reached Destination City status"
        traceback.print_exc()
        
def process_first_delivery_attempt_orders(provider):
    try:
        orders_tobe_first_delivery_attempted = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY])
        first_atdl_orders = read_first_delivery_attempt_orders(orders_tobe_first_delivery_attempted)
        if first_atdl_orders:
            update_first_atdl_orders(provider.id, first_atdl_orders)
    except:
        print "Some issue while processing the orders for First delivery attempt status"
        traceback.print_exc()
        
def process_delivery_report(provider):
    try:
        orders_tobe_delivered = fetch_data(provider.id, [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE])
        delivered_orders, returned_orders, undelivered_orders = read_delivery_orders(orders_tobe_delivered)
        if delivered_orders:
            update_delivered_orders(provider.id, delivered_orders)
        if returned_orders:
            update_returned_orders(provider.id, returned_orders)
        if undelivered_orders:
            update_reason_of_undelivered_orders(provider.id, undelivered_orders)
    except:
        print "Some issue while processing the orders for delivery status"
        traceback.print_exc()

def read_delivery_orders(orders_tobe_delivered):
    delivered_orders = {}
    returned_orders = {}
    undelivered_orders = {}
    order_list = []
    for order in orders_tobe_delivered:
        order_list.append(order.id)
        
    try:
        crmServiceClient = CRMClient().get_client()
        delivered_orders = crmServiceClient.getFedexReconciliationDataMap(order_list, "delivered_orders")                  
        returned_orders = crmServiceClient.getFedexReconciliationDataMap(order_list, "returned_orders")
        undelivered_orders = crmServiceClient.getFedexReconciliationDataMap(order_list, "undelivered_orders")
    except:
        pass
    
    print "Delivered Orders:"
    print delivered_orders
    
    print "Returned Orders:"
    print returned_orders
    
    print "Undelivered Orders"
    print undelivered_orders
    
    return delivered_orders, returned_orders, undelivered_orders

def read_first_delivery_attempt_orders(orders_tobe_first_delivery_attempted):
    first_atdl_orders = {}
    order_list = []
    for order in orders_tobe_first_delivery_attempted:
        order_list.append(order.id)
        
    try:
        crmServiceClient = CRMClient().get_client()
        first_atdl_orders = crmServiceClient.getFedexReconciliationDataMap(order_list, "first_delivery_attempted_orders")                  
    except:
        pass
    
    print "FIRST DELIVERY ATTEMPT MADE Orders"
    print first_atdl_orders
    
    return first_atdl_orders

def read_reached_destination_orders(orders_tobe_reached_destination_city):
    destination_city_reached_orders = {}
    order_list = []
    for order in orders_tobe_reached_destination_city:
        order_list.append(order.id)
        
    try:
        crmServiceClient = CRMClient().get_client()
        destination_city_reached_orders = crmServiceClient.getFedexReconciliationDataMap(order_list, "destination_city_reached_orders")                  
    except:
        pass
    
    print "Destination City Reached Orders"
    print destination_city_reached_orders
    
    return destination_city_reached_orders
       
def read_local_connection_orders(orders_tobe_local_connected):
    local_connected_orders = {}
    order_list = []
    for order in orders_tobe_local_connected:
        order_list.append(order.id)
        
    try:
        crmServiceClient = CRMClient().get_client()
        local_connected_orders = crmServiceClient.getFedexReconciliationDataMap(order_list, "local_connection_orders")                  
    except:
        pass
    
    print "Local Connected Orders"
    print local_connected_orders
    
    return local_connected_orders

def read_dao_return_pickup_orders(orders_tobe_picked_up):
    picked_up_orders = {}
    order_list = []
    for order in orders_tobe_picked_up:
        order_list.append(order.id)
        
    try:
        crmServiceClient = CRMClient().get_client()
        picked_up_orders = crmServiceClient.getFedexReconciliationDataMap(order_list, "dao_return_pickup_orders")                  
    except:
        pass
    
    print "Picked up Orders:"
    print picked_up_orders
    return picked_up_orders

def read_pickup_orders(orders_tobe_picked_up):
    picked_up_orders = {}
    order_list = []
    for order in orders_tobe_picked_up:
        order_list.append(order.id)
        
    try:
        crmServiceClient = CRMClient().get_client()
        picked_up_orders = crmServiceClient.getFedexReconciliationDataMap(order_list, 'picked_up_orders')                  
    except:
        pass
    
    print "Picked up Orders:"
    print picked_up_orders
    return picked_up_orders


def update_reason_of_undelivered_orders(provider_id, undelivered_orders):
    txnClient = TransactionClient().get_client()
    try:
        txnClient.updateNonDeliveryReason(provider_id, undelivered_orders)
    except TransactionServiceException as tex:
        print tex.message
        
def update_returned_orders(provider_id, returned_orders):
    txnClient = TransactionClient().get_client()
    try:
        txnClient.markAsRTOrders(provider_id, returned_orders)
    except TransactionServiceException as tex:
        print tex.message
        
def update_delivered_orders(provider_id, delivered_orders):
    txnClient = TransactionClient().get_client()
    try:
        txnClient.markOrdersAsDelivered(provider_id, delivered_orders)
    except TransactionServiceException as tex:
        print tex.message
        
def update_first_atdl_orders(provider_id, first_atdl_orders):
    txnClient = TransactionClient().get_client()
    try:
        txnClient.markOrdersAsFirstDeliveryAttempted(provider_id, first_atdl_orders)
    except TransactionServiceException as tex:
        print tex.message
        
        
def update_destination_city_reached_orders(provider_id, destination_city_reached_orders):
    txnClient = TransactionClient().get_client()
    try:
        txnClient.markOrdersAsDestinationCityReached(provider_id, destination_city_reached_orders)
    except TransactionServiceException as tex:
        print tex.message

def update_local_connected_orders(provider_id, local_connected_orders):
    txnClient = TransactionClient().get_client()
    try:
        txnClient.markOrdersAsLocalConnected(provider_id, local_connected_orders)
    except TransactionServiceException as tex:
        print tex.message


def update_picked_returns(provider_id, returns_pickup_details):
    txnClient = TransactionClient().get_client()
    try:
        txnClient.markReturnOrdersAsPickedUp(provider_id, returns_pickup_details)
    except TransactionServiceException as tex:
        print tex.message

def update_picked_doas(provider_id, doa_pickup_details):
    txnClient = TransactionClient().get_client()
    try:
        txnClient.markDoasAsPickedUp(provider_id, doa_pickup_details)
    except TransactionServiceException as tex:
        print tex.message
        
        
def update_picked_orders(provider_id, pickup_details):
    txnClient = TransactionClient().get_client()
    try:
        txnClient.markOrdersAsPickedUp(provider_id, pickup_details)
    except TransactionServiceException as tex:
        print tex.message

        
def fetch_data(provider_id, order_status_list):
    txnClient = TransactionClient().get_client()
    try:
        doas_tobe_picked_up = txnClient.getOrdersForProviderForStatus(provider_id, order_status_list)
        return doas_tobe_picked_up
    except TransactionServiceException as tex:
        print tex.message

def get_provider_by_name(provider_name):
    logistics_client = LogisticsClient().get_client()
    provider = None
    providers = logistics_client.getAllProviders()
    for p in providers:
        if p.name == provider_name:
            provider=p
            break
    if provider == None:
        sys.exit("Can't continue execution: No such provider")
    return provider

def create_crm_tickets_for_delivey_attempted_orders(provider):
    try:
        tickets_tobe_created = fetch_data(provider.id, [OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE])
        userClient = UserClient().get_client()
        crmServiceClient = CRMClient().get_client()
        for order in tickets_tobe_created:
            ticket_created = False
            searchFilter = SearchFilter()
            user = userClient.getUserByEmail(order.customer_email)
            if user is None or user.userId == -1:
                searchFilter.customerEmailId = order.customer_email
                searchFilter.customerMobileNumber = order.customer_mobilenumber
            else:
                searchFilter.customerId = user.userId
            searchFilter.ticketCategory = TicketCategory.UNDELIVERED
            tickets = crmServiceClient.getTickets(searchFilter)
            print tickets
            for old_ticket in tickets:
                if old_ticket.orderId == order.id:
                    ticket_created = True
                    break
            if not ticket_created:
                print "creating ticket for orderId:"+str(order.id)
                ticket = Ticket()
                activity = Activity()
                description = order.statusDescription + "\n\nOrder not delivered by courier due to problems at customer end."
                ticket.creatorId = 1
                ticket.assigneeId = defaultUndeliveredAsssigneeId
                ticket.category = TicketCategory.UNDELIVERED
                ticket.priority = TicketPriority.HIGH
                ticket.status = TicketStatus.OPEN
                ticket.description = description
                ticket.orderId = order.id
                ticket.airwayBillNo = order.airwaybill_no
                
                activity.creatorId = 1
                activity.ticketAssigneeId = ticket.assigneeId
                activity.type = ActivityType.OTHER
                activity.description = description
                activity.ticketCategory = ticket.category
                activity.ticketDescription = ticket.description
                activity.ticketPriority = ticket.priority
                activity.ticketStatus = ticket.status
                
                if user is None or user.userId == -1:
                    ticket.customerEmailId = order.customer_email
                    ticket.customerMobileNumber = order.customer_mobilenumber
                    ticket.customerName = order.customer_name
                    activity.customerEmailId = order.customer_email
                    activity.customerMobileNumber = order.customer_mobilenumber
                    activity.customerName = order.customer_name
                else:
                    ticket.customerId = user.userId
                    activity.customerId = user.userId
                
                crmServiceClient.insertTicket(ticket, activity)
                '''
                Inform user about first delivery attempt
                '''
                enqueueMailForFDA(order)
    except:
        print "Some issue while creating crm tickets for orders in FIRST_DELIVERY_ATTEMPT_MADE status"
        traceback.print_exc()

def auto_close_crm_tickets_created():
    try:
        ticket_created_orders = []
        tickets_map = {}
        crmServiceClient = CRMClient().get_client()
        searchFilter = SearchFilter()
        searchFilter.ticketCategory = TicketCategory.UNDELIVERED
        searchFilter.ticketAssigneeIds = [defaultUndeliveredAsssigneeId]
        searchFilter.ticketPriority = TicketPriority.HIGH
        searchFilter.ticketStatuses = [TicketStatus.OPEN]
        tickets = crmServiceClient.getTickets(searchFilter)
        print tickets
        for old_ticket in tickets:
            ticket_created_orders.append(old_ticket.orderId)
            tickets_map[old_ticket.orderId] = old_ticket
        print ticket_created_orders
        txnClient = TransactionClient().get_client()
        orders = txnClient.getOrderList(ticket_created_orders)
        for order in orders:
            if order.status not in [OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
                old_ticket = tickets_map.get(order.id)
                old_ticket.status = TicketStatus.CLOSED
                activity = Activity()
                activity.creatorId = 1
                activity.ticketAssigneeId = old_ticket.assigneeId
                activity.type = ActivityType.OTHER
                activity.description = "Ticket Closed bcoz order status changed to:" + order.statusDescription
                activity.ticketCategory = old_ticket.category
                activity.ticketDescription = old_ticket.description
                activity.ticketPriority = old_ticket.priority
                activity.ticketStatus = old_ticket.status
                
                if old_ticket.customerId is None or old_ticket.customerId == -1:
                    activity.customerEmailId = old_ticket.customerEmailId
                    activity.customerMobileNumber = old_ticket.customerMobileNumber
                    activity.customerName = old_ticket.customerName
                else:
                    activity.customerId = old_ticket.customerId
                
                crmServiceClient.updateTicket(old_ticket, activity)
    except:
        print "Some issue while closing crm tickets for orders in DELIVERY_SUCCESS status"
        traceback.print_exc()

def generate_reports(provider):
    #get_doas_not_picked_up(provider)
    #get_returns_not_picked_up(provider)
    get_orders_not_picked_up(provider)
    get_orders_pending_local_connection(provider)
    get_returned_orders(provider)
    get_orders_not_delivered(provider)
    
def get_doas_not_picked_up(provider):
    txnClient = TransactionClient().get_client()
    try:
        doas_not_picked_up = txnClient.getDoasNotPickedUp(provider.id)
    except TransactionServiceException as tex:
        print tex.message
    
    try:
        if doas_not_picked_up:
            print "DOAs not Picked up:"
            print doas_not_picked_up
            mismatch_file = "/tmp/FedEx_DoaPickupMismatch.csv"
            print "Some of our DOA orders were not picked up. Printing report to:" + mismatch_file
            print_dao_return_pickup_mismatch_report(mismatch_file, doas_not_picked_up)
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
            mail(from_user, from_pwd, to,\
                 "DOA Pickup Mismatch for " + provider.name,\
                 "This is a system generated email.Please don't reply to it.",\
                 pickup_mismatch_part)
    except Exception:
        print "Some issue sending the DOA mismatch report"
        traceback.print_exc()

def get_returns_not_picked_up(provider):
    txnClient = TransactionClient().get_client()
    try:
        returns_not_picked_up = txnClient.getReturnOrdersNotPickedUp(provider.id)
    except TransactionServiceException as tex:
        print tex.message
    
    try:
        if returns_not_picked_up:
            print "Return Orders not Picked up:"
            print returns_not_picked_up
            mismatch_file = "/tmp/FedEx_ReturnsPickupMismatch.csv"
            print "Some of our Return orders were not picked up. Printing report to:" + mismatch_file
            print_dao_return_pickup_mismatch_report(mismatch_file, returns_not_picked_up)
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
            mail(from_user, from_pwd, to,\
                 "Return orders Pickup Mismatch for " + provider.name,\
                 "This is a system generated email.Please don't reply to it.",\
                 pickup_mismatch_part)
    except Exception:
        print "Some issue sending the Return orders mismatch report"
        traceback.print_exc()

def get_orders_not_picked_up(provider):
    txnClient = TransactionClient().get_client()
    try:
        orders_not_picked_up = txnClient.getOrdersNotPickedUp(provider.id)
    except TransactionServiceException as tex:
        print tex.message
    
    try:
        if orders_not_picked_up:
            print "Orders not Picked up:"
            print orders_not_picked_up
            mismatch_file = "/tmp/FedEx_PickupMismatch.csv"
            print "Some of our orders were not picked up. Printing report to:" + mismatch_file
            print_pickup_mismatch_report(mismatch_file, orders_not_picked_up)
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
            mail(from_user, from_pwd, to,\
                 "Order Pickup Mismatch for " + provider.name,\
                 "This is a system generated email.Please don't reply to it.",\
                 pickup_mismatch_part)
    except Exception:
        print "Some issue sending the pickup mismatch report"
        traceback.print_exc()

def get_orders_pending_local_connection(provider):
    txnClient = TransactionClient().get_client()
    try:
        orders_pending_local_connection = txnClient.getOrdersNotLocalConnected(provider.id)
    except TransactionServiceException as tex:
        print tex.message
    
    try:
        if orders_pending_local_connection:
            print "Local Connection Pending Orders:"
            print orders_pending_local_connection
            mismatch_file = "/tmp/FedEx_LocalConnectionPendingOrders.csv"
            print "Some of our Orders were not Shipped to Destination yet. Printing report to:" + mismatch_file
            print_undelivered_orders_report(mismatch_file, orders_pending_local_connection)
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
            mail(from_user, from_pwd, to,\
                 "Orders that are not Shipped to Destination yet for " + provider.name,\
                 "This is a system generated email.Please don't reply to it.",\
                 pickup_mismatch_part)
    except Exception:
        print "Some issue updating and sending the Local Connection orders report"
        traceback.print_exc()

def get_returned_orders(provider):
    txnClient = TransactionClient().get_client()
    try:
        returned_orders = txnClient.getRTOrders(provider.id)
    except TransactionServiceException as tex:
        print tex.message
    
    try:
        if returned_orders:
            print "Returned Orders:"
            print returned_orders
            returned_orders_file = "/tmp/Fedex_ReturnedOrders.csv"
            print "Some of our Orders were returned by logistics provider. Printing report to:" + returned_orders_file
            print_rto_orders_report(returned_orders_file, returned_orders)
            returned_orders_report = [get_attachment_part(returned_orders_file)]
            mail(from_user, from_pwd, to,\
                 "Returned Orders Report for " + provider.name,\
                 "This is a system generated email.Please don't reply to it.",\
                 returned_orders_report)
    except:
        print "Some issue sending the returned orders report"
        traceback.print_exc()

def get_orders_not_delivered(provider):
    txnClient = TransactionClient().get_client()
    try:
        orders_not_delivered = txnClient.getNonDeliveredOrdersbyCourier(provider.id)
    except TransactionServiceException as tex:
        print tex.message
    
    try:
        if orders_not_delivered:
            print "Undelivered Orders:"
            print orders_not_delivered
            mismatch_file = "/tmp/FedEx_UndeliveredOrders.csv"
            print "Some of our Orders were not delivered. Printing report to:" + mismatch_file
            print_undelivered_orders_report(mismatch_file, orders_not_delivered)
            pickup_mismatch_part = [get_attachment_part(mismatch_file)]
            mail(from_user, from_pwd, to,\
                 "Orders that are undelivered but picked up or shipped four days ago for " + provider.name,\
                 "This is a system generated email.Please don't reply to it.",\
                 pickup_mismatch_part)
    except Exception:
        print "Some issue updating and sending the undelivered orders report"
        traceback.print_exc()

def print_pickup_mismatch_report(filename, orders):
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
    writer.writerow(['Order Id', 'AWB No', 'Shipping timestamp'])
    for order in orders:
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.shipping_timestamp)])

def print_dao_return_pickup_mismatch_report(filename, orders):
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
    writer.writerow(['Order Id', 'Pickup Request No', 'Authorization timestamp'])
    for order in orders:
        writer.writerow([order.id, order.pickupRequestNo, to_py_date(order.doa_auth_timestamp)])

def print_rto_orders_report(filename, orders):
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
    writer.writerow(['Order Id', 'AWB No', 'Return date', 'Reason'])
    for order in orders:
        statusDescription = ''
        if order.statusDescription is not None:
            statusDescription = order.statusDescription.replace(","," ")
        writer.writerow([order.id, order.airwaybill_no, to_py_date(order.delivery_timestamp), statusDescription])

def print_undelivered_orders_report(filename, orders):
    writer = csv.writer(open(filename, "wb"), delimiter=',', quoting=csv.QUOTE_NONE)
    writer.writerow(['Order Id', 'AWB No', 'Status', 'Status Description', 'Shipping timestamp', 'Pickup timestamp', 'Promised delivery date', 'Expected delivery date', 'OTG'])
    for order in orders:
        statusDescription = ''
        if order.statusDescription is not None:
            statusDescription = order.statusDescription.replace(","," ")
        writer.writerow([order.id, order.airwaybill_no, order.status, statusDescription, to_py_date(order.shipping_timestamp), to_py_date(order.pickup_timestamp), to_py_date(order.promised_delivery_time), to_py_date(order.expected_delivery_time), 'True'  if order.otg else 'False'])


def main():
    parser = optparse.OptionParser()
    parser.add_option("-p", "--pickup", dest="pickup_report",
                   action="store_true",
                   help="Run the pickup reconciliation")
    parser.add_option("-d", "--delivery", dest="delivery_report",
                   action="store_true",
                   help="Run the delivery reconciliation")
    parser.add_option("-r", "--reports", dest="gen_reports",
                   action="store_true",
                   help="Generate logistic reconciliation reports")
    parser.add_option("-a", "--all", dest="all_reports",
                   action="store_true",
                   help="Run all reconciliations")
    parser.add_option("-P", "--provider", dest="provider",
                   default="FedEx", type="string",
                   help="The PROVIDER this report is for",
                   metavar="PROVIDER")
    parser.set_defaults(pickup_report=False, delivery_report=False, gen_reports=False, all_reports=False)
    (options, args) = parser.parse_args()
    if len(args) != 0:
        parser.error("You've supplied extra arguments. Are you sure you want to run this program?")
    
    if options.all_reports:
        options.pickup_report = True
        options.delivery_report = True
    
    provider = get_provider_by_name(options.provider)
    
    if options.pickup_report:
        process_pickup_records(provider)
        #process_dao_pickup_orders(provider)
        #process_return_pickup_orders(provider)
    if options.delivery_report:
        process_local_connection_orders(provider)
        process_reached_destination_city_orders(provider)
        process_first_delivery_attempt_orders(provider)
        process_delivery_report(provider)
        create_crm_tickets_for_delivey_attempted_orders(provider)
        auto_close_crm_tickets_created()
    if options.gen_reports:
        generate_reports(provider)

if __name__ == '__main__':
    main()