Business-Fixflo/lib/Business/Fixflo/Resource.pm
package Business::Fixflo::Resource;
=head1 NAME
Business::Fixflo::Resource
=head1 DESCRIPTION
This is a base class for Fixflo resource classes, it implements common
behaviour. You shouldn't use this class directly, but extend it instead.
=cut
use strict;
use warnings;
use Moo;
use Carp qw/ confess carp /;
use JSON ();
use Try::Tiny;
use Business::Fixflo::Paginator;
=head1 ATTRIBUTES
client
url
url_no_id
=cut
has client => (
is => 'ro',
isa => sub {
confess( "$_[0] is not a Business::Fixflo::Client" )
if ref $_[0] ne 'Business::Fixflo::Client';
},
required => 1,
);
has [ qw/ url / ] => (
is => 'rw',
lazy => 1,
default => sub {
my ( $self ) = @_;
join( '/',$self->url_no_id,$self->Id )
},
);
has 'warn_unknown_attributes' => (
is => 'rw',
isa => sub { $_[0] || ! $_[0] },
default => 0,
);
has [ qw/ url_no_id / ] => (
is => 'rw',
lazy => 1,
default => sub {
my ( $self ) = @_;
return join(
'/',
$self->client->base_url . $self->client->api_path,
( split( ':',ref( $self ) ) )[-1],
);
},
);
=head1 METHODS
=head2 to_hash
Returns a hash representation of the object.
my %data = $Issue->to_hash;
=head2 to_json
Returns a json string representation of the object.
my $json = $Issue->to_json;
=head2 get
Populates the object with its attributes (calls the API)
$Issue->get
As the data returned in the call to list objects does not contain the full data
of the objects (it only contains lightweight information, such as the URLs of
the objects you are interested in) you need to call the ->get method to
populate the attributes on an object. Really the Paginator just contains a list
of URLs and an easy way to navigate through them.
Note that Fixflo have a habit of updating their API to add new attributes to the
entities - these would normally cause the parsing of the envelope data to throw
an exception, but a check is in place to defend against this. If you want to see
warnings about those then set C<warn_unknown_attributes> on this Resource object
(a boolean, which defaults to false).
=cut
sub to_hash {
my ( $self ) = @_;
my %hash = %{ $self };
delete( $hash{client} );
delete( $hash{warn_unknown_attributes} );
return %hash;
}
sub to_json {
my ( $self ) = @_;
return JSON->new->canonical->encode( { $self->to_hash } );
}
sub get {
my ( $self ) = @_;
my $data = $self->client->api_get( $self->url );
foreach my $attr ( keys( %{ $data } ) ) {
try { $self->$attr( $data->{$attr} ); }
catch {
my $e = $_;
if (
$e =~ /Can't locate object method/
&& $self->warn_unknown_attributes
) {
carp( "Couldn't set $attr on @{[ ref( $self ) ]}: $e" );
}
};
}
return $self;
}
sub _parse_envelope_data {
my ( $self,$data ) = @_;
return $self if ! ref( $data );
my $Envelope = Business::Fixflo::Envelope->new(
client => $self->client,
%{ $data }
);
foreach my $attr ( keys( %{ $Envelope->Entity // {} } ) ) {
try { $self->$attr( $Envelope->Entity->{$attr} ); }
catch {
my $e = $_;
if (
$e =~ /Can't locate object method/
&& $self->warn_unknown_attributes
) {
carp( "Couldn't set $attr on @{[ ref( $self ) ]}: $e" );
}
};
}
return $self;
}
sub _create {
my ( $self,$update,$class,$cb ) = @_;
if ( ! $update && $self->Id ) {
Business::Fixflo::Exception->throw({
message => "Can't create $class when Id is already set",
});
} elsif ( $update && ! $self->Id ) {
Business::Fixflo::Exception->throw({
message => "Can't update $class if Id is not set",
});
}
my $post_data = $cb->( $self );
return $self->_parse_envelope_data(
$self->client->api_post( $class,$post_data )
);
}
sub _paginated_items {
my ( $self,$class,$item_class,$item_class_singular ) = @_;
my $items = $self->client->api_get(
"$class/@{[ $self->Id ]}/$item_class",
);
my $b_ff_class = "Business::Fixflo::$item_class_singular";
my $Paginator = Business::Fixflo::Paginator->new(
links => {
next => $items->{NextURL},
previous => $items->{PreviousURL},
},
client => $self->client,
class => 'Business::Fixflo::Issue',
objects => [ map { $b_ff_class->new(
client => $self->client,
%{ $_ },
) } @{ $items->{Items} } ],
);
return $Paginator;
}
sub update {
my ( $self ) = @_;
return $self->create( 'update' );
}
=head1 AUTHOR
Lee Johnson - C<leejo@cpan.org>
This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself. If you would like to contribute documentation,
features, bug fixes, or anything else then please raise an issue / pull request:
https://github.com/Humanstate/business-fixflo
=cut
1;
# vim: ts=4:sw=4:et