Bugfix 356, bei Zahlenformat 1000.00 wurden nachfolgende Nullen abgeschnitten
[kivitendo-erp.git] / SL / Form.pm
index e7fea51..b97833e 100644 (file)
 package Form;
 
 use HTML::Template;
+use SL::Menu;
 
 sub _input_to_hash {
-  $main::lxdebug->enter_sub();
+  $main::lxdebug->enter_sub(2);
 
   my $input = $_[0];
   my %in    = ();
@@ -51,13 +52,13 @@ sub _input_to_hash {
     $in{$name} = unescape(undef, $value);
   }
 
-  $main::lxdebug->leave_sub();
+  $main::lxdebug->leave_sub(2);
 
   return %in;
 }
 
 sub _request_to_hash {
-  $main::lxdebug->enter_sub();
+  $main::lxdebug->enter_sub(2);
 
   my ($input) = @_;
   my ($i,        $loc,  $key,    $val);
@@ -108,11 +109,11 @@ sub _request_to_hash {
       }
     }
 
-    $main::lxdebug->leave_sub();
+    $main::lxdebug->leave_sub(2);
     return %ATTACH;
 
       } else {
-    $main::lxdebug->leave_sub();
+    $main::lxdebug->leave_sub(2);
     return _input_to_hash($input);
   }
 }
@@ -142,7 +143,7 @@ sub new {
   $self->{action} = lc $self->{action};
   $self->{action} =~ s/( |-|,|#)/_/g;
 
-  $self->{version}   = "2.2.0";
+  $self->{version}   = "2.3.0";
 
   $main::lxdebug->leave_sub();
 
@@ -162,7 +163,7 @@ sub debug {
 }
 
 sub escape {
-  $main::lxdebug->enter_sub();
+  $main::lxdebug->enter_sub(2);
 
   my ($self, $str, $beenthere) = @_;
 
@@ -173,13 +174,13 @@ sub escape {
 
   $str =~ s/([^a-zA-Z0-9_.-])/sprintf("%%%02x", ord($1))/ge;
 
-  $main::lxdebug->leave_sub();
+  $main::lxdebug->leave_sub(2);
 
   return $str;
 }
 
 sub unescape {
-  $main::lxdebug->enter_sub();
+  $main::lxdebug->enter_sub(2);
 
   my ($self, $str) = @_;
 
@@ -188,7 +189,7 @@ sub unescape {
 
   $str =~ s/%([0-9a-fA-Z]{2})/pack("c",hex($1))/eg;
 
-  $main::lxdebug->leave_sub();
+  $main::lxdebug->leave_sub(2);
 
   return $str;
 }
@@ -197,7 +198,7 @@ sub quote {
   my ($self, $str) = @_;
 
   if ($str && !ref($str)) {
-    $str =~ s/"/"/g;
+    $str =~ s/\"/"/g;
   }
 
   $str;
@@ -208,7 +209,7 @@ sub unquote {
   my ($self, $str) = @_;
 
   if ($str && !ref($str)) {
-    $str =~ s/"/"/g;
+    $str =~ s/"/\"/g;
   }
 
   $str;
@@ -242,12 +243,8 @@ sub error {
 
   if ($ENV{HTTP_USER_AGENT}) {
     $msg =~ s/\n/<br>/g;
-
-    $self->header;
     $self->show_generic_error($msg);
 
-    die "Error: $msg\n";
-
   } else {
 
     if ($self->{error_function}) {
@@ -373,7 +370,7 @@ function fokus(){document.$self->{fokus}.focus();}
     }
 
     #Set Calendar
-    $jsscript = "";
+    my $jsscript = "";
     if ($self->{jsscript} == 1) {
 
       $jsscript = qq|
@@ -410,7 +407,6 @@ function fokus(){document.$self->{fokus}.focus();}
   $main::lxdebug->leave_sub();
 }
 
-use Data::Dumper;
 sub parse_html_template {
   $main::lxdebug->enter_sub();
 
@@ -461,6 +457,28 @@ sub parse_html_template {
       "<br><em>DEBUG INFORMATION:</em><pre>" . $additional_params->{"DEBUG"} . "</pre>";
   }
 
+  if (%main::myconfig) {
+    map({ $additional_params->{"myconfig_${_}"} = $main::myconfig{$_}; } keys(%main::myconfig));
+    my $jsc_dateformat = $main::myconfig{"dateformat"};
+    $jsc_dateformat =~ s/d+/\%d/gi;
+    $jsc_dateformat =~ s/m+/\%m/gi;
+    $jsc_dateformat =~ s/y+/\%Y/gi;
+    $additional_params->{"myconfig_jsc_dateformat"} = $jsc_dateformat;
+  }
+
+  $additional_params->{"conf_jscalendar"} = $main::jscalendar;
+  $additional_params->{"conf_lizenzen"} = $main::lizenzen;
+  $additional_params->{"conf_latex_templates"} = $main::latex;
+  $additional_params->{"conf_opendocument_templates"} = $main::opendocument_templates;
+
+  my $menu;
+  if (-f $self->{"login"} . "_menu.ini") {
+    $menu = Menu->new($self->{"login"} . "_menu.ini");
+  } else {
+    $menu = Menu->new("menu.ini");
+  }
+  $menu->generate_acl("", $additional_params);
+
   my @additional_param_names = keys(%{$additional_params});
 
   foreach my $key ($template->param()) {
@@ -485,7 +503,23 @@ sub show_generic_error {
   $add_params->{"title"} = $title if ($title);
   $self->{"label_error"} = $error;
 
+  $self->header();
   print($self->parse_html_template("generic/error", $add_params));
+
+  die("Error: $error\n");
+}
+
+sub show_generic_information {
+  my ($self, $error, $title) = @_;
+
+  my $add_params = {};
+  $add_params->{"title"} = $title if ($title);
+  $self->{"label_information"} = $error;
+
+  $self->header();
+  print($self->parse_html_template("generic/information", $add_params));
+
+  die("Information: $error\n");
 }
 
 # write Trigger JavaScript-Code ($qty = quantity of Triggers)
@@ -536,7 +570,7 @@ sub write_trigger {
       );
        |;
   }
-  $jsscript = qq|
+  my $jsscript = qq|
        <script type="text/javascript">
        <!--| . join("", @triggers) . qq|//-->
         </script>
@@ -576,115 +610,49 @@ sub sort_columns {
 
   return @columns;
 }
-
+#
 sub format_amount {
-  $main::lxdebug->enter_sub();
+  $main::lxdebug->enter_sub(2);
 
   my ($self, $myconfig, $amount, $places, $dash) = @_;
+  my $neg = ($amount =~ s/-//);
 
-  #Workaround for $format_amount calls without $places
-  if (!defined $places) {
-    (my $dec) = ($amount =~ /\.(\d+)/);
-    $places = length $dec;
-  }
-
-  if ($places =~ /\d/) {
-    $amount = $self->round_amount($amount, $places);
-  }
-
-  # is the amount negative
-  my $negative = ($amount < 0);
-  my $fillup   = "";
-
-  if ($amount != 0) {
-    if ($myconfig->{numberformat} && ($myconfig->{numberformat} ne '1000.00'))
-    {
-      my ($whole, $dec) = split /\./, "$amount";
-      $whole =~ s/-//;
-      $amount = join '', reverse split //, $whole;
-      $fillup = "0" x ($places - length($dec));
-
-      if ($myconfig->{numberformat} eq '1,000.00') {
-        $amount =~ s/\d{3,}?/$&,/g;
-        $amount =~ s/,$//;
-        $amount = join '', reverse split //, $amount;
-        $amount .= "\.$dec" . $fillup if ($places ne '' && $places * 1 != 0);
-      }
-
-      if ($myconfig->{numberformat} eq '1.000,00') {
-        $amount =~ s/\d{3,}?/$&./g;
-        $amount =~ s/\.$//;
-        $amount = join '', reverse split //, $amount;
-        $amount .= ",$dec" . $fillup if ($places ne '' && $places * 1 != 0);
-      }
+  $amount = $self->round_amount($amount, $places) if ($places =~ /\d/);
 
-      if ($myconfig->{numberformat} eq '1000,00') {
-        $amount = "$whole";
-        $amount .= ",$dec" . $fillup if ($places ne '' && $places * 1 != 0);
-      }
+  my @d = map { s/\d//g; reverse split // } my $tmp = $myconfig->{numberformat}; # get delim chars
+  my @p = split /\./, $amount ; # split amount at decimal point
 
-      if ($dash =~ /-/) {
-        $amount = ($negative) ? "($amount)" : "$amount";
-      } elsif ($dash =~ /DRCR/) {
-        $amount = ($negative) ? "$amount DR" : "$amount CR";
-      } else {
-        $amount = ($negative) ? "-$amount" : "$amount";
-      }
-    }
-  } else {
-    if ($dash eq "0" && $places) {
-      if ($myconfig->{numberformat} eq '1.000,00') {
-        $amount = "0" . "," . "0" x $places;
-      } else {
-        $amount = "0" . "." . "0" x $places;
-      }
-    } else {
-      $amount = ($dash ne "") ? "$dash" : "0";
-    }
-  }
-
-  $main::lxdebug->leave_sub();
+  $p[0] =~ s/\B(?=(...)*$)/$d[1]/g if $d[1]; # add 1,000 delimiters
 
+  $amount = $p[0];
+  $amount .= $d[0].$p[1].(0 x ($places - length $p[1])) if ($places || $p[1] ne '');
+  $amount = ($neg) ? "($amount)"  : "$amount"    if $dash =~ ?-?;
+  $amount = ($neg) ? "$amount DR" : "$amount CR" if $dash =~ ?DRCR?;
+  $amount = ($neg) ? "-$amount"   : "$amount"    if $dash =~ ??;
+  reset;
+  
+  $main::lxdebug->leave_sub(2);
   return $amount;
 }
-
+#
 sub parse_amount {
-  $main::lxdebug->enter_sub();
+  $main::lxdebug->enter_sub(2);
 
   my ($self, $myconfig, $amount) = @_;
-  $main::lxdebug->message(LXDebug::DEBUG2, "Start amount: $amount");
 
   if ($myconfig->{in_numberformat} == 1) {
-
     # Extra input number format 1000.00 or 1000,00
-    $main::lxdebug->message(LXDebug::DEBUG2,
-              "in_numberformat: " . $main::locale->text('1000,00 or 1000.00'));
     $amount =~ s/,/\./g;
-
-    #$main::lxdebug->message(LXDebug::DEBUG2, "1.Parsed Number: $amount") if ($amount);
     $amount = scalar reverse $amount;
-
-    #$main::lxdebug->message(LXDebug::DEBUG2, "2.Parsed Number: $amount") if ($amount);
     $amount =~ s/\./DOT/;
-
-    #$main::lxdebug->message(LXDebug::DEBUG2, "3.Parsed Number: $amount") if ($amount);
     $amount =~ s/\.//g;
-
-    #$main::lxdebug->message(LXDebug::DEBUG2, "4.Parsed Number: $amount") if ($amount);
     $amount =~ s/DOT/\./;
-
-    #$main::lxdebug->message(LXDebug::DEBUG2, "5.Parsed Number:" . $amount) if ($amount);
     $amount = scalar reverse $amount;
-    $main::lxdebug->message(LXDebug::DEBUG2,
-                            "Parsed amount:" . $amount . "\n");
-
+    $main::lxdebug->leave_sub(2);
     return ($amount * 1);
-
   }
-  $main::lxdebug->message(LXDebug::DEBUG2,
-              "in_numberformat: " . $main::locale->text('equal Outputformat'));
-  $main::lxdebug->message(LXDebug::DEBUG2,
-                          " = numberformat: $myconfig->{numberformat}");
+
   if (   ($myconfig->{numberformat} eq '1.000,00')
       || ($myconfig->{numberformat} eq '1000,00')) {
     $amount =~ s/\.//g;
@@ -692,20 +660,18 @@ sub parse_amount {
   }
 
   if ($myconfig->{numberformat} eq "1'000.00") {
-    $amount =~ s/'//g;
+    $amount =~ s/\'//g;
   }
 
   $amount =~ s/,//g;
 
-  $main::lxdebug->message(LXDebug::DEBUG2, "Parsed amount:" . $amount . "\n")
-    if ($amount);
-  $main::lxdebug->leave_sub();
+  $main::lxdebug->leave_sub(2);
 
   return ($amount * 1);
 }
 
 sub round_amount {
-  $main::lxdebug->enter_sub();
+  $main::lxdebug->enter_sub(2);
 
   my ($self, $amount, $places) = @_;
   my $round_amount;
@@ -719,7 +685,7 @@ sub round_amount {
   $amount = $amount * (10**($places));
   $round_amount = int($amount + .5 * ($amount <=> 0)) / (10**($places));
 
-  $main::lxdebug->leave_sub();
+  $main::lxdebug->leave_sub(2);
 
   return $round_amount;
 
@@ -737,9 +703,13 @@ sub parse_template {
   my ($current_page, $current_line, $current_row) = (1, 1, 0);
   my $pagebreak = "";
   my $sum       = 0;
-
   # } Moritz Bunkus
 
+  # The old fixed notation of <%variable%> is changed to a new dynamic one.
+  my ${pre} = '<%'; # Variable Prefix, must be regex save!
+  my ${suf} = '%>'; # Variable Suffix, must be regex save!
+
+
   # Make sure that all *notes* (intnotes, partnotes_*, notes etc) are converted to markup correctly.
   $self->format_string(grep(/notes/, keys(%{$self})));
 
@@ -747,7 +717,7 @@ sub parse_template {
   $self->{"notes"} = $self->{ $self->{"formname"} . "notes" };
 
   map({ $self->{"employee_${_}"} = $myconfig->{$_}; }
-      qw(email tel fax name signature));
+      qw(email tel fax name signature company address businessnumber));
 
   open(IN, "$self->{templates}/$self->{IN}")
     or $self->error("$self->{IN} : $!");
@@ -778,36 +748,45 @@ sub parse_template {
   $two_passes = 0;
 
   # first we generate a tmpfile
-  # read file and replace <%variable%>
+  # read file and replace ${pre}variable${suf}
   while ($_ = shift) {
 
     $par = "";
     $var = $_;
-
+    # Switch ${pre}analyse${suf} for template checking
+    # If ${pre}analyse${suf} is set in the template, you'll find the 
+    # parsed output in the user Directory for analysing
+    # Latex errors
+    # ${pre}analyse${suf} is a switch (allways off, on if set), not a Variable
+    # Set $form->{analysing}="" for system state: never analyse.
+    # Set $form->{analysing}="1" for system state: ever analyse.
+    $self->{analysing} = "1" if (/${pre}analyse${suf}/ && !defined $self->{analysing});    
+    
     $two_passes = 1 if (/\\pageref/);
 
     # { Moritz Bunkus
     # detect pagebreak block and its parameters
-    if (/\s*<%pagebreak ([0-9]+) ([0-9]+) ([0-9]+)%>/) {
+    if (/\s*${pre}pagebreak ([0-9]+) ([0-9]+) ([0-9]+)${suf}/) {
       $chars_per_line       = $1;
       $lines_on_first_page  = $2;
       $lines_on_second_page = $3;
 
       while ($_ = shift) {
-        last if (/\s*<%end pagebreak%>/);
+        last if (/\s*${pre}end pagebreak${suf}/);
         $pagebreak .= $_;
       }
     }
 
     # } Moritz Bunkus
-
-    if (/\s*<%foreach /) {
+    
+    if (/\s*${pre}foreach /) {
 
       # this one we need for the count
       chomp $var;
-      $var =~ s/\s*<%foreach (.+?)%>/$1/;
+      $var =~ s/\s*${pre}foreach (.+?)${suf}/$1/;
       while ($_ = shift) {
-        last if (/\s*<%end /);
+        last if (/\s*${pre}end /);
 
         # store line in $par
         $par .= $_;
@@ -818,7 +797,7 @@ sub parse_template {
 
         # { Moritz Bunkus
         # Try to detect whether a manual page break is necessary
-        # but only if there was a <%pagebreak ...%> block before
+        # but only if there was a ${pre}pagebreak ...${suf} block before
 
         if ($chars_per_line) {
           my $lines =
@@ -846,17 +825,17 @@ sub parse_template {
             ) {
             my $pb = $pagebreak;
 
-            # replace the special variables <%sumcarriedforward%>
-            # and <%lastpage%>
+            # replace the special variables ${pre}sumcarriedforward${suf}
+            # and ${pre}lastpage${suf}
 
             my $psum = $self->format_amount($myconfig, $sum, 2);
-            $pb =~ s/<%sumcarriedforward%>/$psum/g;
-            $pb =~ s/<%lastpage%>/$current_page/g;
+            $pb =~ s/${pre}sumcarriedforward${suf}/$psum/g;
+            $pb =~ s/${pre}lastpage${suf}/$current_page/g;
 
             # only "normal" variables are supported here
-            # (no <%if, no <%foreach, no <%include)
+            # (no ${pre}if, no ${pre}foreach, no ${pre}include)
 
-            $pb =~ s/<%(.+?)%>/$self->{$1}/g;
+            $pb =~ s/${pre}(.+?)${suf}/$self->{$1}/g;
 
             # page break block is ready to rock
             print(OUT $pb);
@@ -872,22 +851,22 @@ sub parse_template {
 
         # don't parse par, we need it for each line
         $_ = $par;
-        s/<%(.+?)%>/$self->{$1}[$i]/mg;
+        s/${pre}(.+?)${suf}/$self->{$1}[$i]/mg;
         print OUT;
       }
       next;
     }
 
     # if not comes before if!
-    if (/\s*<%if not /) {
+    if (/\s*${pre}if not /) {
 
       # check if it is not set and display
       chop;
-      s/\s*<%if not (.+?)%>/$1/;
+      s/\s*${pre}if not (.+?)${suf}/$1/;
 
       unless ($self->{$_}) {
         while ($_ = shift) {
-          last if (/\s*<%end /);
+          last if (/\s*${pre}end /);
 
           # store line in $par
           $par .= $_;
@@ -897,21 +876,21 @@ sub parse_template {
 
       } else {
         while ($_ = shift) {
-          last if (/\s*<%end /);
+          last if (/\s*${pre}end /);
         }
         next;
       }
     }
 
-    if (/\s*<%if /) {
+    if (/\s*${pre}if /) {
 
       # check if it is set and display
       chop;
-      s/\s*<%if (.+?)%>/$1/;
+      s/\s*${pre}if (.+?)${suf}/$1/;
 
       if ($self->{$_}) {
         while ($_ = shift) {
-          last if (/\s*<%end /);
+          last if (/\s*${pre}end /);
 
           # store line in $par
           $par .= $_;
@@ -921,21 +900,21 @@ sub parse_template {
 
       } else {
         while ($_ = shift) {
-          last if (/\s*<%end /);
+          last if (/\s*${pre}end /);
         }
         next;
       }
     }
 
-    # check for <%include filename%>
-    if (/\s*<%include /) {
+    # check for ${pre}include filename${suf}
+    if (/\s*${pre}include /) {
 
-      # get the filename
+      # get the directory/filename
       chomp $var;
-      $var =~ s/\s*<%include (.+?)%>/$1/;
+      $var =~ s/\s*${pre}include (.+?)${suf}/$1/;
 
-      # mangle filename
-      $var =~ s/(\/|\.\.)//g;
+      # mangle filename on basedir
+      $var =~ s/^(\/|\.\.)//g;
 
       # prevent the infinite loop!
       next if ($self->{"$var"});
@@ -950,7 +929,7 @@ sub parse_template {
       next;
     }
 
-    s/<%(.+?)%>/$self->{$1}/g;
+    s/${pre}(.+?)${suf}/$self->{$1}/g;
     s/<nobr><\/nobr>/&nbsp;/g;
     print OUT;
   }
@@ -1086,10 +1065,10 @@ Content-Length: $numbytes
       close(IN);
     }
 
-    $self->cleanup;
-
   }
 
+  $self->cleanup;
+
   chdir("$self->{cwd}");
   $main::lxdebug->leave_sub();
 }
@@ -1108,12 +1087,14 @@ sub cleanup {
     close(FH);
   }
 
-  if ($self->{tmpfile}) {
+  if ($self->{analysing} eq "") {
+    if ($self->{tmpfile}) {
 
-    # strip extension
-    $self->{tmpfile} =~ s/\.\w+$//g;
-    my $tmpfile = $self->{tmpfile};
-    unlink(<$tmpfile.*>);
+      # strip extension
+      $self->{tmpfile} =~ s/\.\w+$//g;  
+      my $tmpfile = $self->{tmpfile};
+      unlink(<$tmpfile.*>);
+    }
   }
 
   chdir("$self->{cwd}");
@@ -1158,7 +1139,7 @@ sub format_string {
         '&', quotemeta('\n'), '
 ',
         '"', '\$', '%', '_', '#', quotemeta('^'),
-        '{', '}',  '<', '>', '£', "\r"
+        '{', '}',  '<', '>', '£', "\r", '²'
       ]
     },
     'html' => {
@@ -1184,6 +1165,7 @@ sub format_string {
       '
 '          => '\newline ',
       '£'  => '\pounds ',
+      '²'  => '$^2$',
       "\r" => ""
     });
 
@@ -1740,7 +1722,7 @@ sub create_links {
     $query = qq| SELECT * FROM tax t|;
     $sth   = $dbh->prepare($query);
     $sth->execute || $self->dberror($query);
-    $form->{TAX} = ();
+    $self->{TAX} = ();
     while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
       push @{ $self->{TAX} }, $ref;
     }
@@ -2115,7 +2097,7 @@ sub update_defaults {
 
   $query = qq|UPDATE defaults
               SET $fld = '$var'|;
-  $dbh->do($query) || $form->dberror($query);
+  $dbh->do($query) || $self->dberror($query);
 
   $dbh->commit;
   $dbh->disconnect;
@@ -2143,7 +2125,7 @@ sub update_business {
   }
   $query = qq|UPDATE business
               SET customernumberinit = '$var' WHERE id=$business_id|;
-  $dbh->do($query) || $form->dberror($query);
+  $dbh->do($query) || $self->dberror($query);
 
   $dbh->commit;
   $dbh->disconnect;