Revision 68329cf0
Von Cem Aydin vor mehr als 1 Jahr hinzugefügt
SL/Helper/QrBillFunctions.pm | ||
---|---|---|
2 | 2 |
|
3 | 3 |
use List::Util qw(first); |
4 | 4 |
|
5 |
use SL::Util qw(trim); |
|
6 |
|
|
5 | 7 |
use strict; |
6 | 8 |
use warnings; |
7 | 9 |
|
8 | 10 |
use Exporter qw(import); |
9 |
our @EXPORT_OK = qw(get_qrbill_account assemble_ref_number get_ref_number_formatted |
|
10 |
get_iban_formatted get_amount_formatted); |
|
11 |
our @EXPORT_OK = qw( |
|
12 |
get_street_name_from_address_line |
|
13 |
get_building_number_from_address_line |
|
14 |
get_postal_code_from_address_line |
|
15 |
get_town_name_from_address_line |
|
16 |
get_qrbill_account |
|
17 |
assemble_ref_number |
|
18 |
get_ref_number_formatted |
|
19 |
get_iban_formatted |
|
20 |
get_amount_formatted |
|
21 |
); |
|
22 |
|
|
23 |
use constant { |
|
24 |
REGEX_STREET_NAME_FROM_ADDRESS_LINE => qr{^([^\d]+)\s*}, |
|
25 |
REGEX_BUILDING_NUMBER_FROM_ADDRESS_LINE => qr{(\d+.*)}, |
|
26 |
REGEX_POSTAL_CODE_FROM_ADDRESS_LINE => qr{^(\d+).*$}, |
|
27 |
REGEX_TOWN_FROM_ADDRESS_LINE => qr{^\d+\s(.*)$}, |
|
28 |
}; |
|
29 |
|
|
30 |
sub get_street_name_from_address_line { |
|
31 |
my $address_line = $_[0]; |
|
32 |
|
|
33 |
my ($street_name) = $address_line =~ REGEX_STREET_NAME_FROM_ADDRESS_LINE; |
|
34 |
|
|
35 |
return trim($street_name) // ''; |
|
36 |
} |
|
37 |
|
|
38 |
sub get_building_number_from_address_line { |
|
39 |
my $address_line = $_[0]; |
|
40 |
|
|
41 |
my ($building_number) = $address_line =~ REGEX_BUILDING_NUMBER_FROM_ADDRESS_LINE; |
|
42 |
|
|
43 |
return trim($building_number) // ''; |
|
44 |
} |
|
45 |
|
|
46 |
sub get_postal_code_from_address_line { |
|
47 |
my $address_line = $_[0]; |
|
48 |
|
|
49 |
my ($postal_code) = $address_line =~ REGEX_POSTAL_CODE_FROM_ADDRESS_LINE; |
|
50 |
|
|
51 |
return trim($postal_code) // ''; |
|
52 |
} |
|
53 |
|
|
54 |
sub get_town_name_from_address_line { |
|
55 |
my $address_line = $_[0]; |
|
56 |
|
|
57 |
my ($town_name) = $address_line =~ REGEX_TOWN_FROM_ADDRESS_LINE; |
|
58 |
|
|
59 |
return trim($town_name) // ''; |
|
60 |
} |
|
11 | 61 |
|
12 | 62 |
sub get_qrbill_account { |
13 | 63 |
$main::lxdebug->enter_sub(); |
... | ... | |
202 | 252 |
|
203 | 253 |
=over 4 |
204 | 254 |
|
255 |
=item C<get_street_name_from_address_line> |
|
256 |
|
|
257 |
Returns the street name from a combined street name and number. |
|
258 |
|
|
259 |
=item C<get_street_number_from_address_line> |
|
260 |
|
|
261 |
Returns the street number from a combined street name and number. |
|
262 |
|
|
263 |
=item C<get_postal_code_from_address_line> |
|
264 |
|
|
265 |
Returns the postal code from an combined postal code and town. |
|
266 |
|
|
267 |
=item C<get_town_name_from_address_line> |
|
268 |
|
|
269 |
Returns the town name from an combined postal code and town. |
|
270 |
|
|
205 | 271 |
=item C<get_qrbill_account> |
206 | 272 |
|
207 | 273 |
Return the bank account flagged for the QR bill. And a string containing an |
SL/Helper/QrBillParser.pm | ||
---|---|---|
3 | 3 |
use strict; |
4 | 4 |
use warnings; |
5 | 5 |
|
6 |
use SL::Helper::QrBillFunctions qw( |
|
7 |
get_street_name_from_address_line |
|
8 |
get_building_number_from_address_line |
|
9 |
get_postal_code_from_address_line |
|
10 |
get_town_name_from_address_line |
|
11 |
); |
|
12 |
|
|
6 | 13 |
use Rose::Object::MakeMethods::Generic( |
7 | 14 |
scalar => [ qw(is_valid error raw_data) ], |
8 | 15 |
'scalar --get_set_init' => [ qw(spec) ], |
... | ... | |
29 | 36 |
REGEX_TRAILER => qr{^EPD$}, |
30 | 37 |
REGEX_BILL_INFORMATION => qr{^.{0,140}$}, |
31 | 38 |
REGEX_ALTERNATIVE_SCHEME_PARAMETER => qr{^.{0,100}$}, |
32 |
REGEX_STREET_NAME_FROM_ADDRESS_LINE => qr{^(.*)\s+\d.*$}, |
|
33 |
REGEX_BUILDING_NUMBER_FROM_ADDRESS_LINE => qr{^.*\s+(\d+.*)$}, |
|
34 |
REGEX_POSTAL_CODE_FROM_ADDRESS_LINE => qr{^(\d+).*$}, |
|
35 |
REGEX_TOWN_FROM_ADDRESS_LINE => qr{^\d+\s(.*)$}, |
|
36 | 39 |
}; |
37 | 40 |
|
38 | 41 |
sub new { |
... | ... | |
74 | 77 |
|
75 | 78 |
sub get_creditor_field { |
76 | 79 |
my $self = shift; |
77 |
my ($structured_field, $extract_field, $extract_regex) = @_;
|
|
80 |
my ($structured_field, $extract_field, $extract_fn) = @_;
|
|
78 | 81 |
|
79 | 82 |
if ($self->{creditor}->{address_type} eq 'S') { |
80 | 83 |
return $self->{creditor}->{$structured_field}; |
81 | 84 |
} |
82 | 85 |
# extract |
83 |
$self->{creditor}->{$extract_field} =~ $extract_regex;
|
|
86 |
my $r = $extract_fn->($self->{creditor}->{$extract_field});
|
|
84 | 87 |
|
85 |
return $1 // '';
|
|
88 |
return $r // '';
|
|
86 | 89 |
} |
87 | 90 |
|
88 | 91 |
sub get_creditor_street_name { |
89 |
# extract street name from street_or_address_line_1 |
|
90 |
# the regex matches everything until the first digit |
|
91 | 92 |
return shift->get_creditor_field( |
92 | 93 |
'street_or_address_line_1', |
93 | 94 |
'street_or_address_line_1', |
94 |
REGEX_STREET_NAME_FROM_ADDRESS_LINE
|
|
95 |
\&get_street_name_from_address_line
|
|
95 | 96 |
); |
96 | 97 |
} |
97 | 98 |
|
98 | 99 |
sub get_creditor_building_number { |
99 |
# extract building number from street_or_address_line_1 |
|
100 |
# the regex matches the first digit and everything after |
|
101 | 100 |
return shift->get_creditor_field( |
102 | 101 |
'building_number_or_address_line_2', |
103 | 102 |
'street_or_address_line_1', |
104 |
REGEX_BUILDING_NUMBER_FROM_ADDRESS_LINE
|
|
103 |
\&get_building_number_from_address_line
|
|
105 | 104 |
); |
106 | 105 |
} |
107 | 106 |
|
108 | 107 |
sub get_creditor_post_code { |
109 |
# extract post code from building_number_or_address_line_2 |
|
110 |
# the regex matches the first digits |
|
111 | 108 |
return shift->get_creditor_field( |
112 | 109 |
'postal_code', |
113 | 110 |
'building_number_or_address_line_2', |
114 |
REGEX_POSTAL_CODE_FROM_ADDRESS_LINE
|
|
111 |
\&get_postal_code_from_address_line
|
|
115 | 112 |
); |
116 | 113 |
} |
117 | 114 |
|
118 | 115 |
sub get_creditor_town_name { |
119 |
# extract town name from building_number_or_address_line_2 |
|
120 |
# the regex matches everything after the first digits |
|
121 | 116 |
return shift->get_creditor_field( |
122 | 117 |
'town', |
123 | 118 |
'building_number_or_address_line_2', |
124 |
REGEX_TOWN_FROM_ADDRESS_LINE
|
|
119 |
\&get_town_name_from_address_line
|
|
125 | 120 |
); |
126 | 121 |
} |
127 | 122 |
|
t/helper/qrbill_functions.t | ||
---|---|---|
1 |
use Test::More tests => 22;
|
|
1 |
use Test::More tests => 38;
|
|
2 | 2 |
|
3 | 3 |
use strict; |
4 | 4 |
|
5 | 5 |
use lib 't'; |
6 | 6 |
use Support::TestSetup; |
7 | 7 |
|
8 |
use_ok('SL::Helper::QrBillFunctions', qw(assemble_ref_number get_ref_number_formatted |
|
9 |
get_iban_formatted get_amount_formatted)); |
|
8 |
use_ok('SL::Helper::QrBillFunctions', qw( |
|
9 |
get_street_name_from_address_line |
|
10 |
get_building_number_from_address_line |
|
11 |
get_postal_code_from_address_line |
|
12 |
get_town_name_from_address_line |
|
13 |
assemble_ref_number |
|
14 |
get_ref_number_formatted |
|
15 |
get_iban_formatted |
|
16 |
get_amount_formatted |
|
17 |
)); |
|
10 | 18 |
|
11 | 19 |
Support::TestSetup::login(); |
12 | 20 |
|
21 |
is(get_street_name_from_address_line('Musterstrasse 12'), 'Musterstrasse', 'get_street_name_from_address_line'); |
|
22 |
is(get_street_name_from_address_line('Musterstrasse St. Jakob 22'), 'Musterstrasse St. Jakob', 'get_street_name_from_address_line_with_multi_word_street_name'); |
|
23 |
is(get_street_name_from_address_line('Musterstrasse St. Jakob 22b'), 'Musterstrasse St. Jakob', 'get_street_name_from_address_line_with_multi_word_street_name_and_letter'); |
|
24 |
is(get_street_name_from_address_line('Musterstrasse 12a'), 'Musterstrasse', 'get_street_name_from_address_line_with_building_number'); |
|
25 |
is(get_street_name_from_address_line('Musterstrasse 12a 1234 Musterhausen'), 'Musterstrasse', 'get_street_name_from_address_line_with_building_number_and_zip'); |
|
26 |
is(get_street_name_from_address_line('Musterstrasse'), 'Musterstrasse', 'get_street_name_from_address_line_without_building_number'); |
|
27 |
|
|
28 |
is(get_building_number_from_address_line('Musterstrasse 12'), '12', 'get_building_number_from_address_line'); |
|
29 |
is(get_building_number_from_address_line('Musterstrasse 12a'), '12a', 'get_building_number_from_address_line_with_building_number'); |
|
30 |
is(get_building_number_from_address_line('Musterstrasse 12a 1234 Musterhausen'), '12a 1234 Musterhausen', 'get_building_number_from_address_line_with_building_number_and_zip'); |
|
31 |
is(get_building_number_from_address_line('Musterstrasse'), '', 'get_building_number_from_address_line_without_building_number'); |
|
32 |
|
|
33 |
is(get_postal_code_from_address_line('8000 Zürich'), '8000', 'get_postal_code_from_address_line'); |
|
34 |
is(get_postal_code_from_address_line('8000 Zürich 1'), '8000', 'get_postal_code_from_address_line_with_zip_extension'); |
|
35 |
is(get_postal_code_from_address_line('8000'), '8000', 'get_postal_code_from_address_line_without_town_name'); |
|
36 |
|
|
37 |
is(get_town_name_from_address_line('8000 Zürich'), 'Zürich', 'get_town_name_from_address_line'); |
|
38 |
is(get_town_name_from_address_line('8000 Zürich 1'), 'Zürich 1', 'get_town_name_from_address_line_with_zip_extension'); |
|
39 |
is(get_town_name_from_address_line('8000'), '', 'get_town_name_from_address_line_without_town_name'); |
|
40 |
|
|
13 | 41 |
# assemble_ref_number returns successfully |
14 | 42 |
is_deeply([ assemble_ref_number('123123', 'c1', 'R2022-02') ], |
15 | 43 |
[ '123123000001000000002022027', undef ], |
Auch abrufbar als: Unified diff
Schweizer QR-Rechnung: Aufsplitten von kombinierten Adressfelder in Helferfunktionen ausgelagert