File Coverage

blib/lib/Business/CyberSource/Report.pm
Criterion Covered Total %
statement 50 50 100.0
branch 17 20 85.0
condition 4 6 66.6
subroutine 12 12 100.0
pod 7 7 100.0
total 90 95 94.7


line stmt bran cond sub pod time code
1             package Business::CyberSource::Report;
2              
3 14     14   20398 use strict;
  14         19  
  14         380  
4 14     14   58 use warnings;
  14         20  
  14         390  
5              
6 14     14   58 use Carp;
  14         21  
  14         857  
7 14     14   6872 use Class::Load qw();
  14         282251  
  14         394  
8 14     14   9363 use Storable qw();
  14         41954  
  14         8410  
9              
10              
11             =head1 NAME
12              
13             Business::CyberSource::Report - Factory class for modules that retrieve CyberSource's XML reports.
14              
15              
16             =head1 VERSION
17              
18             Version 1.2.0
19              
20             =cut
21              
22             our $VERSION = '1.2.0';
23              
24             our $LOADED_REPORT_MODULES;
25              
26              
27             =head1 SYNOPSIS
28              
29             use Business::CyberSource::Report;
30             use Business::CyberSource::Report::Test;
31              
32             # Generate a report factory.
33             my $report_factory = Business::CyberSource::Report->new(
34             merchant_id => $merchant_id,
35             username => $username,
36             password => $password,
37             use_production_system => $use_production_system,
38             );
39              
40             # Use the factory to get a Business::CyberSource::Report::Test object with
41             # the correct connection parameters.
42             my $test_report = $report_factory->build( 'test' );
43              
44             # Retrieve a list of the report modules that have been loaded in memory,
45             # either via "use" or a require by build()
46             my $available_reports = $report_factory->list_loaded();
47              
48             =head1 METHODS
49              
50             =head2 new()
51              
52             Create a new Business::CyberSource::Report factory object.
53              
54             my $report_factory = Business::CyberSource::Report->new(
55             merchant_id => $merchant_id,
56             username => $username,
57             password => $password,
58             use_production_system => $use_production_system,
59             );
60              
61             Parameters:
62              
63             =over
64              
65             =item *
66              
67             merchant_id: a merchant ID provided by CyberSource.
68              
69             =item *
70              
71             username/password: login access information you can create in
72             CyberSource's B Business Center. The access will be automatically
73             available then in the test Business Center. Don't forget to give that user
74             reporting permissions.
75              
76             =item *
77              
78             use_production_system: whether queries should be sent to the production
79             system (1) or the test system (0). Off by default.
80              
81             =back
82              
83             =cut
84              
85             sub new
86             {
87 18     18 1 17744 my ( $class, %args ) = @_;
88              
89             # Check for required arguments.
90 18         49 foreach my $arg ( qw( merchant_id password ) )
91             {
92             croak "The parameter >$arg< is missing"
93 34 100 100     279 if !defined( $args{ $arg } ) || ( $args{ $arg } eq '' );
94             }
95              
96             # By default per CyberSource's interface, the username is the merchant ID.
97             $args{'username'} = $args{'merchant_id'}
98 14 50       83 unless defined( $args{'username'} );
99              
100             # By default, use the test environment.
101             $args{'use_production_system'} = 0
102 14 100       53 unless defined( $args{'use_production_system'} );
103              
104             # Build the object, blessed with the child's class to simplify new() in
105             # children classes.
106             my $self = bless(
107             {
108 14         35 map { $_ => $args{ $_ } }
  70         174  
109             qw( merchant_id username version password use_production_system )
110             },
111             $class,
112             );
113              
114 14         78 return $self;
115             }
116              
117              
118             =head2 list_loaded()
119              
120             Return a list of report modules that have been loaded, either via a "use" or
121             dynamically when calling build().
122              
123             my $loaded_report_modules = $report_factory->list_loaded();
124              
125             =cut
126              
127             sub list_loaded
128             {
129 9     9 1 20 my ( $self ) = @_;
130              
131 9 100       29 if ( !defined( $LOADED_REPORT_MODULES ) )
132             {
133 6         13 $LOADED_REPORT_MODULES = {};
134              
135 6         15 my $main_module_path = __PACKAGE__;
136 6         71 $main_module_path =~ s/::/\//g;
137              
138 6         289 foreach my $module ( keys %INC )
139             {
140 613 100       1819 next unless $module =~ m/^\Q$main_module_path\/\E([^\/]+)\.pm/;
141 5         25 $LOADED_REPORT_MODULES->{ $1 } = undef;
142             }
143             }
144              
145 9         95 return [ keys %$LOADED_REPORT_MODULES ];
146             }
147              
148              
149             =head2 build()
150              
151             Create a Business::CyberSource::Report::* object with the correct connection
152             parameters.
153              
154             # Use the factory to get a Business::CyberSource::Report::Test object with
155             # the correct connection parameters.
156             my $test_report = $report_factory->build( 'SingleTransaction' );
157              
158             Parameters:
159              
160             =over
161              
162             =item *
163              
164             The submodule name, such as SingleTransaction for
165             Business::CyberSource::Report::SingleTransaction.
166              
167             =back
168              
169             =cut
170              
171             sub build
172             {
173 6     6 1 842 my ( $self, $module ) = @_;
174              
175 6 50 33     54 croak 'Please specify the name of the module to build'
176             if !defined( $module ) || ( $module eq '' );
177              
178 6         22 my $class = __PACKAGE__ . '::' . $module;
179              
180             # If the module isn't already loaded, do that now.
181 6 50       10 if ( scalar( grep { $module eq $_ } @{ $self->list_loaded() || [] } ) == 0 )
  4 100       19  
  6         19  
182             {
183 3 100       17 Class::Load::load_optional_class( $class ) || croak "Failed to load $class, double-check the class name";
184 2         99 $LOADED_REPORT_MODULES->{ $module } = undef;
185             }
186              
187 5         513 my $object = bless(
188             # Create a copy of the factory's guts, the object will be a subclass of
189             # the factory and will be able to use all the information.
190             # Also, we don't want a change in the factory parameters to cascade to
191             # the objects previously built, so it makes sense to copy.
192             # TBD: copy only a selected subset of the content?
193             Storable::dclone( $self ),
194             $class,
195             );
196              
197 5         38 return $object;
198             }
199              
200              
201             =head1 ACCESSORS
202              
203             =head2 get_username()
204              
205             Return the username to use to connect to the service.
206              
207             my $username = $report_factory->get_username();
208              
209             =cut
210              
211             sub get_username
212             {
213 18     18 1 27 my ( $self ) = @_;
214              
215 18         59 return $self->{'username'};
216             }
217              
218              
219             =head2 get_password()
220              
221             Return the password to use to connect to the service.
222              
223             my $password = $report_factory->get_password();
224              
225             =cut
226              
227             sub get_password
228             {
229 18     18 1 26 my ( $self ) = @_;
230              
231 18         93 return $self->{'password'};
232             }
233              
234              
235             =head2 get_merchant_id()
236              
237             Return the merchant ID to use to connect to the service.
238              
239             my $merchant_id = $report_factory->get_merchant_id();
240              
241             =cut
242              
243             sub get_merchant_id
244             {
245 13     13 1 23 my ( $self ) = @_;
246              
247 13         51 return $self->{'merchant_id'};
248             }
249              
250              
251             =head2 use_production_system()
252              
253             Return a boolean indicating whether the production system is used in queries.
254             Otherwise, the Test Business Center is used.
255              
256             my $use_production_system = $report_factory->use_production_system();
257              
258             =cut
259              
260             sub use_production_system
261             {
262 10     10 1 984 my ( $self ) = @_;
263              
264 10 100       101 return $self->{'use_production_system'} ? 1 : 0;
265             }
266              
267              
268             =head1 BUGS
269              
270             Please report any bugs or feature requests through the web interface at
271             L.
272             I will be notified, and then you'll automatically be notified of progress on
273             your bug as I make changes.
274              
275              
276             =head1 SUPPORT
277              
278             You can find documentation for this module with the perldoc command.
279              
280             perldoc Business::CyberSource::Report
281              
282              
283             You can also look for information at:
284              
285             =over
286              
287             =item *
288              
289             GitHub's request tracker
290              
291             L
292              
293             =item *
294              
295             AnnoCPAN: Annotated CPAN documentation
296              
297             L
298              
299             =item *
300              
301             CPAN Ratings
302              
303             L
304              
305             =item *
306              
307             MetaCPAN
308              
309             L
310              
311             =back
312              
313              
314             =head1 AUTHOR
315              
316             L, C<< >>.
317              
318              
319             =head1 ACKNOWLEDGEMENTS
320              
321             I originally developed this project for ThinkGeek
322             (L). Thanks for allowing me to open-source it!
323              
324              
325             =head1 COPYRIGHT & LICENSE
326              
327             Copyright 2011-2017 Guillaume Aubert.
328              
329             This code is free software; you can redistribute it and/or modify it under the
330             same terms as Perl 5 itself.
331              
332             This program is distributed in the hope that it will be useful, but WITHOUT ANY
333             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
334             PARTICULAR PURPOSE. See the LICENSE file for more details.
335              
336             =cut
337              
338             1;