Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision ccb40ac4

Von Bernd Bleßmann vor fast 11 Jahren hinzugefügt

CSV-Import mit Multiplex-Daten: Die Spalte datatype muss nicht an der ersten Position sein.

Unterschiede anzeigen:

SL/Helper/Csv.pm
7 7
use Carp;
8 8
use IO::File;
9 9
use Params::Validate qw(:all);
10
use List::MoreUtils qw(all pairwise);
10
use List::MoreUtils qw(all pairwise firstidx);
11 11
use Text::CSV_XS;
12 12
use Rose::Object::MakeMethods::Generic scalar => [ qw(
13 13
  file encoding sep_char quote_char escape_char header profile
14 14
  numberformat dateformat ignore_unknown_columns strict_profile is_multiplexed
15 15
  _row_header _io _csv _objects _parsed _data _errors all_cvar_configs case_insensitive_header
16
  _multiplex_datatype_position
16 17
) ];
17 18

  
18 19
use SL::Helper::Csv::Dispatcher;
......
59 60
  $self->_open_file;
60 61
  return if ! $self->_check_multiplexed;
61 62
  return if ! $self->_check_header;
63
  return if ! $self->_check_multiplex_datatype_position;
62 64
  return if ! $self->dispatcher->parse_profile;
63 65
  return if ! $self->_parse_data;
64 66

  
......
216 218
  return $self->header($header);
217 219
}
218 220

  
221
sub _check_multiplex_datatype_position {
222
  my ($self) = @_;
223

  
224
  return 1 if !$self->is_multiplexed; # ok if if not multiplexed
225

  
226
  my @positions = map { firstidx { 'datatype' eq lc($_) } @{ $_ } } @{ $self->header };
227
  my $first_pos = $positions[0];
228
  if (all { $first_pos == $_ } @positions) {
229
    $self->_multiplex_datatype_position($first_pos);
230
    return 1;
231
  } else {
232
    $self->_push_error([0,
233
                        "datatype field must be at the same position for all datatypes for multiplexed data",
234
                        0,
235
                        0]);
236
    return 0;
237
  }
238
}
239

  
219 240
sub _parse_data {
220 241
  my ($self, %params) = @_;
221 242
  my (@data, @errors);
......
261 282
  }
262 283

  
263 284
  if ($self->is_multiplexed) {
264
    return $self->_row_header->{$row->[0]}
285
    return $self->_row_header->{$row->[$self->_multiplex_datatype_position]}
265 286
  } else {
266 287
    return $self->header;
267 288
  }
......
380 401
This module can handle multiplexed data of different class types. In that case
381 402
multiple profiles with classes and row identifiers must be given. Multiple
382 403
headers may also be given or read from csv data. Data must contain the row
383
identifier in the first column and it's field name must be 'datatype'.
404
identifier in the column named 'datatype'.
384 405

  
385 406
=back
386 407

  
......
446 467
If not given, headers are taken from the first n lines of data, where n is the
447 468
number of different class types.
448 469

  
449
In case of multiplexed data the first column must be named 'datatype'. This
450
name must be given in the header.
470
In case of multiplexed data there must be a column named 'datatype'. This
471
column must be given in each header and must be at the same position in each
472
header.
451 473

  
452 474
Examples:
453 475

  
454 476
  classic data of one type:
455 477
  [ 'name', 'street', 'zipcode', 'city' ]
456 478

  
457
  multiplexed data with two different types
479
  multiplexed data with two different types:
458 480
  [ [ 'datatype', 'ordernumber', 'customer', 'transdate' ],
459 481
    [ 'datatype', 'partnumber', 'qty', 'sellprice' ] ]
460 482

  
locale/de/all
2116 2116
  'The client has been created.' => 'Der Mandant wurde angelegt.',
2117 2117
  'The client has been deleted.' => 'Der Mandant wurde gelöscht.',
2118 2118
  'The client has been saved.'  => 'Der Mandant wurde gespeichert.',
2119
  'The column "datatype" must be present and must be the first column. The values must be the row names (see settings) for order and item data respectively.' => 'Die Spalte "datatype" muss vorhanden sein und sie muss die erste Spalte sein. Die Werte in dieser Spalte müssen die Namen der Auftrag-/Positions-Zeilen (siehe Einstellungen) sein.',
2119
  'The column "datatype" must be present and must be at the same position / column in each data set. The values must be the row names (see settings) for order and item data respectively.' => 'Die Spalte "datatype" muss vorhanden sein und sie muss in jedem Datensatz an der gleichen Stelle / Spalte sein. Die Werte in dieser Spalte müssen die Namen der Auftrag-/Positions-Zeilen (siehe Einstellungen) sein.',
2120 2120
  'The column "make_X" can contain either a vendor\'s database ID, a vendor number or a vendor\'s name.' => 'Die Spalte "make_X" can entweder die Datenbank-ID des Lieferanten, eine Lieferantennummer oder einen Lieferantennamen enthalten.',
2121 2121
  'The column triplets can occur multiple times with different numbers "X" each time (e.g. "make_1", "model_1", "lastcost_1", "make_2", "model_2", "lastcost_2", "make_3", "model_3", "lastcost_3" etc).' => 'Die Spalten-Dreiergruppen können mehrfach auftreten, sofern sie unterschiedliche Nummern "X" verwenden (z.B. "make_1", "model_1", "lastcost_1", "make_2", "model_2", "lastcost_2", "make_3", "model_3", "lastcost_3" etc).',
2122 2122
  'The columns "Dunning Duedate", "Total Fees" and "Interest" show data for the previous dunning created for this invoice.' => 'Die Spalten "Zahlbar bis", "Kumulierte Gebühren" und "Zinsen" zeigen Daten der letzten für diese Rechnung erzeugten Mahnung.',
locale/en/all
2079 2079
  'The client has been created.' => '',
2080 2080
  'The client has been deleted.' => '',
2081 2081
  'The client has been saved.'  => '',
2082
  'The column "datatype" must be present and must be the first column. The values must be the row names (see settings) for order and item data respectively.' => '',
2082
  'The column "datatype" must be present and must be at the same position / column in each data set. The values must be the row names (see settings) for order and item data respectively.' => '',
2083 2083
  'The column "make_X" can contain either a vendor\'s database ID, a vendor number or a vendor\'s name.' => '',
2084 2084
  'The column triplets can occur multiple times with different numbers "X" each time (e.g. "make_1", "model_1", "lastcost_1", "make_2", "model_2", "lastcost_2", "make_3", "model_3", "lastcost_3" etc).' => '',
2085 2085
  'The columns "Dunning Duedate", "Total Fees" and "Interest" show data for the previous dunning created for this invoice.' => '',
t/helper/csv.t
1
use Test::More tests => 71;
1
use Test::More tests => 75;
2 2

  
3 3
use lib 't';
4 4
use utf8;
......
551 551

  
552 552
#####
553 553

  
554
$csv = SL::Helper::Csv->new(
555
  file   => \<<EOL,
556
description;longdescription;datatype
557
name;customernumber;datatype
558
Kaffee;"lecker Kaffee";P
559
Meier;1;C
560
Bier;"kühles Bier";P
561
Mueller;2;C
562
EOL
563
# " # make emacs happy
564
  profile => [
565
              {class  => 'SL::DB::Part',     row_ident => 'P'},
566
              {class  => 'SL::DB::Customer', row_ident => 'C'},
567
             ],
568
  ignore_unknown_columns => 1,
569
);
570
$csv->parse;
571
is $csv->_multiplex_datatype_position, 2, 'multiplex check detects datatype field position right';
572

  
573
is_deeply $csv->get_data, [ { datatype => 'P', description => 'Kaffee', longdescription => 'lecker Kaffee' },
574
                            { datatype => 'C', name => 'Meier', customernumber => 1},
575
                            { datatype => 'P', description => 'Bier', longdescription => 'kühles Bier' },
576
                            { datatype => 'C', name => 'Mueller', customernumber => 2}
577
                          ],
578
                          'multiplex: datatype not at first position works';
579

  
580
#####
581

  
582
$csv = SL::Helper::Csv->new(
583
  file   => \<<EOL,
584
datatype;description;longdescription
585
name;datatype;customernumber
586
P;Kaffee;"lecker Kaffee"
587
Meier;C;1
588
P;Bier;"kühles Bier"
589
Mueller;C;2
590
EOL
591
# " # make emacs happy
592
  profile => [
593
              {class  => 'SL::DB::Part',     row_ident => 'P'},
594
              {class  => 'SL::DB::Customer', row_ident => 'C'},
595
             ],
596
  ignore_unknown_columns => 1,
597
);
598
ok !$csv->parse, 'multiplex check detects incosistent datatype field position';
599
is_deeply( ($csv->errors)[0], [ 0, 'datatype field must be at the same position for all datatypes for multiplexed data', 0, 0 ], 'multiplex data with inconsistent datatype field posiotion throws error');
600

  
601
#####
602

  
554 603
$csv = SL::Helper::Csv->new(
555 604
  file   => \"Datatype;Description\nDatatype;Name\nP;Kaffee\nC;Meier",        # " # make emacs happy
556 605
  case_insensitive_header => 1,
templates/webpages/csv_import/form.html
133 133
[%- ELSIF SELF.type == 'orders' %]
134 134
   <p>
135 135
    [1]:
136
    [% LxERP.t8('The column "datatype" must be present and must be the first column. The values must be the row names (see settings) for order and item data respectively.') %]
136
    [% LxERP.t8('The column "datatype" must be present and must be at the same position / column in each data set. The values must be the row names (see settings) for order and item data respectively.') %]
137 137
   </p>
138 138
   <p>
139 139
    [2]:

Auch abrufbar als: Unified diff