def init_shipment(self, doc): shipment = FedexProcessShipmentRequest(self.config_obj) self.set_shipment_details(doc, shipment) shipper_details = self.set_shipper_info(doc.company_address_name, shipment) recipient_details = self.set_recipient_info(doc, shipment) FedexController.set_fedex_label_info(shipment) FedexController.set_commodities_info(doc, shipment) self.set_commercial_invoice_info(shipment, doc) self.set_email_notification(shipment, doc, shipper_details, recipient_details) self.pkg_count = doc.no_of_packages return shipment
def create_shipment_service(self, credentials, from_address_doc, to_address_doc, \ from_country_doc, to_country_doc, transporter_doc, contact_doc): from fedex.services.ship_service import FedexProcessShipmentRequest customer_transaction_id = self.name # Optional transaction_id shipment = FedexProcessShipmentRequest(credentials, \ customer_transaction_id=customer_transaction_id) self.set_shipment_details(shipment, credentials, transporter_doc) shipper_details = self.set_shipper_info(shipment, from_address_doc, credentials) recipient_details = self.set_recipient_info(shipment, to_address_doc, credentials) self.set_fedex_label_info(shipment) self.set_commodities_info(self, shipment) self.set_commercial_invoice_info(shipment) #self.set_email_notification(shipment, from_address_doc, to_address_doc, contact_doc) pkg_count = self.total_handling_units for index, pkg in enumerate(self.shipment_package_details): pkg_doc = frappe.get_doc("Shipment Package", pkg.shipment_package) if index: shipment.RequestedShipment.MasterTrackingId.TrackingNumber = self.awb_number shipment.RequestedShipment.MasterTrackingId.TrackingIdType.value = \ transporter_doc.type_of_service self.set_package_data(pkg, pkg_doc, shipment, index + 1) else: shipment.RequestedShipment.TotalWeight.Units = self.uom_mapper.get( self.weight_uom) shipment.RequestedShipment.TotalWeight.Value = self.total_weight self.set_package_data(pkg, pkg_doc, shipment, index + 1) shipment.send_validation_request() shipment.send_request() self.validate_fedex_shipping_response(shipment, pkg.idx) tracking_id = shipment.response.CompletedShipmentDetail.CompletedPackageDetails[ 0].TrackingIds[0].TrackingNumber if index == 0: self.awb_number = tracking_id self.status = "Booked" self.set_package_details(pkg, cstr(shipment.response), tracking_id) self.store_label(self, shipment, tracking_id, self.doctype, self.name) self.save() return shipment
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
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
#!/usr/bin/env python """ This module prints three FedEx Express shipping labels for the label certification process. See your FedEx Label Developer Tool Kit documentation for more details. """ import logging from cert_config import CONFIG_OBJ, SHIPPER_CONTACT_INFO, SHIPPER_ADDRESS, LABEL_SPECIFICATION from cert_config import transfer_config_dict from cert_config import LabelPrinterClass from fedex.services.ship_service import FedexProcessShipmentRequest logging.basicConfig(level=logging.INFO) shipment = FedexProcessShipmentRequest(CONFIG_OBJ) shipment.RequestedShipment.DropoffType = 'REGULAR_PICKUP' shipment.RequestedShipment.ServiceType = 'PRIORITY_OVERNIGHT' shipment.RequestedShipment.PackagingType = 'YOUR_PACKAGING' # Shipper contact info. transfer_config_dict(shipment.RequestedShipment.Shipper.Contact, SHIPPER_CONTACT_INFO) # Shipper address. transfer_config_dict(shipment.RequestedShipment.Shipper.Address, SHIPPER_ADDRESS) # Recipient contact info. shipment.RequestedShipment.Recipient.Contact.PersonName = 'Recipient Name' shipment.RequestedShipment.Recipient.Contact.CompanyName = 'Recipient Company'
import sys from example_config import CONFIG_OBJ from fedex.services.ship_service import FedexProcessShipmentRequest # What kind of file do you want this example to generate? # Valid choices for this example are PDF, PNG GENERATE_IMAGE_TYPE = 'PDF' # Un-comment to see the response from Fedex printed in stdout. logging.basicConfig(stream=sys.stdout, level=logging.INFO) # This is the object that will be handling our shipment request. # We're using the FedexConfig object from example_config.py in this dir. customer_transaction_id = "*** ShipService Request v17 using Python ***" # Optional transaction_id shipment = FedexProcessShipmentRequest(CONFIG_OBJ, customer_transaction_id=customer_transaction_id) # This is very generalized, top-level information. # REGULAR_PICKUP, REQUEST_COURIER, DROP_BOX, BUSINESS_SERVICE_CENTER or STATION shipment.RequestedShipment.DropoffType = 'BUSINESS_SERVICE_CENTER' # 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 = 'PRIORITY_OVERNIGHT' # What kind of package this will be shipped in. # FEDEX_BOX, FEDEX_PAK, FEDEX_TUBE, YOUR_PACKAGING, FEDEX_ENVELOPE shipment.RequestedShipment.PackagingType = 'FEDEX_PAK' # Shipper contact info.
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
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)
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, }