File Coverage

blib/lib/Net/Correios.pm
Criterion Covered Total %
statement 52 62 83.8
branch 9 22 40.9
condition 6 17 35.2
subroutine 14 14 100.0
pod 3 5 60.0
total 84 120 70.0


line stmt bran cond sub pod time code
1 7     7   1678397 use strict;
  7         56  
  7         216  
2 7     7   36 use warnings;
  7         15  
  7         181  
3              
4 7     7   5973 use HTTP::Tiny;
  7         314831  
  7         295  
5 7     7   3434 use MIME::Base64 ();
  7         5899  
  7         185  
6 7     7   52 use Carp ();
  7         15  
  7         101  
7 7     7   38 use Scalar::Util ();
  7         14  
  7         90  
8 7     7   2686 use JSON ();
  7         43943  
  7         1282  
9              
10             $Carp::Internal{ 'Net::Correios' }++;
11              
12             package Net::Correios;
13              
14             our $VERSION = '0.001';
15              
16             my %libs = (
17             token => 'Token',
18             cep => 'CEP',
19             sro => 'SRO',
20             preco => 'Preco',
21             prazo => 'Prazo',
22             empresas => 'Empresas',
23             prepostagens => 'Prepostagens',
24             faturas => 'Faturas',
25             agencias => 'Agencias',
26             );
27              
28             # create lazy accessors.
29             foreach my $method (keys %libs) {
30             $Carp::Internal{ 'Net::Correios::' . $libs{$method} }++;
31             my $sub = sub {
32 5     5   3353 my ($self, %args) = @_;
33 5         22 my $internal_key = 'endpoint_' . $method;
34 5 50       33 if (!$self->{$internal_key}) {
35 5         24 my $module = 'Net/Correios/' . $libs{$method} . '.pm';
36 5         2449 require $module;
37 5         30 my $class = 'Net::Correios::' . $libs{$method};
38 5         26 $self->{$internal_key} = $class->new( $self );
39             }
40 5         38 return $self->{$internal_key};
41             };
42 7     7   55 { no strict 'refs';
  7         18  
  7         3988  
43             *{"Net\::Correios\::$method"} = $sub;
44             }
45             }
46              
47             sub new {
48 10     10 1 42052 my ($class, %args) = @_;
49             Carp::croak 'Net::Correios::new - "username" and "password" are required'
50 10 100 100     530 unless $args{username} && $args{password};
51 7         144 my $auth_basic = MIME::Base64::encode_base64($args{username} . ':' . $args{password}, '');
52             return bless {
53             contrato => $args{contrato},
54             cartao => $args{cartao},
55             sandbox => !!$args{sandbox},
56             base_url => 'https://api' . (('hom')x!!$args{sandbox}) . '.correios.com.br/',
57             auth_basic => $auth_basic,
58             agent => HTTP::Tiny->new(
59             default_headers => {
60             'Accept' => 'application/json',
61             'Content-Type' => 'application/json',
62             },
63             verify_SSL => 1,
64 7   50     182 timeout => $args{timeout} || 5,
65             ),
66             }, $class;
67             }
68              
69 2     2 1 261 sub is_sandbox { $_[0]->{sandbox} }
70              
71             sub access_token {
72 8     8 1 19 my ($self, $token_type) = @_;
73 8 50 33     104 die 'token deve ser "cartao", "contrato" ou undef'
      33        
74             if defined $token_type && $token_type ne 'cartao' && $token_type ne 'contrato';
75              
76 8 50       44 my $storage_key = 'token' . (defined $token_type ? '_' . $token_type : '');
77 8 50       56 return $self->{$storage_key} if defined $self->{$storage_key};
78              
79             my $token_res = $self->token->autentica(
80 0 0       0 (defined $token_type ? ($token_type => $self->{$token_type}) : ())
81             );
82              
83 0         0 $self->{$storage_key} = $token_res->{token};
84 0 0 0     0 if ($token_res->{cartaoPostagem} && (!$self->{cartao} || $self->{cartao} eq $token_res->{cartaoPostagem}{numero})) {
      0        
85 0         0 $self->{dr} = $token_res->{cartaoPostagem}{dr};
86 0 0       0 $self->{contrato} = $token_res->{cartaoPostagem}{contrato} if !$self->{contrato};
87             }
88 0         0 return $self->{$storage_key};
89             }
90              
91             sub make_request {
92 7     7 0 26 my ($self, $token_type, $method, $url, $args) = @_;
93 7 100       24 $args = {} if !defined $args;
94 7         20 $url = $self->{base_url} . $url;
95 7         25 my $token = $self->access_token($token_type);
96 7         34 $args->{headers}{Authorization} = 'Bearer ' . $token;
97 7         32 my $res = $self->{agent}->request($method, $url, $args);
98 7         25636 return $res;
99             }
100              
101             sub parse_response {
102 8     8 0 26 my ($self, $res) = @_;
103 8 50       44 if ($res->{success}) {
104 8         143 my $data = JSON::decode_json($res->{content});
105 8         45 return $data;
106             }
107             else {
108 0           my $error = $res->{status} . ' ' . $res->{reason};
109 0 0         $error .= ":\n" . $res->{content} if length $res->{content};
110 0           $error .= "\n " . $res->{url};
111 0           Carp::croak($error);
112             }
113             }
114              
115             1;
116             __END__