View | Details | Raw Unified | Return to bug 38489
Collapse All | Expand All

(-)a/Koha/Edifact/Transport.pm (-38 / +79 lines)
Lines 32-38 use Net::SFTP::Foreign; Link Here
32
32
33
use Koha::Database;
33
use Koha::Database;
34
use Koha::DateUtils qw( dt_from_string );
34
use Koha::DateUtils qw( dt_from_string );
35
use Koha::Encryption;
35
use Koha::SFTP::Servers;
36
36
37
sub new {
37
sub new {
38
    my ( $class, $account_id ) = @_;
38
    my ( $class, $account_id ) = @_;
Lines 62-90 sub download_messages { Link Here
62
    my ( $self, $message_type ) = @_;
62
    my ( $self, $message_type ) = @_;
63
    $self->{message_type} = $message_type;
63
    $self->{message_type} = $message_type;
64
64
65
    my $sftp_server_id = $self->{account}->download_sftp_server_id;
66
    my $sftp_server_transport;
67
    $sftp_server_transport = Koha::SFTP::Servers->find($sftp_server_id)->transport
68
        if ($sftp_server_id);
69
65
    my @retrieved_files;
70
    my @retrieved_files;
66
71
67
    if ( $self->{account}->transport eq 'SFTP' ) {
72
    if ($message_type) {
68
        @retrieved_files = $self->sftp_download();
73
        if ( !$sftp_server_transport ) {
69
    } elsif ( $self->{account}->transport eq 'FILE' ) {
74
            @retrieved_files = $self->file_download();
70
        @retrieved_files = $self->file_download();
75
        } elsif ( $sftp_server_transport eq 'sftp' ) {
71
    } else {    # assume FTP
76
            @retrieved_files = $self->sftp_download();
72
        @retrieved_files = $self->ftp_download();
77
        } elsif ( $sftp_server_transport eq 'ftp' ) {
78
            @retrieved_files = $self->ftp_download();
79
        }
73
    }
80
    }
81
74
    return @retrieved_files;
82
    return @retrieved_files;
75
}
83
}
76
84
77
sub upload_messages {
85
sub upload_messages {
78
    my ( $self, @messages ) = @_;
86
    my ( $self, @messages ) = @_;
87
88
    my $sftp_server_id = $self->{account}->upload_sftp_server_id;
89
    my $sftp_server_transport;
90
    $sftp_server_transport = Koha::SFTP::Servers->find($sftp_server_id)->transport
91
        if ($sftp_server_id);
92
79
    if (@messages) {
93
    if (@messages) {
80
        if ( $self->{account}->transport eq 'SFTP' ) {
94
        if ( !$sftp_server_transport ) {
95
            $self->ftp_upload(@messages);
96
        } elsif ( $sftp_server_transport eq 'sftp' ) {
81
            $self->sftp_upload(@messages);
97
            $self->sftp_upload(@messages);
82
        } elsif ( $self->{account}->transport eq 'FILE' ) {
98
        } elsif ( $sftp_server_transport eq 'ftp' ) {
83
            $self->file_upload(@messages);
99
            $self->file_upload(@messages);
84
        } else {    # assume FTP
85
            $self->ftp_upload(@messages);
86
        }
100
        }
87
    }
101
    }
102
88
    return;
103
    return;
89
}
104
}
90
105
Lines 125-141 sub file_download { Link Here
125
sub sftp_download {
140
sub sftp_download {
126
    my $self = shift;
141
    my $self = shift;
127
142
143
    my $sftp_server_id = $self->{account}->download_sftp_server_id;
144
    return
145
        unless $sftp_server_id;
146
    my $sftp_server = Koha::SFTP::Servers->find($sftp_server_id);
147
    return
148
        unless $sftp_server;
149
128
    my $file_ext = _get_file_ext( $self->{message_type} );
150
    my $file_ext = _get_file_ext( $self->{message_type} );
129
151
130
    # C = ready to retrieve E = Edifact
152
    # C = ready to retrieve E = Edifact
131
    my $msg_hash = $self->message_hash();
153
    my $msg_hash = $self->message_hash();
132
    my @downloaded_files;
154
    my @downloaded_files;
133
    my $port = $self->{account}->download_port ? $self->{account}->download_port : '22';
134
    my $sftp = Net::SFTP::Foreign->new(
155
    my $sftp = Net::SFTP::Foreign->new(
135
        host     => $self->{account}->host,
156
        host     => $sftp_server->host,
136
        user     => $self->{account}->username,
157
        user     => $sftp_server->user_name,
137
        password => Koha::Encryption->new->decrypt_hex( $self->{account}->password ),
158
        password => $sftp_server->plain_text_password,
138
        port     => $port,
159
        port     => $sftp_server->port,
139
        timeout  => 10,
160
        timeout  => 10,
140
    );
161
    );
141
    if ( $sftp->error ) {
162
    if ( $sftp->error ) {
Lines 215-239 sub ingest { Link Here
215
sub ftp_download {
236
sub ftp_download {
216
    my $self = shift;
237
    my $self = shift;
217
238
239
    my $sftp_server_id = $self->{account}->download_sftp_server_id;
240
    return
241
        unless $sftp_server_id;
242
    my $sftp_server = Koha::SFTP::Servers->find($sftp_server_id);
243
    return
244
        unless $sftp_server;
245
218
    my $file_ext = _get_file_ext( $self->{message_type} );
246
    my $file_ext = _get_file_ext( $self->{message_type} );
219
247
220
    # C = ready to retrieve E = Edifact
248
    # C = ready to retrieve E = Edifact
221
249
222
    my $msg_hash = $self->message_hash();
250
    my $msg_hash = $self->message_hash();
223
    my @downloaded_files;
251
    my @downloaded_files;
224
    my $port = $self->{account}->download_port ? $self->{account}->download_port : '21';
252
    my $ftp = Net::FTP->new(
225
    my $ftp  = Net::FTP->new(
253
        $sftp_server->host,
226
        $self->{account}->host,
254
        Port    => $sftp_server->port,
227
        Port    => $port,
228
        Timeout => 10,
255
        Timeout => 10,
229
        Passive => 1
256
        Passive => $sftp_server->passiv,
230
        )
257
        )
231
        or return $self->_abort_download(
258
        or return $self->_abort_download(
232
        undef,
259
        undef,
233
        "Cannot connect to " . $self->{account}->host . ": $EVAL_ERROR"
260
        "Cannot connect to " . $sftp_server->host . ": " . $EVAL_ERROR
234
        );
261
        );
235
    $ftp->login( $self->{account}->username, Koha::Encryption->new->decrypt_hex( $self->{account}->password ) )
262
    $ftp->login( $sftp_server->user_name, $sftp_server->plain_text_password )
236
        or return $self->_abort_download( $ftp, "Cannot login: " . $ftp->message() );
263
        or return $self->_abort_download( $ftp, "Cannot login: $ftp->message()" );
237
    $ftp->cwd( $self->{account}->download_directory )
264
    $ftp->cwd( $self->{account}->download_directory )
238
        or return $self->_abort_download(
265
        or return $self->_abort_download(
239
        $ftp,
266
        $ftp,
Lines 269-287 sub ftp_download { Link Here
269
296
270
sub ftp_upload {
297
sub ftp_upload {
271
    my ( $self, @messages ) = @_;
298
    my ( $self, @messages ) = @_;
272
    my $port = $self->{account}->upload_port ? $self->{account}->upload_port : '21';
299
273
    my $ftp  = Net::FTP->new(
300
    my $sftp_server_id = $self->{account}->upload_sftp_server_id;
274
        $self->{account}->host,
301
    return
275
        Port    => $port,
302
        unless $sftp_server_id;
303
    my $sftp_server = Koha::SFTP::Servers->find($sftp_server_id);
304
    return
305
        unless $sftp_server;
306
307
    my $ftp = Net::FTP->new(
308
        $sftp_server->host,
309
        Port    => $sftp_server->port,
276
        Timeout => 10,
310
        Timeout => 10,
277
        Passive => 1
311
        Passive => $sftp_server->passiv
278
        )
312
        )
279
        or return $self->_abort_download(
313
        or return $self->_abort_download(
280
        undef,
314
        undef,
281
        "Cannot connect to " . $self->{account}->host . ": $EVAL_ERROR"
315
        "Cannot connect to " . $sftp_server->host . ": " . $EVAL_ERROR
282
        );
316
        );
283
    $ftp->login( $self->{account}->username, Koha::Encryption->new->decrypt_hex( $self->{account}->password ) )
317
    $ftp->login( $sftp_server->user_name, $sftp_server->plain_text_password )
284
        or return $self->_abort_download( $ftp, "Cannot login: " . $ftp->message() );
318
        or return $self->_abort_download( $ftp, "Cannot login: $ftp->message()" );
285
    $ftp->cwd( $self->{account}->upload_directory )
319
    $ftp->cwd( $self->{account}->upload_directory )
286
        or return $self->_abort_download(
320
        or return $self->_abort_download(
287
        $ftp,
321
        $ftp,
Lines 310-324 sub ftp_upload { Link Here
310
344
311
sub sftp_upload {
345
sub sftp_upload {
312
    my ( $self, @messages ) = @_;
346
    my ( $self, @messages ) = @_;
313
    my $port = $self->{account}->upload_port ? $self->{account}->upload_port : '22';
347
348
    my $sftp_server_id = $self->{account}->upload_sftp_server_id;
349
    return
350
        unless $sftp_server_id;
351
    my $sftp_server = Koha::SFTP::Servers->find($sftp_server_id);
352
    return
353
        unless $sftp_server;
354
314
    my $sftp = Net::SFTP::Foreign->new(
355
    my $sftp = Net::SFTP::Foreign->new(
315
        host     => $self->{account}->host,
356
        host     => $sftp_server->host,
316
        user     => $self->{account}->username,
357
        user     => $sftp_server->user_name,
317
        password => Koha::Encryption->new->decrypt_hex( $self->{account}->password ),
358
        password => $sftp_server->plain_text_password,
318
        port     => $port,
359
        port     => $sftp_server->port,
319
        timeout  => 10,
360
        timeout  => 10,
320
    );
361
    );
321
    $sftp->die_on_error( "Cannot ssh to " . $self->{account}->host );
362
    $sftp->die_on_error( "Cannot ssh to " . $sftp_server->host );
322
    $sftp->setcwd( $self->{account}->upload_directory )
363
    $sftp->setcwd( $self->{account}->upload_directory )
323
        or return $self->_abort_download(
364
        or return $self->_abort_download(
324
        $sftp,
365
        $sftp,
(-)a/Koha/Schema/Result/SftpServer.pm (-56 / +77 lines)
Lines 1-5 Link Here
1
use utf8;
1
use utf8;
2
3
package Koha::Schema::Result::SftpServer;
2
package Koha::Schema::Result::SftpServer;
4
3
5
# Created by DBIx::Class::Schema::Loader
4
# Created by DBIx::Class::Schema::Loader
Lines 56-62 __PACKAGE__->table("sftp_servers"); Link Here
56
  extra: {list => ["ftp","sftp"]}
55
  extra: {list => ["ftp","sftp"]}
57
  is_nullable: 0
56
  is_nullable: 0
58
57
59
=head2 passiv
58
=head2 passive
60
59
61
  data_type: 'tinyint'
60
  data_type: 'tinyint'
62
  default_value: 1
61
  default_value: 1
Lines 110-158 __PACKAGE__->table("sftp_servers"); Link Here
110
=cut
109
=cut
111
110
112
__PACKAGE__->add_columns(
111
__PACKAGE__->add_columns(
113
    "id",
112
  "id",
114
    { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
113
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
115
    "name",
114
  "name",
116
    { data_type => "varchar", is_nullable => 0, size => 80 },
115
  { data_type => "varchar", is_nullable => 0, size => 80 },
117
    "host",
116
  "host",
118
    {
117
  {
119
        data_type     => "varchar",
118
    data_type => "varchar",
120
        default_value => "localhost",
119
    default_value => "localhost",
121
        is_nullable   => 0,
120
    is_nullable => 0,
122
        size          => 80,
121
    size => 80,
123
    },
122
  },
124
    "port",
123
  "port",
125
    { data_type => "integer", default_value => 22, is_nullable => 0 },
124
  { data_type => "integer", default_value => 22, is_nullable => 0 },
126
    "transport",
125
  "transport",
127
    {
126
  {
128
        data_type     => "enum",
127
    data_type => "enum",
129
        default_value => "sftp",
128
    default_value => "sftp",
130
        extra         => { list => [ "ftp", "sftp" ] },
129
    extra => { list => ["ftp", "sftp"] },
131
        is_nullable   => 0,
130
    is_nullable => 0,
132
    },
131
  },
133
    "passiv",
132
  "passive",
134
    { data_type => "tinyint", default_value => 1, is_nullable => 0 },
133
  { data_type => "tinyint", default_value => 1, is_nullable => 0 },
135
    "user_name",
134
  "user_name",
136
    { data_type => "varchar", is_nullable => 1, size => 80 },
135
  { data_type => "varchar", is_nullable => 1, size => 80 },
137
    "password",
136
  "password",
138
    { data_type => "mediumtext", is_nullable => 1 },
137
  { data_type => "mediumtext", is_nullable => 1 },
139
    "key_file",
138
  "key_file",
140
    { data_type => "mediumtext", is_nullable => 1 },
139
  { data_type => "mediumtext", is_nullable => 1 },
141
    "auth_mode",
140
  "auth_mode",
142
    {
141
  {
143
        data_type     => "enum",
142
    data_type => "enum",
144
        default_value => "password",
143
    default_value => "password",
145
        extra         => { list => [ "password", "key_file", "noauth" ] },
144
    extra => { list => ["password", "key_file", "noauth"] },
146
        is_nullable   => 0,
145
    is_nullable => 0,
147
    },
146
  },
148
    "download_directory",
147
  "download_directory",
149
    { data_type => "mediumtext", is_nullable => 1 },
148
  { data_type => "mediumtext", is_nullable => 1 },
150
    "upload_directory",
149
  "upload_directory",
151
    { data_type => "mediumtext", is_nullable => 1 },
150
  { data_type => "mediumtext", is_nullable => 1 },
152
    "status",
151
  "status",
153
    { data_type => "varchar", is_nullable => 1, size => 32 },
152
  { data_type => "varchar", is_nullable => 1, size => 32 },
154
    "debug",
153
  "debug",
155
    { data_type => "tinyint", default_value => 0, is_nullable => 0 },
154
  { data_type => "tinyint", default_value => 0, is_nullable => 0 },
156
);
155
);
157
156
158
=head1 PRIMARY KEY
157
=head1 PRIMARY KEY
Lines 167-186 __PACKAGE__->add_columns( Link Here
167
166
168
__PACKAGE__->set_primary_key("id");
167
__PACKAGE__->set_primary_key("id");
169
168
170
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2024-12-17 10:30:17
169
=head1 RELATIONS
171
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Dnz0prvPxRoopZCdRaUtnA
172
170
173
__PACKAGE__->add_columns(
171
=head2 vendor_edi_accounts_download_sftp_servers
174
    '+passive' => { is_boolean => 1 },
172
175
    '+debug'   => { is_boolean => 1 },
173
Type: has_many
174
175
Related object: L<Koha::Schema::Result::VendorEdiAccount>
176
177
=cut
178
179
__PACKAGE__->has_many(
180
  "vendor_edi_accounts_download_sftp_servers",
181
  "Koha::Schema::Result::VendorEdiAccount",
182
  { "foreign.download_sftp_server_id" => "self.id" },
183
  { cascade_copy => 0, cascade_delete => 0 },
176
);
184
);
177
185
178
sub koha_objects_class {
186
=head2 vendor_edi_accounts_upload_sftp_servers
179
    'Koha::SFTP::Servers';
187
180
}
188
Type: has_many
189
190
Related object: L<Koha::Schema::Result::VendorEdiAccount>
191
192
=cut
193
194
__PACKAGE__->has_many(
195
  "vendor_edi_accounts_upload_sftp_servers",
196
  "Koha::Schema::Result::VendorEdiAccount",
197
  { "foreign.upload_sftp_server_id" => "self.id" },
198
  { cascade_copy => 0, cascade_delete => 0 },
199
);
200
201
202
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-08-12 12:49:53
203
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:1rBIrA/XFM7Yx78v3SKo6Q
181
204
182
sub koha_object_class {
183
    'Koha::SFTP::Server';
184
}
185
205
206
# You can replace this text with custom code or comments, and it will be preserved on regeneration
186
1;
207
1;
(-)a/Koha/Schema/Result/VendorEdiAccount.pm (-40 / +50 lines)
Lines 34-64 __PACKAGE__->table("vendor_edi_accounts"); Link Here
34
  data_type: 'mediumtext'
34
  data_type: 'mediumtext'
35
  is_nullable: 0
35
  is_nullable: 0
36
36
37
=head2 host
37
=head2 download_sftp_server_id
38
39
  data_type: 'varchar'
40
  is_nullable: 1
41
  size: 40
42
43
=head2 username
44
45
  data_type: 'varchar'
46
  is_nullable: 1
47
  size: 40
48
49
=head2 password
50
51
  data_type: 'mediumtext'
52
  is_nullable: 1
53
54
=head2 upload_port
55
38
56
  data_type: 'integer'
39
  data_type: 'integer'
40
  is_foreign_key: 1
57
  is_nullable: 1
41
  is_nullable: 1
58
42
59
=head2 download_port
43
=head2 upload_sftp_server_id
60
44
61
  data_type: 'integer'
45
  data_type: 'integer'
46
  is_foreign_key: 1
62
  is_nullable: 1
47
  is_nullable: 1
63
48
64
=head2 last_activity
49
=head2 last_activity
Lines 103-115 __PACKAGE__->table("vendor_edi_accounts"); Link Here
103
  is_nullable: 1
88
  is_nullable: 1
104
  size: 3
89
  size: 3
105
90
106
=head2 transport
107
108
  data_type: 'varchar'
109
  default_value: 'FTP'
110
  is_nullable: 1
111
  size: 6
112
113
=head2 quotes_enabled
91
=head2 quotes_enabled
114
92
115
  data_type: 'tinyint'
93
  data_type: 'tinyint'
Lines 160-175 __PACKAGE__->add_columns( Link Here
160
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
138
  { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
161
  "description",
139
  "description",
162
  { data_type => "mediumtext", is_nullable => 0 },
140
  { data_type => "mediumtext", is_nullable => 0 },
163
  "host",
141
  "download_sftp_server_id",
164
  { data_type => "varchar", is_nullable => 1, size => 40 },
142
  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
165
  "username",
143
  "upload_sftp_server_id",
166
  { data_type => "varchar", is_nullable => 1, size => 40 },
144
  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
167
  "password",
168
  { data_type => "mediumtext", is_nullable => 1 },
169
  "upload_port",
170
  { data_type => "integer", is_nullable => 1 },
171
  "download_port",
172
  { data_type => "integer", is_nullable => 1 },
173
  "last_activity",
145
  "last_activity",
174
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
146
  { data_type => "date", datetime_undef_if_invalid => 1, is_nullable => 1 },
175
  "vendor_id",
147
  "vendor_id",
Lines 184-191 __PACKAGE__->add_columns( Link Here
184
  { data_type => "varchar", default_value => "EUR", is_nullable => 1, size => 3 },
156
  { data_type => "varchar", default_value => "EUR", is_nullable => 1, size => 3 },
185
  "id_code_qualifier",
157
  "id_code_qualifier",
186
  { data_type => "varchar", default_value => 14, is_nullable => 1, size => 3 },
158
  { data_type => "varchar", default_value => 14, is_nullable => 1, size => 3 },
187
  "transport",
188
  { data_type => "varchar", default_value => "FTP", is_nullable => 1, size => 6 },
189
  "quotes_enabled",
159
  "quotes_enabled",
190
  { data_type => "tinyint", default_value => 0, is_nullable => 0 },
160
  { data_type => "tinyint", default_value => 0, is_nullable => 0 },
191
  "invoices_enabled",
161
  "invoices_enabled",
Lines 216-221 __PACKAGE__->set_primary_key("id"); Link Here
216
186
217
=head1 RELATIONS
187
=head1 RELATIONS
218
188
189
=head2 download_sftp_server
190
191
Type: belongs_to
192
193
Related object: L<Koha::Schema::Result::SftpServer>
194
195
=cut
196
197
__PACKAGE__->belongs_to(
198
  "download_sftp_server",
199
  "Koha::Schema::Result::SftpServer",
200
  { id => "download_sftp_server_id" },
201
  {
202
    is_deferrable => 1,
203
    join_type     => "LEFT",
204
    on_delete     => "RESTRICT",
205
    on_update     => "RESTRICT",
206
  },
207
);
208
219
=head2 edifact_messages
209
=head2 edifact_messages
220
210
221
Type: has_many
211
Type: has_many
Lines 251-256 __PACKAGE__->belongs_to( Link Here
251
  },
241
  },
252
);
242
);
253
243
244
=head2 upload_sftp_server
245
246
Type: belongs_to
247
248
Related object: L<Koha::Schema::Result::SftpServer>
249
250
=cut
251
252
__PACKAGE__->belongs_to(
253
  "upload_sftp_server",
254
  "Koha::Schema::Result::SftpServer",
255
  { id => "upload_sftp_server_id" },
256
  {
257
    is_deferrable => 1,
258
    join_type     => "LEFT",
259
    on_delete     => "RESTRICT",
260
    on_update     => "RESTRICT",
261
  },
262
);
263
254
=head2 vendor
264
=head2 vendor
255
265
256
Type: belongs_to
266
Type: belongs_to
Lines 272-279 __PACKAGE__->belongs_to( Link Here
272
);
282
);
273
283
274
284
275
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2024-04-19 16:25:44
285
# Created by DBIx::Class::Schema::Loader v0.07051 @ 2025-01-02 12:46:08
276
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:jenUF3Wx7J7F5270mLQMbw
286
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZXN7In7aiggTtjnBVHxCBQ
277
287
278
__PACKAGE__->add_columns(
288
__PACKAGE__->add_columns(
279
    '+auto_orders'       => { is_boolean => 1 },
289
    '+auto_orders'       => { is_boolean => 1 },
(-)a/admin/edi_accounts.pl (-36 / +33 lines)
Lines 24-30 use CGI; Link Here
24
use C4::Auth   qw( get_template_and_user );
24
use C4::Auth   qw( get_template_and_user );
25
use C4::Output qw( output_html_with_http_headers );
25
use C4::Output qw( output_html_with_http_headers );
26
use Koha::Database;
26
use Koha::Database;
27
use Koha::Encryption;
28
use Koha::Plugins;
27
use Koha::Plugins;
29
28
30
our $input  = CGI->new();
29
our $input  = CGI->new();
Lines 39-51 our ( $template, $loggedinuser, $cookie ) = get_template_and_user( Link Here
39
    }
38
    }
40
);
39
);
41
40
42
my $crypt = Koha::Encryption->new;
43
44
my $op = $input->param('op');
41
my $op = $input->param('op');
45
$op ||= 'display';
42
$op ||= 'display';
46
43
47
if ( $op eq 'acct_form' ) {
44
if ( $op eq 'acct_form' ) {
48
    show_account($crypt);
45
    show_account();
49
    $template->param( acct_form => 1 );
46
    $template->param( acct_form => 1 );
50
    my @vendors = $schema->resultset('Aqbookseller')->search(
47
    my @vendors = $schema->resultset('Aqbookseller')->search(
51
        undef,
48
        undef,
Lines 56-61 if ( $op eq 'acct_form' ) { Link Here
56
    );
53
    );
57
    $template->param( vendors => \@vendors );
54
    $template->param( vendors => \@vendors );
58
55
56
    my @sftp_servers = $schema->resultset('SftpServer')->search(
57
        undef,
58
        {
59
            columns  => [ 'name', 'host', 'port', 'id' ],
60
            order_by => { -asc => 'name' },
61
        }
62
    );
63
    $template->param( sftp_servers => \@sftp_servers );
64
59
    if ( C4::Context->config("enable_plugins") ) {
65
    if ( C4::Context->config("enable_plugins") ) {
60
        my @plugins = Koha::Plugins->new()->GetPlugins(
66
        my @plugins = Koha::Plugins->new()->GetPlugins(
61
            {
67
            {
Lines 65-99 if ( $op eq 'acct_form' ) { Link Here
65
        $template->param( plugins => \@plugins );
71
        $template->param( plugins => \@plugins );
66
    }
72
    }
67
} elsif ( $op eq 'delete_confirm' ) {
73
} elsif ( $op eq 'delete_confirm' ) {
68
    show_account($crypt);
74
    show_account();
69
    $template->param( delete_confirm => 1 );
75
    $template->param( delete_confirm => 1 );
70
} else {
76
} else {
71
    if ( $op eq 'cud-save' ) {
77
    if ( $op eq 'cud-save' ) {
72
78
73
        # validate & display
79
        # validate & display
74
        my $id       = $input->param('id');
80
        my $id     = $input->param('id');
75
        my $password = scalar $input->param('password');
76
        $password = $crypt->encrypt_hex($password);
77
        my $fields = {
81
        my $fields = {
78
            description   => scalar $input->param('description'),
82
            description             => scalar $input->param('description'),
79
            host          => scalar $input->param('host'),
83
            upload_sftp_server_id   => $input->param('upload_sftp_server_id')   || undef,
80
            username      => scalar $input->param('username'),
84
            download_sftp_server_id => $input->param('download_sftp_server_id') || undef,
81
            password      => $password,
85
            vendor_id               => scalar $input->param('vendor_id'),
82
            upload_port   => scalar $input->param('upload_port')   || $input->param('transport') eq 'FTP' ? 21 : 22,
86
            upload_directory        => scalar $input->param('upload_directory'),
83
            download_port => scalar $input->param('download_port') || $input->param('transport') eq 'FTP' ? 21 : 22,
87
            download_directory      => scalar $input->param('download_directory'),
84
            vendor_id          => scalar $input->param('vendor_id'),
88
            san                     => scalar $input->param('san'),
85
            upload_directory   => scalar $input->param('upload_directory'),
89
            standard                => scalar $input->param('standard'),
86
            download_directory => scalar $input->param('download_directory'),
90
            quotes_enabled          => $input->param('quotes_enabled')    ? 1 : 0,
87
            san                => scalar $input->param('san'),
91
            invoices_enabled        => $input->param('invoices_enabled')  ? 1 : 0,
88
            standard           => scalar $input->param('standard'),
92
            orders_enabled          => $input->param('orders_enabled')    ? 1 : 0,
89
            transport          => scalar $input->param('transport'),
93
            responses_enabled       => $input->param('responses_enabled') ? 1 : 0,
90
            quotes_enabled     => $input->param('quotes_enabled')    ? 1 : 0,
94
            auto_orders             => $input->param('auto_orders')       ? 1 : 0,
91
            invoices_enabled   => $input->param('invoices_enabled')  ? 1 : 0,
95
            id_code_qualifier       => scalar $input->param('id_code_qualifier'),
92
            orders_enabled     => $input->param('orders_enabled')    ? 1 : 0,
96
            plugin                  => scalar $input->param('plugin'),
93
            responses_enabled  => $input->param('responses_enabled') ? 1 : 0,
94
            auto_orders        => $input->param('auto_orders')       ? 1 : 0,
95
            id_code_qualifier  => scalar $input->param('id_code_qualifier'),
96
            plugin             => scalar $input->param('plugin'),
97
        };
97
        };
98
98
99
        if ($id) {
99
        if ($id) {
Lines 159-172 sub get_account { Link Here
159
}
159
}
160
160
161
sub show_account {
161
sub show_account {
162
    my $crypt   = shift;
163
    my $acct_id = $input->param('id');
162
    my $acct_id = $input->param('id');
164
    if ($acct_id) {
163
    return unless $acct_id;
165
        my $acct = $schema->resultset('VendorEdiAccount')->find($acct_id);
164
166
        $acct->password( $crypt->decrypt_hex( $acct->password ) );
165
    my $acct = $schema->resultset('VendorEdiAccount')->find($acct_id);
167
        if ($acct) {
166
    return unless $acct;
168
            $template->param( account => $acct );
167
169
        }
168
    return $template->param( account => $acct );
170
    }
171
    return;
172
}
169
}
(-)a/installer/data/mysql/atomicupdate/bug_38489-move_edi_SFTP_data_to_SFTP_tables.pl (+115 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number  => "38489",
5
    description => "Move SFTP data from EDI module to FTP/SFTP table",
6
    up          => sub {
7
        my ($args)        = @_;
8
        my ( $dbh, $out ) = @$args{qw(dbh out)};
9
10
        if ( TableExists('sftp_servers') ) {
11
            if ( column_exists( 'vendor_edi_accounts', 'host')
12
            && column_exists( 'vendor_edi_accounts', 'download_port' )
13
            && column_exists( 'vendor_edi_accounts', 'upload_port' )
14
            && column_exists( 'vendor_edi_accounts', 'transport' )
15
            && column_exists( 'vendor_edi_accounts', 'username' )
16
            && column_exists( 'vendor_edi_accounts', 'password' ) )
17
            {
18
                ## copy edi vendor sftp servers to sftp_servers
19
                $dbh->do(
20
                    q{
21
                        INSERT IGNORE INTO `sftp_servers` (name,host,port,transport,user_name,password,download_directory,upload_directory)
22
                        SELECT description,host,download_port,LOWER(transport),username,password,download_directory,upload_directory
23
                        FROM vendor_edi_accounts
24
                        WHERE vendor_edi_accounts.download_port IS NOT NULL;
25
                    }
26
                );
27
                say $out "Copied FTP/SFTP download servers from vendor_edi_accounts table";
28
29
                $dbh->do(
30
                    q{
31
                        INSERT IGNORE INTO `sftp_servers` (name,host,port,transport,user_name,password,download_directory,upload_directory)
32
                        SELECT description,host,upload_port,LOWER(transport),username,password,download_directory,upload_directory
33
                        FROM vendor_edi_accounts
34
                        WHERE vendor_edi_accounts.upload_port IS NOT NULL;
35
                    }
36
                );
37
                say $out "Copied FTP/SFTP upload servers from vendor_edi_accounts table";
38
39
                ## add foreign keys
40
                unless ( column_exists( 'vendor_edi_accounts', 'download_sftp_server_id' )
41
                    || column_exists( 'vendor_edi_accounts', 'upload_sftp_server_id' ) )
42
                {
43
                    $dbh->do(
44
                        q{
45
                            ALTER TABLE `vendor_edi_accounts`
46
                                ADD COLUMN `download_sftp_server_id` int(11) DEFAULT NULL AFTER `description`,
47
                                ADD COLUMN `upload_sftp_server_id` int(11) DEFAULT NULL AFTER `download_sftp_server_id`;
48
                        }
49
                    );
50
                    say $out "Added download_sftp_server_id column in vendor_edi_accounts table";
51
                    say $out "Added upload_sftp_server_id column in vendor_edi_accounts table";
52
                }
53
                unless ( foreign_key_exists( 'vendor_edi_accounts', 'vfk_download_sftp_server_id' )
54
                    || foreign_key_exists( 'vendor_edi_accounts', 'vfk_upload_sftp_server_id' ) )
55
                {
56
                    $dbh->do(
57
                        q{
58
                            ALTER TABLE `vendor_edi_accounts`
59
                                ADD CONSTRAINT `vfk_download_sftp_server_id` FOREIGN KEY (`download_sftp_server_id`) REFERENCES `sftp_servers` (`id`),
60
                                ADD CONSTRAINT `vfk_upload_sftp_server_id` FOREIGN KEY (`upload_sftp_server_id`) REFERENCES `sftp_servers` (`id`);
61
                        }
62
                    );
63
                    say $out "Added vfk_download_sftp_server_id constraint in vendor_edi_accounts table";
64
                    say $out "Added vfk_upload_sftp_server_id constraint in vendor_edi_accounts table";
65
                }
66
67
                ## set matching sftp server ids in new foreign keys
68
                $dbh->do(
69
                    q{
70
                        UPDATE IGNORE `vendor_edi_accounts`, `sftp_servers`
71
                            SET vendor_edi_accounts.download_sftp_server_id = sftp_servers.id
72
                            WHERE vendor_edi_accounts.host = sftp_servers.host
73
                            AND vendor_edi_accounts.download_port = sftp_servers.port
74
                            AND vendor_edi_accounts.transport = sftp_servers.transport
75
                            AND vendor_edi_accounts.download_directory = sftp_servers.download_directory
76
                            AND vendor_edi_accounts.upload_directory = sftp_servers.upload_directory;
77
                    }
78
                );
79
                say $out "Matched sftp_server.id with vendor_edi_accounts.download_sftp_server_id";
80
                $dbh->do(
81
                    q{
82
                        UPDATE IGNORE `vendor_edi_accounts`, `sftp_servers`
83
                            SET vendor_edi_accounts.upload_sftp_server_id = sftp_servers.id
84
                            WHERE vendor_edi_accounts.host = sftp_servers.host
85
                            AND vendor_edi_accounts.upload_port = sftp_servers.port
86
                            AND vendor_edi_accounts.transport = sftp_servers.transport
87
                            AND vendor_edi_accounts.download_directory = sftp_servers.download_directory
88
                            AND vendor_edi_accounts.upload_directory = sftp_servers.upload_directory;
89
                    }
90
                );
91
                say $out "Matched sftp_server.id with vendor_edi_accounts.upload_sftp_server_id";
92
93
94
                ## drop useless columns from edi vendors
95
                $dbh->do(
96
                    q{
97
                        ALTER TABLE vendor_edi_accounts
98
                            DROP COLUMN `host`,
99
                            DROP COLUMN `username`,
100
                            DROP COLUMN `password`,
101
                            DROP COLUMN `download_port`,
102
                            DROP COLUMN `upload_port`,
103
                            DROP COLUMN `transport`;
104
                    }
105
                );
106
                say $out "Dropped host column in vendor_edi_accounts table";
107
                say $out "Dropped username column in vendor_edi_accounts table";
108
                say $out "Dropped password column in vendor_edi_accounts table";
109
                say $out "Dropped download_port column in vendor_edi_accounts table";
110
                say $out "Dropped upload_port column in vendor_edi_accounts table";
111
                say $out "Dropped transport column in vendor_edi_accounts table";
112
            }
113
        }
114
    },
115
};
(-)a/installer/data/mysql/kohastructure.sql (-6 / +6 lines)
Lines 6672-6682 DROP TABLE IF EXISTS `vendor_edi_accounts`; Link Here
6672
CREATE TABLE `vendor_edi_accounts` (
6672
CREATE TABLE `vendor_edi_accounts` (
6673
  `id` int(11) NOT NULL AUTO_INCREMENT,
6673
  `id` int(11) NOT NULL AUTO_INCREMENT,
6674
  `description` mediumtext NOT NULL,
6674
  `description` mediumtext NOT NULL,
6675
  `host` varchar(40) DEFAULT NULL,
6675
  `download_sftp_server_id` int(11) DEFAULT NULL,
6676
  `username` varchar(40) DEFAULT NULL,
6676
  `upload_sftp_server_id` int(11) DEFAULT NULL,
6677
  `password` mediumtext DEFAULT NULL,
6678
  `upload_port` int(11) DEFAULT NULL,
6679
  `download_port` int(11) DEFAULT NULL,
6680
  `last_activity` date DEFAULT NULL,
6677
  `last_activity` date DEFAULT NULL,
6681
  `vendor_id` int(11) DEFAULT NULL,
6678
  `vendor_id` int(11) DEFAULT NULL,
6682
  `download_directory` mediumtext DEFAULT NULL,
6679
  `download_directory` mediumtext DEFAULT NULL,
Lines 6684-6690 CREATE TABLE `vendor_edi_accounts` ( Link Here
6684
  `san` varchar(20) DEFAULT NULL,
6681
  `san` varchar(20) DEFAULT NULL,
6685
  `standard` varchar(3) DEFAULT 'EUR',
6682
  `standard` varchar(3) DEFAULT 'EUR',
6686
  `id_code_qualifier` varchar(3) DEFAULT '14',
6683
  `id_code_qualifier` varchar(3) DEFAULT '14',
6687
  `transport` varchar(6) DEFAULT 'FTP',
6688
  `quotes_enabled` tinyint(1) NOT NULL DEFAULT 0,
6684
  `quotes_enabled` tinyint(1) NOT NULL DEFAULT 0,
6689
  `invoices_enabled` tinyint(1) NOT NULL DEFAULT 0,
6685
  `invoices_enabled` tinyint(1) NOT NULL DEFAULT 0,
6690
  `orders_enabled` tinyint(1) NOT NULL DEFAULT 0,
6686
  `orders_enabled` tinyint(1) NOT NULL DEFAULT 0,
Lines 6695-6701 CREATE TABLE `vendor_edi_accounts` ( Link Here
6695
  PRIMARY KEY (`id`),
6691
  PRIMARY KEY (`id`),
6696
  KEY `vendorid` (`vendor_id`),
6692
  KEY `vendorid` (`vendor_id`),
6697
  KEY `shipmentbudget` (`shipment_budget`),
6693
  KEY `shipmentbudget` (`shipment_budget`),
6694
  KEY `vfk_download_sftp_server_id` (`download_sftp_server_id`),
6695
  KEY `vfk_upload_sftp_server_id` (`upload_sftp_server_id`),
6696
  CONSTRAINT `vfk_download_sftp_server_id` FOREIGN KEY (`download_sftp_server_id`) REFERENCES `sftp_servers` (`id`),
6698
  CONSTRAINT `vfk_shipment_budget` FOREIGN KEY (`shipment_budget`) REFERENCES `aqbudgets` (`budget_id`),
6697
  CONSTRAINT `vfk_shipment_budget` FOREIGN KEY (`shipment_budget`) REFERENCES `aqbudgets` (`budget_id`),
6698
  CONSTRAINT `vfk_upload_sftp_server_id` FOREIGN KEY (`upload_sftp_server_id`) REFERENCES `sftp_servers` (`id`),
6699
  CONSTRAINT `vfk_vendor_id` FOREIGN KEY (`vendor_id`) REFERENCES `aqbooksellers` (`id`)
6699
  CONSTRAINT `vfk_vendor_id` FOREIGN KEY (`vendor_id`) REFERENCES `aqbooksellers` (`id`)
6700
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
6700
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
6701
/*!40101 SET character_set_client = @saved_cs_client */;
6701
/*!40101 SET character_set_client = @saved_cs_client */;
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/edi_accounts.tt (-39 / +62 lines)
Lines 134-172 Link Here
134
                        <input type="text" name="description" id="description" size="20" value="[% account.description | html %]" />
134
                        <input type="text" name="description" id="description" size="20" value="[% account.description | html %]" />
135
                    </li>
135
                    </li>
136
                    <li>
136
                    <li>
137
                        [% transport_types = [ 'FTP', 'SFTP', 'FILE' ] %]
137
                        <label for="download_sftp_server_id">Download FTP/SFTP server: </label>
138
                        <label for="transport">Transport: </label>
138
                        <select name="download_sftp_server_id" id="download_sftp_server_id">
139
                        <select name="transport" title="valid types of transport are FTP and SFTP" id="transport">
139
                            <option value="">(do not use FTP/SFTP Server)</option>
140
                            [% FOREACH transport_type IN transport_types %]
140
                            [% FOREACH sftp_server IN sftp_servers %]
141
                                [% IF transport_type == account.transport %]
141
                                [% IF account.download_sftp_server.id == sftp_server.id %]
142
                                    <option value="[% transport_type | html %]" selected="selected">[% transport_type | html %]</option>
142
                                    <option value="[% sftp_server.id | html %]" selected="selected">[% sftp_server.name | html %] ([% sftp_server.host | html %]:[% sftp_server.port | html %])</option>
143
                                [% ELSE %]
143
                                [% ELSE %]
144
                                    <option value="[% transport_type | html %]">[% transport_type | html %]</option>
144
                                    <option value="[% sftp_server.id | html %]"> [% sftp_server.name | html %]([% sftp_server.host | html %]:[% sftp_server.port | html %])</option>
145
                                [% END %]
145
                                [% END %]
146
                            [% END %]
146
                            [% END %]
147
                        </select>
147
                        </select>
148
                    </li>
148
                    </li>
149
                    <li>
149
                    <li>
150
                        <label for="host">Remote host: </label>
150
                        <label for="upload_sftp_server_id">Upload FTP/SFTP server: </label>
151
                        <input type="text" name="host" id="host" size="20" maxlength="40" value="[% account.host | html %]" />
151
                        <select name="upload_sftp_server_id" id="upload_sftp_server_id">
152
                    </li>
152
                            <option value="">(do not use FTP/SFTP Server)</option>
153
                    <li>
153
                            [% FOREACH sftp_server IN sftp_servers %]
154
                        <label for="username">Username: </label>
154
                                [% IF account.upload_sftp_server.id == sftp_server.id %]
155
                        <input type="text" name="username" id="username" size="20" maxlength="40" value="[% account.username | html %]" />
155
                                    <option value="[% sftp_server.id | html %]" selected="selected">[% sftp_server.name | html %] ([% sftp_server.host | html %]:[% sftp_server.port | html %])</option>
156
                    </li>
156
                                [% ELSE %]
157
                    <li>
157
                                    <option value="[% sftp_server.id | html %]">[% sftp_server.name | html %] ([% sftp_server.host | html %]:[% sftp_server.port | html %])</option>
158
                        <label for="password">Password: </label>
158
                                [% END %]
159
                        <input type="text" name="password" id="password" size="20" maxlength="40" value="[% account.password | html %]" />
159
                            [% END %]
160
                    </li>
160
                        </select>
161
                    <li>
161
                        <div class="hint">Configure under <a href="/cgi-bin/koha/admin/sftp_servers.pl">FTP/SFTP Servers</a></div>
162
                        <label for="upload_port">Upload port: </label>
163
                        <input type="text" name="upload_port" id="upload_port" size="20" maxlength="40" value="[% account.upload_port | html %]" />
164
                        <div class="hint">The upload port will default to 22 (for SFTP) or 21 (for FTP) if not set.</div>
165
                    </li>
166
                    <li>
167
                        <label for="download_port">Download port: </label>
168
                        <input type="text" name="download_port" id="download_port" size="20" maxlength="40" value="[% account.download_port | html %]" />
169
                        <div class="hint">The download port will default to 22 (for SFTP) or 21 (for FTP) if not set.</div>
170
                    </li>
162
                    </li>
171
                    <li>
163
                    <li>
172
                        <label for="download_directory">Download directory: </label>
164
                        <label for="download_directory">Download directory: </label>
Lines 300-311 Link Here
300
                            <th>ID</th>
292
                            <th>ID</th>
301
                            <th>Vendor</th>
293
                            <th>Vendor</th>
302
                            <th>Description</th>
294
                            <th>Description</th>
303
                            <th>Transport</th>
295
                            <th>Upload FTP/SFTP server</th>
304
                            <th>Remote host</th>
296
                            <th>Download FTP/SFTP server</th>
305
                            <th>Username</th>
306
                            <th>Password</th>
307
                            <th>Upload port</th>
308
                            <th>Download port</th>
309
                            <th>Download directory</th>
297
                            <th>Download directory</th>
310
                            <th>Upload directory</th>
298
                            <th>Upload directory</th>
311
                            <th>Qualifier</th>
299
                            <th>Qualifier</th>
Lines 325-336 Link Here
325
                                <td>[% account.id | html %]</td>
313
                                <td>[% account.id | html %]</td>
326
                                <td><a href="/cgi-bin/koha/acquisition/vendors/[% account.vendor_id | uri %]">[% account.vendor.name | html %]</a></td>
314
                                <td><a href="/cgi-bin/koha/acquisition/vendors/[% account.vendor_id | uri %]">[% account.vendor.name | html %]</a></td>
327
                                <td>[% account.description | html %]</td>
315
                                <td>[% account.description | html %]</td>
328
                                <td>[% account.transport | html %]</td>
316
                                <td>
329
                                <td>[% account.host | html %]</td>
317
                                    [% IF (account.upload_sftp_server) %]
330
                                <td>[% account.username | html %]</td>
318
                                        <a href="/cgi-bin/koha/admin/sftp_servers.pl?op=edit_form&sftp_server_id=[% account.upload_sftp_server.id | url %]">[% account.upload_sftp_server.name | html %]</a>
331
                                <td>[% IF account.password %]*****[% END %]</td>
319
                                    [% ELSE %]
332
                                <td>[% account.upload_port | html %]</td>
320
                                        <em>None set</em>
333
                                <td>[% account.download_port | html %]</td>
321
                                    [% END %]
322
                                </td>
323
                                <td>
324
                                    [% IF (account.download_sftp_server) %]
325
                                        <a href="/cgi-bin/koha/admin/sftp_servers.pl?op=edit_form&sftp_server_id=[% account.download_sftp_server.id | url %]">[% account.download_sftp_server.name | html %]</a>
326
                                    [% ELSE %]
327
                                        <em>None set</em>
328
                                    [% END %]
329
                                </td>
334
                                <td>[% account.download_directory | html %]</td>
330
                                <td>[% account.download_directory | html %]</td>
335
                                <td>[% account.upload_directory | html %]</td>
331
                                <td>[% account.upload_directory | html %]</td>
336
                                <td>
332
                                <td>
Lines 403-408 Link Here
403
[% MACRO jsinclude BLOCK %]
399
[% MACRO jsinclude BLOCK %]
404
    [% Asset.js("js/admin-menu.js") | $raw %]
400
    [% Asset.js("js/admin-menu.js") | $raw %]
405
    [% INCLUDE 'datatables.inc' %]
401
    [% INCLUDE 'datatables.inc' %]
402
    [% IF acct_form %]
403
        <script>
404
            document.addEventListener("DOMContentLoaded", function (event) {
405
                $('select[name="download_sftp_server_id"]').on("change", function () {
406
                    var parent = $('select[name="download_sftp_server_id"]');
407
                    var option = parent.find("option:selected").first();
408
                    var value = option.val();
409
                    var target = $('input[name="download_directory"]');
410
411
                    $.get("/api/v1/config/sftp_servers/" + value, function (data, status) {
412
                        if (data.download_directory) target.val(data.download_directory);
413
                    });
414
                });
415
416
                $('select[name="upload_sftp_server_id"]').on("change", function () {
417
                    var parent = $('select[name="upload_sftp_server_id"]');
418
                    var option = parent.find("option:selected").first();
419
                    var value = option.val();
420
                    var target = $('input[name="upload_directory"]');
421
422
                    $.get("/api/v1/config/sftp_servers/" + value, function (data, status) {
423
                        if (data.upload_directory) target.val(data.upload_directory);
424
                    });
425
                });
426
            });
427
        </script>
428
    [% END %]
406
    <script>
429
    <script>
407
        $(document).ready(function(){
430
        $(document).ready(function(){
408
            var table_settings = [% TablesSettings.GetTableSettings( 'admin', 'edi_accounts', 'edi_accounts_table', 'json' ) | $raw %];
431
            var table_settings = [% TablesSettings.GetTableSettings( 'admin', 'edi_accounts', 'edi_accounts_table', 'json' ) | $raw %];
(-)a/t/db_dependent/Koha/Edifact/Transport.t (-2 / +3 lines)
Lines 21-27 my $account = $builder->build( Link Here
21
    {
21
    {
22
        source => 'VendorEdiAccount',
22
        source => 'VendorEdiAccount',
23
        value  => {
23
        value  => {
24
            description => 'test vendor', transport => 'FILE',
24
            description             => 'test vendor',
25
            upload_sftp_server_id   => undef,
26
            download_sftp_server_id => undef,
25
        }
27
        }
26
    }
28
    }
27
);
29
);
28
- 

Return to bug 38489