line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Business::GoCardless::Resource; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=head1 NAME |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
Business::GoCardless::Resource |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 DESCRIPTION |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
This is a base class for gocardless resource classes, it implements common |
10
|
|
|
|
|
|
|
behaviour. You shouldn't use this class directly, but extend it instead. |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=cut |
13
|
|
|
|
|
|
|
|
14
|
19
|
|
|
19
|
|
8441
|
use strict; |
|
19
|
|
|
|
|
44
|
|
|
19
|
|
|
|
|
486
|
|
15
|
19
|
|
|
19
|
|
88
|
use warnings; |
|
19
|
|
|
|
|
33
|
|
|
19
|
|
|
|
|
390
|
|
16
|
|
|
|
|
|
|
|
17
|
19
|
|
|
19
|
|
85
|
use Moo; |
|
19
|
|
|
|
|
38
|
|
|
19
|
|
|
|
|
82
|
|
18
|
19
|
|
|
19
|
|
6312
|
use Carp qw/ carp confess /; |
|
19
|
|
|
|
|
52
|
|
|
19
|
|
|
|
|
1006
|
|
19
|
19
|
|
|
19
|
|
666
|
use JSON (); |
|
19
|
|
|
|
|
8217
|
|
|
19
|
|
|
|
|
14468
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head2 endpoint |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
The gocardless API endpoint that corresponds to the resource, for example a |
26
|
|
|
|
|
|
|
L object will have an endpoint of "bills". This |
27
|
|
|
|
|
|
|
is handled automatically, you do not need to pass this unless the name of the |
28
|
|
|
|
|
|
|
resource differs significantly from the endpoint. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head2 client |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
The client object, defaults to L. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=cut |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
has endpoint => ( |
37
|
|
|
|
|
|
|
is => 'ro', |
38
|
|
|
|
|
|
|
default => sub { |
39
|
|
|
|
|
|
|
my ( $self ) = @_; |
40
|
|
|
|
|
|
|
my ( $class ) = ( split( ':',ref( $self ) ) )[-1]; |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
confess( "You must subclass Business::GoCardless::Resource" ) |
43
|
|
|
|
|
|
|
if $class eq 'Resource'; |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
$class =~ s/([a-z])([A-Z])/$1 . '_' . lc( $2 )/eg; |
46
|
|
|
|
|
|
|
$class = lc( $class ); |
47
|
|
|
|
|
|
|
return "/${class}s/%s"; |
48
|
|
|
|
|
|
|
}, |
49
|
|
|
|
|
|
|
); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
has client => ( |
52
|
|
|
|
|
|
|
is => 'ro', |
53
|
|
|
|
|
|
|
isa => sub { |
54
|
|
|
|
|
|
|
confess( "$_[0] is not a Business::GoCardless::Client" ) |
55
|
|
|
|
|
|
|
if ref $_[0] ne 'Business::GoCardless::Client' |
56
|
|
|
|
|
|
|
}, |
57
|
|
|
|
|
|
|
required => 1, |
58
|
|
|
|
|
|
|
); |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=head1 METHODS |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=head2 find_with_client |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
Calls the gocardless API and populates the resource object with the data. |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
my $Bill = Business::GoCardless::Bill->new( client => $self->client ); |
67
|
|
|
|
|
|
|
$Bill->find_with_client; |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=cut |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub find_with_client { |
72
|
18
|
|
|
18
|
1
|
61
|
my ( $self,$sub_key ) = @_; |
73
|
|
|
|
|
|
|
|
74
|
18
|
|
|
|
|
205
|
my $path = sprintf( $self->endpoint,$self->id ); |
75
|
18
|
|
|
|
|
118
|
my $data = $self->client->api_get( $path ); |
76
|
|
|
|
|
|
|
|
77
|
18
|
100
|
|
|
|
75
|
$data = $data->{$sub_key} if $sub_key; |
78
|
|
|
|
|
|
|
|
79
|
18
|
|
|
|
|
37
|
foreach my $attr ( keys( %{ $data } ) ) { |
|
18
|
|
|
|
|
91
|
|
80
|
|
|
|
|
|
|
# as per https://developer.gocardless.com/api-reference/#overview-backwards-compatibility |
81
|
|
|
|
|
|
|
# |
82
|
|
|
|
|
|
|
# The following changes are considered backwards compatible |
83
|
|
|
|
|
|
|
# "Adding new properties to the responses from existing API endpoints" |
84
|
|
|
|
|
|
|
# |
85
|
|
|
|
|
|
|
# so we need to be able to handle attributes we don't know about yet, hence the eval |
86
|
203
|
|
|
|
|
246
|
eval { $self->$attr( $data->{$attr} ); }; |
|
203
|
|
|
|
|
544
|
|
87
|
203
|
50
|
|
|
|
358
|
$@ && do { |
88
|
0
|
|
|
|
|
0
|
carp( "Couldn't set $attr on @{[ ref( $self ) ]}: $@" ); |
|
0
|
|
|
|
|
0
|
|
89
|
|
|
|
|
|
|
}; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
18
|
|
|
|
|
166
|
return $self; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub _operation { |
96
|
8
|
|
|
8
|
|
29
|
my ( $self,$operation,$method,$params,$suffix ) = @_; |
97
|
|
|
|
|
|
|
|
98
|
8
|
100
|
100
|
|
|
84
|
$method //= 'api_post', |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
my $uri = $operation |
101
|
|
|
|
|
|
|
? sprintf( $self->endpoint,$self->id ) . "/$operation" |
102
|
|
|
|
|
|
|
: sprintf( $self->endpoint,$self->id ); |
103
|
|
|
|
|
|
|
|
104
|
8
|
100
|
|
|
|
29
|
$uri .= "/$suffix" if $suffix; |
105
|
|
|
|
|
|
|
|
106
|
8
|
|
|
|
|
46
|
my $data = $self->client->$method( $uri,$params ); |
107
|
|
|
|
|
|
|
|
108
|
8
|
100
|
|
|
|
170
|
if ( $self->client->api_version > 1 ) { |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
$data = $data->{payments} |
111
|
3
|
100
|
|
|
|
36
|
if ref( $self ) eq 'Business::GoCardless::Payment'; |
112
|
|
|
|
|
|
|
$data = $data->{subscriptions} |
113
|
3
|
100
|
|
|
|
12
|
if ref( $self ) eq 'Business::GoCardless::Subscription'; |
114
|
|
|
|
|
|
|
$data = $data->{mandates} |
115
|
3
|
50
|
|
|
|
11
|
if ref( $self ) eq 'Business::GoCardless::Mandate'; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
8
|
|
|
|
|
60
|
foreach my $attr ( keys( %{ $data } ) ) { |
|
8
|
|
|
|
|
39
|
|
119
|
129
|
|
|
|
|
150
|
eval { $self->$attr( $data->{$attr} ); }; |
|
129
|
|
|
|
|
299
|
|
120
|
129
|
50
|
|
|
|
210
|
$@ && do { |
121
|
0
|
|
|
|
|
0
|
carp( "Couldn't set $attr on @{[ ref( $self ) ]}: $@" ); |
|
0
|
|
|
|
|
0
|
|
122
|
|
|
|
|
|
|
}; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
8
|
|
|
|
|
76
|
return $self; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub uri { |
129
|
3
|
|
|
3
|
0
|
10
|
my ( $self ) = @_; |
130
|
|
|
|
|
|
|
|
131
|
3
|
|
|
|
|
29
|
my $endpoint = sprintf( $self->endpoint,$self->id ); |
132
|
|
|
|
|
|
|
|
133
|
3
|
100
|
|
|
|
83
|
return $self->client->api_version > 1 |
134
|
|
|
|
|
|
|
? join( '/',$self->client->base_url . $self->client->api_path . $endpoint ) |
135
|
|
|
|
|
|
|
: join( '/',$self->client->base_url . $endpoint ); |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=head2 to_hash |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
Returns a hash representation of the object. |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
my %data = $Bill->to_hash; |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=head2 to_json |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
Returns a json string representation of the object. |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
my $json = $Bill->to_json; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=cut |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
sub to_hash { |
153
|
2
|
|
|
2
|
1
|
2797
|
my ( $self ) = @_; |
154
|
|
|
|
|
|
|
|
155
|
2
|
|
|
|
|
6
|
my %hash = %{ $self }; |
|
2
|
|
|
|
|
14
|
|
156
|
2
|
|
|
|
|
8
|
delete( $hash{client} ); |
157
|
2
|
|
|
|
|
43
|
return %hash; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub to_json { |
161
|
1
|
|
|
1
|
1
|
11199
|
my ( $self ) = @_; |
162
|
1
|
|
|
|
|
27
|
return JSON->new->canonical->encode( { $self->to_hash } ); |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
=head1 AUTHOR |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
Lee Johnson - C |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify it under |
170
|
|
|
|
|
|
|
the same terms as Perl itself. If you would like to contribute documentation, |
171
|
|
|
|
|
|
|
features, bug fixes, or anything else then please raise an issue / pull request: |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
https://github.com/Humanstate/business-gocardless |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
=cut |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
1; |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
# vim: ts=4:sw=4:et |