Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 7f1f5efe

Von Moritz Bunkus vor mehr als 13 Jahren hinzugefügt

  • ID 7f1f5efedc0b738f8e8faaeca52f649150448e32
  • Vorgänger c2cf302a
  • Nachfolger f5594740

Speichern, Laden, Löschen von Importprofilen implementiert

Unterschiede anzeigen:

SL/Controller/CsvImport.pm
1
package SL::Controller::CsvImport;
2

  
3
use strict;
4

  
5
use SL::DB::CsvImportProfile;
6
use SL::Helper::Flash;
7

  
8
use List::MoreUtils qw(none);
9

  
10
use parent qw(SL::Controller::Base);
11

  
12
use Rose::Object::MakeMethods::Generic
13
(
14
 scalar => [ qw(type profile all_profiles all_charsets sep_char all_sep_chars quote_char all_quote_chars escape_char all_escape_chars) ],
15
);
16

  
17
__PACKAGE__->run_before('check_auth');
18
__PACKAGE__->run_before('ensure_form_structure');
19
__PACKAGE__->run_before('check_type');
20
__PACKAGE__->run_before('load_all_profiles');
21

  
22
#
23
# actions
24
#
25

  
26
sub action_new {
27
  my ($self) = @_;
28

  
29
  $self->load_default_profile unless $self->profile;
30
  $self->render_inputs;
31
}
32

  
33
sub action_test {
34
  my ($self) = @_;
35
  $self->test_and_import(test => 1);
36
}
37

  
38
sub action_import {
39
  my $self = shift;
40
  $self->test_and_import(test => 0);
41
}
42

  
43
sub action_save {
44
  my ($self) = @_;
45

  
46
  $self->profile_from_form(SL::DB::Manager::CsvImportProfile->find_by(name => $::form->{profile}->{name}));
47
  $self->profile->save;
48

  
49
  flash_later('info', $::locale->text("The profile has been saved under the name '#1'.", $self->profile->name));
50
  $self->redirect_to(action => 'new', 'profile.type' => $self->type, 'profile.id' => $self->profile->id);
51
}
52

  
53
sub action_destroy {
54
  my $self = shift;
55

  
56
  my $profile = SL::DB::CsvImportProfile->new(id => $::form->{profile}->{id});
57
  $profile->delete(cascade => 1);
58

  
59
  flash_later('info', $::locale->text('The profile \'#1\' has been deleted.', $profile->name));
60
  $self->redirect_to(action => 'new', 'profile.type' => $self->type);
61
}
62

  
63
#
64
# filters
65
#
66

  
67
sub check_auth {
68
  $::auth->assert('config');
69
}
70

  
71
sub check_type {
72
  my ($self) = @_;
73

  
74
  die "Invalid CSV import type" if none { $_ eq $::form->{profile}->{type} } qw(parts customers_vendors addresses contacts);
75
  $self->type($::form->{profile}->{type});
76
}
77

  
78
sub ensure_form_structure {
79
  my ($self, %params) = @_;
80

  
81
  $::form->{profile}  = {} unless ref $::form->{profile}  eq 'HASH';
82
  $::form->{settings} = {} unless ref $::form->{settings} eq 'HASH';
83
}
84

  
85
#
86
# helpers
87
#
88

  
89
sub render_inputs {
90
  my ($self, %params) = @_;
91

  
92
  $self->all_charsets([ [ 'UTF-8',       'UTF-8'                 ],
93
                        [ 'ISO-8859-1',  'ISO-8859-1 (Latin 1)'  ],
94
                        [ 'ISO-8859-15', 'ISO-8859-15 (Latin 9)' ],
95
                        [ 'CP850',       'CP850 (DOS/ANSI)'      ],
96
                        [ 'CP1252',      'CP1252 (Windows)'      ],
97
                      ]);
98

  
99
  my %char_map = $self->char_map;
100

  
101
  foreach my $type (qw(sep quote escape)) {
102
    my $sub = "all_${type}_chars";
103
    $self->$sub([ sort { $a->[0] cmp $b->[0] } values %{ $char_map{$type} } ]);
104

  
105
    my $char = $self->profile->get($type . '_char');
106
    $sub     = "${type}_char";
107
    $self->$sub(($char_map{$type}->{$char} || [])->[0] || $char);
108
  }
109

  
110
  if ($self->type eq 'customers_vendors') {
111
    $self->render('csv_import/form_customers_vendors', title => $::locale->text('CSV import: customers and vendors'));
112

  
113
  } elsif ($self->type eq 'addresses') {
114
    $self->render('csv_import/form_addresses',         title => $::locale->text('CSV import: shipping addresses'));
115

  
116
  } elsif ($self->type eq 'contacts') {
117
    $self->render('csv_import/form_contacts',          title => $::locale->text('CSV import: contacts'));
118

  
119
  } elsif ($self->type eq 'parts') {
120
    $self->render('csv_import/form_parts',             title => $::locale->text('CSV import: parts, services and assemblies'));
121

  
122
  } else {
123
    die;
124
  }
125
}
126

  
127
sub test_and_import {
128
  my ($self, %params) = @_;
129

  
130
  $self->profile_from_form;
131

  
132
  # do the import thingy...
133
  $self->action_new;
134
}
135

  
136
sub load_default_profile {
137
  my ($self) = @_;
138

  
139
  if ($::form->{profile}->{id}) {
140
    $self->profile(SL::DB::CsvImportProfile->new(id => $::form->{profile}->{id})->load);
141

  
142
  } else {
143
    $self->profile(SL::DB::Manager::CsvImportProfile->find_by(type => $self->{type}, is_default => 1));
144
    $self->profile(SL::DB::CsvImportProfile->new(type => $self->{type})) unless $self->profile;
145
  }
146

  
147
  $self->profile->set_defaults;
148
}
149

  
150
sub load_all_profiles {
151
  my ($self, %params) = @_;
152

  
153
  $self->all_profiles(SL::DB::Manager::CsvImportProfile->get_all(where => [ type => $self->type ], sort_by => 'name'));
154
}
155

  
156
sub profile_from_form {
157
  my ($self, $existing_profile) = @_;
158

  
159
  delete $::form->{profile}->{id};
160

  
161
  my %char_map = $self->char_map;
162
  my @settings;
163

  
164
  foreach my $type (qw(sep quote escape)) {
165
    my %rev_chars = map { $char_map{$type}->{$_}->[0] => $_ } keys %{ $char_map{$type} };
166
    my $char      = $::form->{"${type}_char"} eq 'custom' ? $::form->{"custom_${type}_char"} : $rev_chars{ $::form->{"${type}_char"} };
167

  
168
    push @settings, { key => "${type}_char", value => $char };
169
  }
170

  
171
  delete $::form->{profile}->{id};
172
  $self->profile($existing_profile || SL::DB::CsvImportProfile->new);
173
  $self->profile->assign_attributes(%{ $::form->{profile} });
174
  $self->profile->settings(map({ { key => $_, value => $::form->{settings}->{$_} } } keys %{ $::form->{settings} }),
175
                           @settings);
176
  $self->profile->set_defaults;
177
}
178

  
179
sub char_map {
180
  return ( sep    => { ','  => [ 'comma',     $::locale->text('Comma')     ],
181
                       ';'  => [ 'semicolon', $::locale->text('Semicolon') ],
182
                       "\t" => [ 'tab',       $::locale->text('Tab')       ],
183
                       ' '  => [ 'space',     $::locale->text('Space')     ],
184
                     },
185
           quote  => { '"' => [ 'quote', $::locale->text('Quotes') ],
186
                       "'" => [ 'singlequote', $::locale->text('Single quotes') ],
187
                     },
188
           escape => { '"' => [ 'quote', $::locale->text('Quotes') ],
189
                       "'" => [ 'singlequote', $::locale->text('Single quotes') ],
190
                     },
191
         );
192
}
193

  
194
1;
SL/DB/CsvImportProfile.pm
24 24
# public functions
25 25
#
26 26

  
27
sub new_with_default {
28
  my ($class, $type) = @_;
29

  
30
  return $class->new(type => $type)->set_defaults;
31
}
32

  
33
sub set_defaults {
34
  my ($self) = @_;
35

  
36
  $self->_set_defaults(sep_char     => ',',
37
                       quote_char   => '"',
38
                       escape_char  => '"',
39
                       charset      => 'CP850',
40
                       numberformat => $::myconfig{numberformat},
41
                      );
42

  
43
  if ($self->type eq 'parts') {
44
    my $bugru = SL::DB::Manager::Buchungsgruppe->find_by(name => { like => 'Standard%19%' });
45

  
46
    $self->_set_defaults(sellprice_places          => 2,
47
                         sellprice_adjustment      => 0,
48
                         sellprice_adjustment_type => 'percent',
49
                         article_number_policy     => 'update_price',
50
                         price_group_sep_char      => '!',
51
                         shoparticle_if_missing    => 0,
52
                         parts_type                => 'part',
53
                         default_buchungsgruppe    => ($bugru ? $bugru->name : undef),
54
                        );
55
  } else {
56
    $self->_set_defaults(table => 'customer');
57
  }
58

  
59
  return $self;
60
}
61

  
27 62
sub set {
28 63
  my ($self, %params) = @_;
29 64

  
......
32 67

  
33 68
    if (!$setting) {
34 69
      $setting = SL::DB::CsvImportProfileSetting->new(key => $key);
35
      $self->add_settings($setting);
70
      $self->settings(@{ $self->settings || [] }, $setting);
36 71
    }
37 72

  
38 73
    $setting->value($value);
......
48 83
  return $setting ? $setting->value : $default;
49 84
}
50 85

  
86
sub _set_defaults {
87
  my ($self, %params) = @_;
88

  
89
  while (my ($key, $value) = each %params) {
90
    $self->settings(@{ $self->settings || [] }, { key => $key, value => $value }) if !$self->_get_setting($key);
91
  }
92

  
93
  return $self;
94
}
95

  
51 96
#
52 97
# hooks
53 98
#
......
70 115

  
71 116
sub _get_setting {
72 117
  my ($self, $key) = @_;
73
  return first { $_->key eq $key } @{ $self->settings };
118
  return first { $_->key eq $key } @{ $self->settings || [] };
74 119
}
75 120

  
76 121
1;
templates/webpages/csv_import/form_customers_vendors.html
1
[% USE HTML %][% USE LxERP %][% USE L %]
2
<body>
3

  
4
 <div class="listtop">[% FORM.title %]</div>
5

  
6
 [%- INCLUDE 'common/flash.html' %]
7

  
8
 <form method="post" action="controller.pl">
9
  [% L.hidden_tag('action', 'CsvImport/dispatch') %]
10
  [% L.hidden_tag('profile.type', SELF.profile.type) %]
11

  
12
  <h2>[%- LxERP.t8('Import profiles') %]</h2>
13

  
14
  <table>
15
   [%- IF SELF.profile.id %]
16
    <tr>
17
     <th align="right">[%- LxERP.t8('Current profile') %]:</th>
18
     <td>[%- HTML.escape(SELF.profile.name) %]</td>
19
    </tr>
20
   [%- END %]
21

  
22
   [%- IF SELF.all_profiles.size %]
23
    <tr>
24
     <th align="right">[%- LxERP.t8('Existing profiles') %]:</th>
25
     <td>
26
      [% L.select_tag('profile.id', L.options_for_select(SELF.all_profiles, title => 'name', default => SELF.profile.id), style => 'width: 300px') %]
27
     </td>
28
     <td>
29
      [% L.submit_tag('action_new', LxERP.t8('Load profile')) %]
30
      [% L.submit_tag('action_destroy', LxERP.t8('Delete profile'), confirm => LxERP.t8('Do you really want to delete this object?')) %]
31
     </td>
32
    </tr>
33
   [%- END %]
34

  
35
   <tr>
36
    <th align="right" valign="top">[%- LxERP.t8('Save settings as') %]:</th>
37
    <td valign="top">
38
     [% L.input_tag('profile.name', '', style => 'width: 300px') %]
39
     <br>
40
     [% L.checkbox_tag('profile.is_default', label => LxERP.t8('Make default profile')) %]
41
    </td>
42
    <td valign="top">[% L.submit_tag('action_save', LxERP.t8('Save profile')) %]</td>
43
   </tr>
44
  </table>
45

  
46
  <hr>
47

  
48
  <h2>[%- LxERP.t8('Settings') %]</h2>
49

  
50
  <table>
51
   <tr>
52
    <th align="right">[%- LxERP.t8('Charset') %]:</th>
53
    <td colspan="10">[% L.select_tag('settings.charset', L.options_for_select(SELF.all_charsets, default => SELF.profile.get('charset'))) %]</td>
54
   </tr>
55

  
56
   <tr>
57
    <th align="right">[%- LxERP.t8('Separator') %]:</th>
58
    [% SET custom_sep_char = SELF.sep_char %]
59
    [% FOREACH entry = SELF.all_sep_chars %]
60
     <td>
61
      [% IF SELF.sep_char == entry.first %] [% SET custom_sep_char = '' %] [%- END %]
62
      [% L.radio_button_tag('sep_char', value => entry.first, label => entry.last, checked => SELF.sep_char == entry.first) %]
63
     </td>
64
    [%- END %]
65

  
66
    <td>
67
     [% L.radio_button_tag('sep_char', value => 'custom', checked => custom_sep_char != '') %]
68
     [% L.input_tag('custom_sep_char', custom_sep_char, size => 3, maxlength => 1) %]
69
    </td>
70
   </tr>
71

  
72
   <tr>
73
    <th align="right">[%- LxERP.t8('Quote character') %]:</th>
74
    [% SET custom_quote_char = SELF.quote_char %]
75
    [% FOREACH entry = SELF.all_quote_chars %]
76
     <td>
77
      [% IF SELF.quote_char == entry.first %] [% SET custom_quote_char = '' %] [%- END %]
78
      [% L.radio_button_tag('quote_char', value => entry.first, label => entry.last, checked => SELF.quote_char == entry.first) %]
79
     </td>
80
    [%- END %]
81

  
82
    <td>
83
     [% L.radio_button_tag('quote_char', value => 'custom', checked => custom_quote_char != '') %]
84
     [% L.input_tag('custom_quote_char', custom_quote_char, size => 3, maxlength => 1) %]
85
    </td>
86
   </tr>
87

  
88
   <tr>
89
    <th align="right">[%- LxERP.t8('Escape character') %]:</th>
90
    [% SET custom_escape_char = SELF.escape_char %]
91
    [% FOREACH entry = SELF.all_escape_chars %]
92
     <td>
93
      [% IF SELF.escape_char == entry.first %] [% SET custom_escape_char = '' %] [%- END %]
94
      [% L.radio_button_tag('escape_char', value => entry.first, label => entry.last, checked => SELF.escape_char == entry.first) %]
95
     </td>
96
    [%- END %]
97

  
98
    <td>
99
     [% L.radio_button_tag('escape_char', value => 'custom', checked => custom_escape_char != '') %]
100
     [% L.input_tag('custom_escape_char', custom_escape_char, size => 3, maxlength => 1) %]
101
    </td>
102
   </tr>
103

  
104
  </table>
105

  
106
  [% L.submit_tag('action_test', LxERP.t8('Gogogo')) %]
107

  
108
 </form>
109

  
110
 <script type="text/javascript">
111
  <!--
112
    $(document).ready(function() {
113
      $('#action_save').click(function() {
114
        if ($('#profile_name').attr('value') != '')
115
          return true;
116
        alert('[% LxERP.t8('Please enter a profile name.') %]');
117
        return false;
118
      })
119
    });
120
    -->
121
 </script>
122
</body>
123
</html>

Auch abrufbar als: Unified diff