Merge branch 'master' of vc.linet-services.de:public/lx-office-erp
authorMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 16 Aug 2012 08:54:23 +0000 (10:54 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 16 Aug 2012 08:54:23 +0000 (10:54 +0200)
32 files changed:
SL/Auth.pm
SL/DB/MetaSetup/CustomVariable.pm
SL/FU.pm
SL/Form.pm
SL/OE.pm
SL/ReportGenerator.pm
SL/Request.pm
SL/SessionFile.pm
SL/SessionFile/Random.pm [new file with mode: 0644]
SL/VK.pm
bin/mozilla/ap.pl
bin/mozilla/do.pl
bin/mozilla/gl.pl
bin/mozilla/ic.pl
bin/mozilla/vk.pl
bin/mozilla/wh.pl
css/kivitendo/dhtmlsuite/menu-item.css
css/lx-office-erp/dhtmlsuite/menu-item.css
js/dhtmlsuite/menu-for-applications.js
locale/de/all
scripts/task_server.pl
sql/Pg-upgrade2/custom_variables_sub_module_not_null.sql [new file with mode: 0644]
t/Support/TestSetup.pm
t/request/post_multipart.t [new file with mode: 0644]
t/request/post_multipart_1 [new file with mode: 0644]
templates/webpages/admin/list_users.html
templates/webpages/ap/form_footer.html [new file with mode: 0644]
templates/webpages/csv_import/_preview.html
templates/webpages/csv_import/form.html
templates/webpages/fu/report_top.html
templates/webpages/report_generator/csv_export_options.html
templates/webpages/vk/search_invoice.html

index 6652aed..4c50ddf 100644 (file)
@@ -424,15 +424,30 @@ sub read_all_users {
   my $self  = shift;
 
   my $dbh   = $self->dbconnect();
-  my $query = qq|SELECT u.id, u.login, cfg.cfg_key, cfg.cfg_value
-                 FROM auth.user_config cfg
-                 LEFT JOIN auth."user" u ON (cfg.user_id = u.id)|;
+  my $query = qq|SELECT u.id, u.login, cfg.cfg_key, cfg.cfg_value, s.mtime AS last_action
+
+                 FROM auth."user" AS  u
+
+                 LEFT JOIN auth.user_config AS cfg
+                   ON (cfg.user_id = u.id)
+
+                 LEFT JOIN auth.session_content AS sc_login
+                   ON (sc_login.sess_key = 'login' AND sc_login.sess_value = ('--- ' \|\| u.login \|\| '\n'))
+
+                 LEFT JOIN auth.session AS s
+                   ON (s.id = sc_login.session_id)
+              |;
   my $sth   = prepare_execute_query($main::form, $dbh, $query);
 
   my %users;
 
   while (my $ref = $sth->fetchrow_hashref()) {
-    $users{$ref->{login}}                    ||= { 'login' => $ref->{login}, 'id' => $ref->{id} };
+
+    $users{$ref->{login}}                    ||= {
+                                                'login' => $ref->{login},
+                                                'id' => $ref->{id},
+                                                'last_action' => $ref->{last_action},
+                                             };
     $users{$ref->{login}}->{$ref->{cfg_key}}   = $ref->{cfg_value} if (($ref->{cfg_key} ne 'login') && ($ref->{cfg_key} ne 'id'));
   }
 
index bb2380a..be839d9 100644 (file)
@@ -19,7 +19,7 @@ __PACKAGE__->meta->setup(
     number_value    => { type => 'numeric', precision => 5, scale => 25 },
     itime           => { type => 'timestamp', default => 'now()' },
     mtime           => { type => 'timestamp' },
-    sub_module      => { type => 'text' },
+    sub_module      => { type => 'text', default => '', not_null => 1 },
   ],
 
   primary_key_columns => [ 'id' ],
index ad6149d..e2d2fc9 100644 (file)
--- a/SL/FU.pm
+++ b/SL/FU.pm
@@ -374,13 +374,13 @@ sub link_details {
 
   } elsif ($params{trans_type} eq 'ar_transaction') {
     $link = {
-      'url'   => 'ar.pl?action=editid=' . $params{trans_id},
+      'url'   => 'ar.pl?action=edit&id=' . $params{trans_id},
       'title' => $locale->text('AR Transaction') . " $params{trans_info}",
     };
 
   } elsif ($params{trans_type} eq 'ap_transaction') {
     $link = {
-      'url'   => 'ap.pl?action=editid=' . $params{trans_id},
+      'url'   => 'ap.pl?action=edit&id=' . $params{trans_id},
       'title' => $locale->text('AP Transaction') . " $params{trans_info}",
     };
 
index 8491673..70d3a65 100644 (file)
@@ -1995,8 +1995,17 @@ sub get_duedate {
   $reference_date = $reference_date ? conv_dateq($reference_date) . '::DATE' : 'current_date';
 
   my $dbh         = $self->get_standard_dbh($myconfig);
+  my $payment_id;
+
+  if($self->{payment_id}) {
+    $payment_id = $self->{payment_id};
+  } elsif($self->{vendor_id}) {
+    my $query = 'SELECT payment_id FROM vendor WHERE id = ?';
+    ($payment_id) = selectrow_query($self, $dbh, $query, $self->{vendor_id});
+  }
+
   my $query       = qq|SELECT ${reference_date} + terms_netto FROM payment_terms WHERE id = ?|;
-  my ($duedate)   = selectrow_query($self, $dbh, $query, $self->{payment_id});
+  my ($duedate)   = selectrow_query($self, $dbh, $query, $payment_id);
 
   $main::lxdebug->leave_sub();
 
@@ -2567,7 +2576,8 @@ sub all_vc {
   # setup sales contacts
   $query = qq|SELECT e.id, e.name
               FROM employee e
-              WHERE (e.sales = '1') AND (NOT e.id = ?)|;
+              WHERE (e.sales = '1') AND (NOT e.id = ?)
+              ORDER BY name|;
   $self->{all_employees} = selectall_hashref_query($self, $dbh, $query, $self->{employee_id});
 
   # this is for self
@@ -2575,11 +2585,6 @@ sub all_vc {
        { id   => $self->{employee_id},
          name => $self->{employee} });
 
-  # sort the whole thing
-  @{ $self->{all_employees} } =
-    sort { $a->{name} cmp $b->{name} } @{ $self->{all_employees} };
-
-
     # prepare query for departments
     $query = qq|SELECT id, description
                 FROM department
index 9694026..07758a8 100644 (file)
--- a/SL/OE.pm
+++ b/SL/OE.pm
@@ -725,9 +725,6 @@ sub retrieve {
 
   my ($query, $query_add, @values, @ids, $sth);
 
-  my $ic_cvar_configs = CVar->get_configs(module => 'IC',
-                                          dbh    => $dbh);
-
   # translate the ids (given by id_# and trans_id_#) into one array of ids, so we can join them later
   map {
     push @ids, $form->{"trans_id_$_"}
index 3f5cdeb..688f165 100644 (file)
@@ -72,6 +72,12 @@ sub set_columns {
   foreach my $column (values %{ $self->{columns} }) {
     $column->{visible} = $self->{options}->{std_column_visibility} unless defined $column->{visible};
   }
+  
+  if( $::form->{report_generator_csv_options_for_import} ) {
+    foreach my $key (keys %{ $self->{columns} }) {
+      $self->{columns}{$key}{text} = $key;
+    }
+  }
 
   $self->set_column_order(sort keys %{ $self->{columns} });
 }
index 6466287..a8ae4c1 100644 (file)
@@ -53,6 +53,10 @@ sub _input_to_hash {
 sub _parse_multipart_formdata {
   my ($target, $temp_target, $input) = @_;
   my ($name, $filename, $headers_done, $content_type, $boundary_found, $need_cr, $previous, $p_attachment, $encoding, $transfer_encoding);
+  my $data_start = 0;
+
+  # teach substr and length to use good ol' bytes, not 'em fancy characters
+  use bytes;
 
   # We SHOULD honor encodings and transfer-encodings here, but as hard as I
   # looked I couldn't find a reasonably recent webbrowser that makes use of
@@ -63,12 +67,21 @@ sub _parse_multipart_formdata {
   $ENV{'CONTENT_TYPE'} =~ /multipart\/form-data\s*;\s*boundary\s*=\s*(.+)$/;
   my $boundary = '--' . $1;
 
+  my $index = 0;
+  my $line_length;
   foreach my $line (split m/\n/, $input) {
-    last if (($line eq "${boundary}--") || ($line eq "${boundary}--\r"));
+    $line_length = length $line;
+
+    if ($line =~ /^\Q$boundary\E(--)?\r?$/) {
+      my $last_boundary = $1;
+      my $data       =  substr $input, $data_start, $index - $data_start;
+      $data =~ s/\r?\n$//;
 
-    if (($line eq $boundary) || ($line eq "$boundary\r")) {
-      ${ $previous } =~ s|\r?\n$|| if $previous;
-      ${ $previous } =  Encode::decode($encoding, $$previous) if $previous && !$filename && !$transfer_encoding eq 'binary';
+      if ($previous && !$filename && $transfer_encoding && $transfer_encoding ne 'binary') {
+        ${ $previous } = Encode::decode($encoding, $data);
+      } else {
+        ${ $previous } = $data;
+      }
 
       undef $previous;
       undef $filename;
@@ -79,7 +92,7 @@ sub _parse_multipart_formdata {
       $need_cr        = 0;
       $encoding       = $::lx_office_conf{system}->{dbcharset} || Common::DEFAULT_CHARSET;
       $transfer_encoding = undef;
-
+      last if $last_boundary;
       next;
     }
 
@@ -90,6 +103,7 @@ sub _parse_multipart_formdata {
 
       if (!$line) {
         $headers_done = 1;
+        $data_start = $index + $line_length + 1;
         next;
       }
 
@@ -159,11 +173,10 @@ sub _parse_multipart_formdata {
 
     next unless $previous;
 
-    ${ $previous } .= "${line}\n";
+  } continue {
+    $index += $line_length + 1;
   }
 
-  ${ $previous } =~ s|\r?\n$|| if $previous;
-
   $::lxdebug->leave_sub(2);
 }
 
index 69997e9..6f04041 100644 (file)
@@ -24,6 +24,8 @@ sub new {
   $file_name =~ s:.*/::g;
   $file_name =  "${path}/${file_name}";
 
+  $self->file_name($file_name);
+
   if ($params{mode}) {
     my $mode = $params{mode};
 
@@ -35,11 +37,14 @@ sub new {
     $self->fh(IO::File->new($file_name, $mode));
   }
 
-  $self->file_name($file_name);
-
   return $self;
 }
 
+sub open {
+  my ($self, $mode) = @_;
+  return $self->fh(IO::File->new($self->file_name, $mode));
+}
+
 sub exists {
   my ($self) = @_;
   return -f $self->file_name;
@@ -139,6 +144,10 @@ Returns the full relative file name associated with this instance. If
 it has been created for "customer.csv" then the value returned might
 be C<users/session_files/e8789b98721347/customer.csv>.
 
+=item C<open, %params]>
+
+Opens the file_name given at creation with the given parameters.
+
 =item C<exists>
 
 Returns trueish if the file exists.
diff --git a/SL/SessionFile/Random.pm b/SL/SessionFile/Random.pm
new file mode 100644 (file)
index 0000000..366baf4
--- /dev/null
@@ -0,0 +1,62 @@
+package SL::SessionFile::Random;
+
+use strict;
+use parent qw(SL::SessionFile);
+
+my @CHARS = ('A'..'Z', 'a'..'z', 0..9, '_');
+my $template = 'X' x 10;
+use constant MAX_TRIES => 1000;
+
+sub new {
+  my ($class, %params) = @_;
+
+  my $filename;
+  my $tries = 0;
+  $filename = _get_file() while $tries++ < MAX_TRIES && (!$filename || -e $filename);
+
+  $class->SUPER::new($filename, %params);
+}
+
+sub _get_file {
+  my $filename = $template;
+  $filename =~ s/X(?=X*\z)/$CHARS[ int( rand( @CHARS ) ) ]/ge;
+  $filename;
+}
+
+1;
+
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+SL::SessionFile::Random - SessionFile with a random name
+
+=head1 SYNOPSIS
+
+  use SL::SessionFile::Random;
+
+  # Create a session file named "customer.csv" (relative names only)
+  my $sfile = SL::SessionFile::Random->new("w");
+  $sfile->fh->print("col1;col2;col3\n" .
+                    "value1;value2;value3\n");
+  $sfile->fh->close;
+
+=head1 DESCRIPTION
+
+This modules gives you a random file in the current session cache that is guaranteed to be unique
+
+=head1 FUNCTIONS
+
+same as SL::SessioNFile
+
+=head1 BUGS
+
+NONE yet.
+
+=head1 AUTHOR
+
+Sven Schoeling E<lt>s.schoeling@linet-services.deE<gt>
+
+=cut
index 55c46f2..f2df17b 100644 (file)
--- a/SL/VK.pm
+++ b/SL/VK.pm
@@ -51,7 +51,7 @@ sub invoice_transactions {
   my @values;
 
   my $query =
-    qq|SELECT ct.id as customerid, ct.name as customername,ct.customernumber,ct.country,ar.invnumber,ar.id,ar.transdate,p.partnumber,pg.partsgroup,i.parts_id,i.qty,i.price_factor,i.discount,i.description as description,i.lastcost,i.sellprice,i.fxsellprice,i.marge_total,i.marge_percent,i.unit,b.description as business,e.name as employee,e2.name as salesman, to_char(ar.transdate,'Month') as month, to_char(ar.transdate, 'YYYYMM') as nummonth | .
+    qq|SELECT ct.id as customerid, ct.name as customername,ct.customernumber,ct.country,ar.invnumber,ar.id,ar.transdate,p.partnumber,pg.partsgroup,i.parts_id,i.qty,i.price_factor,i.discount,i.description as description,i.lastcost,i.sellprice,i.fxsellprice,i.marge_total,i.marge_percent,i.unit,b.description as business,e.name as employee,e2.name as salesman, to_char(ar.transdate,'Month') as month, to_char(ar.transdate, 'YYYYMM') as nummonth, p.unit as parts_unit | .
     qq|FROM invoice i | .  
     qq|JOIN ar on (i.trans_id = ar.id) | .
     qq|JOIN parts p on (i.parts_id = p.id) | .
index f62294e..f961ead 100644 (file)
@@ -371,7 +371,7 @@ sub form_header {
 
     # with JavaScript Calendar
     $button1 = qq|
-       <td><input name=transdate id=transdate size=11 title="$myconfig{dateformat}" value="$form->{transdate}" onBlur=\"check_right_date_format(this)\" $readonly></td>
+       <td><input name=transdate onchange="set_duedate()" id=transdate size=11 title="$myconfig{dateformat}" value="$form->{transdate}" onBlur=\"check_right_date_format(this)\" $readonly></td>
        <td><input type=button name=transdate id="trigger1" value=|
       . $locale->text('button') . qq|></td>
        |;
@@ -389,7 +389,7 @@ sub form_header {
 
     # without JavaScript Calendar
     $button1 =
-      qq|<td><input name=transdate id=transdate size=11 title="$myconfig{dateformat}" value="$form->{transdate}" onBlur=\"check_right_date_format(this)\" $readonly></td>|;
+      qq|<td><input name=transdate onchange="set_duedate()" id=transdate size=11 title="$myconfig{dateformat}" value="$form->{transdate}" onBlur=\"check_right_date_format(this)\" $readonly></td>|;
     $button2 =
       qq|<td><input name=duedate id=duedate size=11 title="$myconfig{dateformat}" value="$form->{duedate}" onBlur=\"check_right_date_format(this)\" $readonly></td>|;
   }
@@ -832,90 +832,37 @@ $jsscript
 }
 
 sub form_footer {
-  $main::lxdebug->enter_sub();
+  $::lxdebug->enter_sub;
+  $::auth->assert('general_ledger');
 
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-  my $locale   = $main::locale;
-  my $cgi      = $::request->{cgi};
+  my $num_due;
+  my $num_follow_ups;
+  if ($::form->{id}) {
+    my $follow_ups = FU->follow_ups('trans_id' => $::form->{id});
 
-  $main::auth->assert('general_ledger');
-
-  my $follow_ups_block;
-  if ($form->{id}) {
-    my $follow_ups = FU->follow_ups('trans_id' => $form->{id});
-
-    if (@{ $follow_ups} ) {
-      my $num_due       = sum map { $_->{due} * 1 } @{ $follow_ups };
-      $follow_ups_block = qq|<p>| . $locale->text("There are #1 unfinished follow-ups of which #2 are due.", scalar @{ $follow_ups }, $num_due) . qq|</p>|;
+    if (@{ $follow_ups }) {
+      $num_due        = sum map { $_->{due} * 1 } @{ $follow_ups };
+      $num_follow_ups = scalar @{ $follow_ups }
     }
   }
 
-  print qq|
+  my $transdate = $::form->datetonum($::form->{transdate}, \%::myconfig);
+  my $closedto  = $::form->datetonum($::form->{closedto},  \%::myconfig);
 
-$follow_ups_block
-
-<input name=callback type=hidden value="$form->{callback}">
-<input name="gldate" type="hidden" value="| . Q($form->{gldate}) . qq|">
-|
-. $cgi->hidden('-name' => 'draft_id', '-default' => [$form->{draft_id}])
-. $cgi->hidden('-name' => 'draft_description', '-default' => [$form->{draft_description}])
-. qq|
-
-<br>
-|;
-
-  if (!$form->{id} && $form->{draft_id}) {
-    print(NTI($cgi->checkbox('-name' => 'remove_draft', '-id' => 'remove_draft',
-                             '-value' => 1, '-checked' => $form->{remove_draft},
-                             '-label' => '')) .
-          qq|&nbsp;<label for="remove_draft">| .
-          $locale->text("Remove draft when posting") .
-          qq|</label><br>|);
-  }
-
-  my $transdate = $form->datetonum($form->{transdate}, \%myconfig);
-  my $closedto  = $form->datetonum($form->{closedto},  \%myconfig);
+  my $storno = $::form->{id}
+            && !IS->has_storno(\%::myconfig, $::form, 'ap')
+            && !IS->is_storno( \%::myconfig, $::form, 'ap', $::form->{id})
+            && ($::form->{totalpaid} == 0 || $::form->{totalpaid} eq '');
 
-  print qq|<input class="submit" type="submit" name="action" id="update_button" value="| . $locale->text('Update') . qq|">|;
+  $::form->header;
+  print $::form->parse_html_template('ap/form_footer', {
+    num_due         => $num_due,
+    num_follow_ups  => $num_follow_ups,
+    show_post_draft => ($transdate > $closedto) && !$::form->{id},
+    show_storno     => $storno,
+  });
 
-  if ($form->{id}) {
-    if ($form->{radier}) {
-      print qq| <input class=submit type=submit name=action value="| . $locale->text('Post') . qq|">
-                <input class=submit type=submit name=action value="| . $locale->text('Delete') . qq|">
-|;
-    }
-    # ToDO: - insert a global check for stornos, so that a storno is only possible a limited time after saving it
-    print qq| <input class=submit type=submit name=action value="| . $locale->text('Storno') . qq|"> |
-      if ($form->{id} && !IS->has_storno(\%myconfig, $form, 'ap') && !IS->is_storno(\%myconfig, $form, 'ap', $form->{id}) && (($form->{totalpaid} == 0) || ($form->{totalpaid} eq "")));
-
-    print qq| <input class=submit type=submit name=action value="| . $locale->text('Post Payment') . qq|">
-              <input class=submit type=submit name=action value="| . $locale->text('Use As Template') . qq|">
-              <input type="button" class="submit" onclick="follow_up_window()" value="| . $locale->text('Follow-Up') . qq|">
-|;
-  } elsif (($transdate > $closedto) && !$form->{id}) {
-    print qq|
-      <input class=submit type=submit name=action value="| . $locale->text('Post') . qq|"> | .
-      NTI($cgi->submit('-name' => 'action', '-value' => $locale->text('Save draft'), '-class' => 'submit'));
-  }
-  # button for saving history
-  if($form->{id} ne "") {
-    print qq| <input type="button" class="submit" onclick="set_history_window($form->{id});" name="history" id="history" value="| . $locale->text('history') . qq|"> |;
-  }
-  # /button for saving history
-  # mark_as_paid button
-  if($form->{id} ne "") {
-    print qq| <input type="submit" class="submit" name="action" value="| . $locale->text('mark as paid') . qq|"> |;
-  }
-  # /mark_as_paid button
-  print "
-</form>
-
-</body>
-</html>
-";
-
-  $main::lxdebug->leave_sub();
+  $::lxdebug->leave_sub;
 }
 
 sub mark_as_paid {
index d18378a..25020a0 100644 (file)
@@ -258,9 +258,6 @@ sub form_header {
   # use JavaScript Calendar or not
   $form->{jsscript} = 1;
 
-  #write Trigger
-  my $jsscript = Form->write_trigger(\%myconfig, "2", "transdate", "BL", "trigger1", "reqdate", "BL", "trigger2");
-
   my @old_project_ids = ($form->{"globalproject_id"});
   map({ push(@old_project_ids, $form->{"project_id_$_"})
           if ($form->{"project_id_$_"}); } (1..$form->{"rowcount"}));
@@ -615,8 +612,7 @@ sub orders {
     };
 
     $row->{donumber}->{link}  = $edit_url       . "&id=" . E($dord->{id})      . "&callback=${callback}";
-    $row->{ordnumber}->{link} = $edit_order_url . "&id=" . E($dord->{oe_id})   . "&callback=${callback}";
-
+    $row->{ordnumber}->{link} = $edit_order_url . "&id=" . E($dord->{oe_id})   . "&callback=${callback}" if $dord->{oe_id};
     $report->add_data($row);
 
     $idx++;
index ce1d1a9..fb6166f 100644 (file)
@@ -466,7 +466,7 @@ sub generate_report {
 
     my $row_set = [ $row ];
 
-    if (($form->{l_subtotal} eq 'Y')
+    if ( ($form->{l_subtotal} eq 'Y' && !$form->{report_generator_csv_options_for_import} )
         && (($idx == (scalar @{ $form->{GL} } - 1))
             || ($ref->{ $form->{sort} } ne $form->{GL}->[$idx + 1]->{ $form->{sort} }))) {
       push @{ $row_set }, create_subtotal_row(\%subtotals, \@columns, \%column_alignment, [ qw(debit credit) ], 'listsubtotal');
@@ -477,8 +477,6 @@ sub generate_report {
     $idx++;
   }
 
-  $report->add_separator();
-
   # = 0 for balanced ledger
   my $balanced_ledger = $totals{debit} + $totals{debit_tax} - $totals{credit} - $totals{credit_tax};
 
@@ -496,8 +494,11 @@ sub generate_report {
   $data .= $sh;
 
   $row->{balance}->{data}        = $data;
-
-  $report->add_data($row);
+    
+  if ( !$form->{report_generator_csv_options_for_import} ) {
+    $report->add_separator();
+    $report->add_data($row);
+  }
 
   my $raw_bottom_info_text;
 
index 0eb7995..f7985cf 100644 (file)
@@ -1401,7 +1401,7 @@ sub generate_report {
     $idx++;
   }
 
-  if ($form->{"l_linetotal"}) {
+  if ($form->{"l_linetotal"} && !$form->{report_generator_csv_options_for_import}) {
     my $row = { map { $_ => { 'class' => 'listtotal', } } @columns };
 
     map { $row->{"linetotal$_"}->{data} = $form->format_amount(\%myconfig, $totals{$_}, 2) } @subtotal_columns;
index 9e9116e..097b637 100644 (file)
@@ -34,6 +34,7 @@
 use POSIX qw(strftime);
 use List::Util qw(sum first);
 
+use SL::AM;
 use SL::VK;
 use SL::IS;
 use SL::ReportGenerator;
@@ -149,7 +150,7 @@ sub invoice_transactions {
   $form->{title} = $locale->text('Sales Report');
 
   @columns =
-    qw(description invnumber transdate customernumber customername partnumber partsgroup country business transdate qty unit sellprice sellprice_total discount lastcost lastcost_total marge_total marge_percent employee salesman);
+    qw(description invnumber transdate customernumber customername partnumber partsgroup country business transdate qty parts_unit sellprice sellprice_total discount lastcost lastcost_total marge_total marge_percent employee salesman);
 
   my @includeable_custom_variables = grep { $_->{includeable} } @{ $cvar_configs_ic }, @{ $cvar_configs_ct };
   my @searchable_custom_variables  = grep { $_->{searchable} }  @{ $cvar_configs_ic }, @{ $cvar_configs_ct };
@@ -184,7 +185,7 @@ sub invoice_transactions {
     'invnumber'               => { 'text' => $locale->text('Invoice Number'), },
     'transdate'               => { 'text' => $locale->text('Invoice Date'), },
     'qty'                     => { 'text' => $locale->text('Quantity'), },
-    'unit'                    => { 'text' => $locale->text('Unit'), },
+    'parts_unit'              => { 'text' => $locale->text('Base unit'), },
     'sellprice'               => { 'text' => $locale->text('Sales price'), },
     'sellprice_total'         => { 'text' => $locale->text('Sales net amount'), },
     'lastcost_total'          => { 'text' => $locale->text('Purchase net amount'), },
@@ -203,7 +204,7 @@ sub invoice_transactions {
 
   map { $column_defs{$_}->{visible} = $form->{"l_$_"} eq 'Y' } @columns;
 
-  my %column_alignment = map { $_ => 'right' } qw(lastcost sellprice sellprice_total lastcost_total unit discount marge_total marge_percent qty);
+  my %column_alignment = map { $_ => 'right' } qw(lastcost sellprice sellprice_total lastcost_total parts_unit discount marge_total marge_percent qty);
 
   
   # so now the check-box "Description" is only used as switch for part description in invoice-mode
@@ -322,15 +323,20 @@ sub invoice_transactions {
 
   my $idx = 0;
 
+  my $basefactor;
+  my $all_units = AM->retrieve_all_units();
+
   foreach my $ar (@{ $form->{AR} }) {
+    $basefactor = $all_units->{$ar->{unit}}->{factor} / $all_units->{$ar->{parts_unit}}->{factor};
+    $basefactor = 1 unless $basefactor;
 
     $ar->{price_factor} = 1 unless $ar->{price_factor};
     # calculate individual sellprice
     # discount was already accounted for in db sellprice
-    $ar->{sellprice} = $ar->{sellprice} / $ar->{price_factor};
+    $ar->{sellprice} = $ar->{sellprice} / $ar->{price_factor} / $basefactor;
     $ar->{lastcost} = $ar->{lastcost} / $ar->{price_factor};
-    $ar->{sellprice_total} = $ar->{qty} * ( $ar->{fxsellprice} * ( 1 - $ar->{discount} ) ) ;
-    $ar->{lastcost_total}  = $ar->{qty} * $ar->{lastcost};
+    $ar->{sellprice_total} = $ar->{qty} * ( $ar->{fxsellprice} * ( 1 - $ar->{discount} ) ) / $ar->{price_factor};
+    $ar->{lastcost_total}  = $ar->{qty} * $ar->{lastcost} * $basefactor;
     # marge_percent wird neu berechnet, da Wert in invoice leer ist (Bug)
     $ar->{marge_percent} = $ar->{sellprice_total} ? (($ar->{sellprice_total}-$ar->{lastcost_total}) / $ar->{sellprice_total} * 100) : 0;
     # marge_total neu berechnen
@@ -415,6 +421,10 @@ sub invoice_transactions {
     # wird laufend bei jeder Position neu berechnet
     $totals{marge_percent}    = $totals{sellprice_total}    ? ( ($totals{sellprice_total} - $totals{lastcost_total}) / $totals{sellprice_total}   ) * 100 : 0;
 
+    #passt die qty an die gewählte Einheit an
+    #qty wurde bisher noch für andere Berechnungen benötigt und daher erst am Schluss überschrieben
+    $ar->{qty} *= $basefactor;
+
     map { $ar->{$_} = $form->format_amount(\%myconfig, $ar->{$_}, 2) } qw(marge_total marge_percent);
     map { $ar->{$_} = $form->format_amount(\%myconfig, $ar->{$_}, $form->{"decimalplaces"} )} qw(lastcost sellprice sellprice_total lastcost_total);
 
index b3550b2..aa37246 100644 (file)
@@ -896,7 +896,7 @@ sub generate_report {
 
     my $row_set = [ { map { $_ => { 'data' => $entry->{$_}, 'align' => $column_alignment{$_} } } @columns } ];
 
-    if (($form->{subtotal} eq 'Y')
+    if ( ($form->{subtotal} eq 'Y' && !$form->{report_generator_csv_options_for_import} )
         && (($idx == (scalar @contents - 1))
             || ($entry->{$sort_col} ne $contents[$idx + 1]->{$sort_col}))) {
 
@@ -916,7 +916,7 @@ sub generate_report {
     $idx++;
   }
 
-  if ($column_defs{stock_value}->{visible}) {
+  if ( $column_defs{stock_value}->{visible} && !$form->{report_generator_csv_options_for_import} ) {
     $report->add_separator();
 
     my $row                      = { map { $_ => { 'data' => '', 'class' => 'listsubtotal', } } @columns };
index 604b730..5f75312 100644 (file)
        background-color:#D1D1D1;\r
 }\r
 \r
-\r
+.DHTMLSuite_menuItem_textContent\r
+{\r
+  border-bottom-style: none !important;\r
+  background-color: inherit !important;\r
+  color: inherit !important;\r
+}\r
index b50805d..992a60d 100644 (file)
        background-color:#6A8CCB;       /* background color for the separator - blue */\r
 }\r
 \r
-\r
+.DHTMLSuite_menuItem_textContent\r
+{\r
+  border-bottom-style: none !important;\r
+  background-color: inherit !important;\r
+  color: inherit !important;\r
+}\r
index 7a7d76e..48d0303 100644 (file)
@@ -1187,7 +1187,7 @@ DHTMLSuite.menuItem.prototype =
                }else{          \r
                        /* Add events */\r
                        var tmpVar = this.objectIndex/1;\r
-                       this.divElement.onclick = function(e) { DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[tmpVar].__navigate(e); }\r
+                       //this.divElement.onclick = function(e) { DHTMLSuite.variableStorage.arrayOfDhtmlSuiteObjects[tmpVar].__navigate(e); }\r
                        this.divElement.onmousedown = this.__clickMenuItem;                     // on mouse down effect\r
                        this.divElement.onmouseup = this.__rolloverMenuItem;            // on mouse up effect\r
                        this.divElement.onmouseover = this.__rolloverMenuItem;          // mouse over effect\r
@@ -1264,7 +1264,17 @@ DHTMLSuite.menuItem.prototype =
                        parentEl.style.backgroundPosition = 'left center';      \r
                }\r
                if(this.modelItemRef.itemText){\r
-                       var div = document.createElement('DIV');\r
+                 var div;\r
+                 if( this.modelItemRef.url )\r
+                 {\r
+                         div = document.createElement('a');\r
+                         div.href = this.modelItemRef.url;\r
+                         div.target = this.modelItemRef.frameTarget;\r
+                         div.style.display = 'block';\r
+                       }\r
+                       else\r
+                         div = document.createElement('div');\r
+                         \r
                        div.className = 'DHTMLSuite_textContent';\r
                        div.innerHTML = this.modelItemRef.itemText;     \r
                        div.className = this.cssPrefix + 'menuItem_textContent';\r
index 9f31c8c..077f23e 100644 (file)
@@ -846,6 +846,7 @@ $self->{texts} = {
   'Filter for customer variables' => 'Filter für benutzerdefinierte Kundenvariablen',
   'Filter for item variables'   => 'Filter für benutzerdefinierte Artikelvariablen',
   'Finish'                      => 'Abschlie&szlig;en',
+  'First 20 Lines'              => 'Nur erste 20 Datensätze',
   'Fix transaction'             => 'Buchung korrigieren',
   'Fix transactions'            => 'Buchungen korrigieren',
   'Folgekonto'                  => 'Folgekonto',
@@ -879,6 +880,7 @@ $self->{texts} = {
   'From'                        => 'Von',
   'From Date'                   => 'Von',
   'Full Access'                 => 'Vollzugriff',
+  'Full Preview'                => 'Alles',
   'Full access to all functions' => 'Vollzugriff auf alle Funktionen',
   'Fwd'                         => 'Vorw&auml;rts',
   'GL Transaction'              => 'Dialogbuchung',
@@ -908,7 +910,6 @@ $self->{texts} = {
   'Hardcopy'                    => 'Seite drucken',
   'Has serial number'           => 'Hat eine Serienummer',
   'Heading'                     => 'Überschrift',
-  'Headings'                    => 'Überschriften',
   'Help'                        => 'Hilfe',
   'Help Template Variables'     => 'Hilfe zu Dokumenten-Variablen',
   'Help on column names'        => 'Hilfe zu Spaltennamen',
@@ -1050,6 +1051,7 @@ $self->{texts} = {
   'Language missing!'           => 'Sprache fehlt!',
   'Language saved!'             => 'Sprache gespeichert!',
   'Languages'                   => 'Sprachen',
+  'Last Action'                 => 'Letzte Aktivität',
   'Last Article Number'         => 'Letzte Artikelnummer',
   'Last Cost'                   => 'Einkaufspreis',
   'Last Credit Note Number'     => 'Letzte Gutschriftnummer',
@@ -1113,6 +1115,7 @@ $self->{texts} = {
   'Main sorting'                => 'Hauptsortierung',
   'Make'                        => 'Lieferant',
   'Make (with X being a number)' => 'Lieferant (X ist eine fortlaufende Zahl)',
+  'Make compatible for import'  => 'Für den Import kompatibel machen',
   'Make default profile'        => 'Zu Standardprofil machen',
   'Manage Custom Variables'     => 'Benutzerdefinierte Variablen',
   'Mandantennummer'             => 'Mandantennummer',
@@ -1270,6 +1273,7 @@ $self->{texts} = {
   'On Hand'                     => 'Auf Lager',
   'On Order'                    => 'Ist bestellt',
   'One or more Perl modules missing' => 'Ein oder mehr Perl-Module fehlen',
+  'Only Warnings and Errors'    => 'Nur Warnungen und Fehler',
   'Only due follow-ups'         => 'Nur f&auml;llige Wiedervorlagen',
   'Only shown in item mode'     => 'werden nur im Artikelmodus angezeigt',
   'Oops. No valid action found to dispatch. Please report this case to the Lx-Office team.' => 'Ups. Es wurde keine gültige Funktion zum Aufrufen gefunden. Bitte berichten Sie diesen Fall den Lx-Office-Entwicklern.',
@@ -1404,6 +1408,7 @@ $self->{texts} = {
   'Prepare bank transfer via SEPA XML' => 'Überweisung via SEPA XML vorbereiten',
   'Prepayment'                  => 'Vorauszahlung',
   'Preview'                     => 'Druckvorschau',
+  'Preview Mode'                => 'Vorschaumodus',
   'Previous transdate text'     => 'wurde gespeichert am',
   'Previous transnumber text'   => 'Letzte Buchung mit der Buchungsnummer',
   'Price'                       => 'Preis',
@@ -2278,6 +2283,7 @@ $self->{texts} = {
   'not configured'              => 'nicht konfiguriert',
   'not delivered'               => 'nicht geliefert',
   'not executed'                => 'nicht ausgeführt',
+  'not logged in'               => 'nicht eingeloggt',
   'not transferred in yet'      => 'noch nicht eingelagert',
   'not transferred out yet'     => 'noch nicht ausgelagert',
   'not yet executed'            => 'Noch nicht ausgeführt',
index f438b74..8c17ca7 100755 (executable)
@@ -27,6 +27,7 @@ use SL::DB::BackgroundJob;
 use SL::BackgroundJob::ALL;
 use SL::Form;
 use SL::Helper::DateTime;
+use SL::InstanceConfiguration;
 use SL::LXDebug;
 use SL::LxOfficeConf;
 use SL::Locale;
@@ -38,11 +39,12 @@ sub lxinit {
 
   package main;
 
-  $::lxdebug = LXDebug->new;
-  $::locale  = Locale->new($::lx_office_conf{system}->{language});
-  $::form    = Form->new;
-  $::auth    = SL::Auth->new;
-  $::request = { cgi => CGI->new({}) };
+  $::lxdebug       = LXDebug->new;
+  $::locale        = Locale->new($::lx_office_conf{system}->{language});
+  $::form          = Form->new;
+  $::auth          = SL::Auth->new;
+  $::instance_conf = SL::InstanceConfiguration->new;
+  $::request       = { cgi => CGI->new({}) };
 
   die 'cannot reach auth db'               unless $::auth->session_tables_present;
 
diff --git a/sql/Pg-upgrade2/custom_variables_sub_module_not_null.sql b/sql/Pg-upgrade2/custom_variables_sub_module_not_null.sql
new file mode 100644 (file)
index 0000000..feef5aa
--- /dev/null
@@ -0,0 +1,8 @@
+-- @tag: custom_variables_sub_module_not_null
+-- @description: sub_module in custom_variables auf NOT NULL ändern.
+-- @encoding: utf-8
+-- @depends: release_2_7_0
+UPDATE custom_variables SET sub_module = '' WHERE sub_module IS NULL;
+ALTER TABLE custom_variables ALTER COLUMN sub_module SET DEFAULT '';
+ALTER TABLE custom_variables ALTER COLUMN sub_module SET NOT NULL;
+
index 5b6e2bb..cb8fd7f 100644 (file)
@@ -11,7 +11,6 @@ use SL::LXDebug;
 use Data::Dumper;
 use SL::LxOfficeConf;
 use SL::InstanceConfiguration;
-SL::LxOfficeConf->read;
 
 sub _login {
   my $login = shift;
@@ -45,6 +44,8 @@ sub _login {
 }
 
 sub login {
+  SL::LxOfficeConf->read;
+
   my $login        = shift || $::lx_office_conf{testing}{login}        || 'demo';
   _login($login);
 }
diff --git a/t/request/post_multipart.t b/t/request/post_multipart.t
new file mode 100644 (file)
index 0000000..767807b
--- /dev/null
@@ -0,0 +1,107 @@
+use strict;
+use utf8;
+
+use lib 't';
+use lib 'modules/fallback';
+BEGIN {
+  unshift @INC, 'modules/override';
+}
+
+use Support::TestSetup;
+use Test::More tests => 2;
+use Data::Dumper;
+require Test::Deep;
+use Encode;
+
+use SL::Request;
+
+Support::TestSetup::login();
+
+open my $fh, '<', 't/request/post_multipart_1' or die "can't load test";
+my $data = do { $/ = undef; <$fh> };
+
+my $t = {};
+my $tt = {};
+
+local $ENV{CONTENT_TYPE} = 'multipart/form-data; boundary=---------------------------23281168279961';
+SL::Request::_parse_multipart_formdata($t, $tt, $data);
+
+
+my $blob = Encode::encode('utf-8', qq|\x{feff}Stunde;Montag;Dienstag;Mittwoch;Donnerstag;Freitag
+1;Mathe;Deutsch;Englisch;Mathe;Kunst
+2;Sport;Französisch;Geschichte;Sport;Geschichte
+3;Sport;"Religion ev;kath";Kunst;;Kunst|);
+
+my $t_cmp = {
+          'profile' => {
+                       'name' => undef,
+                       'type' => undef
+                     },
+          'quote_char' => undef,
+          'file' => $blob,
+          'custom_sep_char' => undef,
+          'sep_char' => undef,
+          'settings' => {
+                        'article_number_policy' => undef,
+                        'sellprice_places' => undef,
+                        'charset' => undef,
+                        'apply_buchungsgruppe' => undef,
+                        'full_preview' => undef,
+                        'parts_type' => undef,
+                        'default_unit' => undef,
+                        'default_buchungsgruppe' => undef,
+                        'duplicates' => undef,
+                        'numberformat' => undef,
+                        'sellprice_adjustment_type' => undef,
+                        'shoparticle_if_missing' => undef,
+                        'sellprice_adjustment' => undef
+                      },
+          'custom_escape_char' => undef,
+          'action_test' => undef,
+          'custom_quote_char' => undef,
+          'escape_char' => undef,
+          'action' => undef
+        };
+$t_cmp->{ATTACHMENTS}{file}{data} =  \$t_cmp->{'file'};
+
+
+is_deeply $t, $t_cmp;
+
+is_deeply $tt,
+        {
+          'profile' => {
+                       'name' => '',
+                       'type' =>'parts',
+                     },
+          'file' => undef,
+          'quote_char' => 'quote',
+          'custom_sep_char' => '',
+          'sep_char' => 'semicolon',
+          'settings' => {
+                        'article_number_policy' => 'update_prices',
+                        'sellprice_places' => 2,
+                        'charset' => 'UTF-8',
+                        'apply_buchungsgruppe' => 'all',
+                        'full_preview' => '0',
+                        'parts_type' => 'part',
+                        'default_unit' => 'g',
+                        'default_buchungsgruppe' => '815',
+                        'duplicates' => 'no_check',
+                        'numberformat' => '1.000,00',
+                        'sellprice_adjustment_type' => 'percent',
+                        'shoparticle_if_missing' => '0',
+                        'sellprice_adjustment' =>'0'
+                      },
+          'custom_escape_char' => '',
+          'action_test' => 'Test und Vorschau',
+          'ATTACHMENTS' => {
+                           'file' => {
+                                     'filename' => 'from_wikipedia.csv'
+                                   }
+                         },
+          'custom_quote_char' => '',
+          'escape_char' => 'quote',
+          'action' => 'CsvImport/dispatch',
+          'FILENAME' => 'from_wikipedia.csv'
+        };
+
diff --git a/t/request/post_multipart_1 b/t/request/post_multipart_1
new file mode 100644 (file)
index 0000000..c3ced0f
--- /dev/null
@@ -0,0 +1,101 @@
+-----------------------------23281168279961
+Content-Disposition: form-data; name="action"
+
+CsvImport/dispatch
+-----------------------------23281168279961
+Content-Disposition: form-data; name="profile.type"
+
+parts
+-----------------------------23281168279961
+Content-Disposition: form-data; name="profile.name"
+
+
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.numberformat"
+
+1.000,00
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.charset"
+
+UTF-8
+-----------------------------23281168279961
+Content-Disposition: form-data; name="sep_char"
+
+semicolon
+-----------------------------23281168279961
+Content-Disposition: form-data; name="custom_sep_char"
+
+
+-----------------------------23281168279961
+Content-Disposition: form-data; name="quote_char"
+
+quote
+-----------------------------23281168279961
+Content-Disposition: form-data; name="custom_quote_char"
+
+
+-----------------------------23281168279961
+Content-Disposition: form-data; name="escape_char"
+
+quote
+-----------------------------23281168279961
+Content-Disposition: form-data; name="custom_escape_char"
+
+
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.duplicates"
+
+no_check
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.article_number_policy"
+
+update_prices
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.sellprice_places"
+
+2
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.sellprice_adjustment"
+
+0
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.sellprice_adjustment_type"
+
+percent
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.shoparticle_if_missing"
+
+0
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.parts_type"
+
+part
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.default_buchungsgruppe"
+
+815
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.apply_buchungsgruppe"
+
+all
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.default_unit"
+
+g
+-----------------------------23281168279961
+Content-Disposition: form-data; name="settings.full_preview"
+
+0
+-----------------------------23281168279961
+Content-Disposition: form-data; name="file"; filename="from_wikipedia.csv"
+Content-Type: text/comma-separated-values
+
+Stunde;Montag;Dienstag;Mittwoch;Donnerstag;Freitag
+1;Mathe;Deutsch;Englisch;Mathe;Kunst
+2;Sport;Französisch;Geschichte;Sport;Geschichte
+3;Sport;"Religion ev;kath";Kunst;;Kunst
+-----------------------------23281168279961
+Content-Disposition: form-data; name="action_test"
+
+Test und Vorschau
+-----------------------------23281168279961--
index 2c625da..17778c2 100644 (file)
@@ -16,6 +16,7 @@
      <th class="listtop">[% 'Language' | $T8 %]</th>
      <th class="listtop">[% 'Dataset' | $T8 %]</th>
      <th class="listtop">[% 'Host' | $T8 %]</th>
+     <th class="listtop">[% 'Last Action' | $T8 %]</th>
 <!-- <th class="listtop">[% 'Driver' | $T8 %]</th> -->
     </tr>
 
       <td>&nbsp;[% HTML.escape(row.countrycode) %]</td>
       <td>&nbsp;[% HTML.escape(row.dbname) %]</td>
       <td>&nbsp;[% IF row.dbhost %][% HTML.escape(row.dbhost) %][% ELSE %]localhost[% END %]</td>
+      <td>&nbsp;
+        [% IF( row.last_action ) %]
+          [% HTML.escape(row.last_action) %]
+        [% ELSE %]
+          [% 'not logged in' | $T8 %]
+        [% END %]</td>
 <!--  <td>&nbsp;[% HTML.escape(row.dbdriver) %]</td> -->
      </tr>
     [% END %]
diff --git a/templates/webpages/ap/form_footer.html b/templates/webpages/ap/form_footer.html
new file mode 100644 (file)
index 0000000..466ab34
--- /dev/null
@@ -0,0 +1,70 @@
+[%- USE T8 %]
+[%- USE HTML %]
+[%- USE L %]
+[%- USE LxERP %]
+
+[%- IF (num_follow_ups && num_due) %]
+  <p>[% 'There are #1 unfinished follow-ups of which #2 are due.' | $T8(num_follow_ups, num_due) %]</p>
+[%- END %]
+
+<input name=callback type=hidden value="[% callback | html %]">
+<input name=gldate type=hidden value="[% gldate | html %]">
+<input type=hidden name=draft_id value="[% draft_id %]">
+<input type=hidden name=draft_description value="[% draft_description | html %]">
+
+[%- IF ( !id && draft_id ) %]
+  [% L.checkbox_tag('remove_draft', checked=remove_draft, label=LxERP.t8('Remove draft when posting')) %]
+  <br>
+[%- END %]
+
+<br>
+
+<input class="submit" type="submit" name="action" id="update_button" value="[% 'Update' | $T8 %]">
+
+[%- IF id %]
+  [%- IF radier %]
+    <input class=submit type=submit name=action value="[% 'Post' | $T8 %]">
+    <input class=submit type=submit name=action value="[% 'Delete' | $T8 %]">
+  [%- END %]
+
+  [%- IF show_storno %]
+    <input class=submit type=submit name=action value="[% 'Storno' | $T8 %]">
+  [%- END %]
+
+  <input class=submit type=submit name=action value="[% 'Post Payment' | $T8 %]">
+  <input class=submit type=submit name=action value="[% 'Use As Template' | $T8 %]">
+  <input type="button" class="submit" onclick="follow_up_window()" value="[% 'Follow-Up' | $T8 %]">
+
+[%- ELSIF show_post_draft %]
+    <input class=submit type=submit name=action value="[% 'Post' | $T8 %]">
+    <input type="submit" name="action" value="[% 'Save draft' | $T8 %]" class="submit">
+[%- END %]
+
+[%- IF id %]
+  <input type="submit" onclick="set_history_window([% id %]);" name="history" id="history" value="[% 'history' | $T8 %]">
+  <input type="submit" name="action" value="[% 'mark as paid' | $T8 %]">
+[%- END %]
+
+</form>
+
+<script type="text/javascript">
+<!--
+function set_duedate() {
+   $.ajax({
+     url: 'is.pl?action=set_duedate',
+     data: {
+       invdate: $('#transdate').val(),
+       vendor_id: $('[name=vendor_id]').val(),
+     },
+     dataType: 'text',
+     success: function(data) {
+       $('#duedate').val(data);
+     }
+   });
+ }
+//-->
+</script>
+
+
+</body>
+</html>
index fe088e2..01fe4d9 100644 (file)
@@ -25,6 +25,7 @@
   </tr>
 
   [%- FOREACH row = SELF.data %]
+  [%- IF (SELF.profile.get('full_preview') == 2) || ((SELF.profile.get('full_preview') == 1) && (row.errors.size || row.information.size)) || ((SELF.profile.get('full_preview') == 0) && (loop.count < 21)) %]
   <tr class="[% IF row.errors.size %]redrow[% ELSE %]listrow[% END %][% loop.count % 2 %]">
    [%- FOREACH method = SELF.info_headers.methods %]
     <td>[%- HTML.escape(row.info_data.$method) %]</td>
@@ -41,6 +42,7 @@
    </td>
   </tr>
   [%- END %]
+  [%- END %]
 
  </table>
 [%- END %]
index b146465..e835ed5 100644 (file)
  [%- INCLUDE 'csv_import/_form_customers_vendors.html' %]
 [%- END %]
 
+   <tr>
+    <th align="right">[%- LxERP.t8('Preview Mode') %]:</th>
+    <td colspan="10">
+      [% L.radio_button_tag('settings.full_preview', value=2, checked=SELF.profile.get('full_preview')==2, label=LxERP.t8('Full Preview')) %]
+      [% L.radio_button_tag('settings.full_preview', value=1, checked=SELF.profile.get('full_preview')==1, label=LxERP.t8('Only Warnings and Errors')) %]
+      [% L.radio_button_tag('settings.full_preview', value=0, checked=!SELF.profile.get('full_preview'),   label=LxERP.t8('First 20 Lines')) %]
+    </td>
+   </tr>
+
    <tr>
     <th align="right">[%- LxERP.t8('Import file') %]:</th>
     <td colspan="10">[% L.input_tag('file', '', type => 'file', accept => '*') %]</td>
index f6847d9..2c0fa1b 100644 (file)
@@ -1,3 +1,7 @@
+[%- IF SAVED_MESSAGE %]
+  <p>[% SAVED_MESSAGE %]</p>
+[%- END %]
+
 [%- IF OPTIONS.size %]
 <p>
  [%- FOREACH option = OPTIONS %]
index 996adfc..70c39af 100644 (file)
@@ -61,6 +61,8 @@
     <td valign="top">
      <input type="checkbox" name="report_generator_csv_options_headers" id="report_generator_csv_options_headers" value="1" checked>
      <label for="report_generator_csv_options_headers">[% 'Include column headings' | $T8 %]</label>
+     <input type="checkbox" name="report_generator_csv_options_for_import" id="report_generator_csv_options_for_import" value="1">
+     <label for="report_generator_csv_options_for_import">[% 'Make compatible for import' | $T8 %]</label>
     </td>
    </tr>
 
index 77f1d38..25ec860 100644 (file)
@@ -29,8 +29,8 @@
                <option value="month">[% 'Month' | $T8 %]</option>
                </select>
              </td>
-             <td align=left><input name="l_headers_mainsort" class=checkbox type=checkbox value="Y" checked> [% 'Heading' | $T8 %]</td>
-             <td align=left><input name="l_subtotal_mainsort" class=checkbox type=checkbox value="Y" checked> [% 'Subtotal' | $T8 %]</td>
+             <td align=left><input name="l_headers_mainsort" class=checkbox type=checkbox value=Y checked> [% 'Heading' | $T8 %]</td>
+             <td align=left><input name="l_subtotal_mainsort" class=checkbox type=checkbox value=Y checked> [% 'Subtotal' | $T8 %]</td>
              </tr>
              <tr>
                <td align="right">[% 'Secondary sorting' | $T8 %]</td>
              </tr>
            <tr>
            <th align="right">[% 'Item mode' | $T8 %]</th>
-           <td colspan="3" align=left><input name="l_parts" class=checkbox type=checkbox value="Y"> ([%'Show items from invoices individually' | $T8 %]) </td>
+           <td colspan="3" align=left><input name="l_parts" class=checkbox type=checkbox value=Y> ([%'Show items from invoices individually' | $T8 %]) </td>
           </tr>
           <tr> 
            <th align="right">
              [% 'Total sum' | $T8 %]
            </th>
-           <td colspan="1" align=left><input name="l_total" class=checkbox type=checkbox value="Y" checked></td>
+           <td colspan="1" align=left><input name="l_total" class=checkbox type=checkbox value=Y checked></td>
             <td align="right" nowrap>[% 'Decimalplaces' | $T8 %]: </td>
             <td colspan="2"><input name="decimalplaces" size="2" value="2"></td>
           </tr>
            <td colspan="4">([% 'averaged values, in invoice mode only useful when filtered by a part' | $T8 %])</td>
           </tr>
           <tr>
-           <td align=left><input name="l_qty" class=checkbox type=checkbox value="Y" checked>[% 'Quantity' | $T8 %]</td>
-           <td align=left><input name="l_discount" class=checkbox type=checkbox value="Y">[% 'Discount' | $T8 %]</td>
+           <td align=left><input name="l_qty" class=checkbox type=checkbox value=Y checked>[% 'Quantity' | $T8 %]</td>
+           <td align=left><input name="l_discount" class=checkbox type=checkbox value=Y>[% 'Discount' | $T8 %]</td>
            <td></td>
            <td colspan="4">([% 'averaged values, in invoice mode only useful when filtered by a part' | $T8 %])</td>
           </tr>
            <td align=left><input name="l_description" class=checkbox type=checkbox value=Y checked>[% 'Description' | $T8 %]</td>
            <td align=left><input name="l_partnumber" class=checkbox type=checkbox value=Y>[% 'Part Number' | $T8 %]</td>
            <td align=left><input name="l_invnumber" class=checkbox type=checkbox value=Y>[% 'Invnumber' | $T8 %]</td>
-           <td align=left><input name="l_transdate" class=checkbox type=checkbox value="Y">[% 'Invdate' | $T8 %]</td>
+           <td align=left><input name="l_transdate" class=checkbox type=checkbox value=Y>[% 'Invdate' | $T8 %]</td>
           </tr>
           <tr>
-           <td align=left><input name="l_unit" class=checkbox type=checkbox value="Y">[% 'Unit' | $T8 %]</td>
+           <td align=left><input name="l_parts_unit" class=checkbox type=checkbox value=Y>[% 'Base unit' | $T8 %]</td>
            <td align=left><input name="l_partsgroup" class=checkbox type=checkbox value=Y>[% 'Group' | $T8 %]</td>
            <td align=left><input name="l_salesman" class=checkbox type=checkbox value=Y>[% 'Salesperson' | $T8 %]</td>
            <td align=left><input name="l_employee" class=checkbox type=checkbox value=Y>[% 'Employee' | $T8 %]</td>