-
Notifications
You must be signed in to change notification settings - Fork 138
/
create_freight_shipment.py
212 lines (169 loc) · 9.08 KB
/
create_freight_shipment.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#!/usr/bin/env python
"""
This example shows how to create a freight shipment and generate
a waybill as output. The variables populated below
represents the minimum required values. You will need to fill all of these, or
risk seeing a SchemaValidationError exception thrown.
Near the bottom of the module, you'll see some different ways to handle the
label data that is returned with the reply.
"""
import logging
import sys
import binascii
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)
# NOTE: A VALID 'freight_account_number' REQUIRED IN YOUR 'CONFIB_OBJ' FOR THIS SERVICE TO WORK.
# OTHERWISE YOU WILL GET FEDEX FREIGHT OR ASSOCIATED ADDRESS IS REQUIRED, ERROR 3619.
# This is the object that will be handling our freight shipment request.
# We're using the FedexConfig object from example_config.py in this dir.
shipment = FedexProcessShipmentRequest(CONFIG_OBJ)
shipment.RequestedShipment.DropoffType = 'REGULAR_PICKUP'
shipment.RequestedShipment.ServiceType = 'FEDEX_FREIGHT_ECONOMY'
shipment.RequestedShipment.PackagingType = 'YOUR_PACKAGING'
shipment.RequestedShipment.FreightShipmentDetail.FedExFreightAccountNumber = CONFIG_OBJ.freight_account_number
# Shipper contact info.
shipment.RequestedShipment.Shipper.Contact.PersonName = 'Sender Name'
shipment.RequestedShipment.Shipper.Contact.CompanyName = 'Some Company'
shipment.RequestedShipment.Shipper.Contact.PhoneNumber = '9012638716'
# Shipper address.
shipment.RequestedShipment.Shipper.Address.StreetLines = ['1202 Chalet Ln']
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 = 'Recipient Name'
shipment.RequestedShipment.Recipient.Contact.CompanyName = 'Recipient Company'
shipment.RequestedShipment.Recipient.Contact.PhoneNumber = '9012637906'
# Recipient address
shipment.RequestedShipment.Recipient.Address.StreetLines = ['2000 Freight LTL Testing']
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 = False
shipment.RequestedShipment.FreightShipmentDetail.TotalHandlingUnits = 1
shipment.RequestedShipment.ShippingChargesPayment.Payor.ResponsibleParty.AccountNumber = \
CONFIG_OBJ.freight_account_number
billing_contact_address = shipment.RequestedShipment.FreightShipmentDetail.FedExFreightBillingContactAndAddress
billing_contact_address.Contact.PersonName = 'Sender Name'
billing_contact_address.Contact.CompanyName = 'Some Company'
billing_contact_address.Contact.PhoneNumber = '9012638716'
billing_contact_address.Address.StreetLines = ['2000 Freight LTL Testing']
billing_contact_address.Address.City = 'Harrison'
billing_contact_address.Address.StateOrProvinceCode = 'AR'
billing_contact_address.Address.PostalCode = '72601'
billing_contact_address.Address.CountryCode = 'US'
billing_contact_address.Address.Residential = False
spec = shipment.create_wsdl_object_of_type('ShippingDocumentSpecification')
spec.ShippingDocumentTypes = [spec.CertificateOfOrigin]
# shipment.RequestedShipment.ShippingDocumentSpecification = spec
role = shipment.create_wsdl_object_of_type('FreightShipmentRoleType')
shipment.RequestedShipment.FreightShipmentDetail.Role = role.SHIPPER
shipment.RequestedShipment.FreightShipmentDetail.CollectTermsType = 'STANDARD'
# Specifies the label type to be returned.
shipment.RequestedShipment.LabelSpecification.LabelFormatType = 'FEDEX_FREIGHT_STRAIGHT_BILL_OF_LADING'
# Specifies which format the label file will be sent to you in.
# DPL, EPL2, PDF, PNG, ZPLII
shipment.RequestedShipment.LabelSpecification.ImageType = 'PDF'
# 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_LETTER'
# 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.EdtRequestType = 'NONE'
# 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 = 500.0
package1_weight.Units = "LB"
shipment.RequestedShipment.FreightShipmentDetail.PalletWeight = package1_weight
package1 = shipment.create_wsdl_object_of_type('FreightShipmentLineItem')
package1.Weight = package1_weight
package1.Packaging = 'PALLET'
package1.Description = 'Products'
package1.FreightClass = 'CLASS_500'
package1.HazardousMaterials = None
package1.Pieces = 12
shipment.RequestedShipment.FreightShipmentDetail.LineItems = 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)
# 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.
# from fedex.tools.conversion import sobject_to_dict
# response_dict = sobject_to_dict(shipment.response)
# response_dict['CompletedShipmentDetail']['ShipmentDocuments'][0]['Parts'][0]['Image'] = ''
# print(response_dict) # Image is empty string for display purposes.
# This will dump the response data dict to json.
# from fedex.tools.conversion import sobject_to_json
# print(sobject_to_json(shipment.response))
# 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.MasterTrackingId.TrackingNumber))
# Net shipping costs.
amount = shipment.response.CompletedShipmentDetail.ShipmentRating.ShipmentRateDetails[0].TotalNetCharge.Amount
print("Net Shipping Cost (US$): {}".format(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.ShipmentDocuments[0].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 local file.
"""
# This will be the file we write the label out to.
out_path = 'example_freight_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()
"""
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()