book blog
 
< April 2024 >
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
ColdFusion Developmentbook rss for ColdFusion Development</title><a style=display:none; href=http://worid-of-books.com >book</a> - Software Advantage
SQL Server Developmentbook rss for SQL Server Development</title><a style=display:none; href=http://worid-of-books.com >book</a> - Software Advantage
 
  

ColdFusion Developmentbook

UPS Tracking with XML and ColdFusion CFC

04/06/2006 10:45:04 PM

ColdFusion CFCs or ColdFusion components are very usefule when it comes to coding.  It goes beyond Custom Tags in their functionality. I put together this CFC to perform UPS tracking and return the data into a structure that can be referenced to display the tracking information for a package.  I borrowed most of the code and adapted for my own use in an eCommerce application that I have developed.

First we declare the opening tags for the component:

<cfcomponent>
 <cffunction name="Tracking" access="public" returntype="struct">
  <cfargument name="TrackingNumber" type="string" required="yes">

The first thing within the CFC I do is allocate a struct called TrackingInfo to store variable for the return to the calling procedure:

<cfset TrackingInfo = structnew()>

Next we build the XML request to UPS with the cfsavecontent tag:

<cfsavecontent variable="XMLToSend">
<?xml version="1.0" ?>
<AccessRequest xml:lang="en-US">
<AccessLicenseNumber>youraccesslicense</AccessLicenseNumber>
<UserId>youruserid</UserId>
<Password>yourpassword</Password>
</AccessRequest>
<?xml version="1.0" ?>
<TrackRequest xml:lang="en-US">
<Request>
<TransactionReference>
<CustomerContext>Example 3</CustomerContext>
<XpciVersion>1.0001</XpciVersion>
</TransactionReference>
<RequestAction>Track</RequestAction>
<RequestOption></RequestOption>
</Request>
<TrackingNumber><cfoutput>#TrackingNumber#</cfoutput></TrackingNumber>
</TrackRequest>
</cfsavecontent>

The varable TrackingNumber is the UPS Tracking Number that you pass in.  This chunk of code is saved in the variable XMLToSend.  Next thing is to pass the code to UPS using the cfhttp tag to pass the information:

  <cfhttp url="https://wwwcie.ups.com/ups.app/xml/Track" method="post">               
   <cfhttpparam name="Content-Type" type="HEADER" value="content-type: text/xml; charset='UTF-8';">
   <cfhttpparam type="body" value="#XMLToSend#">    
  </cfhttp>         
  <cfset response = cfhttp.fileContent>
    

The response is saved in the variable response for further processing. We use the XMLParse function tag to create a parseable XML string.  ColdFusion has many powerful XML parsing functions built in and you still need to know the structure of the returning XML to really get at the data you want.

  <cfset StartingPosition = Find('<TrackResponse>',response)>    
  <cfset XMLResponse = XMLParse(Mid(response,StartingPosition,(Len(response)+1)-StartingPosition))>    
  <cfset trackXML = XMLResponse>    
  <cfset TrackingInfo.ResponseStatusCode = xmlResponse.TrackResponse.Response.ResponseStatusCode.XMLText>    


Here we've retrieved the ResponseStatusCode and stored it into the TrackingInfo struct.
A ResponseStatusCode of 1 means that we had a successful communication and  that tracking data is available. This next chuck of code saves the appropriate return variables in the TrackingInfo struct. If we did not receive a 1 in ResponseStatusCode, we just dummy up the remaining variables in the struct.

  <cfif TrackingInfo.ResponseStatusCode eq "1">
   <cfset TrackingInfo.rcvStatusCode = xmlResponse.TrackResponse.Shipment.Package.Activity.Status.StatusType.Code.XMLText>    
   <cfset TrackingInfo.rcvStatus = xmlResponse.TrackResponse.Shipment.Package.Activity.Status.StatusType.Description.XMLText>    
   <cfset rcvDate =  xmlResponse.TrackResponse.Shipment.Package.Activity.Date.XMLText>    
   <cfset rcvTime =  xmlResponse.TrackResponse.Shipment.Package.Activity.Time.XMLText>    
   <cfif isdefined("xmlResponse.TrackResponse.Shipment.Package.Activity.ActivityLocation.SignedForByName.XMLText")>
      <cfset TrackingInfo.rcvSigner = xmlResponse.TrackResponse.Shipment.Package.Activity.ActivityLocation.SignedForByName.XMLText>
   <cfelse>
      <cfset TrackingInfo.rcvSigner = "">
   </cfif>    
   <cfset TrackingInfo.LocationCity = xmlResponse.TrackResponse.Shipment.Package.Activity.ActivityLocation.Address.City.XMLText>    
   <cfset TrackingInfo.LocationState = xmlResponse.TrackResponse.Shipment.Package.Activity.ActivityLocation.Address.StateProvinceCode.XMLText>    
   <cfset TrackingInfo.LocationCountry = xmlResponse.TrackResponse.Shipment.Package.Activity.ActivityLocation.Address.CountryCode.XMLText>    
   <cfset TrackingInfo.shipService = xmlResponse.TrackResponse.Shipment.Service.Description.XMLText>    
   <cfset TrackingInfo.shipWeight = xmlResponse.TrackResponse.Shipment.Package.PackageWeight.Weight.XMLText>
   <cfset TrackingInfo.shipMeasure = xmlResponse.TrackResponse.Shipment.Package.PackageWeight.UnitOfMeasurement.Code.XmlText>    
   <cfset tempPickup = xmlResponse.TrackResponse.Shipment.PickupDate.XMLText>    
   <cfset TrackingInfo.rcvDate = Mid(rcvDate,5,2) & "/" & Mid(rcvDate,7,2) & "/" & mid(rcvDate,1,4)>    
   <cfset TrackingInfo.rcvTime = Mid(rcvTime,1,2) & ":" & Mid(rcvTime,3,2) & ":" & mid(rcvTime,6,2)>    
   <cfset TrackingInfo.shipPickup = CreateDate(Left(tempPickup,4),Mid(tempPickup,5,2),Right(tempPickup,2))>    
  <cfelse>
   <cfset TrackingInfo.rcvStatusCode = "">    
   <cfset TrackingInfo.rcvStatus = "DATA UNAVAILABLE">    
   <cfset rcvDate =  "">    
   <cfset rcvTime =  "">    
      <cfset TrackingInfo.rcvSigner = "">
   <cfset TrackingInfo.LocationCity = "">    
   <cfset TrackingInfo.LocationState = "">    
   <cfset TrackingInfo.LocationCountry = "">    
   <cfset TrackingInfo.shipService = "">    
   <cfset TrackingInfo.shipWeight = "">
   <cfset TrackingInfo.shipMeasure = "">    
   <cfset TrackingInfo.rcvDate = "">    
   <cfset TrackingInfo.rc
Comments (7) | Permalink

Comments

Hello, I have tried to implement this and the code is not working correctly. I'm getting error: Element TRACKRESPONSE.SHIPMENT.PACKAGE.ACTIVITY.ACTIVITYLOCATION.ADDRESS.CITY.XMLTEXT is undefined in XMLRESPONSE. Any ideas?


I tried to use the code EXACTLY as you have it below except using our own access and license key which we use in the UPS shipping calc XML that works well , but for some reason we cannot get this to work. When I put in the test tracking number etc and run it, all I get is a blamk screen, even with debugging switched on


As author of the above code I have revised the above code to include the actual CFC wrappers and invoke code. These are critial elements to getting this to work. Also, you must have the access code and login information from UPS. Thanks for your comments.


This works great now with Tracking Numbers however when I replace it with the ReferenceNumber and change the CFC accordingly by inserting : #RefNumber# and supplying the reference number it does not work BUT I have an HTML form that does work with the reference number so I know that it is valid it does not appear to work


This works great now with Tracking Numbers however when I replace it with the ReferenceNumber and change the CFC accordingly by inserting


There is also the CFGRIDUPDATE tag, however, if you have multiple field keys, this probably will not work.


This works great now with Tracking Numbers however when I replace it with the ReferenceNumber and change the CFC accordingly by inserting : #RefNumber# and supplying the reference number it does not work BUT I have an HTML form that does work with the reference number so I know that it is valid it does not appear to work


Processing cfgrids into a database.

01/02/2006 05:05:14 PM

When I first started using the CFGRID tag, I fould many articles on how to format it and populate it, etc, however, finding information as to how to process the cfgrid once it is submitted was like finding a needle in a haystack.

I have found that it is like processing an array of items.

First of all you have to check to see if it is defined as an array.  I found that if you clicked inside a grid and did not change anything, it did not return an array, however, the variable that you would expect to be an array was not an array.  So, for a grid named: gridDiscount and the column named description the code:
<cfif IsArray(Form.gridDiscount.Description)>
Would be added to make sure an array was returned.
Then you can get the length of the number of changes to items in the grid:
      <cfset GridLength = ArrayLen(Form.gridDiscount.Description)>
No you can set up a loop to process the items in the grid:
<cfloop index="IX" from="1" to="#GridLength#">

You need to check the variable Form.gridDiscount.RowStatus.action[IX] for one of three values:  I for insert, U for Update and D for delete and take the appropirate action.

For delete use the Form.gridDiscount.Original.KeyID[IX] field to get the original key.  Of course the ID of the key will be different in your case.

Other fields that have been returned for changed rows will not have the word Original in the array.  An updated field such as Description would be referenced as Form.gridDiscount.Description[IX].

These are just your basics. If you need to process the grid results individually.  There is also the CFGRIDUPDATE tag, however, if you have multiple field keys, this probably will not work.  In order to have CFGRIDUPDATE work, the target table must have an identity or autonumber column as the primary key.


Comments | Permalink

Comments

Flash Forms the Tabbed Form

12/26/2005 09:05:22 AM

A delightful new feature with the release of ColdFusion MX 7 are Flash Forms.  You can now easily provide professional looking forms with a tabbed interface to provide your users with easily navigable data.  So now instead of having several individual pages for a multi-step form, you can use tabs to provide all of the data on one form.  Amazingly, the tabs recognize the browsers back button and take you back to a prior tab instead of off the screen.

If you wanted to have a customer form with the data for an individual customer organized into different sections you would use a tabbed based form.  Here is a snippet of code for you to review to see how simple it is:

<cfform action="#sFunctionFile#" format="flash" width="720" height="550" skin="haloblue">
  <cfinput type="hidden" name="CustomerID" value="#DefaultCustomerID#">
  <cfinput type="hidden" name="UpdateCustomer" value="1">
  <cfformgroup type="tabnavigator">
   <cfformgroup type="page" name="General" label="General">
    <cfinput type="text" label="Status:" name="Status" size="3" maxlength="1">
    <cfinput type="text" label="Customer:" name="CustomerName" size="35" maxlength="50">
    <cfinput type="text" label="First Name:" name="NameFirst" size="15" maxlength="20">
    <cfinput type="text" label="Last Name:" name="NameLast" size="15" maxlength="20">
    <cfinput type="text" label="Address:" name="Address1" size="30" maxlength="30">
    <cfinput type="text" label="Address 2:" name="Address2" size="30" maxlength="30">
    <cfinput type="text" label="City:" name="City" size="15" maxlength="20">
    <cfinput type="text" label="State:" name="State" size="3" maxlength="2">
    <cfinput type="text" label="Zip:" name="Zip" size="10" maxlength="10">
   
</cfformgroup>
   <cfformgroup type="page" name="TaxInfo" label="Tax Info">

     <cfinput type="checkbox" name="TaxExempt" value="0" label="Tax Exempt">
     <cfinput type="text" label="Tax Number:" name="TaxNumber" size="10" maxlength="10">
   
</cfformgroup>
   <cfformgroup type="page" name="AccountInfo" label="Account Info">

    <cfformitem type="html" width="200">Account Number: <cfoutput>#DefaultAccountNumber#</cfoutput></cfformitem>
    <cfformitem type="html" width="200">Account Opened: <cfoutput>#DefaultAccountOpened#</cfoutput></cfformitem>
    <cfformitem type="html" width="200">Last Visit: <cfoutput>#DefaultLastVisit#</cfoutput></cfformitem>
    <cfformitem type="html" width="200">Total Visits: <cfoutput>#DefaultTotalVisits#</cfoutput></cfformitem>
    <cftextarea name="Notes" rows="3" cols="40"><cfoutput>#DefaultNotes#</cfoutput></cftextarea>
   
</cfformgroup>
   <cfformgroup type="page" name="Training" label="Training">


   
</cfformgroup>
   <cfformgroup type="page" name="CreditCard" label="Credit Card">

   </cfformgroup>
   <cfformgroup type="page" name="ShipTo" label="Ship To">

   </cfformgroup>
   <cfformgroup type="page" name="Subscription" label="Subscription">

   </cfformgroup>
  </cfformgroup>
  <cfformgroup type="horizontal">
    <cfinput type="Submit" value="Submit Form" name="UpdateCustomerBTN">
  </cfformgroup>
 </cfform>

As you can see from the basic code it is fairly simple to setup a tabbed form.  The first pair of cfformgroup tags designate that the container is a tabnavigator.  Each cfformgroup pair within that container are the individual page(s) within the tabnavigator group.  This would generate several tabs on a form.  You just ned to insert the cfinput tags with their labels.  Gone are the days of having to create a table and line up all of the input fields.  So have fun with this one.


Comments (2) | Permalink

Comments

These are just your basics. If you need to process the grid results individually. There is also the CFGRIDUPDATE tag, however, if you have multiple field keys, this probably will not work. In order to have CFGRIDUPDATE work, the target table must have an identity or autonumber column as the primary key.


tried to use the code EXACTLY as you have it below except using our own access and license key which we use in the UPS shipping calc XML that works well , but for some reason we cannot get this to work. When I put in the test tracking number etc and run it, all I get is a blamk screen, even with debugging switched on


 




Home
~ Internet Based Solutions ~ Computer Consulting ~ Portfolio ~ About Us
Dynamic Content Features ~ Web Page Design in Michigan ~ Hosting Services ~ Contact Us

Copyright 2001-2024 Software Advantage Consulting Corporation. All rights reserved.