File Coverage

blib/lib/Business/CanadaPost.pm
Criterion Covered Total %
statement 13 193 6.7
branch 0 76 0.0
condition 0 101 0.0
subroutine 5 37 13.5
pod 26 29 89.6
total 44 436 10.0


line stmt bran cond sub pod time code
1             package Business::CanadaPost;
2             BEGIN {
3 1     1   1505 $Business::CanadaPost::AUTHORITY = 'cpan:YANICK';
4             }
5             {
6             $Business::CanadaPost::VERSION = '1.06';
7             }
8             # ABSTRACT: Fetch shipping costs for Canada Post
9              
10 1     1   10 use strict;
  1         2  
  1         33  
11 1     1   823 use LWP;
  1         49930  
  1         40  
12 1     1   10 use vars qw($VERSION @ISA @EXPORT);
  1         1  
  1         71  
13 1     1   6 use Exporter;
  1         3  
  1         2915  
14              
15             @ISA = qw(Exporter);
16             @EXPORT = qw();
17              
18              
19             sub new # {{{
20             {
21 0     0 1   my ($class, %data) = @_;
22              
23 0           my $self = {
24             language => 'en', #canada post supports english (en) and french (fr)
25             frompostalcode => '', #canada post says to send a space if we have no entry...
26             turnaroundtime => '',
27             merchantid => '',
28             totalprice => '0.00',
29             units => 'metric', #allows for metric (cm and kg) or imperial (in and lb) measurements.
30             items => [],
31             testing => 0
32             };
33              
34 0           foreach (keys %data)
35             {
36 0           $self->{$_} = $data{$_};
37             }
38              
39 0           bless $self, $class;
40              
41 0           return $self;
42             } # }}}
43              
44              
45             sub geterror # {{{
46             {
47 0     0 1   my $self = shift;
48 0           my $error = $self->{'error'};
49 0           $self->{'error'} = ''; #clear it once we've sent it.
50 0           return $error;
51             } # }}}
52              
53             sub setlanguage # {{{
54             {
55 0     0 1   my ($self, $lang) = @_;
56              
57 0           $lang = lc($lang);
58 0 0 0       return $self->_error(4) unless $lang eq 'fr' or $lang eq 'en' or $lang eq '';
      0        
59              
60 0   0       $self->{'language'} = $lang || 'en';
61             } # }}}
62              
63              
64             sub settocity # {{{
65              
66             {
67 0     0 1   my ($self, $city) = @_;
68 0           $self->{'city'} = $city;
69             } # }}}
70              
71              
72             sub settesting # {{{
73            
74             {
75 0     0 1   my ($self, $testing) = @_;
76              
77 0           $self->{'testing'} = $testing;
78             } # }}}
79              
80              
81             sub setcountry # {{{
82              
83             {
84 0     0 1   my ($self, $country) = @_;
85 0           $self->{'country'} = $country;
86             } # }}}
87              
88              
89             sub setmerchantid # {{{
90              
91             {
92 0     0 1   my ($self, $id) = @_;
93            
94 0   0       $self->{'merchantid'} = $id || ' ';
95             } # }}}
96              
97              
98             sub setunits # {{{
99              
100             {
101 0     0 1   my ($self, $units) = @_;
102              
103             #FIXME -- make it go through each item and convert to/from metric if they change!
104 0           $units = lc($units);
105 0 0 0       return $self->_error(5) unless $units eq 'metric' or $units eq 'imperial';
106 0           $self->{'units'} = $units;
107             } # }}}
108              
109              
110             sub setfrompostalcode # {{{
111              
112             {
113 0     0 1   my ($self, $code) = @_;
114              
115 0   0       $self->{'frompostalcode'} = $code || ' ';
116             } # }}}
117              
118              
119             sub settopostalzip # {{{
120              
121             {
122 0     0 0   my ($self, $code) = @_;
123              
124 0   0       $self->{'postalcode'} = $code || ' ';
125             } # }}}
126              
127              
128             sub setprovstate # {{{
129              
130             {
131 0     0 1   my ($self, $province) = @_;
132 0   0       $self->{'provstate'} = $province || ' ';
133             } # }}}
134              
135              
136             sub setturnaroundtime # {{{
137              
138             {
139 0     0 1   my ($self, $code) = @_;
140 0   0       $self->{'turnaroundtime'} = $code || ' ';
141             } # }}}
142              
143              
144             sub settotalprice # {{{
145              
146             {
147 0     0 1   my ($self, $price) = @_;
148 0   0       $self->{'totalprice'} = sprintf('%01.2f', $price) || '0.00';
149             } # }}}
150              
151              
152             sub additem # {{{
153             {
154 0     0 1   my ($self, %item) = @_;
155              
156 0 0 0       $item{'length'} and $item{'width'} and $item{'height'} or
      0        
157             return $self->_error(6);
158              
159 0 0         my @currentitems = @{$self->{'items'}} if ref $self->{'items'};
  0            
160              
161             #canadapost specifies that the longest dimension is the length,
162             #second longest is the width and shortest is height.
163 0           my @dimensions = ($item{'length'}, $item{'height'}, $item{'width'});
164 0           ($item{'length'}, $item{'width'}, $item{'height'}) = reverse sort @dimensions;
165              
166 0 0         my $metric = $self->{'units'} eq 'imperial' ? 0 : 1;
167              
168 0 0 0       push (@currentitems, $item{'quantity'} || 1,
    0 0        
    0          
    0          
    0          
169             $metric ? $item{'weight'} : $item{'weight'} * .45359237, # 1lb = .45359237kg
170             $metric ? $item{'length'} : $item{'length'} * 2.54, # 1in = 2.54cm
171             $metric ? $item{'width'} : $item{'width'} * 2.54,
172             $metric ? $item{'height'} : $item{'height'} * 2.54,
173             $item{'description'} || ' ',
174             $item{'readytoship'} ? '' : '');
175              
176 0           $self->{'items'} = \@currentitems;
177             } # }}}
178              
179              
180             sub getrequest # {{{
181             {
182 0     0 1   my $self = shift;
183 0 0         my $xmlfile = $self->buildXML() or return $self->_error($self->{'error'});
184              
185 0           my $lwp = LWP::UserAgent->new();
186 0           my $result = $lwp->post("http://sellonline.canadapost.ca:30000", { 'XMLRequest' => $xmlfile });
187 0 0         return $self->_error(8) unless $result->is_success;
188              
189 0           my $raw_data = $result->content();
190              
191 0           return $self->parseXML($raw_data);
192             } # }}}
193              
194             sub parseXML # {{{
195              
196             {
197 0     0 0   my ($self, $xml) = @_;
198              
199 0           my ($parcel) = $xml =~ /(.+)<\/eparcel>/s;
200 0           my ($resultcode) = $parcel =~ /([^<]+)<\/statusCode>/s;
201 0 0         unless ($resultcode == 1)
202             {
203 0           my ($resultmessage) = $parcel =~ /([^<]+)<\/statusMessage>/s;
204 0           return $self->_error($resultmessage);
205             }
206 0           my ($products) = $parcel =~ //s; #should be greedy and get them all..
207 0           my @options;
208 0           foreach my $product (split /<\/product>\s+
209             {
210 0           my ($name) = $product =~ /([^<]+)<\/name>/s;
211 0           my ($rate) = $product =~ /([^<]+)<\/rate>/s;
212 0           my ($shipdate) = $product =~ /([^<]+)<\/shippingDate>/s;
213 0           my ($delvdate) = $product =~ /([^<]+)<\/deliveryDate>/s;
214 0           my ($dayofweek) = $product =~ /([^<]+)<\/deliveryDayOfWeek>/s;
215 0           my ($nextdayam) = $product =~ /([^<]+)<\/nextDayAM>/s;
216 0           my $estdays = _getdaysbetween($shipdate, $delvdate);
217 0 0         $estdays = 'Unknown' if $estdays == -1;
218 0 0         $nextdayam = $nextdayam eq 'true' ? 1 : 0;
219 0           push (@options, $name, $rate, $shipdate, $delvdate, $dayofweek, $nextdayam, $estdays);
220             }
221              
222 0           $self->{'shippingoptioncount'} = scalar(@options) / 7;
223 0           $self->{'shiprates'} = \@options;
224              
225 0           my ($soptions) = $parcel =~ /(.+)<\/shippingOptions>/s;
226 0 0         if ($soptions =~ /([^<]+)<\/insurance>/)
227             {
228 0 0         $self->{'shipinsurance'} = $1 eq 'No' ? 0 : 1;
229             }
230 0 0         if ($soptions =~ /([^<]+)<\/deliveryConfirmation>/)
231             {
232 0 0         $self->{'shipconfirm'} = $1 eq 'No' ? 0 : 1;
233             }
234 0 0         if ($soptions =~ /([^<]+)<\/signature>/)
235             {
236 0 0         $self->{'signature'} = $1 eq 'No' ? 0 : 1;
237             }
238              
239 0 0         $self->{'shipcomments'} = $1 if $parcel =~ /([^<]+)<\/comment>/s;
240 0           return 1;
241             } # }}}
242              
243              
244             sub getoptioncount # {{{
245             {
246 0     0 1   my $self = shift;
247 0           return $self->{'shippingoptioncount'};
248             } # }}}
249              
250              
251              
252             sub getsignature # {{{
253              
254             {
255 0     0 1   my $self = shift;
256 0           return $self->{'signature'};
257             } # }}}
258              
259              
260             sub getinsurance # {{{
261              
262             {
263 0     0 1   my $self = shift;
264 0           return $self->{'shipinsurance'};
265             } # }}}
266              
267              
268              
269             sub getshipname # {{{
270              
271             {
272 0     0 1   my $self = shift;
273 0   0       my $shipmentnum = shift || 1;
274 0           $shipmentnum--; #we're looking for the offset in the array...
275              
276 0           my @options = @{$self->{'shiprates'}};
  0            
277 0           return $options[$shipmentnum * 7]
278             } # }}}
279              
280              
281             sub getshiprate # {{{
282              
283             {
284 0     0 1   my $self = shift;
285 0   0       my $shipmentnum = shift || 1;
286 0           $shipmentnum--;
287 0           my @options = @{$self->{'shiprates'}};
  0            
288 0           return $options[$shipmentnum * 7 + 1]
289             } # }}}
290              
291              
292              
293             sub getshipdate # {{{
294              
295             {
296 0     0 1   my $self = shift;
297 0   0       my $shipmentnum = shift || 1;
298 0           $shipmentnum--;
299 0           my @options = @{$self->{'shiprates'}};
  0            
300 0           return $options[$shipmentnum * 7 + 2]
301             } # }}}
302              
303              
304             sub getdelvdate # {{{
305              
306             {
307 0     0 1   my $self = shift;
308 0   0       my $shipmentnum = shift || 1;
309 0           $shipmentnum--;
310 0           my @options = @{$self->{'shiprates'}};
  0            
311 0           return $options[$shipmentnum * 7 + 3]
312             } # }}}
313              
314              
315              
316             sub getdayofweek # {{{
317              
318             {
319 0     0 1   my $self = shift;
320 0   0       my $shipmentnum = shift || 1;
321 0           $shipmentnum--;
322 0           my @options = @{$self->{'shiprates'}};
  0            
323 0           return $options[$shipmentnum * 7 + 4]
324             } # }}}
325              
326              
327              
328             sub getnextdayam # {{{
329              
330             {
331 0     0 1   my $self = shift;
332 0   0       my $shipmentnum = shift || 1;
333 0           $shipmentnum--;
334 0           my @options = @{$self->{'shiprates'}};
  0            
335 0           return $options[$shipmentnum * 7 + 5]
336             } # }}}
337              
338              
339              
340             sub getestshipdays # {{{
341              
342             {
343 0     0 1   my $self = shift;
344 0   0       my $shipmentnum = shift || 1;
345 0           $shipmentnum--;
346 0           my @options = @{$self->{'shiprates'}};
  0            
347 0           return $options[$shipmentnum * 7 + 6]
348             } # }}}
349              
350              
351              
352             sub getconfirmation # {{{
353              
354             {
355 0     0 1   my $self = shift;
356 0           return $self->{'shipconfirm'};
357             } # }}}
358              
359              
360             sub getcomments # {{{
361              
362             {
363 0     0 1   my $self = shift;
364 0           return $self->{'shipcomments'};
365             } # }}}
366              
367             sub _error # {{{
368              
369             {
370 0     0     my ($self, $msgnum) = @_;
371 0           my @englishmessages = ('You need to specify some items to ship!',
372             'You must specify a valid postal code for Canadian shipments!',
373             'You must specify a state for American shipments!',
374             'You must specify the country being shipped to!',
375             'Valid languages are English and French',
376             'Valid units are metric (cm and kg) or imperial (in and lb)',
377             'You must specify a height, width, and length for each item.',
378             'You must specify your Canada Post merchant ID!',
379             'Failed sending to Canada Posts servers!');
380 0           my @frenchmessages = ('Vous devez indiquer quelques pour transporter!',
381             'Vous devez indiquer un code postal valide pour les expéditions Canadiannes!',
382             'Vous devez indiquer un état pour les expéditions américaines!',
383             'Vous devez indiquer le pays que vous voulez embarquer à!',
384             'Les langues valides sont Anglaises et Françaises',
385             'Les unités valides sont métriques (cm et kg) ou impériales (po et lv)',
386             'Vous devez indiquer une taille, une largeur, et une longueur pour chaque article.',
387             'Vous devez indiquer votre identification du Postes Canada!',
388             'Envoi échoué aux serveurs du Postes Canada!');
389              
390 0 0         if ($msgnum == 0)
391             {
392 0           push (@englishmessages, $msgnum);
393 0           push (@frenchmessages, $msgnum);
394 0           $msgnum = scalar(@englishmessages) - 1;
395             }
396              
397 0 0         $self->{'error'} = sprintf("%s\n",
398             $self->{'language'} eq 'fr' ? $frenchmessages[$msgnum] :
399             $englishmessages[$msgnum]);
400 0           return 0;
401             } # }}}
402              
403             sub _getdaysbetween # {{{
404              
405             {
406 0     0     my ($fromdate, $todate) = @_;
407 0           my @daysinmonth = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
408              
409 0           my ($fromyear, $frommon, $fromday) = split /-/, $fromdate;
410 0           my ($toyear, $tomon, $today) = split /-/, $todate;
411              
412 0 0 0       return 0 if $fromyear == $toyear and $frommon == $tomon and $fromday == $today;
      0        
413 0 0 0       return -1 unless $fromyear and $frommon and $fromday and $toyear and $tomon and $today;
      0        
      0        
      0        
      0        
414              
415 0           my $days;
416            
417             do
418 0   0       {
      0        
419 0           $days++;
420 0           $fromday++;
421 0 0         $daysinmonth[2] = _isleapyear($fromyear) ? 29 : 28;
422 0 0         $fromday = 1, $frommon++ if $fromday > $daysinmonth[$frommon];
423 0 0         $frommon = 1, $fromyear++ if $frommon == 13;
424             } until $fromyear == $toyear and $frommon == $tomon and $fromday == $today;
425              
426 0           return $days;
427             } # }}}
428              
429             sub _isleapyear # {{{
430              
431             {
432 0     0     my $year = shift;
433              
434 0 0 0       return 1 if $year % 4 == 0 and $year % 400 == 0;
435 0 0         return 0 if $year % 100 == 0;
436 0 0         return 1 if $year % 4 == 0;
437 0           return 0;
438             } # }}}
439              
440             sub buildXML # {{{
441              
442             {
443 0     0 0   my $self = shift;
444            
445 0           my @items = @{$self->{'items'}};
  0            
446 0 0         return $self->_error(0) unless @items;
447              
448             # language can be en or fr (this is Canada!)
449 0   0       my $xmlfile = sprintf('
      0        
450            
451             %s
452            
453             %s
454             %s
455             %s
456             %.2f%s',
457             $self->{'language'} || 'en',
458             $self->{'merchantid'} || return $self->_error(7),
459             $self->{'frompostalcode'} ? "" . $self->{'frompostalcode'} . "\n" : '',
460             $self->{'turnaroundtime'} ? "" . $self->{'turnaroundtime'} . "\n" : '',
461             $self->{'totalprice'} || '0.00',
462             "\n");
463              
464            
465 0           $xmlfile .= " \n";
466 0           for (my $n = 0; $n < @items; $n += 7)
467             {
468 0           $xmlfile .= sprintf("
469             %d
470             %01.2f
471             %01.2f
472             %01.2f
473             %01.2f
474             %s
475             %s
476             \n",
477             @items[$n .. $n+6]);
478             }
479 0           $xmlfile .= " \n";
480              
481 0 0 0       if (!$self->{'country'} or $self->{'country'} =~ /^\s*$/) # no country specified...
    0 0        
    0 0        
      0        
482             {
483 0           return $self->_error(3);
484             }
485             elsif (uc($self->{'country'}) eq 'CANADA' or uc($self->{'country'}) eq 'CA')
486             {
487             #canada post docs state that only postal code must exist for canadian shipments
488 0           $self->{'postalcode'} =~ s/[^\d\w]//g;
489 0 0         $self->{'postalcode'} =~ /^\w\d\w\d\w\d$/
490             or return $self->_error(1);
491              
492             }
493             elsif (uc($self->{'country'}) eq 'UNITED STATES' or uc($self->{'country'} eq 'US')
494             or uc($self->{'country'}) eq 'ÉTATS-UNIS')
495             {
496             #canada post says that all they require for now is country and provorstate; however,
497             #zipcodes will be used in the future...
498 0 0         $self->{'provstate'} or return $self->_error(2);
499 0   0       $self->{'postalcode'} ||= ' ';
500 0           $self->{'postalcode'} =~ s/\D//g;
501             }
502            
503 0   0       $xmlfile .= sprintf(" %s
      0        
      0        
504             %s
505             %s
506             %s
507            
508             ",
509             $self->{'city'} || ' ',
510             $self->{'provstate'} || ' ',
511             $self->{'country'},
512             $self->{'postalcode'} || ' ');
513              
514 0           return $xmlfile;
515             } # }}}
516              
517             1;
518              
519              
520              
521             =pod
522              
523             =head1 NAME
524              
525             Business::CanadaPost - Fetch shipping costs for Canada Post
526              
527             =head1 VERSION
528              
529             version 1.06
530              
531             =head1 SYNOPSIS
532              
533             use Business::CanadaPost;
534            
535             #initialise object - specifying from postal code, and canada post merchant id
536             my $shiprequest = Business::CanadaPost->new( merchantid => 'CPC_DEMO_XML',
537             frompostal => 'M1P1C0',
538             testing => 1 );
539              
540             # add an item to be shipped
541             $shiprequest->additem(quantity => 1,
542             height => 60,
543             width => 15,
544             length => 60,
545             weight => 7,
546             description => 'box o stuff',
547             readytoship => 1);
548              
549             # set more parameters on the item being shipped
550             $shiprequest->setcountry('United States');
551             $shiprequest->setprovstate('New York');
552             $shiprequest->settopostalzip('11726');
553             $shiprequest->settocity('New York');
554             $shiprequest->getrequest() || print "Failed sending request: " . $shiprequest->geterror() . "\n";
555             print "There are " . $shiprequest->getoptioncount() . " available shipping methods.\n";
556              
557             =head1 DESCRIPTION
558              
559             Business::CanadaPost is a Perl library created to allow users to fetch real-time options and pricing quotes
560             on shipments sent from Canada using Canada Post.
561              
562             To get off of the development server, you'll need to get an account from Canada Post's "Sell Online" service.
563             While testing, use user id CPC_DEMO_XML and specify a parameter of 'testing' with a value of 1 to the new()
564             constructor, so it knows to use Canada Post's devel server. If you don't, and don't have an account, you'll
565             only receive errors.
566              
567             =head1 PREREQUISITES
568              
569             This module requires C, C, and C.
570              
571             =head1 EXPORT
572              
573             None.
574              
575             =head1 CONSTRUCTOR
576              
577             =head2 C
578              
579             Creates a new Business::CanadaPost object. Different objects available are:
580              
581             =over 8
582              
583             =item language
584              
585             'en' for English, and 'fr' for French. (Default: en)
586              
587             =item frompostalcode
588              
589             This is used to override the setting in our sell online profile for the from
590             address you would be shipping from. Format is A1A1A1 (A being any upper-case
591             character between A-Z, and 1 being any digit 0-9)
592              
593             If not specified, it will default to your setting in your Canada Post Sell
594             Online(tm) profile.
595              
596             =item turnaroundtime
597              
598             Your turnaround time in hours. This is the amount of time between receiving
599             the order and shipping it out. It is used to create a shipping and delivery
600             date for the item. If none is specified, it will default to what you have set
601             in your profile.
602              
603             If you have nothing set in your profile, it will assume you are shipping next-day.
604              
605             (Default: none)
606              
607             =item merchantid
608              
609             This is your merchant ID assigned to you by Canada Post. It usually begins with
610             CPC_. You can use CPC_DEMO_XML if you're testing and using Canada Post's test
611             servers. (Default: none. You need to set this or the module will return a fatal
612             error.)
613              
614             =item totalprice
615              
616             Total value of the shipment you're mailing. This is used to calculate whether or
617             not a signature will be required, and whether it will need to include more insurance
618             to cover the item (beyond the $100 included in the original shipment.) (Default: 0.00)
619              
620             =item units
621              
622             Possible values are 'metric' and 'imperial'.
623              
624             If set to metric, you will be specifying height, length, and width in cm, and
625             weight in kg.
626              
627             If set to imperial, you will be specifying height, length, and width in in, and
628             weight in lb.
629              
630             (Default: metric)
631              
632             =item testing
633              
634             Possible values: 1 or 0.
635              
636             Specifies whether you're using a production account, or a testing account. If you're
637             in testing mode, you'll be connecting to Canada Post's test servers, which run on
638             less stable hardware, on a slower link to the Internet, and are rate-throttled.
639              
640             (Default: 0)
641              
642             =item items
643              
644             An array containing the items in your shipment. Array elements are:
645              
646             (quantity, weight, length, width, height, description, readytoship [1 or 0])
647              
648             readytoship specifies that you have the item already boxed or prepared for shipment.
649              
650             If this is set to 0, then Canada Post server's will calculate the most appropriate box
651             listed in your account profile, and use it for its dimensions and shipping cost.
652              
653             =back
654              
655             =head1 OBJECT METHODS
656              
657             Most errors are fatal. The tool tries to guess for you if a value seems
658             out of whack.
659              
660             =head2 C
661              
662             Used to fetch the error set when a function return 0 for failure.
663              
664             Example:
665              
666             $object->getrequest or print "Error: " . $object->geterror() . "\n";
667              
668             =head2 C
669              
670             Used to change the language.
671              
672             Example:
673              
674             $object->setlanguage('fr'); # changes messages to french.
675              
676             =head2 C
677              
678             Specifies city being shipped to.
679              
680             Example:
681              
682             $object->settocity('New York');
683              
684             =head2 C
685              
686             Specifies whether account is in testing.
687              
688             Example:
689              
690             $object->settesting(1);
691              
692             =head2 C
693              
694             Specifies country being mailed to.
695              
696             Example:
697              
698             $object->setcountry('United States');
699              
700             =head2 C
701              
702             Specifies Canada Post merchant ID.
703              
704             Example:
705              
706             $object->setmerchantid('CPC_DEMO_XML');
707              
708             =head2 C
709              
710             Specifies imperial or metric measurements.
711              
712             Example:
713              
714             $object->setunits('imperial');
715              
716             =head2 C
717              
718             Specifies postal code item is being shipped from.
719              
720             Example:
721              
722             $object->setfrompostalcode(''); # will reset postal code back to default set in canada post profile
723              
724             =head2 C
725              
726             Specifies postal code/zip code item is being shipped to.
727              
728             Example:
729              
730             $object->settopostalcode('N2G5M4');
731              
732             =head2 C
733              
734             Specifies province/state being shipped to.
735              
736             Example:
737              
738             $object->settopostalcode('Ontario');
739              
740             =head2 C
741              
742             Specifies turnaround time in hours.
743              
744             Example:
745              
746             $object->setturnaroundtime(24);
747              
748             =head2 C
749              
750             Specifies total value of items being shipped.
751              
752             Example:
753              
754             $object->settotalprice(5.50);
755              
756             =head2 C
757              
758             Adds an item to be shipped to the request.
759              
760             Example:
761              
762             $object->additem(length => 5,
763             height => 3,
764             width => 2,
765             weight => 5,
766             description => "box of cookies",
767             readytoship => 1,
768             quantity => 1);
769              
770             Weight, length, height, and width are the only requirements.
771              
772             If not specified, quantity will default to 1, readytoship will
773             default to 0, and description will default to an empty string.
774              
775             =head2 C
776              
777             Builds request, sends it to Canada Post, and parses the results.
778              
779             Example:
780              
781             $object->getrequest();
782              
783             returns 1 on success.
784              
785             =head2 C
786              
787             Returns number of available shipping options.
788              
789             Example:
790              
791             my $available_options = $object->getoptioncount();
792              
793             =head2 C
794              
795             Returns 1 or 0 based on whether or not a signature would be required for these deliveries.
796              
797             Example:
798              
799             my $signature_required = $object->getsignature();
800              
801             =head2 C
802              
803             Returns 1 or 0 based on whether or not extra insurance coverage is required (and included) in prices.
804              
805             Example:
806              
807             my $insurance_included = $object->getinsurance();
808              
809             =head2 C
810              
811             Receives an option number between 1 and $object->getoptioncount() and returns that
812             option's name.
813              
814             Example:
815              
816             print "First option available is: " . $object->getshipname(1) . "\n";
817              
818             =head2 C
819              
820             Operates the same as C, but returns cost of that shipping method.
821              
822             Example:
823              
824             print "First option would cost: " . $object->getshiprate(1) . " to ship.\n";
825              
826             returns 1 on success.
827              
828             =head2 C
829              
830             Operates the same as C, but returns assumed shipment date.
831              
832             Example:
833              
834             print "Item would be shipped out on " . $object->getshipdate(1) . "\n";
835              
836             =head2 C
837              
838             Operates the same as C, but returns when the approximate
839             delivery date would be based on a shipping date of $object->getshipdate();
840              
841             Example:
842              
843             print "Assuming a delivery date of " . $object->getshipdate(1) .
844             ", this item would arrive on: " . $object->getdelvdate(1) . "\n";
845              
846             =head2 C
847              
848             Operates the same as C, but returns which day of the week
849             $object->getdelvdate() lands on numerically. (1 .. 6; 1 == Sunday,
850             6 == Saturday)
851              
852             Example:
853              
854             print "Your item would likely be delivered on the " .
855             $object->getdayofweek(1) . " day of the week.\n";
856              
857             =head2 C
858              
859             Operates the same as C, but returns whether or not
860             the current option provides for next day AM delivery service.
861              
862             Example:
863              
864             printf("This item is %savailable for next day delivery\n",
865             $object->getnextdayam(1) == 1 ? '' : 'NOT ');
866              
867             =head2 C
868              
869             Operates the same as C, but returns estimated
870             number of days required to ship the item.
871              
872             Example:
873              
874             print "This shipping method would take approximately: " . $object->getestshipdays() .
875             " days to arrive.\n";
876              
877             =head2 C
878              
879             Returns whether or not delivery confirmation is included in price quotes.
880              
881             Example:
882              
883             my $confirmation_included = $object->getconfirmation();
884              
885             =head2 C
886              
887             Returns any extra comments Canada Post might include with your quote.
888              
889             Example:
890              
891             my $extra_info = $object->getcomments();
892              
893             =head1 SEE ALSO
894              
895             For more information on how Canada Post's XML shipping system works, please
896             see http://206.191.4.228/DevelopersResources
897              
898             =head1 AUTHORS
899              
900             =over 4
901              
902             =item *
903              
904             Justin Wheeler
905              
906             =item *
907              
908             Yanick Champoux
909              
910             =back
911              
912             =head1 COPYRIGHT AND LICENSE
913              
914             This software is Copyright (c) 2005 by Justin Wheeler.
915              
916             This is free software, licensed under:
917              
918             The GNU General Public License, Version 2, June 1991
919              
920             =cut
921              
922              
923             __END__