Optionale minimale Excel-Unterstützung für Druckvorlagen (Austausch von Platzhalter...
authorJoachim Zach <joachim@lx-office-hosting.de>
Mon, 26 Apr 2010 07:26:44 +0000 (09:26 +0200)
committerJoachim Zach <joachim@lx-office-hosting.de>
Mon, 26 Apr 2010 07:26:44 +0000 (09:26 +0200)
SL/CT.pm
SL/Form.pm
SL/Template.pm
bin/mozilla/io.pl
config/lx-erp.conf
doc/changelog
doc/excel_templates.txt [new file with mode: 0644]

index a661e8c..9089aab 100644 (file)
--- a/SL/CT.pm
+++ b/SL/CT.pm
@@ -1089,4 +1089,80 @@ sub get_bank_info {
   return $result;
 }
 
+sub parse_excel_file {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form) = @_;
+  my $locale = $main::locale;
+
+  $form->{formname}   = 'sales_quotation';
+  $form->{type}   = 'sales_quotation';
+  $form->{format} = 'excel';
+  $form->{media}  = 'screen';
+  $form->{quonumber} = 1;
+
+
+  # $form->{"notes"} will be overridden by the customer's/vendor's "notes" field. So save it here.
+  $form->{ $form->{"formname"} . "notes" } = $form->{"notes"};
+
+  my $inv                  = "quo";
+  my $due                  = "req";
+  $form->{"${inv}date"} = $form->{transdate};
+  $form->{label}        = $locale->text('Quotation');
+  my $numberfld            = "sqnumber";
+  my $order                = 1;
+
+  # assign number
+  $form->{what_done} = $form->{formname};
+
+  map({ delete($form->{$_}); } grep(/^cp_/, keys(%{ $form })));
+
+  my $output_dateformat = $myconfig->{"dateformat"};
+  my $output_numberformat = $myconfig->{"numberformat"};
+  my $output_longdates = 1;
+
+  # map login user variables
+  map { $form->{"login_$_"} = $myconfig->{$_} } ("name", "email", "fax", "tel", "company");
+
+  # format item dates
+  for my $field (qw(transdate_oe deliverydate_oe)) {
+    map {
+      $form->{$field}[$_] = $locale->date($myconfig, $form->{$field}[$_], 1);
+    } 0 .. $#{ $form->{$field} };
+  }
+
+  if ($form->{shipto_id}) {
+    $form->get_shipto($myconfig);
+  }
+
+  $form->{notes} =~ s/^\s+//g;
+
+  $form->{templates} = $myconfig->{templates};
+
+  delete $form->{printer_command};
+
+  $form->get_employee_info($myconfig);
+
+  my ($cvar_date_fields, $cvar_number_fields) = CVar->get_field_format_list('module' => 'CT', 'prefix' => 'vc_');
+
+  if (scalar @{ $cvar_date_fields }) {
+    format_dates($output_dateformat, $output_longdates, @{ $cvar_date_fields });
+  }
+
+  while (my ($precision, $field_list) = each %{ $cvar_number_fields }) {
+    reformat_numbers($output_numberformat, $precision, @{ $field_list });
+  }
+
+  $form->{excel} = 1;
+  my $extension            = 'xls';
+
+  my $form->{IN}         = "$form->{formname}.${extension}";
+
+  delete $form->{OUT};
+
+  $form->parse_template($myconfig, $main::userspath);
+
+  $main::lxdebug->leave_sub();
+}
+
 1;
index 2ba19b6..11f88ad 100644 (file)
@@ -1178,6 +1178,10 @@ sub parse_template {
   } elsif ( $self->{"format"} =~ /elstertaxbird/i ) {
     $template = XMLTemplate->new($self->{"IN"}, $self, $myconfig, $userspath);
 
+  } elsif ( $self->{"format"} =~ /excel/i ) {
+    $template = ExcelTemplate->new($self->{"IN"}, $self, $myconfig, $userspath);
+    $ext_for_format = 'xls';
+
   } elsif ( defined $self->{'format'}) {
     $self->error("Outputformat not defined. This may be a future feature: $self->{'format'}");
 
@@ -1385,6 +1389,7 @@ sub get_extension_for_format {
   my $extension = $self->{format} =~ /pdf/i          ? ".pdf"
                 : $self->{format} =~ /postscript/i   ? ".ps"
                 : $self->{format} =~ /opendocument/i ? ".odt"
+                : $self->{format} =~ /excel/i        ? ".xls"
                 : $self->{format} =~ /html/i         ? ".html"
                 :                                      "";
 
index 3556dc4..7f4d275 100644 (file)
@@ -1477,4 +1477,95 @@ sub uses_temp_file {
   return 1;
 }
 
+
+##########################################################
+####
+#### ExcelTemplate
+####
+##########################################################
+
+package ExcelTemplate;
+
+use vars qw(@ISA);
+
+@ISA = qw(SimpleTemplate);
+
+sub new {
+  my $type = shift;
+
+  my $self = $type->SUPER::new(@_);
+
+  return $self;
+}
+sub _init {
+  my $self = shift;
+
+  $self->{source}    = shift;
+  $self->{form}      = shift;
+  $self->{myconfig}  = shift;
+  $self->{userspath} = shift;
+
+  $self->{error}     = undef;
+
+  $self->set_tag_style('<<', '>>');
+}
+
+sub get_mime_type() {
+  my ($self) = @_;
+
+  return "application/msexcel";
+}
+
+sub uses_temp_file {
+  return 1;
+}
+
+sub parse {
+  $main::lxdebug->enter_sub();
+
+  my $self   = shift;
+  local *OUT = shift;
+  my $form   = $self->{"form"};
+
+  open(IN, "$form->{templates}/$form->{IN}") or do { $self->{"error"} = "$!"; return 0; };
+  my @lines = <IN>;
+  close IN;
+
+  my $contents = join("", @lines);
+  my @indices;
+  $contents =~ s{
+    $self->{tag_start} [<]* (\s?) [<>\s]* ([\w\s]+) [<>\s]* $self->{tag_end}
+  }{
+    $self->format_vars(align_right => $1 ne '', varstring => $2, length => length($&), indices =>  \@indices)
+  }egx;
+
+  if (!defined($contents)) {
+    $main::lxdebug->leave_sub();
+    return 0;
+  }
+
+  print OUT $contents;
+
+  $main::lxdebug->leave_sub();
+  return 1;
+}
+
+sub format_vars {
+  my ($self, %params) = @_;
+  my $form            = $self->{"form"};
+  my @indices         = @{ $params{indices} };
+  my $align_right     = $params{align_right};
+  my $varstring       = $params{varstring};
+  my $length          = $params{length};
+
+  $varstring =~ s/(\w+)/ $self->_get_loop_variable($1, 0, @indices) /eg;
+  my $old_string=$varstring;
+  my $new_string = sprintf "%*s", ($align_right ? 1 : -1 ) * $length, $varstring;
+  if (!defined($new_string) || $new_string eq ''){
+    $main::lxdebug->message(0, 'varstring' . $varstring . "old" . $old_string); 
+    #  return substr $varstring, ($align_right ? (0, $length) : -$length);
+  }
+  return substr $new_string, ($align_right ? (0, $length) : -$length);
+}
+
 1;
index ce7ce78..44ddc16 100644 (file)
@@ -1184,7 +1184,9 @@ sub print_options {
     (!$options{no_html}) ?
       opthash("html", $form->{DF}{html}, "HTML") : undef,
     ($main::opendocument_templates && !$options{no_opendocument}) ?
-      opthash("opendocument",        $form->{DF}{opendocument},        $locale->text("OpenDocument/OASIS")) : undef;
+      opthash("opendocument",        $form->{DF}{opendocument},        $locale->text("OpenDocument/OASIS")) : undef,
+    ($main::excel_templates && !$options{no_excel}) ?
+      opthash("excel",               $form->{DF}{excel},               $locale->text("Excel")) : undef;
 
   push @LANGUAGE_ID,
     map { opthash($_->{id}, ($_->{id} eq $form->{language_id} ? 'selected' : ''), $_->{description}) } +{}, @{ $form->{languages} }
@@ -1592,6 +1594,9 @@ sub print_form {
   } elsif ($form->{"format"} =~ /opendocument/) {
     $form->{opendocument} = 1;
     $extension            = 'odt';
+  } elsif ($form->{"format"} =~ /excel/) {
+    $form->{excel} = 1;
+    $extension            = 'xls';
   }
 
   my $email_extension = '_email' if (($form->{media} eq 'email') && (-f "$myconfig{templates}/$form->{formname}_email$form->{language}${printer_code}.${extension}"));
index 91bfc83..300d1a7 100644 (file)
@@ -42,6 +42,7 @@ $ENV{PERL5LIB} .= ":/sw/lib/perl5";
 $webdav = 0;
 $lizenzen = 1;
 $vertreter = 0;
+$excel_templates = 0; # Minimalunterstützung für Excel-Druckvorlagen
 
 # Zeige Felder für Mindesthaltbarkeitsdatum
 $show_best_before = 0;
index 8b25926..67a492c 100644 (file)
@@ -2,6 +2,21 @@
 # Veränderungen von Lx-Office ERP #
 ###################################
 
+
+
+
+
+
+
+
+
+
+  Kleinere neue Features und Detailverbesserungen:
+
+  - Druckvorlage optional auf Excel erweitert, um Variablen die sich nicht in foreach-Schleifen
+    befinden anzuzeigen (s.a.: doc/excel_templates.txt).
+
+
 2010-03-24 - Release 2.6.1
 
   Größere neue Features:
diff --git a/doc/excel_templates.txt b/doc/excel_templates.txt
new file mode 100644 (file)
index 0000000..f081862
--- /dev/null
@@ -0,0 +1,79 @@
+Table of Contents
+-----------------
+
+Inhalt der Anleitung
+1 Zusammenfassung
+2 Bedienung
+3 Exceltemplate Syntax
+4 Einschränkungen
+
+
+
+Zusammenfassung
+---------------
+
+Dieses Dokument beschreibt den Mechanismus, mit dem Exceltemplates abgearbeitet
+werden, und die Einschränkungen die damit einhergehen.
+
+
+
+Bedienung
+---------
+
+Der Excel Mechanismus muss in der Konfigurationsdatei aktiviert werden. Die
+Konfigurationsoption heißt:
+
+  $excel_templates = 1;
+
+Eine Excelvorlage kann dann unter dem Namen einer beliebigen anderen Vorlage mit
+der Endung .xls gespeichert werden. In den normalen Verkaufsmasken taucht nun
+"Excel" als auswählbares Format auf, und kann von da an bnutzt weren wie Latex
+oder OpenOffice Vorlagen.
+
+Der Sonderfall der Angebote aus der Kundenmaske ist ebenfalls eine
+Angebotsvorlage, und wird unter dem internen Namen der Angebote
+"sales_quotation.xls" gespeichert.
+
+
+
+Exceltemplate Syntax
+--------------------
+
+Einfache Syntax:  <<varname>>
+
+Wobei "<<" und ">>" die Delimiter sind. Da Excel auf festen Breiten besteht,
+kann der Tag künstlich verlängert werden, indem weitere "<" oder ">" gegefügt
+werden. Der Tag muss nicht symmetrisch sein.
+
+Beispiel: <<<<<varname>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+Um die Limitierung der festen Breite zu reduzieren, können weitere Variablen in
+einem Block interpoliert werden. Whitespace wird dazwishen dann erhalten.
+
+Beispiel: <<<<<varname1 varname2   varname3>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+Die Variablen werden interpoliert, und linksbündig mit Leerzeichen auf die
+gewünschte Länge aufgefüllt. Ist der String zu lang, werden überzählige Zeichen
+abgeschnitten.
+
+Es ist ausserdem möglich Daten rechtsbündig darzustellen, wenn der Block mit
+einem Leerzeichen anfängt.
+
+Beispiel:  <<<<<<            varname>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+würde rechtsbündig triggern. Wenn bei rechtsbündiger Ausrichtung Text
+abgeschnitten werden muss, wird er vom linken Ende entfernt.
+
+
+
+Einschränkungen
+---------------
+
+Das Excelformat bis 2002 ist ein binäres Format, und kann nicht mit vertretbarem
+Aufwand editiert werden. Der Templatemechanismus beschränkt sich daher darauf,
+Textstellen _exakt_ durch einen anderen Text zu ersetzen.
+
+Aus dem gleichen Grund sind die Templatekonstrukte <% if %> und <% foreach %>
+nicht vorhanden. Der Delimiter <% %> kommt in den Headerinformationen evtl vor,
+deshalb wurde auf den sichereren "<<"/">>" gewechselt.
+