def get_ups_rating_request(delivery_note, params):
    # prepate the ups rating request
    dn = delivery_note

    packing_slips = [row.packing_slip for row in dn.packing_slip_details]
    if not packing_slips:
        frappe.throw("Can not find the linked Packing Slip ...")

    ship_from_address_name = params.get("default_warehouse")
    shipper_number = params.get("shipper_number")
    package_type = ups_packages.get(params.get("package_type"))
    ship_to_params = {
        "customer":dn.customer,
        "contact_display":dn.contact_display,
        "contact_mobile":dn.contact_mobile
    }

    shipment = E.Shipment(
                    Helper.get_shipper(params),
                    Helper.get_ship_to_address(ship_to_params, dn.shipping_address_name,),
                    Helper.get_ship_from_address(params, ship_from_address_name),
                    RatingService.service_type(Code='03'),
                )
    packages = Helper.get_packages(packing_slips, package_type)
    shipment.extend(packages)

    rating_request = RatingService.rating_request_type(
        shipment,
    )

    return rating_request
def get_shipping_rates(delivery_note, add_shipping_overhead=False):
    """get packages Information from delivery note, create the xml request to fetch the ups rates"""
    try:
        # dn = frappe.get_doc("Delivery Note",delivery_note)
        if isinstance(delivery_note, DeliveryNote):
            dn = delivery_note
        else:
            dn = frappe.get_doc(json.loads(delivery_note))

        if dn.dn_status in ["Draft", "Partialy Packed"]:
            frappe.throw("First create the packing slips")

        params = Helper.get_ups_api_params()
        rating_api = get_rating_service(params)
        request = get_ups_rating_request(dn, params)

        response = rating_api.request(request)
        shipping_rates = parse_xml_response_to_json(response)

        dn.ups_rates = json.dumps(shipping_rates)
        dn.dn_status = "UPS Rates Fetched"

        dn.save(ignore_permissions= True)

        if shipping_rates.get("03"):
            if add_shipping_overhead: add_shipping_charges(dn_name=dn.name, service_code="03")
            # return True
            return shipping_rates
        else:
            frappe.msgprint("UPS Ground rates are not available. Please select other services")
            return shipping_rates
        # return shipping_rates
    except PyUPSException, e:
        """ e is PyUPSException obj returns tuple as structured (message, request, response)"""
        frappe.throw(e[0])
def get_shipping_labels(delivery_note):
    # get package information from delivery note
    # create xml request for ups shipping_package
    # parse the xml response and store the shipping labels and tracking_id

    # dn = frappe.get_doc("Delivery Note",delivery_note)
    try:
        dn = delivery_note

        params = Helper.get_ups_api_params()
        shipment_confirm_api = get_shipment_confirm_service(params)
        shipment_accept_api = get_shipment_accept_service(params)
        shipment_confirm_request = get_ups_shipment_confirm_request(dn, params)

        response = shipment_confirm_api.request(shipment_confirm_request)
        digest = shipment_confirm_api.extract_digest(response)
        shipment_accept_request = ShipmentAccept.shipment_accept_request_type(
            digest)
        response = shipment_accept_api.request(shipment_accept_request)

        shipping_info = parse_xml_response_to_json(response, dn)

        # save tracking no and labels to delivery note
        save_tracking_number_and_shipping_labels(dn, shipping_info)
        # reduce box items from stock ledger
        dn.boxes_stock_entry = create_boxes_stock_entry(dn)
    except PyUPSException, e:
        frappe.throw(e[0])
def get_shipping_labels(delivery_note):
    # get package information from delivery note
    # create xml request for ups shipping_package
    # parse the xml response and store the shipping labels and tracking_id

    # dn = frappe.get_doc("Delivery Note",delivery_note)
    try:
        dn = delivery_note

        params = Helper.get_ups_api_params()
        shipment_confirm_api = get_shipment_confirm_service(params)
        shipment_accept_api = get_shipment_accept_service(params)
        shipment_confirm_request = get_ups_shipment_confirm_request(dn, params)

        response = shipment_confirm_api.request(shipment_confirm_request)
        digest = shipment_confirm_api.extract_digest(response)
        shipment_accept_request = ShipmentAccept.shipment_accept_request_type(digest)
        response = shipment_accept_api.request(shipment_accept_request)

        shipping_info = parse_xml_response_to_json(response, dn)

        # save tracking no and labels to delivery note
        save_tracking_number_and_shipping_labels(dn, shipping_info)
        # reduce box items from stock ledger
        dn.boxes_stock_entry = create_boxes_stock_entry(dn)
    except PyUPSException, e:
        frappe.throw(e[0])
def get_ups_shipment_confirm_request(delivery_note, params):
    dn = delivery_note
    packing_slips = [row.packing_slip for row in dn.packing_slip_details]
    if not packing_slips:
        frappe.throw("Can not find the linked Packing Slip ...")

    ship_from_address_name = params.get("default_warehouse")
    shipper_number = params.get("shipper_number")
    package_type = ups_packages.get(params.get("package_type"))
    rates = {}
    if dn.ups_rates:
        rates = json.loads(dn.ups_rates)
    service_code = rates.get("service_used") or "03"
    ship_to_params = {
        "customer": dn.customer,
        "contact_display": dn.contact_display,
        "contact_mobile": dn.contact_mobile
    }

    packages = Helper.get_packages(packing_slips, package_type)

    request = ShipmentConfirm.shipment_confirm_request_type(
        Helper.get_shipper(params),
        Helper.get_ship_to_address(
            ship_to_params,
            dn.shipping_address_name,
        ),
        Helper.get_ship_from_address(params, ship_from_address_name),
        Helper.get_payment_info(AccountNumber=shipper_number),
        ShipmentConfirm.service_type(Code=service_code),
        # Labal specification container
        LabelSpecification=E.LabelSpecification(
            E.LabelPrintMethod(E.Code("ZPL"), ),
            E.LabelStockSize(
                E.Height("4"),
                E.Width("6"),
            ),
            E.LabelImageFormat(E.Code("ZPL"), ),
        ),
        Description="Description")
    request.find("Shipment").extend(packages)

    return request
def get_ups_shipment_confirm_request(delivery_note, params):
    dn = delivery_note
    packing_slips = [row.packing_slip for row in dn.packing_slip_details]
    if not packing_slips:
        frappe.throw("Can not find the linked Packing Slip ...")

    ship_from_address_name = params.get("default_warehouse")
    shipper_number = params.get("shipper_number")
    package_type = ups_packages.get(params.get("package_type"))
    rates = {}
    if dn.ups_rates:
        rates = json.loads(dn.ups_rates)
    service_code = rates.get("service_used") or "03"
    ship_to_params = {
        "customer":dn.customer,
        "contact_display":dn.contact_display,
        "contact_mobile":dn.contact_mobile
    }

    packages = Helper.get_packages(packing_slips, package_type)

    request = ShipmentConfirm.shipment_confirm_request_type(
        Helper.get_shipper(params),
        Helper.get_ship_to_address(ship_to_params, dn.shipping_address_name,),
        Helper.get_ship_from_address(params, ship_from_address_name),
        Helper.get_payment_info(AccountNumber=shipper_number),
        ShipmentConfirm.service_type(Code=service_code),
        # Labal specification container
        LabelSpecification = E.LabelSpecification(
            E.LabelPrintMethod(E.Code("ZPL"),),
            E.LabelStockSize(E.Height("4"),E.Width("6"),),
            E.LabelImageFormat(E.Code("ZPL"),),
        ),
        Description="Description"
    )
    request.find("Shipment").extend(packages)

    return request
def get_package_tracking_status(tracking_number=None):
    if not tracking_number:
        create_scheduler_log("Invalid Input", "get_package_tracking_status",
                            "Invalid Tracking Number %s : tracking number can not\
                            be None"%(tracking_number), tracking_number)
    else:
        try:
            params = Helper.get_ups_api_params()
            tracking_api = get_tracking_service(params)
            tracking_request = TrackingRequest.tracking_request_type(
                E.TrackingNumber(tracking_number),
            )
            response = tracking_api.request(tracking_request)
            return parse_xml_response_to_json(response, tracking_number)
        except PyUPSException, e:
            create_scheduler_log(e[0], "get_package_tracking_status", tracking_number, e)