Exemplo n.º 1
0
# BOTTOM_EDGE_OF_TEXT_FIRST or TOP_EDGE_OF_TEXT_FIRST
shipment.RequestedShipment.LabelSpecification.LabelPrintingOrientation = 'BOTTOM_EDGE_OF_TEXT_FIRST'

package1_weight = shipment.create_wsdl_object_of_type('Weight')
# Weight, in pounds.
package1_weight.Value = 1.0
package1_weight.Units = "LB"

package1 = shipment.create_wsdl_object_of_type('RequestedPackageLineItem')
package1.Weight = package1_weight
# Un-comment this to see the other variables you may set on a package.
# print package1

# This adds the RequestedPackageLineItem WSDL object to the shipment. It
# increments the package count and total weight of the shipment for you.
shipment.add_package(package1)

# If you'd like to see some documentation on the ship service WSDL, un-comment
# this line. (Spammy).
# print shipment.client

# Un-comment this to see your complete, ready-to-send request as it stands
# before it is actually sent. This is useful for seeing what values you can
# change.
print shipment.RequestedShipment

# If you want to make sure that all of your entered details are valid, you
# can call this and parse it just like you would via send_request(). If
# shipment.response.HighestSeverity == "SUCCESS", your shipment is valid.
shipment.send_validation_request()
Exemplo n.º 2
0
    def process_ship(self,cr, uid, ids, context=None):
        
        do = self.browse(cr, uid, type(ids)==type([]) and ids[0] or ids, context=context)
        user = self.pool.get('res.users').browse(cr, uid, uid,  context=context)
        print do.ship_company_code
        if do.ship_company_code != 'fedex':
            return super(stock_picking, self).process_ship(cr, uid, ids, context=context)

        if not (do.logis_company and do.logis_company.ship_company_code=='fedex'):
            return super(stock_picking, self).process_ship(cr, uid, ids, context=context)
        
        from fedex.config import FedexConfig
        config_obj = FedexConfig(key=do.logis_company.fedex_key,
                             password=do.logis_company.fedex_password,
                             account_number=do.logis_company.fedex_account_number,
                             meter_number=do.logis_company.fedex_meter_number,
                             use_test_server=do.logis_company.test_mode)        

        
        from fedex.services.ship_service import FedexProcessShipmentRequest
        
#===============================================================================
#        shipment = FedexProcessShipmentRequest(config_obj)
#        
#        
# 
#        shipment.RequestedShipment.DropoffType = do.fedex_dropoff_type
#        shipment.RequestedShipment.ServiceType = do.fedex_service_type
#        shipment.RequestedShipment.PackagingType = do.fedex_packaging_type
#        shipment.RequestedShipment.PackageDetail= do.fedex_package_detail
#        
#        # Shipper contact info.
#        shipment.RequestedShipment.Shipper.Contact.PersonName = user.name
#        #@todo: check the which module add the company to do and add module dependancy 
#        shipment.RequestedShipment.Shipper.Contact.CompanyName = do.company_id.name
#        shipment.RequestedShipment.Shipper.Contact.PhoneNumber = user.address_id and user.address_id.phone or ''
#        
#        # Shipper address.
#        #@todo: check the address should have value and type is browse object
#        address = do.company_id.partner_id.address and do.company_id.partner_id.address[0] or ''
#        
#        shipment.RequestedShipment.Shipper.Address.StreetLines = [address.street, address.street2]
#        shipment.RequestedShipment.Shipper.Address.City = address.city
#        shipment.RequestedShipment.Shipper.Address.StateOrProvinceCode = address.state_id and address.state_id.code or ''
#        
#        #@tod : check which module added zip_id and add module dependancy
#         
#        #shipment.RequestedShipment.Shipper.Address.PostalCode = address.zip        
#        shipment.RequestedShipment.Shipper.Address.PostalCode = address.zip_id and address.zip_id.zipcode
#        shipment.RequestedShipment.Shipper.Address.CountryCode = address.country_id and address.country_id.code or ''
#        shipment.RequestedShipment.Shipper.Address.Residential = True
#        
#                
#        #@todo: Confirm address should have value, else raise error
#        address=do.address_id
#        # Recipient contact info.
#        shipment.RequestedShipment.Recipient.Contact.PersonName = address.partner_id and address.partner_id.name or ''
#        shipment.RequestedShipment.Recipient.Contact.CompanyName = address.partner_id and address.partner_id.name or ''
#        shipment.RequestedShipment.Recipient.Contact.PhoneNumber = address.phone or address.mobile or ''
#        
#        # Recipient address
#        shipment.RequestedShipment.Recipient.Address.StreetLines = [address.street, address.street2]
#        shipment.RequestedShipment.Recipient.Address.City = address.city
#        shipment.RequestedShipment.Recipient.Address.StateOrProvinceCode = address.state_id and address.state_id.code or ''
#        
#        #@todo : zip_id and zip : 
#        shipment.RequestedShipment.Recipient.Address.PostalCode = address.zip_id and address.zip_id.zipcode
#        shipment.RequestedShipment.Recipient.Address.CountryCode = address.country_id and address.country_id.code or ''
#        # This is needed to ensure an accurate rate quote with the response.
#        shipment.RequestedShipment.Recipient.Address.Residential = True
#        
#        # Who pays for the shipment?
#        # RECIPIENT, SENDER or THIRD_PARTY
#        shipment.RequestedShipment.ShippingChargesPayment.PaymentType = do.fedex_payment_type
#        
#        # 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 = 'PNG'
#        
#        # To use doctab stocks, you must change ImageType above to one of the
#        # label printer formats (ZPLII, EPL2, DPL).
#        # See documentation for paper types, there quite a few.
#        shipment.RequestedShipment.LabelSpecification.LabelStockType = 'PAPER_4X6'
#        
#        # This indicates if the top or bottom of the label comes out of the 
#        # printer first.
#        # BOTTOM_EDGE_OF_TEXT_FIRST or TOP_EDGE_OF_TEXT_FIRST
#        shipment.RequestedShipment.LabelSpecification.LabelPrintingOrientation = 'BOTTOM_EDGE_OF_TEXT_FIRST'
#        
#        
#===============================================================================
        
        
        if do.packages_ids:
            str_error = ''
            ship_message = ''
            for pack in do.packages_ids:
                #@todo:  If package already have Tracking no then don't process.
                shipment = FedexProcessShipmentRequest(config_obj)
                
                
        
                shipment.RequestedShipment.DropoffType = do.fedex_dropoff_type
                
                #@todo: Depending upon the Service type some of 
                shipment.RequestedShipment.ServiceType = do.fedex_service_type
                shipment.RequestedShipment.PackagingType = do.fedex_packaging_type
                shipment.RequestedShipment.PackageDetail= do.fedex_package_detail
                
                # Shipper contact info.
                shipment.RequestedShipment.Shipper.Contact.PersonName = user.name
                #@todo: check the which module add the company to do and add module dependancy 
                shipment.RequestedShipment.Shipper.Contact.CompanyName = do.company_id.name
                shipment.RequestedShipment.Shipper.Contact.PhoneNumber = user.address_id and user.address_id.phone or ''
                
                # Shipper address.
                #@todo: check the address should have value and type is browse object
                address = do.company_id.partner_id.address and do.company_id.partner_id.address[0] or ''
                
                shipment.RequestedShipment.Shipper.Address.StreetLines = [address.street or '', address.street2 or '']
                shipment.RequestedShipment.Shipper.Address.City = address.city or ''
                shipment.RequestedShipment.Shipper.Address.StateOrProvinceCode = address.state_id and address.state_id.code or ''
                
                #@tod : check which module added zip_id and add module dependancy
                 
                #shipment.RequestedShipment.Shipper.Address.PostalCode = address.zip        
                shipment.RequestedShipment.Shipper.Address.PostalCode = address.zip_id and address.zip_id.zipcode
                shipment.RequestedShipment.Shipper.Address.CountryCode = address.country_id and address.country_id.code or ''
                shipment.RequestedShipment.Shipper.Address.Residential = False
                
                        
                #@todo: Confirm address should have value, else raise error
                address=do.address_id
                # Recipient contact info.
                shipment.RequestedShipment.Recipient.Contact.PersonName = address.name or ''
                shipment.RequestedShipment.Recipient.Contact.CompanyName = address.partner_id and address.partner_id.name or ''
                shipment.RequestedShipment.Recipient.Contact.PhoneNumber = address.phone or address.mobile or ''
                
                # Recipient address
                shipment.RequestedShipment.Recipient.Address.StreetLines = [address.street or '', address.street2 or '']
                shipment.RequestedShipment.Recipient.Address.City = address.city or ''
                shipment.RequestedShipment.Recipient.Address.StateOrProvinceCode = address.state_id and address.state_id.code or ''
                
                #@todo : zip_id and zip : 
                shipment.RequestedShipment.Recipient.Address.PostalCode = address.zip_id and address.zip_id.zipcode or ''
                shipment.RequestedShipment.Recipient.Address.CountryCode = address.country_id and address.country_id.code or ''
                # This is needed to ensure an accurate rate quote with the response.
                shipment.RequestedShipment.Recipient.Address.Residential = False
                
                # Who pays for the shipment?
                # RECIPIENT, SENDER or THIRD_PARTY
                shipment.RequestedShipment.ShippingChargesPayment.PaymentType = do.fedex_payment_type
                
                # 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 = 'PNG'
                
                # To use doctab stocks, you must change ImageType above to one of the
                # label printer formats (ZPLII, EPL2, DPL).
                # See documentation for paper types, there quite a few.
                shipment.RequestedShipment.LabelSpecification.LabelStockType = 'PAPER_4X8'
                
                # This indicates if the top or bottom of the label comes out of the 
                # printer first.
                # BOTTOM_EDGE_OF_TEXT_FIRST or TOP_EDGE_OF_TEXT_FIRST
                shipment.RequestedShipment.LabelSpecification.LabelPrintingOrientation = 'BOTTOM_EDGE_OF_TEXT_FIRST'
                    
                package_weight = shipment.create_wsdl_object_of_type('Weight')
                
                # Weight, in pounds.
                package_weight.Value = pack.weight
                package_weight.Units = "LB"
                
                package = shipment.create_wsdl_object_of_type('RequestedPackageLineItem')
                package.Weight = package_weight
                
                shipment.add_package(package)
                #Create package
                #Call Print Labels
            
                #print "Shipment SEND VALIDATIOIN REQUEST : ", shipment.send_validation_request()
                #x
                
                try:
                    #print "Shipment : "
                    #print shipment.RequestedShipment
                    shipment.send_request()
        
                    shipment.response.HighestSeverity
                    print "Shipment Response"
                    print shipment.response
                    # Getting the tracking number from the new shipment.
                    tracking_no = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[0].TrackingIds[0].TrackingNumber
                    # Net shipping costs.
                    
                    
                    ascii_label_data = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[0].Label.Parts[0].Image
                    logo = binascii.b2a_base64(str(b64decode(ascii_label_data)))
                    
                    
                    #@todo : if payment type is not SENDER ( may if Recipeint or THIRD PARTY ) the  PackageRating will not present in response, so the next line will be error
                    shipping_cost = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[0].PackageRating.PackageRateDetails[0].NetCharge.Amount
                    
                    #@todo: There is a lot of dfferent rates will present in response, need to clarify it.
                    self.pool.get('stock.packages').write(cr, uid, pack.id, {
                                                                                'logo': logo,
                                                                                'negotiated_rates' : shipping_cost,
                                                                                'tracking_no'   : tracking_no, 
                                                                                'ship_message' : shipment.response.HighestSeverity
                                                                              }, context=context)
                    
                    
                except Exception, e:
                    print "ERROR : ", e
                    str_error =  str_error + str(e)
                    
                    #raise osv.except_osv(_('Error'), _('%s' % (e)))
            if str_error:
                #@todo : if some package lines are process successfully and some other failed then now the status will show error.
                # it need cancell all other succeeded shipment and show error msg.
                # or show appropriate msg for each and every packages .
                #@attention: Must cancel other entris or should check the Tracking no befor doing the process, instead of creating new at everytime.
                self.write(cr, uid, do.id, {'ship_message': str_error}, context=context)
            else :
                self.write(cr, uid, do.id, {'ship_state':'ready_pick','ship_message': 'Shipment has been processed.'}, context=context)
                return {
                    'type': 'ir.actions.report.xml',
                    'report_name':'multiple.label.print',
                    'datas': {
                            'model':'stock.picking',
                            'id': ids and ids[0] or False,
                            'ids': ids and ids or [],
                            'report_type': 'pdf'
                        },
                    'nodestroy': True
                    }
Exemplo n.º 3
0
shipment.RequestedShipment.ShippingChargesPayment.PaymentType = 'SENDER'

# Senders account information
shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = CONFIG_OBJ.account_number

# Label config.
transfer_config_dict(shipment.RequestedShipment.LabelSpecification,
                     LABEL_SPECIFICATION)

package1_weight = shipment.create_wsdl_object_of_type('Weight')
package1_weight.Value = 1.0
package1_weight.Units = "LB"
package1 = shipment.create_wsdl_object_of_type('RequestedPackageLineItem')
package1.Weight = package1_weight
shipment.add_package(package1)

if __name__ == "__main__":
    shipment.send_request()
    device = LabelPrinterClass(shipment)
    device.print_label()

    shipment.RequestedShipment.Recipient.Address.StreetLines = ['456 Peach St']
    shipment.RequestedShipment.Recipient.Address.City = 'Atlanta'
    shipment.RequestedShipment.Recipient.Address.StateOrProvinceCode = 'GA'
    shipment.RequestedShipment.Recipient.Address.PostalCode = '30303'
    shipment.RequestedShipment.Recipient.Address.CountryCode = 'US'

    shipment.send_request()
    device = LabelPrinterClass(shipment)
    device.print_label()
Exemplo n.º 4
0
    def test_create_delete_shipment(self):
        shipment = FedexProcessShipmentRequest(CONFIG_OBJ)

        shipment.RequestedShipment.DropoffType = 'REGULAR_PICKUP'
        shipment.RequestedShipment.ServiceType = 'FEDEX_GROUND'
        shipment.RequestedShipment.PackagingType = 'YOUR_PACKAGING'

        shipment.RequestedShipment.Shipper.Contact.PersonName = 'Sender Name'
        shipment.RequestedShipment.Shipper.Contact.PhoneNumber = '9012638716'

        shipment.RequestedShipment.Shipper.Address.StreetLines = [
            'Address Line 1'
        ]
        shipment.RequestedShipment.Shipper.Address.City = 'Herndon'
        shipment.RequestedShipment.Shipper.Address.StateOrProvinceCode = 'VA'
        shipment.RequestedShipment.Shipper.Address.PostalCode = '20171'
        shipment.RequestedShipment.Shipper.Address.CountryCode = 'US'

        shipment.RequestedShipment.Recipient.Contact.PersonName = 'Recipient Name'
        shipment.RequestedShipment.Recipient.Contact.PhoneNumber = '9012637906'

        shipment.RequestedShipment.Recipient.Address.StreetLines = [
            'Address Line 1'
        ]
        shipment.RequestedShipment.Recipient.Address.City = 'Herndon'
        shipment.RequestedShipment.Recipient.Address.StateOrProvinceCode = 'VA'
        shipment.RequestedShipment.Recipient.Address.PostalCode = '20171'
        shipment.RequestedShipment.Recipient.Address.CountryCode = 'US'
        shipment.RequestedShipment.EdtRequestType = 'NONE'

        shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber \
            = CONFIG_OBJ.account_number

        shipment.RequestedShipment.ShippingChargesPayment.PaymentType = 'SENDER'

        shipment.RequestedShipment.LabelSpecification.LabelFormatType = 'COMMON2D'
        shipment.RequestedShipment.LabelSpecification.ImageType = 'PNG'
        shipment.RequestedShipment.LabelSpecification.LabelStockType = 'PAPER_7X4.75'
        shipment.RequestedShipment.LabelSpecification.LabelPrintingOrientation = 'BOTTOM_EDGE_OF_TEXT_FIRST'

        # Use order if setting multiple labels or delete
        del shipment.RequestedShipment.LabelSpecification.LabelOrder

        package1_weight = shipment.create_wsdl_object_of_type('Weight')
        package1_weight.Value = 2.0
        package1_weight.Units = "LB"
        package1 = shipment.create_wsdl_object_of_type(
            'RequestedPackageLineItem')
        package1.PhysicalPackaging = 'ENVELOPE'
        package1.Weight = package1_weight
        shipment.add_package(package1)

        shipment.send_validation_request()
        shipment.send_request()

        assert shipment.response
        assert shipment.response.HighestSeverity in ['SUCCESS', 'WARNING']
        track_id = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[
            0].TrackingIds[0].TrackingNumber
        assert track_id

        del_shipment = FedexDeleteShipmentRequest(CONFIG_OBJ)
        del_shipment.DeletionControlType = "DELETE_ALL_PACKAGES"
        del_shipment.TrackingId.TrackingNumber = track_id
        del_shipment.TrackingId.TrackingIdType = 'EXPRESS'

        del_shipment.send_request()

        assert del_shipment.response
Exemplo n.º 5
0
    def fedex_get_label(self, picking, data):
        GENERATE_IMAGE_TYPE = 'PDF'
        CONFIG_OBJ = FedexConfig(key=self.fedex_developer_key,
                                 password=self.fedex_developer_password,
                                 account_number=self.fedex_account_number,
                                 meter_number=self.fedex_meter_number,
                                 use_test_server=True if self.fedex_environment
                                 == 'test' else False)
        shipment = FedexProcessShipmentRequest(
            CONFIG_OBJ, customer_transaction_id="Label for %s" % picking.name)
        # REGULAR_PICKUP, REQUEST_COURIER, DROP_BOX, BUSINESS_SERVICE_CENTER or STATION
        shipment.RequestedShipment.DropoffType = 'REGULAR_PICKUP'
        # See page 355 in WS_ShipService.pdf for a full list. Here are the common ones:
        # STANDARD_OVERNIGHT, PRIORITY_OVERNIGHT, FEDEX_GROUND, FEDEX_EXPRESS_SAVER,
        # FEDEX_2_DAY, INTERNATIONAL_PRIORITY, SAME_DAY, INTERNATIONAL_ECONOMY
        # shipment.RequestedShipment.ServiceType = data['serviceCode'].upper()  # TODO mapping SS and FedEx
        shipment.RequestedShipment.ServiceType = data['fedex_code']
        # FEDEX_BOX, FEDEX_PAK, FEDEX_TUBE, YOUR_PACKAGING, FEDEX_ENVELOPE
        shipment.RequestedShipment.PackagingType = 'YOUR_PACKAGING'
        # Shipper contact info.
        # shipment.RequestedShipment.Shipper.Contact.PersonName = 'Sender Name'
        shipment.RequestedShipment.Shipper.Contact.CompanyName = 'Vertical4'
        shipment.RequestedShipment.Shipper.Contact.PhoneNumber = '3136408402'
        # Shipper address.
        shipment.RequestedShipment.Shipper.Address.StreetLines = '15004 3rd Ave'
        shipment.RequestedShipment.Shipper.Address.City = 'Highland Park'
        shipment.RequestedShipment.Shipper.Address.PostalCode = '48203-3718'
        shipment.RequestedShipment.Shipper.Address.StateOrProvinceCode = 'MI'
        shipment.RequestedShipment.Shipper.Address.CountryCode = 'US'
        # Recipient contact info.
        shipment.RequestedShipment.Recipient.Contact.PersonName = data[
            'shipTo']['name']
        # shipment.RequestedShipment.Recipient.Contact.CompanyName =
        shipment.RequestedShipment.Recipient.Contact.PhoneNumber = data[
            'shipTo']['phone']
        # Recipient address
        shipment.RequestedShipment.Recipient.Address.StreetLines = picking.partner_id.street
        shipment.RequestedShipment.Recipient.Address.City = data['shipTo'][
            'city']
        shipment.RequestedShipment.Recipient.Address.PostalCode = data[
            'shipTo']['postalCode']
        shipment.RequestedShipment.Recipient.Address.StateOrProvinceCode = data[
            'shipTo']['state']
        shipment.RequestedShipment.Recipient.Address.CountryCode = data[
            'shipTo']['country']
        shipment.RequestedShipment.Recipient.Address.Residential = picking.residential
        # shipment.RequestedShipment.Recipient.Address.Residential = False
        # This is needed to ensure an accurate rate quote with the response. Use AddressValidation to get ResidentialStatus
        # shipment.RequestedShipment.Recipient.Address.Residential = True
        shipment.RequestedShipment.EdtRequestType = 'NONE'

        # Senders account information
        shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = CONFIG_OBJ.account_number

        # Who pays for the shipment?
        # RECIPIENT, SENDER or THIRD_PARTY
        shipment.RequestedShipment.ShippingChargesPayment.PaymentType = 'SENDER'

        # 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 = GENERATE_IMAGE_TYPE

        # To use doctab stocks, you must change ImageType above to one of the
        # label printer formats (ZPLII, EPL2, DPL).
        # See documentation for paper types, there quite a few.
        shipment.RequestedShipment.LabelSpecification.LabelStockType = 'STOCK_4X6'
        # This indicates if the top or bottom of the label comes out of the
        # printer first.
        # BOTTOM_EDGE_OF_TEXT_FIRST or TOP_EDGE_OF_TEXT_FIRST
        # Timestamp in YYYY-MM-DDThh:mm:ss format, e.g. 2002-05-30T09:00:00
        shipment.RequestedShipment.ShipTimestamp = datetime.now().replace(
            microsecond=0).isoformat()

        # BOTTOM_EDGE_OF_TEXT_FIRST, TOP_EDGE_OF_TEXT_FIRST
        shipment.RequestedShipment.LabelSpecification.LabelPrintingOrientation = 'TOP_EDGE_OF_TEXT_FIRST'

        # Delete the flags we don't want.
        # Can be SHIPPING_LABEL_FIRST, SHIPPING_LABEL_LAST or delete
        if hasattr(shipment.RequestedShipment.LabelSpecification,
                   'LabelOrder'):
            del shipment.RequestedShipment.LabelSpecification.LabelOrder  # Delete, not using.

        package1_weight = shipment.create_wsdl_object_of_type('Weight')
        package1_weight.Value = int(data['weight']['value'])
        package1_weight.Units = "LB"

        package1_dimensions = shipment.create_wsdl_object_of_type('Dimensions')
        package1_dimensions.Length = int(data['dimensions']['length'])
        package1_dimensions.Width = int(data['dimensions']['width'])
        package1_dimensions.Height = int(data['dimensions']['height'])
        package1_dimensions.Units = 'IN'

        package1 = shipment.create_wsdl_object_of_type(
            'RequestedPackageLineItem')
        package1.Weight = package1_weight
        package1.Dimensions = package1_dimensions
        package1.PhysicalPackaging = 'BOX'
        package1.GroupPackageCount = 1
        customer_reference = shipment.create_wsdl_object_of_type(
            'CustomerReference')
        customer_reference.CustomerReferenceType = 'CUSTOMER_REFERENCE'
        customer_reference.Value = picking.origin
        package1.CustomerReferences.append(customer_reference)

        # Add a signature option for the package using SpecialServicesRequested or comment out.
        # SpecialServiceTypes can be APPOINTMENT_DELIVERY, COD, DANGEROUS_GOODS, DRY_ICE, SIGNATURE_OPTION etc..
        # package1.SpecialServicesRequested.SpecialServiceTypes = 'SIGNATURE_OPTION'
        # SignatureOptionType can be ADULT, DIRECT, INDIRECT, NO_SIGNATURE_REQUIRED, SERVICE_DEFAULT
        # package1.SpecialServicesRequested.SignatureOptionDetail.OptionType = 'SERVICE_DEFAULT'
        shipment.add_package(package1)
        shipment.send_request()
        # This will convert the response to a python dict object. To
        # make it easier to work with. Also see basic_sobject_to_dict, it's faster but lacks options.
        response_dict = sobject_to_dict(shipment.response)
        response_dict['CompletedShipmentDetail']['CompletedPackageDetails'][0][
            'Label']['Parts'][0]['Image'] = ''
        print(response_dict)  # Image is empty string for display purposes.
        # Here is the overall end result of the query.
        print("HighestSeverity: {}".format(shipment.response.HighestSeverity))
        # Getting the tracking number from the new shipment.
        print("Tracking #: {}"
              "".format(
                  shipment.response.CompletedShipmentDetail.
                  CompletedPackageDetails[0].TrackingIds[0].TrackingNumber))
        # Net shipping costs. Only show if available. Sometimes sandbox will not include this in the response.
        CompletedPackageDetails = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[
            0]
        if hasattr(CompletedPackageDetails, 'PackageRating'):
            print("Net Shipping Cost (US$): {}"
                  "".format(CompletedPackageDetails.PackageRating.
                            PackageRateDetails[0].NetCharge.Amount))
        else:
            print('WARNING: Unable to get shipping rate.')
        ascii_label_data = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[
            0].Label.Parts[0].Image
        label_binary_data = binascii.a2b_base64(ascii_label_data)
        out_path = '/var/tmp/example_shipment_label.%s' % GENERATE_IMAGE_TYPE.lower(
        )
        print("Writing to file {}".format(out_path))
        out_file = open(out_path, 'wb')
        out_file.write(label_binary_data)
        out_file.close()
        result = {
            'trackingNumber':
            shipment.response.CompletedShipmentDetail.
            CompletedPackageDetails[0].TrackingIds[0].TrackingNumber,
            'voided':
            False,
            'shipmentId':
            '',
            'labelData':
            ascii_label_data
        }
        return result
Exemplo n.º 6
0
    def fedex_send_shipping(self, pickings):
        try:

            result = {
                'exact_price': 0,
                'weight': 0,
                'date_delivery': None,
                'tracking_number': '',
                'attachments': []
            }
            packaging_ids = self.wk_group_by_packaging(pickings=pickings)
            MasterTrackingIds = dict()
            product_uom_obj = self.env['uom.uom']
            currency_id = pickings.sale_id.currency_id and pickings.sale_id.currency_id or pickings.company_id.currency_id
            total_package = 0
            for packaging_id, package_ids in packaging_ids.items():
                self.wk_validate_data(pickings=pickings)
                number_of_packages = len(package_ids)
                total_package += number_of_packages
                for index, package_id in enumerate(package_ids, 1):
                    # _logger.info(
                    #     "WK  %r [%r/%r] %r : %r kg",
                    #     packaging_id,
                    #     number_of_packages,
                    #     total_package,package_id.name,
                    #     package_id.shipping_weight
                    # )

                    shipment = FedexProcessShipmentRequest(self.config_fedex())
                    if number_of_packages > 1:
                        shipment.RequestedShipment.PackageCount = number_of_packages - 1
                    shipment.RequestedShipment.LabelSpecification.LabelFormatType = 'COMMON2D'
                    shipment.RequestedShipment.LabelSpecification.ImageType = 'PNG'
                    shipment.RequestedShipment.LabelSpecification.LabelStockType = self.fedex_label_stock_type
                    shipment.RequestedShipment.LabelSpecification.LabelPrintingOrientation = 'BOTTOM_EDGE_OF_TEXT_FIRST'
                    #####################################
                    if packaging_id.fedex_edt_request_type == 'ALL':
                        shipment.RequestedShipment.SpecialServicesRequested.SpecialServiceTypes = "ELECTRONIC_TRADE_DOCUMENTS"
                        shipment.RequestedShipment.SpecialServicesRequested.EtdDetail.RequestedDocumentCopies = "COMMERCIAL_INVOICE"
                        spec = shipment.create_wsdl_object_of_type(
                            'ShippingDocumentSpecification')
                        spec.ShippingDocumentTypes = 'COMMERCIAL_INVOICE'
                        spec_format = shipment.create_wsdl_object_of_type(
                            'ShippingDocumentFormat')
                        spec_format.ImageType = 'PDF'
                        spec_format.StockType = 'PAPER_LETTER'
                        spec.CommercialInvoiceDetail.Format = spec_format
                        shipment.RequestedShipment.ShippingDocumentSpecification = spec
                    #####################################
                    shipment = self.fedex_preprocessing(shipment,
                                                        packaging_id,
                                                        pickings=pickings,
                                                        package_id=package_id)
                    weight = self._get_api_weight(package_id.shipping_weight)
                    weight = weight and weight or self.default_product_weight

                    package = self.get_fedex_package(shipment, weight,
                                                     packaging_id.length,
                                                     packaging_id.width,
                                                     packaging_id.height,
                                                     packaging_id)
                    package.ItemDescription = package_id.description

                    package.SequenceNumber = index
                    if index == 1:
                        if package_id.cover_amount:
                            package.InsuredValue.Amount = package_id.cover_amount
                            package.InsuredValue.Currency = currency_id.name
                        shipment.add_package(package)

                        shipment.send_request()
                        CompletedPackageDetails = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[
                            0]
                        MasterTrackingIds[
                            packaging_id] = CompletedPackageDetails.TrackingIds[
                                0].TrackingNumber

                    else:
                        if number_of_packages > 1:
                            shipment.RequestedShipment.MasterTrackingId.TrackingIdType = self.fedex_trackingid_type
                            shipment.RequestedShipment.MasterTrackingId.TrackingNumber = MasterTrackingIds.get(
                                packaging_id)
                        shipment.add_package(package)
                        shipment.send_request()

                        CompletedPackageDetails = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[
                            0]
                    TrackingNumber = CompletedPackageDetails.TrackingIds[
                        0].TrackingNumber
                    image = CompletedPackageDetails.Label.Parts[0].Image

                    result['attachments'].append(
                        ('FedEx' + str(TrackingNumber) + '.png',
                         binascii.a2b_base64(str(image))))
                    result['tracking_number'] += ',' + TrackingNumber
                    result['weight'] += weight

                    Amount = hasattr(
                        CompletedPackageDetails, 'PackageRating'
                    ) and CompletedPackageDetails.PackageRating.PackageRateDetails[
                        0].NetCharge.Amount or 0
                    if Amount:
                        CurrencyCode = CompletedPackageDetails.PackageRating.PackageRateDetails[
                            0].NetCharge.Currency
                        if currency_id.name == CurrencyCode:
                            result['exact_price'] += Amount
                        else:
                            currency = currency_id.search(
                                [('name', '=', CurrencyCode)], limit=1)
                            result['exact_price'] += currency.compute(
                                Amount, currency_id)
            pickings.number_of_packages = total_package
            return result
        except (FedexError, FedexFailure, SchemaValidationError) as f_err:
            pickings.message_post(body=f_err.value, subject="FedEx Error:")
            _logger.warning(
                "#1 FEDEX SEND SHIPMENT ERROR-------%r---------------",
                f_err.value)
            raise ValidationError(f_err.value)
        except Exception as e:
            pickings.message_post(body=e, subject="FedEx Error:")
            _logger.warning('#2 FEDEX SEND SHIPMENT ERROR--%r', e)
            raise ValidationError(e)
Exemplo n.º 7
0
class FedexLabelHelper:
    mCommodities = []

    def __init__(self):
        pass

    # ----------------------------------------------------
    # set overall shipment configuration
    def setShipmentConfig(
        self,
        CONFIG_OBJ,
        invoice_info,
        cust_tran_id="*** ShipService Request v17 using Python ***",
        dropoffType="BUSINESS_SERVICE_CENTER",
        shippingPaymentType="SENDER",
        labelFormatType="COMMON2D",
        labelSpecificationImageType="PDF",
        labelSpecificationStockType="PAPER_7X4.75",
        labelPrintingOrientation="TOP_EDGE_OF_TEXT_FIRST",
        LabelOrder="SHIPPING_LABEL_FIRST",
    ):
        self.invoice_info = invoice_info
        self.dropoffType = dropoffType
        self.serviceType = "INTERNATIONAL_PRIORITY" if invoice_info[
            "ShippingExpress"] == True else "INTERNATIONAL_ECONOMY"
        self.mCommodities.clear()
        self.CONFIG_OBJ = CONFIG_OBJ
        self.shipment = FedexProcessShipmentRequest(
            CONFIG_OBJ, customer_transaction_id=cust_tran_id)

        self.shipment.RequestedShipment.DropoffType = dropoffType
        self.shipment.RequestedShipment.ServiceType = self.serviceType
        self.shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = CONFIG_OBJ.account_number
        self.shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Address.CountryCode = "DK"
        self.shipment.RequestedShipment.ShippingChargesPayment.PaymentType = shippingPaymentType

        labelSpecification = self.shipment.create_wsdl_object_of_type(
            "LabelSpecification")
        labelSpecification.LabelFormatType = labelFormatType
        labelSpecification.LabelStockType = labelSpecificationStockType
        labelSpecification.ImageType = labelSpecificationImageType
        labelSpecification.LabelOrder = LabelOrder
        labelSpecification.LabelPrintingOrientation = labelPrintingOrientation
        self.shipment.RequestedShipment.LabelSpecification = labelSpecification

    # ----------------------------------------------------
    # set sender information
    def setSenderInfo(self, sender):

        self.shipment.RequestedShipment.Shipper.Contact.PersonName = sender[
            "Name"]
        self.shipment.RequestedShipment.Shipper.Contact.CompanyName = sender[
            "Company"]
        self.shipment.RequestedShipment.Shipper.Contact.PhoneNumber = sender[
            "Phone"]
        self.shipment.RequestedShipment.Shipper.Contact.EMailAddress = sender[
            "Email"]
        self.shipment.RequestedShipment.Shipper.Address.StreetLines = sender[
            "Address"]
        self.shipment.RequestedShipment.Shipper.Address.City = sender["City"]
        self.shipment.RequestedShipment.Shipper.Address.StateOrProvinceCode = sender[
            "Region"]
        self.shipment.RequestedShipment.Shipper.Address.PostalCode = sender[
            "Zip"]
        self.shipment.RequestedShipment.Shipper.Address.CountryCode = sender[
            "CountryCode"]
        self.shipment.RequestedShipment.Shipper.Address.Residential = sender[
            "Residential"]

        ti = self.shipment.create_wsdl_object_of_type("TaxpayerIdentification")
        ti.Number = sender["VAT"]
        ti.TinType = "BUSINESS_NATIONAL"
        self.shipment.RequestedShipment.Shipper.Tins = ti

    # ----------------------------------------------------
    # upload all documents (invoice and product information)
    def upload_all_documents(self):
        doc_ids = []
        doc_ids.append(
            self.upload_document(self.invoice_info["InvoicePath"],
                                 "COMMERCIAL_INVOICE"))

        for pdf in self.invoice_info["Pdfs"]:
            doc_ids.append(self.upload_document(pdf, "OTHER"))

        return doc_ids

    # ----------------------------------------------------
    # function for uploading documents as electronic trade documents and getting the response doc IDs
    def upload_document(self, path, type):
        from fedex.services.document_service import FedexDocumentServiceRequest

        # specify prefix for use in attachment naming
        if type == "COMMERCIAL_INVOICE":
            prefix = "invoice_"
        else:
            prefix = "product_description_"

        uploadRequest = FedexDocumentServiceRequest(self.CONFIG_OBJ)
        uploadRequest.OriginCountryCode = "DK"
        uploadRequest.DestinationCountryCode = self.shipment.RequestedShipment.Recipient.Address.CountryCode
        uploadRequest.Usage = "ELECTRONIC_TRADE_DOCUMENTS"

        clientdetails = uploadRequest.create_wsdl_object_of_type(
            "ClientDetail")
        clientdetails.AccountNumber = self.CONFIG_OBJ.account_number
        clientdetails.MeterNumber = self.CONFIG_OBJ.meter_number
        uploadRequest.ClientDetail = clientdetails

        webAuthDetails = uploadRequest.create_wsdl_object_of_type(
            "WebAuthenticationDetail")
        webAuthDetails.ParentCredential.Key = self.CONFIG_OBJ.key
        webAuthDetails.ParentCredential.Password = self.CONFIG_OBJ.password
        webAuthDetails.UserCredential.Key = self.CONFIG_OBJ.key
        webAuthDetails.UserCredential.Password = self.CONFIG_OBJ.password
        uploadRequest.WebAuthenticationDetail = webAuthDetails

        docdetails = uploadRequest.create_wsdl_object_of_type(
            "UploadDocumentDetail")
        docdetails.LineNumber = 1
        docdetails.DocumentType = type
        docdetails.FileName = prefix + path
        fileContent = open(path, "rb").read()
        fileBase64 = binascii.b2a_base64(fileContent)
        docdetails.DocumentContent = fileBase64.decode("cp1250")
        uploadRequest.Documents = docdetails

        uploadRequest.send_request()

        doc_id = uploadRequest.response.DocumentStatuses[0].DocumentId

        return doc_id

    # ----------------------------------------------------
    # set recipient information
    def setRecipientInfo(self, recipient):
        self.shipment.RequestedShipment.Recipient.Contact.PersonName = recipient[
            "Name"]
        self.shipment.RequestedShipment.Recipient.Contact.CompanyName = recipient[
            "Company"]
        self.shipment.RequestedShipment.Recipient.Contact.PhoneNumber = recipient[
            "Phone"]
        self.shipment.RequestedShipment.Recipient.Contact.EMailAddress = recipient[
            "Email"]
        self.shipment.RequestedShipment.Recipient.Address.StreetLines = recipient[
            "Address"]
        self.shipment.RequestedShipment.Recipient.Address.City = recipient[
            "City"]
        self.shipment.RequestedShipment.Recipient.Address.StateOrProvinceCode = recipient[
            "Region"]
        self.shipment.RequestedShipment.Recipient.Address.PostalCode = recipient[
            "Zip"]
        self.shipment.RequestedShipment.Recipient.Address.CountryCode = recipient[
            "CountryCode"]
        self.shipment.RequestedShipment.Recipient.Address.Residential = recipient[
            "Residential"]

        ti = self.shipment.create_wsdl_object_of_type("TaxpayerIdentification")
        ti.Number = recipient["VAT"]
        ti.TinType = "BUSINESS_NATIONAL"
        self.shipment.RequestedShipment.Recipient.Tins = ti

    # ----------------------------------------------------
    # add "commercial invoice" reference as the only commodity
    def add_ci_commodity(self):

        self.addCommodity(
            cCustomsValueAmnt=self.invoice_info["Value"],
            cCustomsValueCurrency=self.invoice_info["Currency"],
            cWeightValue=self.invoice_info["Weight"],
            cDescription="See attached commercial invoice",
            cQuantity=self.invoice_info["Quantity"],
            cExportLicenseNumber=self.shipment.RequestedShipment.Shipper.Tins.
            Number,
            cPartNumber=1,
        )

    # ----------------------------------------------------
    # add commodity to shipment (for now, just add 1 commodity to refer to attached CI)
    def addCommodity(
        self,
        cCustomsValueAmnt,
        cCustomsValueCurrency,
        cWeightValue,
        cDescription,
        cQuantity,
        cExportLicenseNumber,
        cPartNumber,
    ):

        commodity = self.shipment.create_wsdl_object_of_type("Commodity")
        commodity.NumberOfPieces = str(cQuantity)
        commodity.Description = cDescription
        commodity.Quantity = cQuantity
        commodity.QuantityUnits = "EA"
        commodity.ExportLicenseNumber = cExportLicenseNumber
        commodity.PartNumber = cPartNumber
        commodity.CountryOfManufacture = "DK"

        mCustomsValue = self.shipment.create_wsdl_object_of_type("Money")
        mCustomsValue.Amount = cCustomsValueAmnt
        mCustomsValue.Currency = cCustomsValueCurrency
        commodity.CustomsValue = mCustomsValue

        commodity_weight = self.shipment.create_wsdl_object_of_type("Weight")
        commodity_weight.Value = cWeightValue
        commodity_weight.Units = "KG"
        commodity.Weight = commodity_weight

        munitPrice = self.shipment.create_wsdl_object_of_type("Money")
        munitPrice.Amount = float(round((cCustomsValueAmnt / cQuantity), 2))
        munitPrice.Currency = cCustomsValueCurrency
        commodity.UnitPrice = munitPrice

        self.mCommodities.append(commodity)

    # ----------------------------------------------------
    # add package to shipment
    def set_packaging_info(self):
        weight = self.invoice_info["Weight"]

        type = "BOX" if weight > 0.5 else "ENVELOPE"
        weight_final = float(round(weight + 0.2, 2)) if weight > 0.5 else 0.4

        self.addShippingPackage(packageWeight=weight_final,
                                physicalPackagingType=type,
                                packagingType=f"FEDEX_{type}")

    # ----------------------------------------------------
    # add package to shipment
    def addShippingPackage(self,
                           packageWeight,
                           physicalPackagingType,
                           packagingType,
                           packageWeightUnit="KG"):
        package_weight = self.shipment.create_wsdl_object_of_type("Weight")
        package_weight.Value = packageWeight
        package_weight.Units = packageWeightUnit

        package = self.shipment.create_wsdl_object_of_type(
            "RequestedPackageLineItem")
        package.PhysicalPackaging = physicalPackagingType
        package.Weight = package_weight

        self.shipment.add_package(package)
        self.shipment.RequestedShipment.TotalWeight = package_weight
        self.shipment.RequestedShipment.PackagingType = packagingType

    # ----------------------------------------------------
    # add information on duties
    def setDutiesPaymentInfo(self):
        mPayment = self.shipment.create_wsdl_object_of_type("Payment")
        mPayment.PaymentType = "RECIPIENT"  # change if sender should pay duties

        mCustomsValue = self.shipment.create_wsdl_object_of_type("Money")
        mCustomsValue.Amount = self.invoice_info["Value"]
        mCustomsValue.Currency = self.invoice_info["Currency"]

        ccd = self.shipment.create_wsdl_object_of_type(
            "CustomsClearanceDetail")
        ccd.Commodities = self.mCommodities
        ccd.CustomsValue = mCustomsValue
        ccd.DutiesPayment = mPayment
        self.shipment.RequestedShipment.CustomsClearanceDetail = ccd

    # ----------------------------------------------------
    # Set ETD (electronic trade documents) settings
    def setSpecialServices(self, doc_ids):
        # construct objects
        ssr = self.shipment.create_wsdl_object_of_type(
            "ShipmentSpecialServicesRequested")
        ssr.SpecialServiceTypes.append("ELECTRONIC_TRADE_DOCUMENTS")
        ssr.SpecialServiceTypes.append("EVENT_NOTIFICATION")

        # set up ETD details
        etd = self.shipment.create_wsdl_object_of_type("EtdDetail")
        etd.RequestedDocumentCopies = "COMMERCIAL INVOICE"

        for i, doc_id in enumerate(doc_ids, start=0):
            udrd = self.shipment.create_wsdl_object_of_type(
                "UploadDocumentReferenceDetail")
            udrd.DocumentType = "COMMERCIAL_INVOICE" if i == 0 else "OTHER"
            udrd.DocumentId = doc_id
            udrd.Description = "Commercial_Invoice" if i == 0 else "Product_Description"
            udrd.DocumentIdProducer = "CUSTOMER"
            ssr.EtdDetail.DocumentReferences.append(udrd)

        self.shipment.RequestedShipment.SpecialServicesRequested = ssr

        # set Event Notification details
        send = self.shipment.create_wsdl_object_of_type(
            "ShipmentEventNotificationDetail")
        send.AggregationType = "PER_SHIPMENT"

        sens = self.shipment.create_wsdl_object_of_type(
            "ShipmentEventNotificationSpecification")
        sens.NotificationDetail.NotificationType = "EMAIL"
        sens.NotificationDetail.EmailDetail.EmailAddress = self.shipment.RequestedShipment.Recipient.Contact.EMailAddress
        sens.NotificationDetail.EmailDetail.Name = self.shipment.RequestedShipment.Recipient.Contact.PersonName
        sens.NotificationDetail.Localization.LanguageCode = "EN"
        sens.Role = "SHIPPER"
        sens.Events.append("ON_SHIPMENT")
        sens.Events.append("ON_EXCEPTION")
        sens.Events.append("ON_DELIVERY")
        sens.FormatSpecification.Type = "HTML"
        send.EventNotifications = sens
        self.shipment.RequestedShipment.SpecialServicesRequested.EventNotificationDetail = send

    # ----------------------------------------------------
    # process the shipment
    def processInternationalShipment(self):
        from shutil import copyfile

        self.shipment.RequestedShipment.ShipTimestamp = datetime.datetime.now(
        ).replace(microsecond=0).isoformat()

        # print(" ---- **** DETAILS ---- ****")
        # print(self.shipment.RequestedShipment)
        # print(self.shipment.ClientDetail)
        # print(self.shipment.TransactionDetail)
        # print("REQUESTED SHIPMENT\n\n", self.shipment.RequestedShipment)

        self.shipment.send_request()

        # print("RESPONSE\n\n", self.shipment.response)

        status = self.shipment.response.HighestSeverity

        if status == "SUCCESS" and "CompletedShipmentDetail" in self.shipment.response:
            shipment_details = self.shipment.response.CompletedShipmentDetail
            package_details = shipment_details.CompletedPackageDetails[0]
            tracking_id = package_details.TrackingIds[0].TrackingNumber
            email = self.shipment.RequestedShipment.Recipient.Contact.EMailAddress
            fedex_cost = "N/A"

            if hasattr(package_details, "PackageRating"):
                fedex_cost = package_details.PackageRating.PackageRateDetails[
                    0].NetCharge.Amount

            # create the shipping PDF label
            ascii_label_data = package_details.Label.Parts[0].Image
            label_binary_data = binascii.a2b_base64(ascii_label_data)
            out_path = self.invoice_info[
                "InvoiceId"] + f"_shipment_label_{tracking_id}.pdf"

            out_file = open(out_path, "wb")
            out_file.write(label_binary_data)
            out_file.close()

            # print output information
            print(
                f"- SUCCESS: Created FedEx label for invoice {self.invoice_info['InvoiceId']}\n     tracking ID: {tracking_id}\n     email: {email}\n     FedEx cost: {fedex_cost}\n     Customs value: {self.invoice_info['Value']} {self.invoice_info['Currency']}\n     Weight: {self.invoice_info['Weight']}\n     output path: {out_path}"
            )
Exemplo n.º 8
0
    def test_create_delete_shipment(self):

        shipment = FedexProcessShipmentRequest(CONFIG_OBJ)

        shipment.RequestedShipment.DropoffType = 'REGULAR_PICKUP'
        shipment.RequestedShipment.ServiceType = 'FEDEX_GROUND'
        shipment.RequestedShipment.PackagingType = 'YOUR_PACKAGING'

        shipment.RequestedShipment.Shipper.Contact.PersonName = 'Sender Name'
        shipment.RequestedShipment.Shipper.Contact.PhoneNumber = '9012638716'

        shipment.RequestedShipment.Shipper.Address.StreetLines = ['Address Line 1']
        shipment.RequestedShipment.Shipper.Address.City = 'Herndon'
        shipment.RequestedShipment.Shipper.Address.StateOrProvinceCode = 'VA'
        shipment.RequestedShipment.Shipper.Address.PostalCode = '20171'
        shipment.RequestedShipment.Shipper.Address.CountryCode = 'US'

        shipment.RequestedShipment.Recipient.Contact.PersonName = 'Recipient Name'
        shipment.RequestedShipment.Recipient.Contact.PhoneNumber = '9012637906'

        shipment.RequestedShipment.Recipient.Address.StreetLines = ['Address Line 1']
        shipment.RequestedShipment.Recipient.Address.City = 'Herndon'
        shipment.RequestedShipment.Recipient.Address.StateOrProvinceCode = 'VA'
        shipment.RequestedShipment.Recipient.Address.PostalCode = '20171'
        shipment.RequestedShipment.Recipient.Address.CountryCode = 'US'
        shipment.RequestedShipment.EdtRequestType = 'NONE'

        shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber \
            = CONFIG_OBJ.account_number

        shipment.RequestedShipment.ShippingChargesPayment.PaymentType = 'SENDER'

        shipment.RequestedShipment.LabelSpecification.LabelFormatType = 'COMMON2D'
        shipment.RequestedShipment.LabelSpecification.ImageType = 'PNG'
        shipment.RequestedShipment.LabelSpecification.LabelStockType = 'PAPER_7X4.75'
        shipment.RequestedShipment.LabelSpecification.LabelPrintingOrientation = 'BOTTOM_EDGE_OF_TEXT_FIRST'

        del shipment.RequestedShipment.LabelSpecification.LabelOrder

        package1_weight = shipment.create_wsdl_object_of_type('Weight')
        package1_weight.Value = 2.0
        package1_weight.Units = "LB"
        package1 = shipment.create_wsdl_object_of_type('RequestedPackageLineItem')
        package1.PhysicalPackaging = 'ENVELOPE'
        package1.Weight = package1_weight
        shipment.add_package(package1)

        shipment.send_request()

        assert shipment.response
        assert shipment.response.HighestSeverity == 'SUCCESS'
        track_id = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[0].TrackingIds[0].TrackingNumber
        assert track_id

        del_shipment = FedexDeleteShipmentRequest(CONFIG_OBJ)
        del_shipment.DeletionControlType = "DELETE_ALL_PACKAGES"
        del_shipment.TrackingId.TrackingNumber = track_id
        del_shipment.TrackingId.TrackingIdType = 'EXPRESS'

        del_shipment.send_request()

        assert del_shipment.response
Exemplo n.º 9
0
    def do_partial(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        assert len(ids) == 1, 'Partial picking processing may only be done one at a time.'
        stock_picking = self.pool.get('stock.picking')
        stock_move = self.pool.get('stock.move')
        uom_obj = self.pool.get('product.uom')
        partial = self.browse(cr, uid, ids[0], context=context)
        partial_data = {
            'delivery_date' : partial.date
        }
        picking_type = partial.picking_id.type
        for wizard_line in partial.move_ids:
            line_uom = wizard_line.product_uom
            move_id = wizard_line.move_id.id

            #Quantiny must be Positive
            if wizard_line.quantity < 0:
                raise osv.except_osv(_('Warning!'), _('Please provide proper Quantity.'))

            #Compute the quantity for respective wizard_line in the line uom (this jsut do the rounding if necessary)
            qty_in_line_uom = uom_obj._compute_qty(cr, uid, line_uom.id, wizard_line.quantity, line_uom.id)

            if line_uom.factor and line_uom.factor <> 0:
                if float_compare(qty_in_line_uom, wizard_line.quantity, precision_rounding=line_uom.rounding) != 0:
                    raise osv.except_osv(_('Warning!'), _('The unit of measure rounding does not allow you to ship "%s %s", only rounding of "%s %s" is accepted by the Unit of Measure.') % (wizard_line.quantity, line_uom.name, line_uom.rounding, line_uom.name))
            if move_id:
                #Check rounding Quantity.ex.
                #picking: 1kg, uom kg rounding = 0.01 (rounding to 10g),
                #partial delivery: 253g
                #=> result= refused, as the qty left on picking would be 0.747kg and only 0.75 is accepted by the uom.
                initial_uom = wizard_line.move_id.product_uom
                #Compute the quantity for respective wizard_line in the initial uom
                qty_in_initial_uom = uom_obj._compute_qty(cr, uid, line_uom.id, wizard_line.quantity, initial_uom.id)
                without_rounding_qty = (wizard_line.quantity / line_uom.factor) * initial_uom.factor
                if float_compare(qty_in_initial_uom, without_rounding_qty, precision_rounding=initial_uom.rounding) != 0:
                    raise osv.except_osv(_('Warning!'), _('The rounding of the initial uom does not allow you to ship "%s %s", as it would let a quantity of "%s %s" to ship and only rounding of "%s %s" is accepted by the uom.') % (wizard_line.quantity, line_uom.name, wizard_line.move_id.product_qty - without_rounding_qty, initial_uom.name, initial_uom.rounding, initial_uom.name))
            else:
                seq_obj_name =  'stock.picking.' + picking_type
                move_id = stock_move.create(cr,uid,{'name' : self.pool.get('ir.sequence').get(cr, uid, seq_obj_name),
                                                    'product_id': wizard_line.product_id.id,
                                                    'product_qty': wizard_line.quantity,
                                                    'product_uom': wizard_line.product_uom.id,
                                                    'prodlot_id': wizard_line.prodlot_id.id,
                                                    'location_id' : wizard_line.location_id.id,
                                                    'location_dest_id' : wizard_line.location_dest_id.id,
                                                    'picking_id': partial.picking_id.id
                                                    },context=context)
                stock_move.action_confirm(cr, uid, [move_id], context)
            partial_data['move%s' % (move_id)] = {
                'product_id': wizard_line.product_id.id,
                'product_qty': wizard_line.quantity,
                'product_uom': wizard_line.product_uom.id,
                'prodlot_id': wizard_line.prodlot_id.id,
            }
            if (picking_type == 'in') and (wizard_line.product_id.cost_method == 'average'):
                partial_data['move%s' % (wizard_line.move_id.id)].update(product_price=wizard_line.cost,
                                                                  product_currency=wizard_line.currency.id)
        
        # Do the partial delivery and open the picking that was delivered
        # We don't need to find which view is required, stock.picking does it.
        done = stock_picking.do_partial(
            cr, uid, [partial.picking_id.id], partial_data, context=context)
        
        
        picking = self.pool.get('stock.picking.out').read(cr, uid, done[partial.picking_id.id]['delivered_picking'], ['origin', 'name'], context)
        so = picking['origin']
        # Set this to the INFO level to see the response from Fedex printed in stdout.
        logging.basicConfig(level=logging.INFO)
        
        # This is the object that will be handling our tracking request.
        # We're using the FedexConfig object from example_config.py in this dir.
        shipment = FedexProcessShipmentRequest(CONFIG_OBJ, customer_transaction_id='ProcessShipmentRequest_v15')
        
        # This is very generalized, top-level information.
        # REGULAR_PICKUP, REQUEST_COURIER, DROP_BOX, BUSINESS_SERVICE_CENTER or STATION
        shipment.RequestedShipment.DropoffType = 'REGULAR_PICKUP'
        
        # See page 355 in WS_ShipService.pdf for a full list. Here are the common ones:
        # STANDARD_OVERNIGHT, PRIORITY_OVERNIGHT, FEDEX_GROUND, FEDEX_EXPRESS_SAVER
        shipment.RequestedShipment.ServiceType = 'FEDEX_GROUND'
        
        # What kind of package this will be shipped in.
        # FEDEX_BOX, FEDEX_PAK, FEDEX_TUBE, YOUR_PACKAGING
        shipment.RequestedShipment.PackagingType = 'YOUR_PACKAGING'
        shipment.RequestedShipment.PreferredCurrency = 'USD'
        
        # Shipper contact info.
        shipment.RequestedShipment.Shipper.Contact.PersonName = 'Sam'
        shipment.RequestedShipment.Shipper.Contact.CompanyName = 'Cute Shoe'
        shipment.RequestedShipment.Shipper.Contact.PhoneNumber = '9012638716'
        shipment.RequestedShipment.Shipper.Contact.EMailAddress = '*****@*****.**'
        
        # Shipper address.
        shipment.RequestedShipment.Shipper.Address.StreetLines = ['2000 Freight LTL Testing', 'Do Not Delete - Test Account']
        shipment.RequestedShipment.Shipper.Address.City = 'Harrison'
        shipment.RequestedShipment.Shipper.Address.StateOrProvinceCode = 'AR'
        shipment.RequestedShipment.Shipper.Address.PostalCode = '72601'
        shipment.RequestedShipment.Shipper.Address.CountryCode = 'US'
        #shipment.RequestedShipment.Shipper.Address.Residential = True
        
        # Recipient contact info.
        shipment.RequestedShipment.Recipient.Contact.PersonName = 'Jack'
        shipment.RequestedShipment.Recipient.Contact.CompanyName = 'Taobao'
        shipment.RequestedShipment.Recipient.Contact.PhoneNumber = '9012637906'
        shipment.RequestedShipment.Recipient.Contact.EMailAddress = '*****@*****.**'
        
        # Recipient address
        shipment.RequestedShipment.Recipient.Address.StreetLines = ['1202 Chalet Ln', 'Do Not Delete - Test Account']
        shipment.RequestedShipment.Recipient.Address.City = 'Harrison'
        shipment.RequestedShipment.Recipient.Address.StateOrProvinceCode = 'AR'
        shipment.RequestedShipment.Recipient.Address.PostalCode = '72601'
        shipment.RequestedShipment.Recipient.Address.CountryCode = 'US'
        # This is needed to ensure an accurate rate quote with the response.
        #shipment.RequestedShipment.Recipient.Address.Residential = True
        shipment.RequestedShipment.EdtRequestType = 'NONE'
        #shipment.RequestedShipment.CustomsClearanceDetail.ClearanceBrokerage = 'BROKER_UNASSIGNED'
        #shipment.RequestedShipment.CustomsClearanceDetail.DocumentContent = 'DOCUMENTS_ONLY'
        #shipment.RequestedShipment.CustomsClearanceDetail.CustomsValue.Currency = 'USD'
        #shipment.RequestedShipment.CustomsClearanceDetail.CustomsValue.Amount = 100
        #shipment.RequestedShipment.CustomsClearanceDetail.FreightOnValue = 'CARRIER_RISK'
        
        shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = CONFIG_OBJ.account_number
        shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Tins = [{'TinType': 'BUSINESS_STATE', 'Number': '353'}]
        shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.Contact = [{'ContactId': '12345', 'PersonName': 'jack'}]
        # Who pays for the shipment?
        # RECIPIENT, SENDER or THIRD_PARTY
        shipment.RequestedShipment.ShippingChargesPayment.PaymentType = 'SENDER' 
        
        # 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 = 'PNG'
        
        # To use doctab stocks, you must change ImageType above to one of the
        # label printer formats (ZPLII, EPL2, DPL).
        # See documentation for paper types, there quite a few.
        shipment.RequestedShipment.LabelSpecification.LabelStockType = 'PAPER_4X6'
        
        # This indicates if the top or bottom of the label comes out of the 
        # printer first.
        # BOTTOM_EDGE_OF_TEXT_FIRST or TOP_EDGE_OF_TEXT_FIRST
        shipment.RequestedShipment.LabelSpecification.LabelPrintingOrientation = 'BOTTOM_EDGE_OF_TEXT_FIRST'
        shipment.RequestedShipment.LabelSpecification.LabelOrder = 'SHIPPING_LABEL_FIRST'
        
        package1_weight = shipment.create_wsdl_object_of_type('Weight')
        # Weight, in pounds.
        package1_weight.Value = 1.0
        package1_weight.Units = "LB"
        
        package1_dim = shipment.create_wsdl_object_of_type('Dimensions')
        package1_dim.Length = 12
        package1_dim.Width = 12
        package1_dim.Height = 12
        package1_dim.Units = 'IN'
        
        
        
        package1 = shipment.create_wsdl_object_of_type('RequestedPackageLineItem')
        package1.PhysicalPackaging = 'BOX'
        package1.Weight = package1_weight
        package1.SequenceNumber = 1
        package1.Dimensions = package1_dim
        package1.CustomerReferences = [{'CustomerReferenceType': 'CUSTOMER_REFERENCE', 'Value': so}]
        # Un-comment this to see the other variables you may set on a package.
        #print package1
        
        # This adds the RequestedPackageLineItem WSDL object to the shipment. It
        # increments the package count and total weight of the shipment for you.
        shipment.client.wsdl.services[0].setlocation('https://wsbeta.fedex.com:443/web-services/ship')
        logging.basicConfig(level=logging.INFO)
        logging.getLogger('suds.client').setLevel(logging.DEBUG)
        logging.getLogger('suds.transport').setLevel(logging.DEBUG)
        logging.getLogger('suds.xsd.schema').setLevel(logging.DEBUG)
        logging.getLogger('suds.wsdl').setLevel(logging.DEBUG)
        shipment.add_package(package1)
        
        # If you'd like to see some documentation on the ship service WSDL, un-comment
        # this line. (Spammy).
        #print shipment.client
        
        # Un-comment this to see your complete, ready-to-send request as it stands
        # before it is actually sent. This is useful for seeing what values you can
        # change.
        #print shipment.RequestedShipment
        
        # If you want to make sure that all of your entered details are valid, you
        # can call this and parse it just like you would via send_request(). If
        # shipment.response.HighestSeverity == "SUCCESS", your shipment is valid.
        #shipment.send_validation_request()
        
        # Fires off the request, sets the 'response' attribute on the object.
        shipment.send_request()
        
        # This will show the reply to your shipment being sent. You can access the
        # attributes through the response attribute on the request object. This is
        # good to un-comment to see the variables returned by the Fedex reply.
        print shipment.response
        
        # Here is the overall end result of the query.
        print "HighestSeverity:", shipment.response.HighestSeverity
        # Getting the tracking number from the new shipment.
        print "Tracking #:", shipment.response.CompletedShipmentDetail.CompletedPackageDetails[0].TrackingIds[0].TrackingNumber
        # Net shipping costs.
        print "Net Shipping Cost (US$):", shipment.response.CompletedShipmentDetail.CompletedPackageDetails[0].PackageRating.PackageRateDetails[0].NetCharge.Amount
        
        # Get the label image in ASCII format from the reply. Note the list indices
        # we're using. You'll need to adjust or iterate through these if your shipment
        # has multiple packages.
        ascii_label_data = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[0].Label.Parts[0].Image
        # Convert the ASCII data to binary.
        label_binary_data = binascii.a2b_base64(ascii_label_data)
        
        """
        This is an example of how to dump a label to a PNG file.
        """
        # This will be the file we write the label out to.
        png_file = open(os.path.dirname(os.path.abspath(__file__)) + '/static/' + picking['name'].replace('/', '') + '.png', 'wb')
        png_file.write(label_binary_data)
        png_file.close()
#         label = open(os.path.dirname(os.path.abspath(__file__)) + '/' + picking['name'].replace('/', '') + '.png', 'rU')
#         label_data = label.read()
#         label_binary_data = base64.b64encode(label_data)
        vals = {
                'courier_label': '/ida_wms_app/static/' + picking['name'].replace('/', '') + '.png'
                }
        self.pool.get('stock.picking.out').write(cr, uid, done[partial.picking_id.id]['delivered_picking'], vals, context)
        """
        This is an example of how to print the label to a serial printer. This will not
        work for all label printers, consult your printer's documentation for more
        details on what formats it can accept.
        """
        # Pipe the binary directly to the label printer. Works under Linux
        # without requiring PySerial. This WILL NOT work on other platforms.
        #label_printer = open("/dev/ttyS0", "w")
        #label_printer.write(label_binary_data)
        #label_printer.close()
        
        """
        This is a potential cross-platform solution using pySerial. This has not been
        tested in a long time and may or may not work. For Windows, Mac, and other
        platforms, you may want to go this route.
        """
        #import serial
        #label_printer = serial.Serial(0)
        #print "SELECTED SERIAL PORT: "+ label_printer.portstr
        #label_printer.write(label_binary_data)
        #label_printer.close()
        
        if done[partial.picking_id.id]['delivered_picking'] == partial.picking_id.id:
            return {'type': 'ir.actions.act_window_close'}
        return {
            'type': 'ir.actions.act_window',
            'res_model': context.get('active_model', 'stock.picking'),
            'name': _('Partial Delivery'),
            'res_id': done[partial.picking_id.id]['delivered_picking'],
            'view_type': 'form',
            'view_mode': 'form,tree,calendar',
            'context': context,
        }