Welcome!

Java Authors: Liz McMillan, Walter H. Pinson, III, Maureen O'Gara, Yakov Werde, Tony Bishop

Related Topics: PowerBuilder

PowerBuilder: Article

PowerBuilder and UPS Shipping

PowerBuilder as a client for UPS Web Services

Let’s discuss all five steps:

1. Create an XML Message
This is tedious, but not technically difficult. Read and follow the UPS manual. Basically, your message will have your user ID and password, the sending and destination address, and other information such as package weight, package size, and type of service, such as UPS Ground versus Overnight. Part of the code is in Listing 1.

2. Send the XML over the Internet to the UPS Site Securely
You could buy a product for this purpose, but in this example we use a free product: the Internet Explorer XML HTTP Request object. This object can send both HTTP and XML to any site over the Internet using either http or https. Simply specify the URL in a string called ls_url. To use HTTPS, begin the string with https:// instead of http://...

oleobject uo_req
uo_req = CREATE oleobject
li_rc=uo_req.ConnectToNewObject(“MSXML2.XMLHTTP”)
CHOOSE CASE li_rc
 ASE 0
  // OK
 CASE ELSE
  MessageBox(‘Error’,’ConnectToNewObject Msxml2.XMLHTTP.4.0 failed with rc=’+String(li_rc))
  RETURN
END CHOOSE
uo_req.open (“POST”,ls_url, false)
uo_req.send (ls_xml_request)

3. Get XML Back from UPS
We’ll use the same object to get the XML back from UPS.

String ls_xml_response, ls_req_status

ls_xml_response = uo_req.responseText
ls_req_status = uo_req.StatusText
//
// Check for HTTP errors
//
  IF uo_req.Status >= 300 THEN
     MessageBox (“HTTP request failed:”, ls_req_status,Exclamation!,OK!)
              RETURN -20
  END IF
...
li_rc=uo_req.DisConnectObject()
DESTROY uo_req

4. Decode the Label Image
The returned XML has the price, tracking number, and label. Price and tracking number are easy to parse and you’ll want to store them in your relational database, so that later on you can report and track. Let’s focus on the label image. Parse the XML, looking for the text in the <GraphicImage> tags.

// Get the Image of the Label:
ll_p0=Pos(as_in,’<GraphicImage>’) IF ll_p0<1 THEN
  // Error, no label image found
  RETURN -1
END IF

ll_p0+=14
as_in=Mid(as_in,ll_p0)
ll_p9=Pos(as_in,’</GraphicImage>’)
IF ll_p9<1 THEN
  // Error, missing end tag
  RETURN -1
END IF

// Build Record:
ls_result=Left(as_in,ll_p9 -1)

Now, ls_result contains a base-64 encoded image. To decode it, you could buy a product, but let’s use the free base64.dll file. You’ll have to register this file:

Regsvr32 base64.dll

You must decode it into a blob. If you use a string, the data is truncated after the first byte with a value of hex 00.

uo_64 = CREATE OLEObject
li_rc=uo_64.ConnectToNewObject(“Base64Lib.Base64”)
IF li_rc<0 THEN
    MessageBox(‘Error’,’Connect to Base64 dll failed’)
    RETURN
END IF

Blob blb_64
Blb_64=uo_64.DecodeArr(ls_result)

5. Print the Label
We’ll print a four-inch by six-inch self-adhesive label on a Zebra LP 2844 printer. (You could print to 8 1⁄2 by 11-inch paper via a laser printer as well using a different technique.)

We take the blob, and simply write it to a flat file:

li_file=FileOpen(‘C:\temp\label.prn’,LineMode!,Write!,Shared!,Replace!)
FileWrite(li_file, blb_64)
FileClose(li_file)

Note: the size of blb_64 is always less than 32,765, so we only need to execute FileWrite() once.

Finally, run a batch file that simply copies the flat file to the printer:

Run(‘C:\temp\printzebra.bat’)

In this case, you don’t need to install a printer driver. However, you do need to make sure that the batch file’s destination matches how the printer is connected. If the printer is connected via a parallel port, you’ll copy to LPT1: If, instead, you use USB then you’d copy the file to USB1, USB2, etc.

This script will create the batch file:

Int li_file,li_rc

li_file=FileOpen(‘C:\temp\printzebra.bat’,LineMode!,Write!, Shared!,Replace!)
li_rc=FileWrite(li_file,’copy C:\temp\label.prn LPT1:’)
li_rc=FileWrite(li_file,’EXIT’)
FileClose(li_file)

You might not like the black screen that appears when you run the batch file. In that case, write PowerScript code, which does a FileOpen(), and use “LPT1:” as the output file name, then use FileWrite() to write the blob and FileClose(). This does the same thing as the batch file. You may be tempted to try using the FileCopy() function, but it doesn’t seem to work when the destination is a printer.

This solution has served us well. All we need now is a label printer for each PC. eBay has many of these printers for sale and even our oldest printer has never had a problem. As an added bonus, the Zebra printer has its own language, which lets us print other labels from PowerBuilder as well. You can also use the Shipping Tool to void a shipment.

We use the Tracking Tool too. Every day, a batch job uses a DataWindow to select all outstanding shipments. For each one, it uses the Tracking Tool and looks up the status based on the Tracking Number. The response tells us whether the package was delivered, and when. We store this right back in our database.

This shows that PowerBuilder can act as a client for the UPS Web Services. Using these same techniques, you could also code for FedEx or other Web Services too.

More Stories By Victor A Reinhart

Victor Reinhart is a PowerBuilder architect and developer at Maintstar.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.