File Coverage

lib/Business/Fixflo/Resource.pm
Criterion Covered Total %
statement 61 65 93.8
branch 6 6 100.0
condition 8 8 100.0
subroutine 16 18 88.8
pod 3 4 75.0
total 94 101 93.0


line stmt bran cond sub pod time code
1             package Business::Fixflo::Resource;
2              
3             =head1 NAME
4              
5             Business::Fixflo::Resource
6              
7             =head1 DESCRIPTION
8              
9             This is a base class for Fixflo resource classes, it implements common
10             behaviour. You shouldn't use this class directly, but extend it instead.
11              
12             =cut
13              
14 16     16   7225 use strict;
  16         35  
  16         399  
15 16     16   69 use warnings;
  16         26  
  16         305  
16              
17 16     16   63 use Moo;
  16         27  
  16         65  
18 16     16   4835 use Carp qw/ confess carp /;
  16         37  
  16         969  
19 16     16   95 use JSON ();
  16         65  
  16         270  
20 16     16   79 use Try::Tiny;
  16         27  
  16         805  
21 16     16   449 use Business::Fixflo::Paginator;
  16         26  
  16         16510  
22              
23             =head1 ATTRIBUTES
24              
25             client
26             url
27             url_no_id
28              
29             =cut
30              
31             has client => (
32             is => 'ro',
33             isa => sub {
34             confess( "$_[0] is not a Business::Fixflo::Client" )
35             if ref $_[0] ne 'Business::Fixflo::Client';
36             },
37             required => 1,
38             );
39              
40             has [ qw/ url / ] => (
41             is => 'rw',
42             lazy => 1,
43             default => sub {
44             my ( $self ) = @_;
45             join( '/',$self->url_no_id,$self->Id )
46             },
47             );
48              
49             has [ qw/ url_no_id / ] => (
50             is => 'rw',
51             lazy => 1,
52             default => sub {
53             my ( $self ) = @_;
54             return join(
55             '/',
56             $self->client->base_url . $self->client->api_path,
57             ( split( ':',ref( $self ) ) )[-1],
58             );
59             },
60             );
61              
62             =head1 METHODS
63              
64             =head2 to_hash
65              
66             Returns a hash representation of the object.
67              
68             my %data = $Issue->to_hash;
69              
70             =head2 to_json
71              
72             Returns a json string representation of the object.
73              
74             my $json = $Issue->to_json;
75              
76             =head2 get
77              
78             Populates the object with its attributes (calls the API)
79              
80             $Issue->get
81              
82             As the data returned in the call to list objects does not contain the full data
83             of the objects (it only contains lightweight information, such as the URLs of
84             the objects you are interested in) you need to call the ->get method to
85             populate the attributes on an object. Really the Paginator just contains a list
86             of URLs and an easy way to navigate through them.
87              
88             If the data returned from Fixflo contains attributes not available on the object
89             then warnings will be raised for those attributes that couldn't be set - if you
90             see any of these please raise an issue against the dist as these are likely due
91             to updates to the Fixflo API.
92              
93             =cut
94              
95             sub to_hash {
96 29     29 1 1073 my ( $self ) = @_;
97              
98 29         44 my %hash = %{ $self };
  29         141  
99 29         63 delete( $hash{client} );
100 29         312 return %hash;
101             }
102              
103             sub to_json {
104 1     1 1 3 my ( $self ) = @_;
105 1         18 return JSON->new->canonical->encode( { $self->to_hash } );
106             }
107              
108             sub get {
109 7     7 1 18 my ( $self ) = @_;
110              
111 7         305 my $data = $self->client->api_get( $self->url );
112              
113 7         61 foreach my $attr ( keys( %{ $data } ) ) {
  7         24  
114 18     18   1279 try { $self->$attr( $data->{$attr} ); }
115             catch {
116 1     1   25 carp( "Couldn't set $attr on @{[ ref( $self ) ]}: $_" );
  1         16  
117 18         343 };
118             }
119              
120 7         1030 return $self;
121             }
122              
123             sub _parse_envelope_data {
124 24     24   2203 my ( $self,$data ) = @_;
125              
126 24 100       174 return $self if ! ref( $data );
127              
128             my $Envelope = Business::Fixflo::Envelope->new(
129             client => $self->client,
130 2         9 %{ $data }
  2         16  
131             );
132              
133 2   100     5 foreach my $attr ( keys( %{ $Envelope->Entity // {} } ) ) {
  2         13  
134 0     0   0 try { $self->$attr( $Envelope->Entity->{$attr} ); }
135             catch {
136 0     0   0 carp( "Couldn't set $attr on @{[ ref( $self ) ]}: $_" );
  0         0  
137 0         0 };
138             }
139              
140 2         24 return $self;
141             }
142              
143             sub _create {
144 27     27   109 my ( $self,$update,$class,$cb ) = @_;
145              
146 27 100 100     251 if ( ! $update && $self->Id ) {
    100 100        
147 6         65 Business::Fixflo::Exception->throw({
148             message => "Can't create $class when Id is already set",
149             });
150             } elsif ( $update && ! $self->Id ) {
151 5         29 Business::Fixflo::Exception->throw({
152             message => "Can't update $class if Id is not set",
153             });
154             }
155              
156 16         41 my $post_data = $cb->( $self );
157              
158 16         83 return $self->_parse_envelope_data(
159             $self->client->api_post( $class,$post_data )
160             );
161             }
162              
163             sub _paginated_items {
164 3     3   11 my ( $self,$class,$item_class,$item_class_singular ) = @_;
165              
166 3         12 my $items = $self->client->api_get(
167 3         17 "$class/@{[ $self->Id ]}/$item_class",
168             );
169              
170 3         22 my $b_ff_class = "Business::Fixflo::$item_class_singular";
171              
172             my $Paginator = Business::Fixflo::Paginator->new(
173             links => {
174             next => $items->{NextURL},
175             previous => $items->{PreviousURL},
176             },
177             client => $self->client,
178             class => 'Business::Fixflo::Issue',
179             objects => [ map { $b_ff_class->new(
180             client => $self->client,
181 9         65 %{ $_ },
  9         133  
182 3         15 ) } @{ $items->{Items} } ],
  3         8  
183             );
184              
185 3         2539 return $Paginator;
186             }
187              
188             sub update {
189 10     10 0 4460 my ( $self ) = @_;
190 10         35 return $self->create( 'update' );
191             }
192              
193             =head1 AUTHOR
194              
195             Lee Johnson - C
196              
197             This library is free software; you can redistribute it and/or modify it under
198             the same terms as Perl itself. If you would like to contribute documentation,
199             features, bug fixes, or anything else then please raise an issue / pull request:
200              
201             https://github.com/Humanstate/business-fixflo
202              
203             =cut
204              
205             1;
206              
207             # vim: ts=4:sw=4:et