]> wagnertech.de Git - mfinanz.git/blobdiff - SL/Form.pm
Consolidation and extended test runs
[mfinanz.git] / SL / Form.pm
index 81b5370b7f579c60877f6ccc98222a99c385fad9..5d754efec30c12b62409271018dac3156cb78f6e 100644 (file)
@@ -945,16 +945,12 @@ sub parse_amount {
     return 0;
   }
 
-  if (   ($myconfig->{numberformat} eq '1.000,00')
+  $amount =~ s/\'//g;
+ if (   ($myconfig->{numberformat} eq '1.000,00')
       || ($myconfig->{numberformat} eq '1000,00')) {
     $amount =~ s/\.//g;
     $amount =~ s/,/\./g;
   }
-
-  if ($myconfig->{numberformat} eq "1'000.00") {
-    $amount =~ s/\'//g;
-  }
-
   $amount =~ s/,//g;
 
   $main::lxdebug->leave_sub(2);
@@ -969,10 +965,21 @@ sub parse_amount {
 }
 
 sub round_amount {
-  my ($self, $amount, $places) = @_;
+  my ($self, $amount, $places, $adjust) = @_;
 
   return 0 if !defined $amount;
 
+  if ($adjust) {
+    my $precision = SL::DB::Default->get->precision || 0.01;
+    # Round amounts to eight places before rounding to the requested
+    # number of places. This gets rid of errors due to internal floating
+    # point representation.
+    $amount = int($amount * 10**8 + .5 * ($amount <=> 0)) / 10**8  if $places < 8;
+    $amount = int($amount / $precision + ($amount <=> 0) * .5) * $precision;
+    $amount = int($amount * 10**$places + .5 * ($amount <=> 0)) / 10**$places;
+    return $amount;
+  }
+
   # We use Perl's knowledge of string representation for
   # rounding. First, convert the floating point number to a string
   # with a high number of places. Then split the string on the decimal
@@ -2604,18 +2611,18 @@ sub all_vc {
 }
 
 sub mtime_ischanged {
-  my ($self, $relation,$option) = @_;
-  #$main::lxdebug->message(LXDebug->DEBUG2(),"mtime_ischanged from rel=".$relation." id=".$id);
-  if ( ! $self->{id} ) { return ; }
-
-  my $query = "SELECT mtime, itime FROM ".$relation." WHERE id = ?";
-  my $ref = selectfirst_hashref_query($self, $self->get_standard_dbh, $query, $self->{id});
-  $ref->{mtime} = $ref->{itime} if !$ref->{mtime};
-  #$main::lxdebug->message(LXDebug->DEBUG2(),"my  mtime=".$self->{lastmtime}." new mtime=".$ref->{mtime});
+  my ($self, $table, $option) = @_;
+
+  return                                       unless $self->{id};
+  croak ("wrong call, no valid table defined") unless $table =~ /^(oe|ar|ap|delivery_orders|parts)$/;
+
+  my $query       = "SELECT mtime, itime FROM " . $table . " WHERE id = ?";
+  my $ref         = selectfirst_hashref_query($self, $self->get_standard_dbh, $query, $self->{id});
+  $ref->{mtime} ||= $ref->{itime};
+
   if ($self->{lastmtime} && $self->{lastmtime} ne $ref->{mtime} ) {
-      my $etxt = $main::locale->text("The document has been changed from other user. Please reopen it in another window and copy the changes to the new window");
-      $etxt = $main::locale->text("The document has been changed from other user. No mail was sent. Please reopen it in another window and copy the changes to the new window")
-                                 if  defined $option && $option eq 'mail';
+      my $etxt = ($option eq 'mail') ? "The document has been changed by another user. Please reopen it in another window and copy the changes to the new window" :
+                                       "The document has been changed by another user. No mail was sent. Please reopen it in another window and copy the changes to the new window";
       $self->error($main::locale->text($etxt));
     ::end_of_request();
   }
@@ -2772,7 +2779,7 @@ sub create_links {
       qq|SELECT
            a.cp_id, a.invnumber, a.transdate, a.${table}_id, a.datepaid,
            a.duedate, a.ordnumber, a.taxincluded, (SELECT cu.name FROM currencies cu WHERE cu.id=a.currency_id) AS currency, a.notes,
-           a.mtime,a.itime,
+           a.mtime, a.itime,
            a.intnotes, a.department_id, a.amount AS oldinvtotal,
            a.paid AS oldtotalpaid, a.employee_id, a.gldate, a.type,
            a.globalproject_id, ${extra_columns}
@@ -2789,7 +2796,7 @@ sub create_links {
     foreach my $key (keys %$ref) {
       $self->{$key} = $ref->{$key};
     }
-    $self->{mtime} = $self->{itime} if ! $self->{mtime};
+    $self->{mtime}   ||= $self->{itime};
     $self->{lastmtime} = $self->{mtime};
     my $transdate = "current_date";
     if ($self->{transdate}) {
@@ -2873,7 +2880,9 @@ sub create_links {
            d.closedto, d.revtrans,
            (SELECT cu.name FROM currencies cu WHERE cu.id=d.currency_id) AS defaultcurrency,
            (SELECT c.accno FROM chart c WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
-           (SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno
+           (SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
+           (SELECT c.accno FROM chart c WHERE d.rndgain_accno_id = c.id) AS rndgain_accno,
+           (SELECT c.accno FROM chart c WHERE d.rndloss_accno_id = c.id) AS rndloss_accno
          FROM defaults d|;
     $ref = selectfirst_hashref_query($self, $dbh, $query);
     map { $self->{$_} = $ref->{$_} } keys %$ref;
@@ -2886,7 +2895,9 @@ sub create_links {
             current_date AS transdate, d.closedto, d.revtrans,
             (SELECT cu.name FROM currencies cu WHERE cu.id=d.currency_id) AS defaultcurrency,
             (SELECT c.accno FROM chart c WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
-            (SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno
+            (SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
+            (SELECT c.accno FROM chart c WHERE d.rndgain_accno_id = c.id) AS rndgain_accno,
+            (SELECT c.accno FROM chart c WHERE d.rndloss_accno_id = c.id) AS rndloss_accno
           FROM defaults d|;
     $ref = selectfirst_hashref_query($self, $dbh, $query);
     map { $self->{$_} = $ref->{$_} } keys %$ref;
@@ -3756,6 +3767,17 @@ Used to override the default favicon.
 
 A html page title will be generated from this
 
+=item mtime_ischanged
+
+Tries to avoid concurrent write operations to records by checking the database mtime with a fetched one.
+
+Can be used / called with any table, that has itime and mtime attributes.
+Valid C<table> names are: oe, ar, ap, delivery_orders, parts.
+Can be called wit C<option> mail to generate a different error message.
+
+Returns undef if no save operation has been done yet ($self->{id} not present).
+Returns undef if no concurrent write process is detected otherwise a error message.
+
 =back
 
 =cut