new precision to round the total amount of sales invoices
authorRolf Fluehmann <rolf.fluehmann@revamp-it.ch>
Wed, 4 Sep 2013 12:07:23 +0000 (14:07 +0200)
committerRolf Fluehmann <rolf.fluehmann@revamp-it.ch>
Thu, 15 Oct 2015 10:53:57 +0000 (12:53 +0200)
Conflicts:
SL/Form.pm
locale/de/all
templates/webpages/admin/create_dataset.html

SL/Form.pm
SL/User.pm
bin/mozilla/is.pl
locale/de/all
locale/en/all
sql/Pg-upgrade2/defaults_add_precision.sql [new file with mode: 0644]
templates/webpages/admin/create_dataset.html

index 50c66d4..8cab71c 100644 (file)
@@ -850,7 +850,7 @@ sub format_amount {
   return $amount;
 }
 
-sub format_amount_units {
+sub format_amount_unit {
   $main::lxdebug->enter_sub();
 
   my $self             = shift;
@@ -967,7 +967,18 @@ sub parse_amount {
 }
 
 sub round_amount {
-  my ($self, $amount, $places) = @_;
+  my ($self, $amount, $places, $adjust) = @_;
+
+  if ($adjust) {
+    my $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 = _get_precision()) + ($amount <=> 0) * .5) * $precision;
+    $amount = int($amount * 10**$places + .5 * ($amount <=> 0)) / 10**$places;
+    return $amount;
+  }
 
   return 0 if !defined $amount;
 
@@ -3683,6 +3694,22 @@ sub calculate_tax {
   return ($amount,$tax);
 };
 
+sub _get_precision {
+  my ( $self ) = @_;
+  my $precision = 0.01;
+  eval {
+    my $client = $::auth->{client};
+    my $dbconnect = 'dbi:Pg:dbname=' . $client->{dbname} . ';host=' . $client->{dbhost} . ';port=' . $client->{dbport};
+    my $dbh       = DBI->connect($dbconnect, $client->{dbuser}, $client->{dbpasswd});
+    my $query = q{ SELECT precision FROM defaults };
+    (my $sth = $dbh->prepare($query))->execute;
+    ($precision) = selectrow_query($::form, $dbh, $query);
+    $sth->finish;
+    $dbh->disconnect;
+  };
+  return $precision;
+}
+
 1;
 
 __END__
index 44efe5c..b63ffc2 100644 (file)
@@ -283,11 +283,16 @@ sub dbcreate {
   # create the tables
   $dbupdater->process_query($dbh, "sql/lx-office.sql");
 
+  # process update-scripts needed before 1st user-login
+  $dbupdater->process_query($dbh, "sql/Pg-upgrade2/defaults_add_precision.sql");
+  $self->create_schema_info_table($form, $dbh);
+  $dbh->do("INSERT INTO schema_info (tag, login) VALUES ('defaults_add_precision', 'admin')");
+
   # load chart of accounts
   $dbupdater->process_query($dbh, "sql/$form->{chart}-chart.sql");
 
-  $query = qq|UPDATE defaults SET coa = ?, accounting_method = ?, profit_determination = ?, inventory_system = ?, curr = ?|;
-  do_query($form, $dbh, $query, map { $form->{$_} } qw(chart accounting_method profit_determination inventory_system defaultcurrency));
+  $query = qq|UPDATE defaults SET coa = ?, accounting_method = ?, profit_determination = ?, inventory_system = ?, curr = ?, precision = ?|;
+  do_query($form, $dbh, $query, map { $form->{$_} } qw(chart accounting_method profit_determination inventory_system defaultcurrency precision));
 
   $dbh->disconnect;
 
index 46abc9e..fdcf5e1 100644 (file)
@@ -462,6 +462,7 @@ sub form_footer {
       }
     }
   }
+  $form->{invtotal} = $form->round_amount($form->{invtotal}, 2, 1);
 
   # follow ups
   if ($form->{id}) {
index 96250a3..579c5d2 100755 (executable)
@@ -1996,6 +1996,7 @@ $self->{texts} = {
   'Posustva_coa'                => 'USTVA Kennz.',
   'Pre-defined Texts'           => 'Vordefinierte Textblöcke',
   'Preamble'                    => 'Einleitung',
+  'Precision'                   => 'Genauigkeit',
   'Preferences'                 => 'Einstellungen',
   'Preferences saved!'          => 'Einstellungen gespeichert!',
   'Prefix for the new bins\' names' => 'Namenspr&auml;fix f&uuml;r die neuen Lagerpl&auml;tze',
index c69f7b7..bcbf323 100644 (file)
@@ -1621,6 +1621,7 @@ $self->{texts} = {
   'Posting Configuration'       => '',
   'Postscript'                  => '',
   'Posustva_coa'                => '',
+  'Precision'                   => '',
   'Preferences'                 => '',
   'Preferences saved!'          => '',
   'Prefix for the new bins\' names' => '',
diff --git a/sql/Pg-upgrade2/defaults_add_precision.sql b/sql/Pg-upgrade2/defaults_add_precision.sql
new file mode 100644 (file)
index 0000000..88f854c
--- /dev/null
@@ -0,0 +1,5 @@
+-- @tag: defaults_add_precision
+-- @description: adds new column 'precision' in table defaults, used to round amounts
+-- @depends: release_3_0_0
+ALTER TABLE defaults ADD COLUMN precision NUMERIC(15,5) NOT NULL DEFAULT(0.01);
+
index 7c45591..36b628d 100644 (file)
    <td>[% L.input_tag('defaultcurrency', FORM.defaultcurrency || 'EUR') %]</td>
   </tr>
 
+  <tr>
+   <th align="right" nowrap>[% LxERP.t8('Precision') %]</th>
+   <td>[% L.input_tag('precision', FORM.precision || '0.01') %]</td>
+  </tr>
+
   <tr>
    <th valign="top" align="right" nowrap>[% LxERP.t8('Accounting method') %]</th>
    <td>[% L.select_tag('accounting_method', SELF.all_accounting_methods, title_key='name', default=(FORM.accounting_method || 'cash')) %]</td>
@@ -76,11 +81,13 @@ function comment_selected_chart(s) {
          "Hinweis vom 20.09.2011");
   } else if (/^Switzerland/.test(s)) {
     document.getElementById('defaultcurrency').value='CHF';
+    document.getElementById('precision').value='0.05';
     document.getElementById('accounting_method').value='accrual';
     document.getElementById('inventory_system').value='periodic';
     document.getElementById('profit_determination').value='balance';
   } else {
     document.getElementById("defaultcurrency").value="EUR";
+    document.getElementById('precision').value='0.01';
     document.getElementById('accounting_method').value='cash';
     document.getElementById('inventory_system').value='periodic';
     document.getElementById('profit_determination').value='income';