File Coverage

blib/lib/Business/UPS/Tracking.pm
Criterion Covered Total %
statement 21 23 91.3
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 29 31 93.5


line stmt bran cond sub pod time code
1             # ============================================================================
2             package Business::UPS::Tracking;
3             # ============================================================================
4 5     5   192717 use utf8;
  5         45  
  5         23  
5 5     5   194 use 5.0100;
  5         13  
6              
7 5     5   2478 use Moose;
  5         1892287  
  5         33  
8             with qw(Business::UPS::Tracking::Role::Base);
9              
10 5     5   27081 no if $] >= 5.017004, warnings => qw(experimental::smartmatch);
  5         10  
  5         44  
11              
12 5     5   3151 use Business::UPS::Tracking::Exception;
  5         11  
  5         141  
13 5     5   3007 use LWP::UserAgent;
  5         168921  
  5         183  
14 5     5   2439 use Business::UPS::Tracking::Utils;
  5         21  
  5         278  
15 5     5   2777 use Business::UPS::Tracking::Request;
  0            
  0            
16              
17             our $VERSION = "1.12";
18             our $AUTHORITY = 'cpan:MAROS';
19             our $CHECKSUM = $ENV{TRACKING_CHECKSUM} // 1 ;
20              
21             =encoding utf8
22              
23             =head1 NAME
24              
25             Business::UPS::Tracking - Interface to the UPS tracking webservice
26              
27             =head1 SYNOPSIS
28              
29             use Business::UPS::Tracking;
30            
31             my $tracking = Business::UPS::Tracking->new(
32             AccessLicenseNumber => '1CFFED5A5E91B17',
33             UserId => 'myupsuser',
34             Password => 'secret',
35             );
36            
37             eval {
38             my $response = $tracking->request(
39             TrackingNumber => '1Z12345E1392654435',
40             )->run();
41            
42             foreach my $shipment ($response->shipment) {
43             say 'Service code is '.$shipment->ServiceCode;
44             foreach my $package ($shipment->Package) {
45             say 'Status is '.$package->CurrentStatus;
46             }
47             }
48             };
49            
50             if (my $e = Exception::Class->caught) {
51             given ($e) {
52             when ($_->isa('Business::UPS::Tracking::X::HTTP')) {
53             say 'HTTP ERROR:'.$e->full_message;
54             }
55             when ($_->isa('Business::UPS::Tracking::X::UPS')) {
56             say 'UPS ERROR:'.$e->full_message.' ('.$e->code.')';
57             }
58             default {
59             say 'SOME ERROR:'.$e;
60             }
61             }
62             }
63              
64             =head1 DESCRIPTION
65              
66             =head2 Class structure
67              
68             .-----------------------------------.
69             | Business::UPS::Tracking |
70             '-----------------------------------'
71             ^
72             HAS ONE
73             |
74             .-----------------------------------.
75             | B::U::T::Request |
76             '-----------------------------------'
77             ^
78             HAS ONE
79             |
80             .-----------------------------------.
81             | B::U::T::Response |
82             '-----------------------------------'
83             |
84             HAS MANY
85             v
86             .-----------------------------------.
87             | B::U::T::Shipment |
88             '-----------------------------------'
89             ^ ^
90             ISA ISA
91             | |
92             .---------------------------------. .-----------------------------------.
93             | B::U::T::Shipment::Freight | | B::U::T::Shipment::Smallpackage |
94             |---------------------------------| |-----------------------------------|
95             | Freight shipment type | | Small package shipment type |
96             | Not yet implemented | '-----------------------------------'
97             '---------------------------------' |
98             HAS MANY
99             v
100             .-----------------------------------.
101             | B::U::T::Element::Package |
102             '-----------------------------------'
103             |
104             HAS MANY
105             v
106             .-----------------------------------.
107             | B::U::T::Element::Activity |
108             '-----------------------------------'
109              
110             =head2 Exception Handling
111              
112             If anythis goes wrong Business::UPS::Tracking throws an exception. Exceptions
113             are always L<Exception::Class> objects which contain structured information
114             about the error. Please refer to the synopsis or to the L<Exception::Class>
115             documentation for documentation how to catch and rethrow exeptions.
116              
117             The following exception classes are defined:
118              
119             =head3 Business::UPS::Tracking::X
120              
121             Basic exception class. All other exception classes inherit from this class.
122              
123             =head3 Business::UPS::Tracking::X::HTTP
124              
125             HTTP error. The object provides additional parameters:
126              
127             =over
128              
129             =item * http_response : L<HTTP::Response> object
130              
131             =item * request : L<Business::UPS::Tracking::Request> object
132              
133             =back
134              
135             =head3 Business::UPS::Tracking::X::UPS
136              
137             UPS error message.The object provides additional parameters:
138              
139             =over
140              
141             =item * code : UPS error code
142              
143             =item * severity : Error severity 'hard' or 'soft'
144              
145             =item * context : L<XML::LibXML::Node> object containing the whole error response.
146              
147             =item * request : L<Business::UPS::Tracking::Request> object
148              
149             =back
150              
151             =head3 Business::UPS::Tracking::X::XML
152              
153             XML parser or schema error.
154              
155             =head2 Accessor / method naming
156              
157             The naming of the methods and accessors tries to stick close to the names
158             used by the UPS webservice. All accessors containg uppercase letters access
159             xml data. Lowercase-only accessors and methods are used for utility
160             functions.
161              
162             =head2 UPS license
163              
164             In order to use this module you need to obtain a "Tracking WebService"
165             license key. See L<http://www.ups.com/e_comm_access/gettools_index> for more
166             information.
167              
168             =head1 METHODS
169              
170             =head2 new
171              
172             my $tracking = Business::UPS::Tracking->new(%params);
173              
174             Create a C<Business::UPS::Tracking> object. See L<ACCESSORS> for available
175             parameters.
176              
177             =head2 access_request
178              
179             UPS access request.
180              
181             =head2 request
182              
183             my $request = $tracking->request(%request_params);
184              
185             Returns a L<Business::UPS::Tracking::Request> object.
186              
187             =head2 request_run
188              
189             my $response = $tracking->request_run(%request_params);
190              
191             Generates a L<Business::UPS::Tracking::Request> object and imideately
192             executes it, returning a L<Business::UPS::Tracking::Response> object.
193              
194             =head1 ACCESSORS
195              
196             =head2 AccessLicenseNumber
197              
198             UPS tracking service access license number
199              
200             =head2 UserId
201              
202             UPS account username
203              
204             =head2 Password
205              
206             UPS account password
207              
208             =head2 config
209              
210             Optionally you can retrieve all or some UPS webservice credentials from a
211             configuration file. This accessor holds the path to this file.
212             Defaults to C<~/.ups_tracking>
213              
214             Example configuration file:
215              
216             <?xml version="1.0"?>
217             <UPS_tracking_webservice_config>
218             <AccessLicenseNumber>1CFFED5A5E91B17</AccessLicenseNumber>
219             <UserId>myupsuser</UserId>
220             <Password>secret</Password>
221             </UPS_tracking_webservice_config>
222              
223             =head2 retry_http
224              
225             Number of retries if http errors occur
226              
227             Defaults to 0
228              
229             =head2 url
230              
231             UPS Tracking webservice url.
232              
233             Defaults to https://wwwcie.ups.com/ups.app/xml/Track
234              
235             =head2 _ua
236              
237             L<LWP::UserAgent> object.
238              
239             Automatically generated
240              
241             =cut
242              
243             has 'retry_http' => (
244             is => 'rw',
245             isa => 'Int',
246             default => 0,
247             documentation => 'Number of retries if HTTP errors occur [Default 0]',
248             );
249             has 'url' => (
250             is => 'rw',
251             default => sub { 'https://wwwcie.ups.com/ups.app/xml/Track' },
252             documentation => 'UPS webservice url',
253             );
254             has '_ua' => (
255             is => 'rw',
256             lazy => 1,
257             isa => 'LWP::UserAgent',
258             builder => '_build_ua',
259             );
260              
261              
262             sub _build_ua {
263             my ($self) = @_;
264              
265             my $ua = LWP::UserAgent->new(
266             agent => __PACKAGE__ . " ". $VERSION,
267             timeout => 50,
268             env_proxy => 1,
269             );
270              
271             return $ua;
272             }
273              
274             sub access_request {
275             my ($self) = @_;
276              
277             my $license = Business::UPS::Tracking::Utils::escape_xml($self->AccessLicenseNumber);
278             my $username = Business::UPS::Tracking::Utils::escape_xml($self->UserId);
279             my $password = Business::UPS::Tracking::Utils::escape_xml($self->Password);
280            
281             return <<ACR
282             <?xml version="1.0"?>
283             <AccessRequest xml:lang='en-US'>
284             <AccessLicenseNumber>$license</AccessLicenseNumber>
285             <UserId>$username</UserId>
286             <Password>$password</Password>
287             </AccessRequest>
288             ACR
289             }
290              
291             sub request {
292             my ( $self, %params ) = @_;
293             return Business::UPS::Tracking::Request->new(
294             %params,
295             tracking => $self,
296             );
297             }
298              
299             sub request_run {
300             my ( $self, %params ) = @_;
301             return $self->request(%params)->run();
302             }
303              
304             __PACKAGE__->meta->make_immutable;
305             no Moose;
306              
307             =head1 SUPPORT
308              
309             Please report any bugs or feature requests to
310             C<bug-buisness-ups-tracking@rt.cpan.org>, or through the web interface at
311             L<http://rt.cpan.org/Public/Bug/Report.html?Queue=Business::UPS::Tracking>.
312             I will be notified, and then you'll automatically be notified of progress on
313             your report as I make changes.
314              
315             =head1 SEE ALSO
316              
317             Download the UPS "OnLine® Tools Tracking Developer Guide" and get a
318             developer key at L<http://www.ups.com/e_comm_access/gettools_index?loc=en_US>.
319             Please check the "Developer Guide" for more detailed documentation on the
320             various fields.
321              
322             The L<WebService::UPS::TrackRequest> provides an alternative simpler
323             implementation.
324              
325             =head1 AUTHOR
326              
327             MaroÅ¡ Kollár
328             CPAN ID: MAROS
329             maros [at] k-1.com
330            
331             http://www.k-1.com
332              
333             =head1 COPYRIGHT
334              
335             Business::UPS::Tracking is Copyright (c) 2012 MaroÅ¡ Kollár
336             - L<http://www.k-1.com>
337              
338             =head1 LICENCE
339              
340             This library is free software, you can redistribute it and/or modify
341             it under the same terms as Perl itself.
342              
343             =cut
344              
345             'Where is my "30 HP NorTrac Bulldozer" I ordered at Amazon recently? (http://www.amazon.com/30-HP-NorTrac-Bulldozer-Backhoe/dp/B000EIWSN0)';