File Coverage

blib/lib/CBI/Wrapper/Flow.pm
Criterion Covered Total %
statement 30 113 26.5
branch 0 20 0.0
condition 0 3 0.0
subroutine 10 20 50.0
pod 0 10 0.0
total 40 166 24.1


line stmt bran cond sub pod time code
1             ##############################################################################
2             #
3             # Copyright (C) 2012 Agile Business Group sagl ()
4             # Copyright (C) 2012 Domsense srl ()
5             # Copyright (C) 2012 Associazione OpenERP Italia
6             # ().
7             # Copyright (C) 2022 Res Binaria Di Paolo Capaldo ()
8             # All Rights Reserved
9             #
10             # This program is free software: you can redistribute it and/or modify
11             # it under the terms of the GNU Affero General Public License as published
12             # by the Free Software Foundation, either version 3 of the License, or
13             # (at your option) any later version.
14             #
15             # This program is distributed in the hope that it will be useful,
16             # but WITHOUT ANY WARRANTY; without even the implied warranty of
17             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18             # GNU Affero General Public License for more details.
19             #
20             # You should have received a copy of the GNU Affero General Public License
21             # along with this program. If not, see .
22             #
23             ##############################################################################
24              
25             package CBI::Wrapper::Flow;
26              
27 1     1   6 use warnings;
  1         1  
  1         28  
28 1     1   4 use strict;
  1         1  
  1         35  
29              
30             # ABSTRACT: Flow of a CBI file.
31             # Fixed length file with 120 chars in every row.
32             # The first and the last rows are the header and the footer;
33             # among these are the disposals.
34             # Es.
35             # IBT123405428040122DEMORIBA 1$05428 E <-Header - 1 Record
36             # 140000001 000000040122300000000000010000-0542811101000000123456 T1234 4 E |
37             # 200000001A.b.c. S.p.A Via Biancoverde, 60 Milano 01234567897 |
38             # 300000001Rossi Carlo A111114111111111 |
39             # 400000001Via Col Vento, 7 90111Milano MI | <- Disposizione 1 - 7 Record
40             # 500000001 30000 |
41             # 5100000010000000001A.b.c. S.p.A |
42             # 700000001 |
43             # 140000002 000000040122300000000000020000-0542811101000000123456 T1234 4 E *
44             # 200000002A.b.c. S.p.A Via Biancoverde, 60 Milano 01234567897 *
45             # 300000002Verdi Mario B111114111111111 *
46             # 400000002Via Garibaldi, 8 90112Firenze Fi * <- Disposizione 2 - 7 Record
47             # 500000002 30000 *
48             # 5100000020000000002A.b.c. S.p.A *
49             # 700000002 *
50             # 140000003 000000040122300000000000030000-0542811101000000123456 T1234 4 E +
51             # 200000003A.b.c. S.p.A Via Biancoverde, 60 Milano 01234567897 +
52             # 300000003Bianchi Alberto C111114111111111 +
53             # 400000003Via Frosinone, 11 90113Torino To + <- Disposizione 3 - 7 Record
54             # 500000003 30000 +
55             # 5100000030000000003A.b.c. S.p.A +
56             # 700000003 +
57             # EFT123405428040122DEMORIBA 00000030000000000000000000000000600000000023 E000000 <- Footer - 1 Record
58              
59 1     1   4 use CBI::Wrapper::Field;
  1         1  
  1         13  
60 1     1   3 use CBI::Wrapper::Record;
  1         2  
  1         26  
61 1     1   3 use CBI::Wrapper::RecordMapping;
  1         2  
  1         13  
62 1     1   4 use CBI::Wrapper::Disposal;
  1         2  
  1         13  
63              
64 1     1   4 use Scalar::Util;
  1         1  
  1         37  
65 1     1   6 use Carp;
  1         1  
  1         37  
66              
67 1     1   596 use Encode;
  1         8565  
  1         60  
68 1     1   440 use Text::Unidecode;
  1         2046  
  1         798  
69              
70             sub new {
71 0     0 0   my $class = shift;
72 0           my $self = {
73             _disposals => shift,
74             _header => shift,
75             _footer => shift,
76             };
77              
78 0           bless $self, $class;
79            
80 0 0         $self->set_disposals([]) unless defined $self->get_disposals();
81              
82 0           return $self;
83             }
84              
85             # Getters and Setters.
86             sub set_header {
87 0     0 0   my( $self, $header) = @_;
88              
89 0           $self->{_header} = $header;
90             }
91              
92             sub get_header {
93 0     0 0   my( $self) = @_;
94              
95 0           return $self->{_header};
96             }
97              
98             sub set_footer {
99 0     0 0   my( $self, $footer) = @_;
100              
101 0           $self->{_footer} = $footer;
102             }
103              
104             sub get_footer {
105 0     0 0   my( $self) = @_;
106              
107 0           return $self->{_footer};
108             }
109              
110             sub set_disposals {
111 0     0 0   my( $self, $disposals) = @_;
112              
113 0           $self->{_disposals} = $disposals;
114             }
115              
116             sub get_disposals {
117 0     0 0   my( $self) = @_;
118              
119 0           return $self->{_disposals};
120             }
121              
122             # Read and load a cbi file the current flow.
123             sub read_file {
124 0     0 0   my( $self, $file_path, $first_record_identifier, $flow_type) = @_;
125              
126 0 0         open my $fh, '<', $file_path or croak('[SystemError] Cannot open file');
127 0           my $file_str = do { local $/; <$fh>};
  0            
  0            
128 0           close ($fh);
129              
130             # Default Values.
131 0 0         $first_record_identifier = '14' unless defined $first_record_identifier;
132 0 0         $flow_type = $CBI::Wrapper::RecordMapping::FLOW_TYPE unless defined $flow_type;
133            
134             # Manage end of line chars in DOS and UNIX.
135 0           $file_str =~ s/\r/\n/g;
136 0           $file_str =~ s/\n\n/\n/g;
137 0           my @rows = split("\n", $file_str);
138 0 0         if (scalar(@rows) < 3) {
139 0           croak('[TypeError] Insufficient number of rows');
140             }
141 0           $self->set_header(new CBI::Wrapper::Record($rows[0], $flow_type));
142 0           $self->set_footer(new CBI::Wrapper::Record($rows[scalar(@rows) - 1], $flow_type));
143 0           $self->set_disposals([]);
144            
145 0           my $current_disposal = new CBI::Wrapper::Disposal();
146             # Add records to the current disposal until a new start record is found;
147             # then create a new disposal and start reading the records again.
148 0           for my $row (@rows[1..(scalar(@rows)-2)]) {
149 0           my $record = new CBI::Wrapper::Record($row, $flow_type);
150 0 0 0       if ($record->get_field_content('tipo_record') eq $first_record_identifier
151 0           and scalar(@{$current_disposal->get_records()}) > 0) {
152 0           my $disposals = $self->get_disposals();
153 0           push(@$disposals, $current_disposal);
154 0           $self->set_disposals($disposals);
155 0           $current_disposal = new CBI::Wrapper::Disposal();
156             }
157 0           $current_disposal->append_record($record);
158             }
159 0 0         if (scalar(@{$current_disposal->get_records()}) > 0) {
  0            
160 0           my $disposals = $self->get_disposals();
161 0           push(@$disposals, $current_disposal);
162 0           $self->set_disposals($disposals);
163             }
164              
165             # Check if every disposal has the start record.
166 0           my $last_record_found = 0;
167 0           for my $disposal (@{$self->get_disposals()}) {
  0            
168 0           for my $r (@{$disposal->get_records()}) {
  0            
169 0 0         if ($first_record_identifier eq $r->get_field_content('tipo_record')) {
170 0           $last_record_found = 1;
171             }
172             }
173             }
174 0 0         unless ($last_record_found) {
175 0           $self->set_disposals([]);
176 0           croak('[IndexError] First record identifier ' . $first_record_identifier . ' for disposals not found');
177             }
178             }
179              
180             # Write current flow on file.
181             sub write_file {
182 0     0 0   my( $self, $file_path) = @_;
183              
184 0 0         open my $fh, '>', $file_path or croak('[SystemError] Cannot open file');
185              
186 0           my $header = $self->get_header();
187 0           $header = $header->to_string();
188 0           $header = Encode::decode_utf8($header);
189 0           $header = Text::Unidecode::unidecode($header);
190 0           print $fh ($header . "\r\n");
191 0           for my $disposal (@{$self->get_disposals()}) {
  0            
192 0           for my $record (@{$disposal->get_records()}) {
  0            
193 0           my $row = $record->to_string();
194 0           $row = Encode::decode_utf8($row);
195 0           $row = Text::Unidecode::unidecode($row);
196 0           print $fh ($row . "\r\n");
197             }
198             }
199 0           my $footer = $self->get_footer();
200 0           $footer = $footer->to_string();
201 0           $footer = Encode::decode_utf8($footer);
202 0           $footer = Text::Unidecode::unidecode($footer);
203 0           print $fh ($footer . "\r\n");
204            
205 0           close $fh;
206             }
207              
208              
209             # Add a disposal in the flow.
210             sub append_disposal {
211 0     0 0   my( $self, $disposal) = @_;
212              
213 0           my $disposals = $self->get_disposals();
214 0           push(@$disposals, $disposal);
215 0           $self->set_disposals($disposals);
216             }
217              
218              
219             1;