def label(self, package, shipper, recipient, customs=None, image_format="PNG"):
        shipper.country_code = get_country_code(shipper.country)
        recipient.country_code = get_country_code(recipient.country)
        shipment = self._prepare_request(FedexProcessShipmentRequest(self.config), shipper, recipient, package)
        shipment.RequestedShipment.ServiceType = package.mail_class

        shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = self.config.account_number

        # Specifies the label type to be returned.
        # LABEL_DATA_ONLY or COMMON2D
        shipment.RequestedShipment.LabelSpecification.LabelFormatType = 'COMMON2D'

        # Specifies which format the label file will be sent to you in.
        # DPL, EPL2, PDF, PNG, ZPLII
        shipment.RequestedShipment.LabelSpecification.ImageType = image_format
        shipment.RequestedShipment.LabelSpecification.LabelStockType = 'STOCK_4X6' if image_format == 'EPL2' else 'PAPER_4X6'
        shipment.RequestedShipment.LabelSpecification.LabelPrintingOrientation = 'BOTTOM_EDGE_OF_TEXT_FIRST'

        if customs:
            customs_label = shipment.create_wsdl_object_of_type('AdditionalLabelsDetail')
            customs_label.Type = 'CUSTOMS'
            customs_label.Count = 1
            shipment.AdditionalLabels.append(customs_label)

            wsdl_customs = shipment.create_wsdl_object_of_type('CustomsClearanceDetail')
            wsdl_customs.CustomsValue = shipment.create_wsdl_object_of_type('Money')
            wsdl_customs.CustomsValue.Currency = 'USD'
            wsdl_customs.CustomsValue.Amount = package.value

            for item in sorted(customs.items, key=lambda i: i.value, reverse=True):
                wsdl_item = shipment.create_wsdl_object_of_type('Commodity')
                wsdl_item.CustomsValue = shipment.create_wsdl_object_of_type('Money')
                wsdl_item.CustomsValue.Amount = item.value
                wsdl_item.CustomsValue.Currency = 'USD'
                wsdl_item.NumberOfPieces = item.quantity
                wsdl_item.CountryOfManufacture = item.country_of_origin
                wsdl_item.Description = item.description
                wsdl_item.Weight = round(item.weight, 2)
                wsdl_customs.Commodities.append(wsdl_item)

            shipment.CustomsClearanceDetail = wsdl_customs

        try:
            shipment.send_request()

        except Exception as e:
            return {"error": str(e)}

        tracking = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[0].TrackingIds[0].TrackingNumber
        net_cost = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[0].PackageRating.PackageRateDetails[0].NetCharge.Amount

        return Label(
            postage=net_cost, tracking=tracking, format=[image_format],
            label=[base64.b64decode(shipment.response.CompletedShipmentDetail.CompletedPackageDetails[0].Label.Parts[0].Image)]
        )
Example #2
0
    def rate(self,
             package,
             shipper,
             recipient,
             insurance='OFF',
             insurance_amount=0,
             delivery_confirmation=False,
             signature_confirmation=False):
        response = {'info': []}

        # Play nice with the other function signatures, which expect to take lists of packages.
        if not isinstance(package, Package):

            # But not too nice.
            if len(package) > 1:
                raise Exception("Can only take one Package at a time!")

            package = package[0]

        shipper.country_code = get_country_code(shipper.country)
        recipient.country_code = get_country_code(recipient.country)

        rate_request = FedexRateServiceRequest(self.config)
        rate_request = self._prepare_request(rate_request, shipper, recipient,
                                             package)
        rate_request.RequestedShipment.ServiceType = None
        rate_request.RequestedShipment.EdtRequestType = 'NONE'
        rate_request.RequestedShipment.PackageDetail = 'INDIVIDUAL_PACKAGES'
        rate_request.RequestedShipment.ShippingChargesPayment.Payor.AccountNumber = self.config.account_number

        seen_quotes = []

        try:
            rate_request.send_request()

            for service in rate_request.response.RateReplyDetails:
                for detail in service.RatedShipmentDetails:
                    response['info'].append({
                        'service':
                        service.ServiceType,
                        'package':
                        service.PackagingType,
                        'delivery_day':
                        '',
                        'cost':
                        float(detail.ShipmentRateDetail.TotalNetFedExCharge.
                              Amount)
                    })

        except Exception as e:
            raise FedExError(e)

        return response
Example #3
0
    def rate(self, package, shipper, recipient, insurance='OFF', insurance_amount=0, delivery_confirmation=False, signature_confirmation=False):
        services = dict(SERVICES)

        # Play nice with the other function signatures, which expect to take lists of packages.
        if not isinstance(package, Package):

            # But not too nice.
            if len(package) > 1:
                raise Exception("Can only take one Package at a time!")

            package = package[0]

        shipper.country_code = get_country_code(shipper.country)
        recipient.country_code = get_country_code(recipient.country)
        data = self.templates.get_template("RatingServiceSelectionRequest.mko").render(
                credentials=self.credentials, shipper=shipper, recipient=recipient, package=package
        )

        try:
            httpresq = urllib2.Request(url=self.endpoints["rate"], data=data.encode('utf_8'),
                                       headers={'Content-Type': 'application/x-www-form-urlencoded'})
            reply = etree.fromstring(urllib2.urlopen(httpresq).read())
            response = { 'status': reply.find('Response/ResponseStatusDescription').text, 'info': list() }
            error = reply.find('Response/Error')

            if error is not None:
                #error_location = error.find("ErrorLocation")
                #error_xpath = error.find("ErrorLocationElementName")
                response["error"] = error.find("ErrorDescription").text

                #if error_location:
                #    response["error_location"] = error_location.text

                #if error_xpath:
                #    response["error_xpath"] = error_xpath.text

                raise UPSError(response["error"])

            for details in reply.findall('RatedShipment'):
                service_code = details.find('Service/Code').text
                response['info'].append({
                    'service': services.get(service_code, service_code),
                    'package': package.shape.name,
                    'delivery_day': '',
                    'cost': float(details.find('TotalCharges/MonetaryValue').text)
                })
            return response

        except urllib2.URLError as e:
            raise UPSError(e)
Example #4
0
    def _add_address(self, address, type, root):
        info = dict()
        info['Company'] = address.company_name
        info['Name'] = address.name
        info['Address1'] = address.address1
        info['City'] = address.city
        info['State'] = address.state
        info['PostalCode'] = address.zip
        info['CountryCode'] = get_country_code(address.country.upper())

        if address.phone:
            info['Phone'] = re.sub(
                r'[^\d]+', '',
                address.phone)  # Strip all non-digit characters.

        if address.address2:
            info['Address2'] = address.address2

        for key, value in info.items():
            # Endicia expects ReturnAddressX instead of FromAddressX
            if type == 'From' and 'Address' in key:
                element_key = 'Return%s' % key
            else:
                element_key = '%s%s' % (type, key)
            etree.SubElement(root, element_key).text = value
Example #5
0
    def rate(self, package, shipper, recipient, insurance='OFF', insurance_amount=0, delivery_confirmation=False, signature_confirmation=False):
        # Play nice with the other function signatures, which expect to take lists of packages.
        if not isinstance(package, Package):

            # But not too nice.
            if len(package) > 1:
                raise Exception("Can only take one Package at a time!")

            package = package[0]
        
        to_country_code = get_country_code(recipient.country)

        request = self.client.factory.create('PostageRatesRequest')
        request.RequesterID = self.credentials['partner_id']
        request.CertifiedIntermediary.AccountID = self.credentials['account_id']
        request.CertifiedIntermediary.PassPhrase = self.credentials['passphrase']

        if package.shape:
            request.MailpieceShape = package.shape

        request.MailClass = 'Domestic' if to_country_code.upper() == 'US' else 'International'
        request.WeightOz = package.weight_in_ozs
        request.MailpieceDimensions.Length = package.length
        request.MailpieceDimensions.Width = package.width
        request.MailpieceDimensions.Height = package.height

        request.FromPostalCode = shipper.zip
        request.ToPostalCode = recipient.zip
        request.ToCountryCode = to_country_code

        request.CODAmount = 0
        request.InsuredValue = insurance_amount
        request.RegisteredMailValue = package.value

        request.Services._InsuredMail = insurance
        if delivery_confirmation:
            request.Services._DeliveryConfirmation = 'ON'
        if signature_confirmation:
            request.Services._SignatureConfirmation = 'ON'

        try:
            reply = self.client.service.CalculatePostageRates(request)
            if reply.Status != 0:
                raise EndiciaError(reply.ErrorMessage)
            logger.debug(reply)

            response = { 'status': reply.Status, 'info': list() }

            for details in reply.PostagePrice:
                response['info'].append({
                    'service': details.Postage.MailService,
                    'package': details.MailClass,
                    'delivery_day': '',
                    'cost': details._TotalAmount
                })
            return response
        except suds.WebFault as e:
            raise EndiciaWebError(e.fault, e.document)
    def rate(self, package, shipper, recipient, insurance='OFF', insurance_amount=0, delivery_confirmation=False, signature_confirmation=False):
        response = {'info': []}

        # Play nice with the other function signatures, which expect to take lists of packages.
        if not isinstance(package, Package):

            # But not too nice.
            if len(package) > 1:
                raise Exception("Can only take one Package at a time!")

            package = package[0]

        shipper.country_code = get_country_code(shipper.country)
        recipient.country_code = get_country_code(recipient.country)

        rate_request = FedexRateServiceRequest(self.config)
        rate_request = self._prepare_request(rate_request, shipper, recipient, package)
        rate_request.RequestedShipment.ServiceType = None
        rate_request.RequestedShipment.EdtRequestType = 'NONE'
        rate_request.RequestedShipment.PackageDetail = 'INDIVIDUAL_PACKAGES'
        rate_request.RequestedShipment.ShippingChargesPayment.Payor.AccountNumber = self.config.account_number

        seen_quotes = []

        try:
            rate_request.send_request()

            for service in rate_request.response.RateReplyDetails:
                for detail in service.RatedShipmentDetails:
                    response['info'].append({
                        'service': service.ServiceType,
                        'package': service.PackagingType,
                        'delivery_day': '',
                        'cost': float(detail.ShipmentRateDetail.TotalNetFedExCharge.Amount)
                    })

        except Exception as e:
            raise FedExError(e)

        return response
Example #7
0
    def _add_address(self, address, type, root):
        info = dict()
        info['Company'] = address.company_name
        info['Name'] = address.name
        info['Address1'] = address.address1
        info['City'] = address.city
        info['State'] = address.state
        info['PostalCode'] = address.zip
        info['CountryCode'] = get_country_code(address.country.upper())

        if address.phone:
            info['Phone'] = re.sub(r'[^\d]+', '', address.phone) # Strip all non-digit characters.

        if address.address2:
            info['Address2'] = address.address2
        
        for key, value in info.items():
            # Endicia expects ReturnAddressX instead of FromAddressX
            if type == 'From' and 'Address' in key:
                element_key = 'Return%s' % key
            else:
                element_key = '%s%s' % (type, key)
            etree.SubElement(root, element_key).text = value
Example #8
0
    def _get_xml(self):
        root = etree.Element('LabelRequest')
        root.set('LabelType', self.label_type)
        root.set('LabelSize', self.label_size)
        root.set('ImageFormat', self.image_format)
        if self.debug:
            root.set('Test', 'YES')

        etree.SubElement(root, u'RequesterID').text = self.partner_id
        etree.SubElement(root, u'AccountID').text = self.account_id
        etree.SubElement(root, u'PassPhrase').text = self.passphrase

        etree.SubElement(root, u'MailClass').text = self.package.mail_class
        etree.SubElement(root, u'WeightOz').text = self.package.weight_oz
        etree.SubElement(root, u'MailpieceShape').text = self.package.shape
        etree.SubElement(root, u'Stealth').text = self.stealth
        etree.SubElement(root, u'Value').text = self.package.value
        etree.SubElement(root, u'Description').text = self.package.description

        etree.SubElement(root, u'PartnerCustomerID').text = 'SomeCustomerID'
        etree.SubElement(root,
                         u'PartnerTransactionID').text = 'SomeTransactionID'

        etree.SubElement(root, u'ResponseOptions').set('PostagePrice', 'TRUE')

        self._add_address(self.shipper, 'From', root)
        self._add_address(self.recipient, 'To', root)

        etree.SubElement(root, u'Stealth').text = self.stealth
        etree.SubElement(root, u'Value').text = str(self.value)
        etree.SubElement(root,
                         u'InsuredValue').text = str(self.insurance_amount)

        etree.SubElement(root, u'DateAdvance').text = str(self.date_advance)

        services = etree.SubElement(root, u'Services')
        services.set(u'DeliveryConfirmation', self.delivery_confirmation)
        services.set(u'SignatureConfirmation', self.signature_confirmation)
        services.set(u'InsuredMail', self.insurance)

        if self.return_services:
            services.set(u'ReturnReceipt', "YES")

        dimensions = etree.SubElement(root, u'MailpieceDimensions')
        etree.SubElement(dimensions, u'Length').text = str(self.package.length)
        etree.SubElement(dimensions, u'Width').text = str(self.package.width)
        etree.SubElement(dimensions, u'Height').text = str(self.package.height)

        # Add customs info, including items.
        if self.customs:
            # Root-level customs fields.
            root.set('LabelSubtype', "Integrated")
            etree.SubElement(
                root, u'IntegratedFormType').text = self.customs.form_type
            etree.SubElement(
                root, u'CustomsSendersCopy'
            ).text = "TRUE" if self.customs.senders_copy else "FALSE"
            etree.SubElement(
                root, u'NonDeliveryOption').text = self.customs.undeliverable

            # CustomsInfo-level customs fields
            customs_info = etree.SubElement(root, u'CustomsInfo')
            etree.SubElement(customs_info,
                             u'ContentsType').text = self.customs.contents_type
            etree.SubElement(customs_info, u'ContentsExplanation'
                             ).text = self.customs.contents_explanation
            etree.SubElement(customs_info, u'NonDeliveryOption'
                             ).text = self.customs.undeliverable or "Return"

            if self.customs.eel_pfc:
                etree.SubElement(customs_info,
                                 u'EelPfc').text = self.customs.eel_pfc

            if self.customs.restriction:
                etree.SubElement(
                    customs_info,
                    u'RestrictionType').text = self.customs.restriction
                etree.SubElement(customs_info, u'RestrictionComments'
                                 ).text = self.customs.restriction_comments

            # CustomsItems
            customs_items = etree.SubElement(customs_info, u'CustomsItems')
            for item in self.customs.items:
                customs_item = etree.SubElement(customs_items, u'CustomsItem')
                etree.SubElement(customs_item,
                                 u'Description').text = item.description
                etree.SubElement(customs_item,
                                 u'Quantity').text = item.quantity
                etree.SubElement(customs_item, u'Weight').text = item.weight
                etree.SubElement(customs_item, u'Value').text = item.value

                if hasattr(item,
                           "country_of_origin") and item.country_of_origin:
                    etree.SubElement(
                        customs_item,
                        u'CountryOfOrigin').text = get_country_code(
                            item.country_of_origin)

        # Customs signature
        if self.customs and self.customs.signature:
            etree.SubElement(root, u'CustomsCertify').text = 'TRUE'
            etree.SubElement(root,
                             u'CustomsSigner').text = self.customs.signature

        #from shipping import debug_print_tree
        #debug_print_tree(root)

        return root
Example #9
0
    def rate(self,
             package,
             shipper,
             recipient,
             insurance='OFF',
             insurance_amount=0,
             delivery_confirmation=False,
             signature_confirmation=False):
        # Play nice with the other function signatures, which expect to take lists of packages.
        if not isinstance(package, Package):

            # But not too nice.
            if len(package) > 1:
                raise Exception("Can only take one Package at a time!")

            package = package[0]

        to_country_code = get_country_code(recipient.country)

        request = self.client.factory.create('PostageRatesRequest')
        request.RequesterID = self.credentials['partner_id']
        request.CertifiedIntermediary.AccountID = self.credentials[
            'account_id']
        request.CertifiedIntermediary.PassPhrase = self.credentials[
            'passphrase']

        if package.shape:
            request.MailpieceShape = package.shape

        request.MailClass = 'Domestic' if to_country_code.upper(
        ) == 'US' else 'International'
        request.WeightOz = package.weight_in_ozs
        request.MailpieceDimensions.Length = package.length
        request.MailpieceDimensions.Width = package.width
        request.MailpieceDimensions.Height = package.height

        request.FromPostalCode = shipper.zip
        request.ToPostalCode = recipient.zip
        request.ToCountryCode = to_country_code

        request.CODAmount = 0
        request.InsuredValue = insurance_amount
        request.RegisteredMailValue = package.value

        request.Services._InsuredMail = insurance
        if delivery_confirmation:
            request.Services._DeliveryConfirmation = 'ON'
        if signature_confirmation:
            request.Services._SignatureConfirmation = 'ON'

        try:
            reply = self.client.service.CalculatePostageRates(request)
            if reply.Status != 0:
                raise EndiciaError(reply.ErrorMessage)
            logger.debug(reply)

            response = {'status': reply.Status, 'info': list()}

            for details in reply.PostagePrice:
                response['info'].append({
                    'service': details.Postage.MailService,
                    'package': details.MailClass,
                    'delivery_day': '',
                    'cost': details._TotalAmount
                })
            return response
        except suds.WebFault as e:
            raise EndiciaWebError(e.fault, e.document)
Example #10
0
    def _get_xml(self):
        root = etree.Element('LabelRequest')
        root.set('LabelType', self.label_type)
        root.set('LabelSize', self.label_size)
        root.set('ImageFormat', self.image_format)
        if self.debug:
            root.set('Test', 'YES')
        
        etree.SubElement(root, u'RequesterID').text = self.partner_id
        etree.SubElement(root, u'AccountID').text = self.account_id
        etree.SubElement(root, u'PassPhrase').text = self.passphrase
        
        etree.SubElement(root, u'MailClass').text = self.package.mail_class
        etree.SubElement(root, u'WeightOz').text = self.package.weight_oz
        etree.SubElement(root, u'MailpieceShape').text = self.package.shape
        etree.SubElement(root, u'Stealth').text = self.stealth
        etree.SubElement(root, u'Value').text = self.package.value
        etree.SubElement(root, u'Description').text = self.package.description
        
        etree.SubElement(root, u'PartnerCustomerID').text = 'SomeCustomerID'
        etree.SubElement(root, u'PartnerTransactionID').text = 'SomeTransactionID'
        
        etree.SubElement(root, u'ResponseOptions').set('PostagePrice', 'TRUE')
        
        self._add_address(self.shipper, 'From', root)
        self._add_address(self.recipient, 'To', root)
        
        etree.SubElement(root, u'Stealth').text = self.stealth
        etree.SubElement(root, u'Value').text = str(self.value)
        etree.SubElement(root, u'InsuredValue').text = str(self.insurance_amount)

        etree.SubElement(root, u'DateAdvance').text = str(self.date_advance)
        
        services = etree.SubElement(root, u'Services')
        services.set(u'DeliveryConfirmation', self.delivery_confirmation)
        services.set(u'SignatureConfirmation', self.signature_confirmation)
        services.set(u'InsuredMail', self.insurance)

        if self.return_services:
            services.set(u'ReturnReceipt', "YES")
       
        dimensions = etree.SubElement(root, u'MailpieceDimensions')
        etree.SubElement(dimensions, u'Length').text = str(self.package.length)
        etree.SubElement(dimensions, u'Width').text = str(self.package.width)
        etree.SubElement(dimensions, u'Height').text = str(self.package.height)

        # Add customs info, including items.
        if self.customs:
            # Root-level customs fields.
            root.set('LabelSubtype', "Integrated")
            etree.SubElement(root, u'IntegratedFormType').text = self.customs.form_type
            etree.SubElement(root, u'CustomsSendersCopy').text = "TRUE" if self.customs.senders_copy else "FALSE"
            etree.SubElement(root, u'NonDeliveryOption').text = self.customs.undeliverable

            # CustomsInfo-level customs fields
            customs_info = etree.SubElement(root, u'CustomsInfo')
            etree.SubElement(customs_info, u'ContentsType').text = self.customs.contents_type
            etree.SubElement(customs_info, u'ContentsExplanation').text = self.customs.contents_explanation
            etree.SubElement(customs_info, u'NonDeliveryOption').text = self.customs.undeliverable or "Return"

            if self.customs.eel_pfc:
                etree.SubElement(customs_info, u'EelPfc').text = self.customs.eel_pfc

            if self.customs.restriction:
                etree.SubElement(customs_info, u'RestrictionType').text = self.customs.restriction
                etree.SubElement(customs_info, u'RestrictionComments').text = self.customs.restriction_comments

            # CustomsItems
            customs_items = etree.SubElement(customs_info, u'CustomsItems')
            for item in self.customs.items:
                customs_item = etree.SubElement(customs_items, u'CustomsItem')
                etree.SubElement(customs_item, u'Description').text = item.description
                etree.SubElement(customs_item, u'Quantity').text = item.quantity
                etree.SubElement(customs_item, u'Weight').text = item.weight
                etree.SubElement(customs_item, u'Value').text = item.value

                if hasattr(item, "country_of_origin") and item.country_of_origin:
                    etree.SubElement(customs_item, u'CountryOfOrigin').text = get_country_code(item.country_of_origin)

        # Customs signature
        if self.customs and self.customs.signature:
            etree.SubElement(root, u'CustomsCertify').text = 'TRUE'
            etree.SubElement(root, u'CustomsSigner').text = self.customs.signature
        
        #from shipping import debug_print_tree
        #debug_print_tree(root)
        
        return root
Example #11
0
    def label(self,
              package,
              shipper,
              recipient,
              customs=None,
              image_format="PNG"):
        shipper.country_code = get_country_code(shipper.country)
        recipient.country_code = get_country_code(recipient.country)
        shipment = self._prepare_request(
            FedexProcessShipmentRequest(self.config), shipper, recipient,
            package)
        shipment.RequestedShipment.ServiceType = package.mail_class

        shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = self.config.account_number

        # Specifies the label type to be returned.
        # LABEL_DATA_ONLY or COMMON2D
        shipment.RequestedShipment.LabelSpecification.LabelFormatType = 'COMMON2D'

        # Specifies which format the label file will be sent to you in.
        # DPL, EPL2, PDF, PNG, ZPLII
        shipment.RequestedShipment.LabelSpecification.ImageType = image_format
        shipment.RequestedShipment.LabelSpecification.LabelStockType = 'STOCK_4X6' if image_format == 'EPL2' else 'PAPER_4X6'
        shipment.RequestedShipment.LabelSpecification.LabelPrintingOrientation = 'BOTTOM_EDGE_OF_TEXT_FIRST'

        if customs:
            customs_label = shipment.create_wsdl_object_of_type(
                'AdditionalLabelsDetail')
            customs_label.Type = 'CUSTOMS'
            customs_label.Count = 1
            shipment.AdditionalLabels.append(customs_label)

            wsdl_customs = shipment.create_wsdl_object_of_type(
                'CustomsClearanceDetail')
            wsdl_customs.CustomsValue = shipment.create_wsdl_object_of_type(
                'Money')
            wsdl_customs.CustomsValue.Currency = 'USD'
            wsdl_customs.CustomsValue.Amount = package.value

            for item in sorted(customs.items,
                               key=lambda i: i.value,
                               reverse=True):
                wsdl_item = shipment.create_wsdl_object_of_type('Commodity')
                wsdl_item.CustomsValue = shipment.create_wsdl_object_of_type(
                    'Money')
                wsdl_item.CustomsValue.Amount = item.value
                wsdl_item.CustomsValue.Currency = 'USD'
                wsdl_item.NumberOfPieces = item.quantity
                wsdl_item.CountryOfManufacture = item.country_of_origin
                wsdl_item.Description = item.description
                wsdl_item.Weight = round(item.weight, 2)
                wsdl_customs.Commodities.append(wsdl_item)

            shipment.CustomsClearanceDetail = wsdl_customs

        try:
            shipment.send_request()

        except Exception as e:
            return {"error": str(e)}

        tracking = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[
            0].TrackingIds[0].TrackingNumber
        net_cost = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[
            0].PackageRating.PackageRateDetails[0].NetCharge.Amount

        return Label(postage=net_cost,
                     tracking=tracking,
                     format=[image_format],
                     label=[
                         base64.b64decode(
                             shipment.response.CompletedShipmentDetail.
                             CompletedPackageDetails[0].Label.Parts[0].Image)
                     ])
Example #12
0
 def __init__(self, description, quantity, weight, value, country):
     self._description = description
     self._quantity = quantity
     self._weight = weight
     self._value = value
     self._country = get_country_code(country)
Example #13
0
    def label(self, package, shipper, recipient, customs=None, image_format="EPL2"):
        shipper.country_code = get_country_code(shipper.country)
        recipient.country_code = get_country_code(recipient.country)
        invoice_date = datetime.date.today().strftime('%Y%m%d')
        data = self.templates.get_template("ShipmentConfirmRequest.mko").render(
                credentials=self.credentials, shipper=shipper, recipient=recipient,
                package=package, invoice_date=invoice_date, customs=customs,
                image_format=image_format
        )

        httpresq = urllib2.Request(url=self.endpoints["confirm"], data=data.encode('utf_8'),
                                   headers={'Content-Type': 'application/x-www-form-urlencoded'})

        reply = etree.fromstring(urllib2.urlopen(httpresq).read())
        response = { 'status': reply.find('Response/ResponseStatusDescription').text, 'info': list() }
        error = reply.find('Response/Error')

        if error:
            error_location = error.find("ErrorLocation")
            error_xpath = error_location.find("ErrorLocationElementName") if error_location else error.find("ErrorLocationElementName")
            response["error"] = error.find("ErrorDescription").text

            if error_location:
                response["error_location"] = error_location.text

            if error_xpath:
                response["error_xpath"] = error_xpath.text

            return response

        data = self.templates.get_template("ShipmentAcceptRequest.mko").render(
                credentials=self.credentials, digest=reply.find('ShipmentDigest').text
        )

        httpresq = urllib2.Request(url=self.endpoints["accept"], data=data.encode('utf_8'),
                                   headers={'Content-Type': 'application/x-www-form-urlencoded'})

        reply = etree.fromstring(urllib2.urlopen(httpresq).read())
        error = reply.find('Response/Error')

        if error:
            response = {}
            error_location = error.find("ErrorLocation")
            error_xpath = error.find("ErrorLocationElementName")
            response["error"] = error.find("ErrorDescription").text

            if error_location:
                response["error_location"] = error_location.text

            if error_xpath:
                response["error_xpath"] = error_xpath.text

            return response

        shipment = reply.find("ShipmentResults")
        label = Label(
            postage=shipment.find("ShipmentCharges/TotalCharges/MonetaryValue").text,
            shipment_id=shipment.find("ShipmentIdentificationNumber").text,
            tracking=shipment.find("PackageResults/TrackingNumber").text,
            label=[base64.b64decode(shipment.find("PackageResults/LabelImage/GraphicImage").text)],
            format=[shipment.find("PackageResults/LabelImage/LabelImageFormat/Code").text]
        )

        # UPS truncates EPL2 to EPL.
        if label.format == "EPL":
            label.format = "EPL2"

        return label