From 7f1f5efedc0b738f8e8faaeca52f649150448e32 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Wed, 23 Feb 2011 18:03:31 +0100 Subject: [PATCH] =?utf8?q?Speichern,=20Laden,=20L=C3=B6schen=20von=20Impor?= =?utf8?q?tprofilen=20implementiert?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- SL/Controller/CsvImport.pm | 194 ++++++++++++++++++ SL/DB/CsvImportProfile.pm | 49 ++++- .../csv_import/form_customers_vendors.html | 123 +++++++++++ 3 files changed, 364 insertions(+), 2 deletions(-) create mode 100644 SL/Controller/CsvImport.pm create mode 100644 templates/webpages/csv_import/form_customers_vendors.html diff --git a/SL/Controller/CsvImport.pm b/SL/Controller/CsvImport.pm new file mode 100644 index 000000000..2406362cb --- /dev/null +++ b/SL/Controller/CsvImport.pm @@ -0,0 +1,194 @@ +package SL::Controller::CsvImport; + +use strict; + +use SL::DB::CsvImportProfile; +use SL::Helper::Flash; + +use List::MoreUtils qw(none); + +use parent qw(SL::Controller::Base); + +use Rose::Object::MakeMethods::Generic +( + scalar => [ qw(type profile all_profiles all_charsets sep_char all_sep_chars quote_char all_quote_chars escape_char all_escape_chars) ], +); + +__PACKAGE__->run_before('check_auth'); +__PACKAGE__->run_before('ensure_form_structure'); +__PACKAGE__->run_before('check_type'); +__PACKAGE__->run_before('load_all_profiles'); + +# +# actions +# + +sub action_new { + my ($self) = @_; + + $self->load_default_profile unless $self->profile; + $self->render_inputs; +} + +sub action_test { + my ($self) = @_; + $self->test_and_import(test => 1); +} + +sub action_import { + my $self = shift; + $self->test_and_import(test => 0); +} + +sub action_save { + my ($self) = @_; + + $self->profile_from_form(SL::DB::Manager::CsvImportProfile->find_by(name => $::form->{profile}->{name})); + $self->profile->save; + + flash_later('info', $::locale->text("The profile has been saved under the name '#1'.", $self->profile->name)); + $self->redirect_to(action => 'new', 'profile.type' => $self->type, 'profile.id' => $self->profile->id); +} + +sub action_destroy { + my $self = shift; + + my $profile = SL::DB::CsvImportProfile->new(id => $::form->{profile}->{id}); + $profile->delete(cascade => 1); + + flash_later('info', $::locale->text('The profile \'#1\' has been deleted.', $profile->name)); + $self->redirect_to(action => 'new', 'profile.type' => $self->type); +} + +# +# filters +# + +sub check_auth { + $::auth->assert('config'); +} + +sub check_type { + my ($self) = @_; + + die "Invalid CSV import type" if none { $_ eq $::form->{profile}->{type} } qw(parts customers_vendors addresses contacts); + $self->type($::form->{profile}->{type}); +} + +sub ensure_form_structure { + my ($self, %params) = @_; + + $::form->{profile} = {} unless ref $::form->{profile} eq 'HASH'; + $::form->{settings} = {} unless ref $::form->{settings} eq 'HASH'; +} + +# +# helpers +# + +sub render_inputs { + my ($self, %params) = @_; + + $self->all_charsets([ [ 'UTF-8', 'UTF-8' ], + [ 'ISO-8859-1', 'ISO-8859-1 (Latin 1)' ], + [ 'ISO-8859-15', 'ISO-8859-15 (Latin 9)' ], + [ 'CP850', 'CP850 (DOS/ANSI)' ], + [ 'CP1252', 'CP1252 (Windows)' ], + ]); + + my %char_map = $self->char_map; + + foreach my $type (qw(sep quote escape)) { + my $sub = "all_${type}_chars"; + $self->$sub([ sort { $a->[0] cmp $b->[0] } values %{ $char_map{$type} } ]); + + my $char = $self->profile->get($type . '_char'); + $sub = "${type}_char"; + $self->$sub(($char_map{$type}->{$char} || [])->[0] || $char); + } + + if ($self->type eq 'customers_vendors') { + $self->render('csv_import/form_customers_vendors', title => $::locale->text('CSV import: customers and vendors')); + + } elsif ($self->type eq 'addresses') { + $self->render('csv_import/form_addresses', title => $::locale->text('CSV import: shipping addresses')); + + } elsif ($self->type eq 'contacts') { + $self->render('csv_import/form_contacts', title => $::locale->text('CSV import: contacts')); + + } elsif ($self->type eq 'parts') { + $self->render('csv_import/form_parts', title => $::locale->text('CSV import: parts, services and assemblies')); + + } else { + die; + } +} + +sub test_and_import { + my ($self, %params) = @_; + + $self->profile_from_form; + + # do the import thingy... + $self->action_new; +} + +sub load_default_profile { + my ($self) = @_; + + if ($::form->{profile}->{id}) { + $self->profile(SL::DB::CsvImportProfile->new(id => $::form->{profile}->{id})->load); + + } else { + $self->profile(SL::DB::Manager::CsvImportProfile->find_by(type => $self->{type}, is_default => 1)); + $self->profile(SL::DB::CsvImportProfile->new(type => $self->{type})) unless $self->profile; + } + + $self->profile->set_defaults; +} + +sub load_all_profiles { + my ($self, %params) = @_; + + $self->all_profiles(SL::DB::Manager::CsvImportProfile->get_all(where => [ type => $self->type ], sort_by => 'name')); +} + +sub profile_from_form { + my ($self, $existing_profile) = @_; + + delete $::form->{profile}->{id}; + + my %char_map = $self->char_map; + my @settings; + + foreach my $type (qw(sep quote escape)) { + my %rev_chars = map { $char_map{$type}->{$_}->[0] => $_ } keys %{ $char_map{$type} }; + my $char = $::form->{"${type}_char"} eq 'custom' ? $::form->{"custom_${type}_char"} : $rev_chars{ $::form->{"${type}_char"} }; + + push @settings, { key => "${type}_char", value => $char }; + } + + delete $::form->{profile}->{id}; + $self->profile($existing_profile || SL::DB::CsvImportProfile->new); + $self->profile->assign_attributes(%{ $::form->{profile} }); + $self->profile->settings(map({ { key => $_, value => $::form->{settings}->{$_} } } keys %{ $::form->{settings} }), + @settings); + $self->profile->set_defaults; +} + +sub char_map { + return ( sep => { ',' => [ 'comma', $::locale->text('Comma') ], + ';' => [ 'semicolon', $::locale->text('Semicolon') ], + "\t" => [ 'tab', $::locale->text('Tab') ], + ' ' => [ 'space', $::locale->text('Space') ], + }, + quote => { '"' => [ 'quote', $::locale->text('Quotes') ], + "'" => [ 'singlequote', $::locale->text('Single quotes') ], + }, + escape => { '"' => [ 'quote', $::locale->text('Quotes') ], + "'" => [ 'singlequote', $::locale->text('Single quotes') ], + }, + ); +} + +1; diff --git a/SL/DB/CsvImportProfile.pm b/SL/DB/CsvImportProfile.pm index 85033e181..c7c0f91ea 100644 --- a/SL/DB/CsvImportProfile.pm +++ b/SL/DB/CsvImportProfile.pm @@ -24,6 +24,41 @@ __PACKAGE__->before_save('_before_save_unset_default_on_others'); # public functions # +sub new_with_default { + my ($class, $type) = @_; + + return $class->new(type => $type)->set_defaults; +} + +sub set_defaults { + my ($self) = @_; + + $self->_set_defaults(sep_char => ',', + quote_char => '"', + escape_char => '"', + charset => 'CP850', + numberformat => $::myconfig{numberformat}, + ); + + if ($self->type eq 'parts') { + my $bugru = SL::DB::Manager::Buchungsgruppe->find_by(name => { like => 'Standard%19%' }); + + $self->_set_defaults(sellprice_places => 2, + sellprice_adjustment => 0, + sellprice_adjustment_type => 'percent', + article_number_policy => 'update_price', + price_group_sep_char => '!', + shoparticle_if_missing => 0, + parts_type => 'part', + default_buchungsgruppe => ($bugru ? $bugru->name : undef), + ); + } else { + $self->_set_defaults(table => 'customer'); + } + + return $self; +} + sub set { my ($self, %params) = @_; @@ -32,7 +67,7 @@ sub set { if (!$setting) { $setting = SL::DB::CsvImportProfileSetting->new(key => $key); - $self->add_settings($setting); + $self->settings(@{ $self->settings || [] }, $setting); } $setting->value($value); @@ -48,6 +83,16 @@ sub get { return $setting ? $setting->value : $default; } +sub _set_defaults { + my ($self, %params) = @_; + + while (my ($key, $value) = each %params) { + $self->settings(@{ $self->settings || [] }, { key => $key, value => $value }) if !$self->_get_setting($key); + } + + return $self; +} + # # hooks # @@ -70,7 +115,7 @@ sub _before_save_unset_default_on_others { sub _get_setting { my ($self, $key) = @_; - return first { $_->key eq $key } @{ $self->settings }; + return first { $_->key eq $key } @{ $self->settings || [] }; } 1; diff --git a/templates/webpages/csv_import/form_customers_vendors.html b/templates/webpages/csv_import/form_customers_vendors.html new file mode 100644 index 000000000..50b2438a1 --- /dev/null +++ b/templates/webpages/csv_import/form_customers_vendors.html @@ -0,0 +1,123 @@ +[% USE HTML %][% USE LxERP %][% USE L %] + + +
[% FORM.title %]
+ + [%- INCLUDE 'common/flash.html' %] + +
+ [% L.hidden_tag('action', 'CsvImport/dispatch') %] + [% L.hidden_tag('profile.type', SELF.profile.type) %] + +

[%- LxERP.t8('Import profiles') %]

+ + + [%- IF SELF.profile.id %] + + + + + [%- END %] + + [%- IF SELF.all_profiles.size %] + + + + + + [%- END %] + + + + + + +
[%- LxERP.t8('Current profile') %]:[%- HTML.escape(SELF.profile.name) %]
[%- LxERP.t8('Existing profiles') %]: + [% L.select_tag('profile.id', L.options_for_select(SELF.all_profiles, title => 'name', default => SELF.profile.id), style => 'width: 300px') %] + + [% L.submit_tag('action_new', LxERP.t8('Load profile')) %] + [% L.submit_tag('action_destroy', LxERP.t8('Delete profile'), confirm => LxERP.t8('Do you really want to delete this object?')) %] +
[%- LxERP.t8('Save settings as') %]: + [% L.input_tag('profile.name', '', style => 'width: 300px') %] +
+ [% L.checkbox_tag('profile.is_default', label => LxERP.t8('Make default profile')) %] +
[% L.submit_tag('action_save', LxERP.t8('Save profile')) %]
+ +
+ +

[%- LxERP.t8('Settings') %]

+ + + + + + + + + + [% SET custom_sep_char = SELF.sep_char %] + [% FOREACH entry = SELF.all_sep_chars %] + + [%- END %] + + + + + + + [% SET custom_quote_char = SELF.quote_char %] + [% FOREACH entry = SELF.all_quote_chars %] + + [%- END %] + + + + + + + [% SET custom_escape_char = SELF.escape_char %] + [% FOREACH entry = SELF.all_escape_chars %] + + [%- END %] + + + + +
[%- LxERP.t8('Charset') %]:[% L.select_tag('settings.charset', L.options_for_select(SELF.all_charsets, default => SELF.profile.get('charset'))) %]
[%- LxERP.t8('Separator') %]: + [% IF SELF.sep_char == entry.first %] [% SET custom_sep_char = '' %] [%- END %] + [% L.radio_button_tag('sep_char', value => entry.first, label => entry.last, checked => SELF.sep_char == entry.first) %] + + [% L.radio_button_tag('sep_char', value => 'custom', checked => custom_sep_char != '') %] + [% L.input_tag('custom_sep_char', custom_sep_char, size => 3, maxlength => 1) %] +
[%- LxERP.t8('Quote character') %]: + [% IF SELF.quote_char == entry.first %] [% SET custom_quote_char = '' %] [%- END %] + [% L.radio_button_tag('quote_char', value => entry.first, label => entry.last, checked => SELF.quote_char == entry.first) %] + + [% L.radio_button_tag('quote_char', value => 'custom', checked => custom_quote_char != '') %] + [% L.input_tag('custom_quote_char', custom_quote_char, size => 3, maxlength => 1) %] +
[%- LxERP.t8('Escape character') %]: + [% IF SELF.escape_char == entry.first %] [% SET custom_escape_char = '' %] [%- END %] + [% L.radio_button_tag('escape_char', value => entry.first, label => entry.last, checked => SELF.escape_char == entry.first) %] + + [% L.radio_button_tag('escape_char', value => 'custom', checked => custom_escape_char != '') %] + [% L.input_tag('custom_escape_char', custom_escape_char, size => 3, maxlength => 1) %] +
+ + [% L.submit_tag('action_test', LxERP.t8('Gogogo')) %] + +
+ + + + -- 2.20.1