File Coverage

blib/lib/Stancer/Sepa.pm
Criterion Covered Total %
statement 46 46 100.0
branch 6 6 100.0
condition n/a
subroutine 19 19 100.0
pod 2 2 100.0
total 73 73 100.0


line stmt bran cond sub pod time code
1             package Stancer::Sepa;
2              
3 17     17   158574 use 5.020;
  17         73  
4 17     17   96 use strict;
  17         33  
  17         442  
5 17     17   73 use warnings;
  17         31  
  17         1563  
6              
7             # ABSTRACT: Representation of a SEPA account
8             our $VERSION = '1.0.3'; # VERSION
9              
10 17     17   490 use Stancer::Core::Types qw(coerce_date coerce_datetime Bic Char Iban InstanceOf Maybe SepaCheckInstance Varchar);
  17         47  
  17         2145  
11 17     17   142 use Try::Tiny;
  17         55  
  17         1347  
12              
13 17     17   106 use Moo;
  17         38  
  17         124  
14              
15             extends 'Stancer::Core::Object';
16             with 'Stancer::Role::Country', 'Stancer::Role::Name';
17              
18 17     17   9693 use namespace::clean;
  17         49  
  17         150  
19              
20 17     17   15992 use Stancer::Sepa::Check;
  17         112  
  17         22269  
21              
22             has '+_date_only' => (
23             default => sub{ [qw(date_birth)] },
24             );
25              
26             has '+endpoint' => (
27             default => 'sepa',
28             );
29              
30             has '+_json_ignore' => (
31             default => sub{ [qw(check endpoint created populated country last4)] },
32             );
33              
34              
35             has bic => (
36             is => 'rw',
37             isa => Maybe[Bic],
38 9     9   406 builder => sub { $_[0]->_attribute_builder('bic') },
39             coerce => sub {
40             my $value = shift;
41              
42             return unless defined $value;
43              
44             $value =~ s/\s//gsm;
45              
46             return uc $value;
47             },
48             lazy => 1,
49             predicate => 1,
50             trigger => sub { $_[0]->_add_modified('bic') },
51             );
52              
53              
54             has check => (
55             is => 'rwp',
56             isa => Maybe[SepaCheckInstance],
57             builder => sub {
58 4     4   15403 my $self = shift;
59 4         11 my $check;
60              
61             try {
62 4 100   4   430 $check = Stancer::Sepa::Check->new($self->id)->populate() if defined $self->id;
63             }
64             catch {
65 2 100   2   157 $_->throw() unless $_->isa('Stancer::Exceptions::Http::NotFound');
66 4         83 };
67              
68 3         197 return $check;
69             },
70             lazy => 1,
71             predicate => 1,
72             );
73              
74              
75             has date_birth => (
76             is => 'rw',
77             isa => Maybe[InstanceOf['DateTime']],
78 7     7   200 builder => sub { $_[0]->_attribute_builder('date_birth') },
79             coerce => coerce_date(),
80             lazy => 1,
81             predicate => 1,
82             trigger => sub { $_[0]->_add_modified('date_birth') },
83             );
84              
85              
86             has date_mandate => (
87             is => 'rw',
88             isa => Maybe[InstanceOf['DateTime']],
89 8     8   297 builder => sub { $_[0]->_attribute_builder('date_mandate') },
90             coerce => coerce_datetime(),
91             lazy => 1,
92             predicate => 1,
93             trigger => sub { $_[0]->_add_modified('date_mandate') },
94             );
95              
96              
97             sub formatted_iban {
98 18     18 1 122 my $this = shift;
99 18         242 my $iban = $this->iban;
100              
101 18 100       102 return undef if not defined $iban;
102              
103 17         145 $iban =~ s/(.{1,4})/$1 /gsm;
104 17         106 $iban =~ s/\s*$//sm;
105              
106 17         101 return $iban;
107             }
108              
109              
110             has iban => (
111             is => 'rw',
112             isa => Maybe[Iban],
113 3     3   1161 builder => sub { $_[0]->_attribute_builder('iban') },
114             coerce => sub {
115             my $value = shift;
116              
117             return unless defined $value;
118              
119             $value =~ s/\s//gsm;
120              
121             return uc $value;
122             },
123             lazy => 1,
124             predicate => 1,
125             trigger => sub {
126             my $this = shift;
127              
128             $this->_add_modified('iban');
129             $this->_set_last4(substr $this->iban, -4);
130             },
131             );
132              
133              
134             has last4 => (
135             is => 'rwp',
136             isa => Maybe[Char[4]],
137 7     7   159 builder => sub { $_[0]->_attribute_builder('last4') },
138             lazy => 1,
139             predicate => 1,
140             );
141              
142              
143             has mandate => (
144             is => 'rw',
145             isa => Maybe[Varchar[3, 35]],
146 8     8   204 builder => sub { $_[0]->_attribute_builder('mandate') },
147             lazy => 1,
148             predicate => 1,
149             trigger => sub { $_[0]->_add_modified('mandate') },
150             );
151              
152              
153             sub validate {
154 2     2 1 31370 my $self = shift;
155 2         195 my $check = Stancer::Sepa::Check->new(sepa => $self);
156              
157 2         27 $self->_set_check($check->send());
158 2         112 $self->_set_id($self->check->id);
159              
160 2         47 return $self;
161             }
162              
163             1;
164              
165             __END__
166              
167             =pod
168              
169             =encoding UTF-8
170              
171             =head1 NAME
172              
173             Stancer::Sepa - Representation of a SEPA account
174              
175             =head1 VERSION
176              
177             version 1.0.3
178              
179             =head1 ATTRIBUTES
180              
181             =head2 C<bic>
182              
183             Read/Write string.
184              
185             BIC code, also called SWIFT code.
186              
187             =head2 C<check>
188              
189             Read-only instance of C<Stancer::SepaMail>.
190              
191             Verification results.
192              
193             =head2 C<country>
194              
195             Read-only string.
196              
197             Account country
198              
199             =head2 C<date_birth>
200              
201             Read/Write instance of C<DateTime>.
202              
203             A DateTime object representing the user birthdate.
204              
205             This value is mandatory to use Sepa check service.
206              
207             =head2 C<date_mandate>
208              
209             Read/Write instance of C<DateTime>.
210              
211             A DateTime object representing the mandate signature date.
212              
213             This value is mandatory if a C<mandate> is provided.
214              
215             =head2 C<formatted_iban>
216              
217             Read-only string.
218              
219             Account number but formatted in 4 characters blocs separated with spaces.
220              
221             =head2 C<iban>
222              
223             Read/Write string.
224              
225             Account number
226              
227             =head2 C<last4>
228              
229             Read-only 4 characters string.
230              
231             Last four account number
232              
233             =head2 C<name>
234              
235             Read/Write 4 to 64 characters.
236              
237             Customer name
238              
239             =head2 C<mandate>
240              
241             Read/Write 3 to 35 characters.
242              
243             The mandate referring to the payment
244              
245             =head1 METHODS
246              
247             =head2 C<< Stancer::Sepa->new() : I<self> >>
248              
249             =head2 C<< Stancer::Sepa->new(I<$token>) : I<self> >>
250              
251             =head2 C<< Stancer::Sepa->new(I<%args>) : I<self> >>
252              
253             =head2 C<< Stancer::Sepa->new(I<\%args>) : I<self> >>
254              
255             This method accept an optional string, it will be used as an entity ID for API calls.
256              
257             # Get an empty new sepa account
258             my $new = Stancer::Sepa->new();
259              
260             # Get an existing sepa account
261             my $exist = Stancer::Sepa->new($token);
262              
263             =head2 C<validate>
264              
265             Will ask for SEPA validation.
266              
267             See L<sepa/check> for more information.
268              
269             =head1 USAGE
270              
271             =head2 Logging
272              
273              
274              
275             We use the L<Log::Any> framework for logging events.
276             You may tell where it should log using any available L<Log::Any::Adapter> module.
277              
278             For example, to log everything to a file you just have to add a line to your script, like this:
279             #! /usr/bin/env perl
280             use Log::Any::Adapter (File => '/var/log/payment.log');
281             use Stancer::Sepa;
282              
283             You must import C<Log::Any::Adapter> before our libraries, to initialize the logger instance before use.
284              
285             You can choose your log level on import directly:
286             use Log::Any::Adapter (File => '/var/log/payment.log', log_level => 'info');
287              
288             Read the L<Log::Any> documentation to know what other options you have.
289              
290             =cut
291              
292             =head1 SECURITY
293              
294             =over
295              
296             =item *
297              
298             Never, never, NEVER register a card or a bank account number in your database.
299              
300             =item *
301              
302             Always uses HTTPS in card/SEPA in communication.
303              
304             =item *
305              
306             Our API will never give you a complete card/SEPA number, only the last four digits.
307             If you need to keep track, use these last four digit.
308              
309             =back
310              
311             =cut
312              
313             =head1 BUGS
314              
315             Please report any bugs or feature requests on the bugtracker website
316             L<https://gitlab.com/wearestancer/library/lib-perl/-/issues> or by email to
317             L<bug-stancer@rt.cpan.org|mailto:bug-stancer@rt.cpan.org>.
318              
319             When submitting a bug or request, please include a test-file or a
320             patch to an existing test-file that illustrates the bug or desired
321             feature.
322              
323             =head1 AUTHOR
324              
325             Joel Da Silva <jdasilva@cpan.org>
326              
327             =head1 COPYRIGHT AND LICENSE
328              
329             This software is Copyright (c) 2018-2024 by Stancer / Iliad78.
330              
331             This is free software, licensed under:
332              
333             The Artistic License 2.0 (GPL Compatible)
334              
335             =cut