Revision 67643d03
Von Sven Schöling vor fast 12 Jahren hinzugefügt
SL/Controller/CsvImport.pm | ||
---|---|---|
4 | 4 |
|
5 | 5 |
use SL::DB::Buchungsgruppe; |
6 | 6 |
use SL::DB::CsvImportProfile; |
7 |
use SL::DB::CsvImportReport; |
|
7 | 8 |
use SL::DB::Unit; |
8 | 9 |
use SL::Helper::Flash; |
9 | 10 |
use SL::SessionFile; |
... | ... | |
26 | 27 |
|
27 | 28 |
__PACKAGE__->run_before('check_auth'); |
28 | 29 |
__PACKAGE__->run_before('ensure_form_structure'); |
29 |
__PACKAGE__->run_before('check_type'); |
|
30 |
__PACKAGE__->run_before('check_type', except => [ qw(report) ]);
|
|
30 | 31 |
__PACKAGE__->run_before('load_all_profiles'); |
31 | 32 |
|
32 | 33 |
# |
... | ... | |
182 | 183 |
$self->num_imported(0); |
183 | 184 |
$worker->save_objects if !$params{test}; |
184 | 185 |
|
186 |
$self->save_report; |
|
187 |
|
|
185 | 188 |
$self->num_importable(scalar grep { !$_ } map { scalar @{ $_->{errors} } } @{ $self->data || [] }); |
186 | 189 |
$self->import_status($params{test} ? 'tested' : 'imported'); |
187 | 190 |
|
... | ... | |
257 | 260 |
); |
258 | 261 |
} |
259 | 262 |
|
263 |
sub save_report { |
|
264 |
my ($self, $report_id) = @_; |
|
265 |
|
|
266 |
my $clone_profile = $self->profile->clone_and_reset_deep; |
|
267 |
$clone_profile->save; # weird bug. if this isn't saved before adding it to the report, it will default back to the last profile. |
|
268 |
|
|
269 |
my $report = SL::DB::CsvImportReport->new( |
|
270 |
session_id => $::auth->create_or_refresh_session, |
|
271 |
profile => $clone_profile, |
|
272 |
type => $self->type, |
|
273 |
file => '', |
|
274 |
)->save(cascade => 1); |
|
275 |
|
|
276 |
my $dbh = $::form->get_standard_dbh; |
|
277 |
$dbh->begin_work; |
|
278 |
|
|
279 |
my $query = 'INSERT INTO csv_import_report_rows (csv_import_report_id, col, row, value) VALUES (?, ?, ?, ?)'; |
|
280 |
|
|
281 |
my $sth = $dbh->prepare($query); |
|
282 |
|
|
283 |
# save headers |
|
284 |
my @headers = ( |
|
285 |
@{ $self->info_headers->{headers} || [] }, |
|
286 |
@{ $self->headers->{headers} || [] }, |
|
287 |
@{ $self->raw_data_headers->{headers} || [] }, |
|
288 |
); |
|
289 |
my @info_methods = keys %{ $self->info_headers->{methods} || {} }; |
|
290 |
my @methods = @{ $self->headers->{methods} || [] }; |
|
291 |
my @raw_methods = keys %{ $self->raw_data_headers->{used} || {} }; |
|
292 |
|
|
293 |
$sth->execute($report->id, $_, 0, $headers[$_]) for 0 .. $#headers; |
|
294 |
|
|
295 |
# col offsets |
|
296 |
my $o1 = @info_methods; |
|
297 |
my $o2 = $o1 + @methods; |
|
298 |
|
|
299 |
for my $row (0 .. $#{ $self->data }) { |
|
300 |
my $data_row = $self->{data}[$row]; |
|
301 |
|
|
302 |
$sth->execute($report->id, $_, $row + 1, $data_row->{info_data}{ $info_methods[$_] }) for 0 .. $#info_methods; |
|
303 |
$sth->execute($report->id, $o1 + $_, $row + 1, $data_row->{object}->${ \ $methods[$_] }) for 0 .. $#methods; |
|
304 |
$sth->execute($report->id, $o2 + $_, $row + 1, $data_row->{raw_data}{ $raw_methods[$_] }) for 0 .. $#raw_methods; |
|
305 |
} |
|
306 |
|
|
307 |
$dbh->commit; |
|
308 |
} |
|
309 |
|
|
310 |
sub action_report { |
|
311 |
my ($self) = @_; |
|
312 |
|
|
313 |
$self->{report} = SL::DB::Manager::CsvImportReport->find_by(id => $::form->{id}); |
|
314 |
|
|
315 |
$self->render('csv_import/report'); |
|
316 |
} |
|
317 |
|
|
260 | 318 |
sub csv_file_name { |
261 | 319 |
my ($self) = @_; |
262 | 320 |
return "csv-import-" . $self->type . ".csv"; |
SL/DB/CsvImportProfile.pm | ||
---|---|---|
5 | 5 |
use List::Util qw(first); |
6 | 6 |
|
7 | 7 |
use SL::DB::MetaSetup::CsvImportProfile; |
8 |
use Rose::DB::Object::Helpers qw(clone_and_reset); |
|
8 | 9 |
|
9 | 10 |
__PACKAGE__->meta->add_relationship( |
10 | 11 |
settings => { |
... | ... | |
94 | 95 |
return $self; |
95 | 96 |
} |
96 | 97 |
|
98 |
sub clone_and_reset_deep { |
|
99 |
my ($self) = @_; |
|
100 |
|
|
101 |
my $clone = $self->clone_and_reset; |
|
102 |
$clone->settings(map { $_->clone_and_reset } $self->settings); |
|
103 |
$clone->name(''); |
|
104 |
|
|
105 |
return $clone; |
|
106 |
} |
|
107 |
|
|
97 | 108 |
# |
98 | 109 |
# hooks |
99 | 110 |
# |
SL/DB/CsvImportProfileSetting.pm | ||
---|---|---|
6 | 6 |
use strict; |
7 | 7 |
|
8 | 8 |
use SL::DB::MetaSetup::CsvImportProfileSetting; |
9 |
use Rose::DB::Object::Helpers qw(clone); |
|
9 | 10 |
|
10 | 11 |
# Creates get_all, get_all_count, get_all_iterator, delete_all and update_all. |
11 | 12 |
__PACKAGE__->meta->make_manager_class; |
12 | 13 |
|
14 |
# Helpers' clone_and_reset also kills compund keys like in this case kay+id |
|
15 |
sub clone_and_reset { |
|
16 |
my $clone = $_[0]->clone; |
|
17 |
$clone->id(undef); |
|
18 |
return $clone; |
|
19 |
} |
|
20 |
|
|
13 | 21 |
1; |
SL/DB/CsvImportReport.pm | ||
---|---|---|
1 |
# This file has been auto-generated only because it didn't exist. |
|
2 |
# Feel free to modify it at will; it will not be overwritten automatically. |
|
3 |
|
|
4 |
package SL::DB::CsvImportReport; |
|
5 |
|
|
6 |
use strict; |
|
7 |
|
|
8 |
use SL::DB::MetaSetup::CsvImportReport; |
|
9 |
|
|
10 |
__PACKAGE__->meta->add_relationships( |
|
11 |
rows => { |
|
12 |
type => 'one to many', |
|
13 |
class => 'SL::DB::CsvImportReportRow', |
|
14 |
column_map => { id => 'csv_import_report_id' }, |
|
15 |
}, |
|
16 |
); |
|
17 |
|
|
18 |
__PACKAGE__->meta->make_manager_class; |
|
19 |
__PACKAGE__->meta->initialize; |
|
20 |
|
|
21 |
sub folded_rows { |
|
22 |
my ($self) = @_; |
|
23 |
|
|
24 |
$self->_fold_rows unless $self->{folded_rows}; |
|
25 |
|
|
26 |
return $self->{folded_rows}; |
|
27 |
} |
|
28 |
|
|
29 |
sub _fold_rows { |
|
30 |
my ($self) = @_; |
|
31 |
|
|
32 |
$self->{folded_rows} = []; |
|
33 |
|
|
34 |
for my $row_obj (@{ $self->rows }) { |
|
35 |
$::lxdebug->dump(0, "adding", $row_obj->row . ' ' . $row_obj->col . ' ' . $row_obj->value); |
|
36 |
$self->{folded_rows}->[ $row_obj->row ] ||= []; |
|
37 |
$self->{folded_rows}->[ $row_obj->row ][ $row_obj->col ] = $row_obj->value; |
|
38 |
$::lxdebug->dump(0, "now", $self->{folded_rows}); |
|
39 |
} |
|
40 |
} |
|
41 |
|
|
42 |
1; |
SL/DB/CsvImportReportRow.pm | ||
---|---|---|
1 |
# This file has been auto-generated only because it didn't exist. |
|
2 |
# Feel free to modify it at will; it will not be overwritten automatically. |
|
3 |
|
|
4 |
package SL::DB::CsvImportReportRow; |
|
5 |
|
|
6 |
use strict; |
|
7 |
|
|
8 |
use SL::DB::MetaSetup::CsvImportReportRow; |
|
9 |
|
|
10 |
# Creates get_all, get_all_count, get_all_iterator, delete_all and update_all. |
|
11 |
__PACKAGE__->meta->make_manager_class; |
|
12 |
|
|
13 |
1; |
SL/DB/CsvImportReportRowStatus.pm | ||
---|---|---|
1 |
# This file has been auto-generated only because it didn't exist. |
|
2 |
# Feel free to modify it at will; it will not be overwritten automatically. |
|
3 |
|
|
4 |
package SL::DB::CsvImportReportRowStatus; |
|
5 |
|
|
6 |
use strict; |
|
7 |
|
|
8 |
use SL::DB::MetaSetup::CsvImportReportRowStatus; |
|
9 |
|
|
10 |
# Creates get_all, get_all_count, get_all_iterator, delete_all and update_all. |
|
11 |
__PACKAGE__->meta->make_manager_class; |
|
12 |
|
|
13 |
1; |
SL/DB/Helper/Mappings.pm | ||
---|---|---|
50 | 50 |
contacts => 'contact', |
51 | 51 |
csv_import_profiles => 'csv_import_profile', |
52 | 52 |
csv_import_profile_settings => 'csv_import_profile_setting', |
53 |
csv_import_reports => 'csv_import_report', |
|
54 |
csv_import_report_rows => 'csv_import_report_row', |
|
55 |
csv_import_report_row_status => 'csv_import_report_row_status', |
|
53 | 56 |
custom_variable_configs => 'custom_variable_config', |
54 | 57 |
custom_variables => 'custom_variable', |
55 | 58 |
custom_variables_validity => 'custom_variable_validity', |
SL/DB/MetaSetup/CsvImportReport.pm | ||
---|---|---|
1 |
# This file has been auto-generated. Do not modify it; it will be overwritten |
|
2 |
# by rose_auto_create_model.pl automatically. |
|
3 |
package SL::DB::CsvImportReport; |
|
4 |
|
|
5 |
use strict; |
|
6 |
|
|
7 |
use base qw(SL::DB::Object); |
|
8 |
|
|
9 |
__PACKAGE__->meta->setup( |
|
10 |
table => 'csv_import_reports', |
|
11 |
|
|
12 |
columns => [ |
|
13 |
id => { type => 'serial', not_null => 1 }, |
|
14 |
session_id => { type => 'text', not_null => 1 }, |
|
15 |
profile_id => { type => 'integer', not_null => 1 }, |
|
16 |
type => { type => 'text', not_null => 1 }, |
|
17 |
file => { type => 'text', not_null => 1 }, |
|
18 |
], |
|
19 |
|
|
20 |
primary_key_columns => [ 'id' ], |
|
21 |
|
|
22 |
foreign_keys => [ |
|
23 |
profile => { |
|
24 |
class => 'SL::DB::CsvImportProfile', |
|
25 |
key_columns => { profile_id => 'id' }, |
|
26 |
}, |
|
27 |
], |
|
28 |
); |
|
29 |
|
|
30 |
1; |
|
31 |
; |
SL/DB/MetaSetup/CsvImportReportRow.pm | ||
---|---|---|
1 |
# This file has been auto-generated. Do not modify it; it will be overwritten |
|
2 |
# by rose_auto_create_model.pl automatically. |
|
3 |
package SL::DB::CsvImportReportRow; |
|
4 |
|
|
5 |
use strict; |
|
6 |
|
|
7 |
use base qw(SL::DB::Object); |
|
8 |
|
|
9 |
__PACKAGE__->meta->setup( |
|
10 |
table => 'csv_import_report_rows', |
|
11 |
|
|
12 |
columns => [ |
|
13 |
id => { type => 'serial', not_null => 1 }, |
|
14 |
csv_import_report_id => { type => 'integer', not_null => 1 }, |
|
15 |
col => { type => 'integer', not_null => 1 }, |
|
16 |
row => { type => 'integer', not_null => 1 }, |
|
17 |
value => { type => 'text' }, |
|
18 |
], |
|
19 |
|
|
20 |
primary_key_columns => [ 'id' ], |
|
21 |
|
|
22 |
foreign_keys => [ |
|
23 |
csv_import_report => { |
|
24 |
class => 'SL::DB::CsvImportReport', |
|
25 |
key_columns => { csv_import_report_id => 'id' }, |
|
26 |
}, |
|
27 |
], |
|
28 |
); |
|
29 |
|
|
30 |
1; |
|
31 |
; |
SL/DB/MetaSetup/CsvImportReportRowStatus.pm | ||
---|---|---|
1 |
# This file has been auto-generated. Do not modify it; it will be overwritten |
|
2 |
# by rose_auto_create_model.pl automatically. |
|
3 |
package SL::DB::CsvImportReportRowStatus; |
|
4 |
|
|
5 |
use strict; |
|
6 |
|
|
7 |
use base qw(SL::DB::Object); |
|
8 |
|
|
9 |
__PACKAGE__->meta->setup( |
|
10 |
table => 'csv_import_report_row_status', |
|
11 |
|
|
12 |
columns => [ |
|
13 |
id => { type => 'serial', not_null => 1 }, |
|
14 |
csv_import_report_row_id => { type => 'integer', not_null => 1 }, |
|
15 |
type => { type => 'text', not_null => 1 }, |
|
16 |
value => { type => 'text' }, |
|
17 |
], |
|
18 |
|
|
19 |
primary_key_columns => [ 'id' ], |
|
20 |
|
|
21 |
foreign_keys => [ |
|
22 |
csv_import_report_row => { |
|
23 |
class => 'SL::DB::CsvImportReportRow', |
|
24 |
key_columns => { csv_import_report_row_id => 'id' }, |
|
25 |
}, |
|
26 |
], |
|
27 |
); |
|
28 |
|
|
29 |
1; |
|
30 |
; |
sql/Pg-upgrade2/csv_import_report_cache.sql | ||
---|---|---|
1 |
-- @tag: csv_import_report_cache |
|
2 |
-- @description: Csv Import Cache |
|
3 |
-- @depends: csv_import_profiles_2 |
|
4 |
-- @encoding: utf-8 |
|
5 |
|
|
6 |
CREATE TABLE csv_import_reports ( |
|
7 |
id SERIAL PRIMARY KEY, |
|
8 |
session_id TEXT NOT NULL, |
|
9 |
profile_id INTEGER NOT NULL REFERENCES csv_import_profiles(id), |
|
10 |
type TEXT NOT NULL, |
|
11 |
file TEXT NOT NULL |
|
12 |
); |
|
13 |
|
|
14 |
CREATE TABLE csv_import_report_rows ( |
|
15 |
id SERIAL PRIMARY KEY, |
|
16 |
csv_import_report_id INTEGER NOT NULL REFERENCES csv_import_reports(id), |
|
17 |
col INTEGER NOT NULL, |
|
18 |
row INTEGER NOT NULL, |
|
19 |
value TEXT |
|
20 |
); |
|
21 |
|
|
22 |
CREATE TABLE csv_import_report_row_status ( |
|
23 |
id SERIAL PRIMARY KEY, |
|
24 |
csv_import_report_row_id INTEGER NOT NULL REFERENCES csv_import_report_rows(id), |
|
25 |
type TEXT NOT NULL, |
|
26 |
value TEXT |
|
27 |
); |
|
28 |
|
|
29 |
ALTER TABLE csv_import_profiles DROP constraint "csv_import_profiles_name_key"; |
templates/webpages/csv_import/report.html | ||
---|---|---|
1 |
[% USE HTML %] |
|
2 |
[% USE LxERP %] |
|
3 |
[% USE L %] |
|
4 |
|
|
5 |
<h3>[%- LxERP.t8('Import result') %]</h3> |
|
6 |
|
|
7 |
<table> |
|
8 |
[%- FOREACH row = SELF.report.folded_rows %] |
|
9 |
[%- IF loop.first %] |
|
10 |
<tr class="listheading"> |
|
11 |
[%- FOREACH value = row %] |
|
12 |
<th>[% value | html %]</th> |
|
13 |
[%- END %] |
|
14 |
<th>[%- LxERP.t8('Notes') %]</th> |
|
15 |
</tr> |
|
16 |
[%- ELSE %] |
|
17 |
<tr class="[% IF row.errors.size %]redrow[% ELSE %]listrow[% END %][% loop.count % 2 %]"> |
|
18 |
[%- FOREACH value = row %] |
|
19 |
<td>[%- value | html %]</td> |
|
20 |
[%- END %] |
|
21 |
<td> |
|
22 |
[%- FOREACH error = row.errors %][%- HTML.escape(error) %][% UNLESS loop.last %]<br>[%- END %][%- END %] |
|
23 |
[%- FOREACH info = row.information %][% IF !loop.first || row.errors.size %]<br>[%- END %][%- HTML.escape(info) %][%- END %] |
|
24 |
</td> |
|
25 |
</tr> |
|
26 |
[%- END %] |
|
27 |
[%- END %] |
|
28 |
|
|
29 |
|
|
30 |
</table> |
Auch abrufbar als: Unified diff
Csv Import in Datenbank zwischenspeichern und rudimentärer Report.