Merge branch '2020-leistungsdatum'
authorMoritz Bunkus <m.bunkus@linet.de>
Thu, 3 Dec 2020 13:13:09 +0000 (14:13 +0100)
committerMoritz Bunkus <m.bunkus@linet.de>
Thu, 3 Dec 2020 13:13:09 +0000 (14:13 +0100)
33 files changed:
SL/AP.pm
SL/AR.pm
SL/BackgroundJob/CreatePeriodicInvoices.pm
SL/DATEV.pm
SL/DB/Helper/FlattenToForm.pm
SL/DB/Helper/PriceTaxCalculator.pm
SL/DB/Invoice.pm
SL/DB/MetaSetup/DeliveryOrder.pm
SL/DB/MetaSetup/GLTransaction.pm
SL/DB/MetaSetup/Invoice.pm
SL/DB/MetaSetup/Order.pm
SL/DB/MetaSetup/PurchaseInvoice.pm
SL/DB/Order.pm
SL/DB/PurchaseInvoice.pm
SL/DO.pm
SL/Form.pm
SL/GL.pm
SL/IC.pm
SL/IR.pm
SL/IS.pm
SL/OE.pm
bin/mozilla/io.pl
locale/de/all
sql/Pg-upgrade2/tax_point.sql [new file with mode: 0644]
sql/Pg-upgrade2/tax_point2.sql [new file with mode: 0644]
templates/webpages/ap/form_header.html
templates/webpages/ar/form_header.html
templates/webpages/do/form_header.html
templates/webpages/gl/form_header.html
templates/webpages/ir/form_header.html
templates/webpages/is/form_header.html
templates/webpages/oe/form_header.html
templates/webpages/order/tabs/basic_data.html

index 937af8b..71c2b4b 100644 (file)
--- a/SL/AP.pm
+++ b/SL/AP.pm
@@ -139,14 +139,14 @@ sub _post_transaction {
 
     $query = qq|UPDATE ap SET invnumber = ?,
                 transdate = ?, ordnumber = ?, vendor_id = ?, taxincluded = ?,
-                amount = ?, duedate = ?, deliverydate = ?, paid = ?, netamount = ?,
+                amount = ?, duedate = ?, deliverydate = ?, tax_point = ?, paid = ?, netamount = ?,
                 currency_id = (SELECT id FROM currencies WHERE name = ?), notes = ?, department_id = ?, storno = ?, storno_id = ?,
                 globalproject_id = ?, direct_debit = ?
                WHERE id = ?|;
     @values = ($form->{invnumber}, conv_date($form->{transdate}),
                   $form->{ordnumber}, conv_i($form->{vendor_id}),
                   $form->{taxincluded} ? 't' : 'f', $form->{invtotal},
-                  conv_date($form->{duedate}), conv_date($form->{deliverydate}),
+                  conv_date($form->{duedate}), conv_date($form->{deliverydate}), conv_date($form->{tax_point}),
                   $form->{invpaid}, $form->{netamount},
                   $form->{currency}, $form->{notes},
                   conv_i($form->{department_id}), $form->{storno},
index 3d31a61..b856f44 100644 (file)
--- a/SL/AR.pm
+++ b/SL/AR.pm
@@ -134,14 +134,14 @@ sub _post_transaction {
     $query =
       qq|UPDATE ar set
            invnumber = ?, ordnumber = ?, transdate = ?, customer_id = ?,
-           taxincluded = ?, amount = ?, duedate = ?, deliverydate = ?, paid = ?,
+           taxincluded = ?, amount = ?, duedate = ?, deliverydate = ?, tax_point = ?, paid = ?,
            currency_id = (SELECT id FROM currencies WHERE name = ?),
            netamount = ?, notes = ?, department_id = ?,
            employee_id = ?, storno = ?, storno_id = ?, globalproject_id = ?,
            direct_debit = ?
          WHERE id = ?|;
     my @values = ($form->{invnumber}, $form->{ordnumber}, conv_date($form->{transdate}), conv_i($form->{customer_id}), $form->{taxincluded} ? 't' : 'f', $form->{amount},
-                  conv_date($form->{duedate}), conv_date($form->{deliverydate}), $form->{paid},
+                  conv_date($form->{duedate}), conv_date($form->{deliverydate}), conv_date($form->{tax_point}), $form->{paid},
                   $form->{currency},
                   $form->{netamount}, $form->{notes}, conv_i($form->{department_id}),
                   conv_i($form->{employee_id}), $form->{storno} ? 't' : 'f', $form->{storno_id},
index 52415f2..f7b9100 100644 (file)
@@ -224,10 +224,17 @@ sub _create_periodic_invoice {
 
     $invoice = SL::DB::Invoice->new_from($order);
 
+    my $tax_point = ($invoice->tax_point // $time_period_vars->{period_end_date}->[0])->clone;
+
+    while ($tax_point < $period_start_date) {
+      $tax_point->add(months => $config->get_billing_period_length);
+    }
+
     my $intnotes  = $invoice->intnotes ? $invoice->intnotes . "\n\n" : '';
     $intnotes    .= "Automatisch am " . $invdate->to_lxoffice . " erzeugte Rechnung";
 
     $invoice->assign_attributes(deliverydate => $period_start_date,
+                                tax_point    => $tax_point,
                                 intnotes     => $intnotes,
                                 employee     => $order->employee, # new_from sets employee to import user
                                 direct_debit => $config->direct_debit,
index af188f7..c6ce5b2 100644 (file)
@@ -517,7 +517,7 @@ sub generate_datev_data {
 
   my $query    =
     qq|SELECT ac.acc_trans_id, ac.transdate, ac.gldate, ac.trans_id,ar.id, ac.amount, ac.taxkey, ac.memo,
-         ar.invnumber, ar.duedate, ar.amount as umsatz, ar.deliverydate, ar.itime::date,
+         ar.invnumber, ar.duedate, ar.amount as umsatz, COALESCE(ar.tax_point, ar.deliverydate) AS deliverydate, ar.itime::date,
          ct.name, ct.ustid, ct.customernumber AS vcnumber, ct.id AS customer_id, NULL AS vendor_id,
          $ar_accno, c.description AS accname, c.taxkey_id as charttax, c.datevautomatik, c.id, ac.chart_link AS link,
          ar.invoice,
@@ -546,7 +546,7 @@ sub generate_datev_data {
        UNION ALL
 
        SELECT ac.acc_trans_id, ac.transdate, ac.gldate, ac.trans_id,ap.id, ac.amount, ac.taxkey, ac.memo,
-         ap.invnumber, ap.duedate, ap.amount as umsatz, ap.deliverydate, ap.itime::date,
+         ap.invnumber, ap.duedate, ap.amount as umsatz, COALESCE(ap.tax_point, ap.deliverydate) AS deliverydate, ap.itime::date,
          ct.name, ct.ustid, ct.vendornumber AS vcnumber, NULL AS customer_id, ct.id AS vendor_id,
          $ap_accno, c.description AS accname, c.taxkey_id as charttax, c.datevautomatik, c.id, ac.chart_link AS link,
          ap.invoice,
@@ -575,7 +575,7 @@ sub generate_datev_data {
        UNION ALL
 
        SELECT ac.acc_trans_id, ac.transdate, ac.gldate, ac.trans_id,gl.id, ac.amount, ac.taxkey, ac.memo,
-         gl.reference AS invnumber, NULL AS duedate, ac.amount as umsatz, gl.deliverydate, gl.itime::date,
+         gl.reference AS invnumber, NULL AS duedate, ac.amount as umsatz, COALESCE(gl.tax_point, gl.deliverydate) AS deliverydate, gl.itime::date,
          gl.description AS name, NULL as ustid, '' AS vcname, NULL AS customer_id, NULL AS vendor_id,
          c.accno, c.description AS accname, c.taxkey_id as charttax, c.datevautomatik, c.id, ac.chart_link AS link,
          FALSE AS invoice,
index 7c001af..5ba2f3d 100644 (file)
@@ -15,7 +15,7 @@ sub flatten_to_form {
   _copy($self, $form, '', '', 0, qw(id type taxzone_id ordnumber quonumber invnumber donumber cusordnumber taxincluded shippingpoint shipvia notes intnotes cp_id
                                     employee_id salesman_id closed department_id language_id payment_id delivery_customer_id delivery_vendor_id shipto_id proforma
                                     globalproject_id delivered transaction_description container_type accepted_by_customer invoice storno storno_id dunning_config_id
-                                    orddate quodate reqdate gldate duedate deliverydate datepaid transdate delivery_term_id));
+                                    orddate quodate reqdate gldate duedate deliverydate datepaid transdate tax_point delivery_term_id));
   $form->{currency} = $form->{curr} = $self->currency_id ? $self->currency->name || '' : '';
 
   if ( $vc eq 'customer' ) {
index f5bc61c..15850d5 100644 (file)
@@ -54,7 +54,7 @@ sub calculate_prices_and_taxes {
   $self->netamount(  0);
   $self->marge_total(0);
 
-  SL::DB::Manager::Chart->cache_taxkeys(date => $self->deliverydate // $self->transdate);
+  SL::DB::Manager::Chart->cache_taxkeys(date => $self->effective_tax_point);
 
   my $idx = 0;
   foreach my $item (@{ $self->items_sorted }) {
@@ -110,7 +110,7 @@ sub _calculate_item {
 
   $data->{invoicediff} += $sellprice * (1 - $item->discount) * $item->qty * $data->{exchangerate} / $item->price_factor - $linetotal if $self->taxincluded;
 
-  my $taxkey     = $part->get_taxkey(date => $self->deliverydate // $self->transdate, is_sales => $data->{is_sales}, taxzone => $self->taxzone_id);
+  my $taxkey     = $part->get_taxkey(date => $self->effective_tax_point, is_sales => $data->{is_sales}, taxzone => $self->taxzone_id);
   my $tax_rate   = $taxkey->tax->rate;
   my $tax_amount = undef;
 
index 93c17e4..26faca1 100644 (file)
@@ -156,7 +156,7 @@ sub new_from {
   my (@columns, @item_columns, $item_parent_id_column, $item_parent_column);
 
   if (ref($source) eq 'SL::DB::Order') {
-    @columns      = qw(quonumber delivery_customer_id delivery_vendor_id);
+    @columns      = qw(quonumber delivery_customer_id delivery_vendor_id tax_point);
     @item_columns = qw(subtotal);
 
     $item_parent_id_column = 'trans_id';
@@ -173,7 +173,7 @@ sub new_from {
   $terms = $source->customer->payment_terms if !defined $terms && $source->customer;
 
   my %args = ( map({ ( $_ => $source->$_ ) } qw(customer_id taxincluded shippingpoint shipvia notes intnotes salesman_id cusordnumber ordnumber department_id
-                                                cp_id language_id taxzone_id globalproject_id transaction_description currency_id delivery_term_id), @columns),
+                                                cp_id language_id taxzone_id tax_point globalproject_id transaction_description currency_id delivery_term_id), @columns),
                transdate   => $params{transdate} // DateTime->today_local,
                gldate      => DateTime->today_local,
                duedate     => $terms ? $terms->calc_date(reference_date => DateTime->today_local) : DateTime->today_local,
@@ -609,6 +609,12 @@ sub mark_as_paid {
   $self->update_attributes(paid => $self->amount);
 }
 
+sub effective_tax_point {
+  my ($self) = @_;
+
+  return $self->tax_point || $self->deliverydate || $self->transdate;
+}
+
 1;
 
 __END__
index d242fcd..780f431 100644 (file)
@@ -35,6 +35,7 @@ __PACKAGE__->meta->columns(
   shippingpoint           => { type => 'text' },
   shipto_id               => { type => 'integer' },
   shipvia                 => { type => 'text' },
+  tax_point               => { type => 'date' },
   taxincluded             => { type => 'boolean' },
   taxzone_id              => { type => 'integer', not_null => 1 },
   transaction_description => { type => 'text' },
index f592513..4d0e41b 100644 (file)
@@ -23,6 +23,7 @@ __PACKAGE__->meta->columns(
   reference      => { type => 'text' },
   storno         => { type => 'boolean', default => 'false' },
   storno_id      => { type => 'integer' },
+  tax_point      => { type => 'date' },
   taxincluded    => { type => 'boolean' },
   transdate      => { type => 'date', default => 'now' },
   type           => { type => 'text' },
index b88c2f5..9b10c93 100644 (file)
@@ -51,6 +51,7 @@ __PACKAGE__->meta->columns(
   shipvia                   => { type => 'text' },
   storno                    => { type => 'boolean', default => 'false' },
   storno_id                 => { type => 'integer' },
+  tax_point                 => { type => 'date' },
   taxincluded               => { type => 'boolean' },
   taxzone_id                => { type => 'integer', not_null => 1 },
   transaction_description   => { type => 'text' },
index d6922bd..6e707ae 100644 (file)
@@ -44,6 +44,7 @@ __PACKAGE__->meta->columns(
   shippingpoint           => { type => 'text' },
   shipto_id               => { type => 'integer' },
   shipvia                 => { type => 'text' },
+  tax_point               => { type => 'date' },
   taxincluded             => { type => 'boolean' },
   taxzone_id              => { type => 'integer', not_null => 1 },
   transaction_description => { type => 'text' },
index c9c74f0..4a443ac 100644 (file)
@@ -39,6 +39,7 @@ __PACKAGE__->meta->columns(
   shipvia                 => { type => 'text' },
   storno                  => { type => 'boolean', default => 'false' },
   storno_id               => { type => 'integer' },
+  tax_point               => { type => 'date' },
   taxincluded             => { type => 'boolean', default => 'false' },
   taxzone_id              => { type => 'integer', not_null => 1 },
   transaction_description => { type => 'text' },
index d996d13..f22c84d 100644 (file)
@@ -139,9 +139,17 @@ sub is_type {
 }
 
 sub deliverydate {
-  # oe doesn't have deliverydate, but PTC checks for deliverydate or transdate to determine tax
-  # oe can't deal with deviating tax rates, but at least make sure PTC doesn't barf
-  return shift->transdate;
+  # oe doesn't have deliverydate, but it does have reqdate.
+  # But this has a different meaning for sales quotations.
+  # deliverydate can be used to determine tax if tax_point isn't set.
+
+  return $_[0]->reqdate if $_[0]->type ne 'sales_quotation';
+}
+
+sub effective_tax_point {
+  my ($self) = @_;
+
+  return $self->tax_point || $self->deliverydate || $self->transdate;
 }
 
 sub displayable_type {
@@ -322,7 +330,7 @@ sub new_from {
 
   my %args = ( map({ ( $_ => $source->$_ ) } qw(amount cp_id currency_id cusordnumber customer_id delivery_customer_id delivery_term_id delivery_vendor_id
                                                 department_id employee_id exchangerate globalproject_id intnotes marge_percent marge_total language_id netamount notes
-                                                ordnumber payment_id quonumber reqdate salesman_id shippingpoint shipvia taxincluded taxzone_id
+                                                ordnumber payment_id quonumber reqdate salesman_id shippingpoint shipvia taxincluded tax_point taxzone_id
                                                 transaction_description vendor_id
                                              )),
                quotation => !!($destination_type =~ m{quotation$}),
index a50884c..dd49433 100644 (file)
@@ -214,6 +214,12 @@ sub mark_as_paid {
   $self->update_attributes(paid => $self->amount);
 }
 
+sub effective_tax_point {
+  my ($self) = @_;
+
+  return $self->tax_point || $self->deliverydate || $self->transdate;
+}
+
 1;
 
 
index 034189f..90599a7 100644 (file)
--- a/SL/DO.pm
+++ b/SL/DO.pm
@@ -511,7 +511,7 @@ SQL
   $query =
     qq|UPDATE delivery_orders SET
          donumber = ?, ordnumber = ?, cusordnumber = ?, transdate = ?, vendor_id = ?,
-         customer_id = ?, reqdate = ?,
+         customer_id = ?, reqdate = ?, tax_point = ?,
          shippingpoint = ?, shipvia = ?, notes = ?, intnotes = ?, closed = ?,
          delivered = ?, department_id = ?, language_id = ?, shipto_id = ?,
          globalproject_id = ?, employee_id = ?, salesman_id = ?, cp_id = ?, transaction_description = ?,
@@ -522,7 +522,7 @@ SQL
   @values = ($form->{donumber}, $form->{ordnumber},
              $form->{cusordnumber}, conv_date($form->{transdate}),
              conv_i($form->{vendor_id}), conv_i($form->{customer_id}),
-             conv_date($form->{reqdate}), $form->{shippingpoint}, $form->{shipvia},
+             conv_date($form->{reqdate}), conv_date($form->{tax_point}), $form->{shippingpoint}, $form->{shipvia},
              $restricter->process($form->{notes}), $form->{intnotes},
              $form->{closed} ? 't' : 'f', $form->{delivered} ? "t" : "f",
              conv_i($form->{department_id}), conv_i($form->{language_id}), conv_i($form->{shipto_id}),
@@ -693,7 +693,7 @@ sub retrieve {
   # so if any of these infos is important (or even different) for any item,
   # it will be killed out and then has to be fetched from the item scope query further down
   $query =
-    qq|SELECT dord.cp_id, dord.donumber, dord.ordnumber, dord.transdate, dord.reqdate,
+    qq|SELECT dord.cp_id, dord.donumber, dord.ordnumber, dord.transdate, dord.reqdate, dord.tax_point,
          dord.shippingpoint, dord.shipvia, dord.notes, dord.intnotes,
          e.name AS employee, dord.employee_id, dord.salesman_id,
          dord.${vc}_id, cv.name AS ${vc},
index b8670ca..c92d267 100644 (file)
@@ -2567,7 +2567,7 @@ sub create_links {
     $query =
       qq|SELECT
            a.cp_id, a.invnumber, a.transdate, a.${table}_id, a.datepaid, a.deliverydate,
-           a.duedate, a.ordnumber, a.taxincluded, (SELECT cu.name FROM currencies cu WHERE cu.id=a.currency_id) AS currency, a.notes,
+           a.duedate, a.tax_point, 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.intnotes, a.department_id, a.amount AS oldinvtotal,
            a.paid AS oldtotalpaid, a.employee_id, a.gldate, a.type,
@@ -3230,7 +3230,7 @@ sub prepare_for_printing {
 
   # Format dates.
   $self->format_dates($output_dateformat, $output_longdates,
-                      qw(invdate orddate quodate pldate duedate reqdate transdate shippingdate deliverydate validitydate paymentdate datepaid
+                      qw(invdate orddate quodate pldate duedate reqdate transdate tax_point shippingdate deliverydate validitydate paymentdate datepaid
                          transdate_oe deliverydate_oe employee_startdate employee_enddate),
                       grep({ /^(?:datepaid|transdate_oe|reqdate|deliverydate|deliverydate_oe|transdate)_\d+$/ } keys(%{$self})));
 
index 245e5b8..9eb741d 100644 (file)
--- a/SL/GL.pm
+++ b/SL/GL.pm
@@ -123,12 +123,12 @@ sub _post_transaction {
   $query =
     qq|UPDATE gl SET
          reference = ?, description = ?, notes = ?,
-         transdate = ?, deliverydate = ?, department_id = ?, taxincluded = ?,
+         transdate = ?, deliverydate = ?, tax_point = ?, department_id = ?, taxincluded = ?,
          storno = ?, storno_id = ?, ob_transaction = ?, cb_transaction = ?
        WHERE id = ?|;
 
   @values = ($form->{reference}, $form->{description}, $form->{notes},
-             conv_date($form->{transdate}), conv_date($form->{deliverydate}), conv_i($form->{department_id}), $form->{taxincluded} ? 't' : 'f',
+             conv_date($form->{transdate}), conv_date($form->{deliverydate}), conv_date($form->{tax_point}), conv_i($form->{department_id}), $form->{taxincluded} ? 't' : 'f',
              $form->{storno} ? 't' : 'f', conv_i($form->{storno_id}), $form->{ob_transaction} ? 't' : 'f', $form->{cb_transaction} ? 't' : 'f',
              conv_i($form->{id}));
   do_query($form, $dbh, $query, @values);
@@ -637,7 +637,7 @@ sub transaction {
 
   if ($form->{id}) {
     $query =
-      qq|SELECT g.reference, g.description, g.notes, g.transdate, g.deliverydate,
+      qq|SELECT g.reference, g.description, g.notes, g.transdate, g.deliverydate, g.tax_point,
            g.storno, g.storno_id,
            g.department_id, d.description AS department,
            e.name AS employee, g.taxincluded, g.gldate,
index 868fb74..ca03e51 100644 (file)
--- a/SL/IC.pm
+++ b/SL/IC.pm
@@ -739,37 +739,14 @@ sub retrieve_accounts {
 
   # transdate madness.
   my $transdate = "";
-  if ($form->{type} eq "invoice" or $form->{type} eq "credit_note") {
+  if (($form->{type} eq "invoice") or ($form->{type} eq "credit_note") or ($form->{script} eq 'ir.pl')) {
     # use deliverydate for sales and purchase invoice, if it exists
     # also use deliverydate for credit notes
-    if (!$form->{deliverydate}) {
-      $transdate = $form->{invdate};
-    } else {
-      $transdate = $form->{deliverydate};
-    }
-  } elsif ($form->{script} eq 'ir.pl') {
-    # when a purchase invoice is opened from the report of purchase invoices
-    # $form->{type} isn't set, but $form->{script} is, not sure why this is or
-    # whether this distinction matters in some other scenario. Otherwise one
-    # could probably take out this elsif and add a
-    # " or $form->{script} eq 'ir.pl' "
-    # to the above if-statement
-    if (!$form->{deliverydate}) {
-      $transdate = $form->{invdate};
-    } else {
-      $transdate = $form->{deliverydate};
-    }
-  } elsif (($form->{type} eq "credit_note") and $form->{deliverydate}) {
-    # if credit_note has a deliverydate, use this instead of invdate
-    # useful for credit_notes of invoices from an old period with different tax
-    # if there is no deliverydate then invdate is used, old default (see next elsif)
-    # Falls hier der Stichtag fĂĽr Steuern anders bestimmt wird,
-    # entsprechend auch bei Taxkeys.pm anpassen
-    $transdate = $form->{deliverydate};
-  } elsif (($form->{type} eq "credit_note") || ($form->{script} eq 'ir.pl')) {
-    $transdate = $form->{invdate};
+    $transdate = $form->{tax_point} || $form->{deliverydate} || $form->{invdate};
   } else {
-    $transdate = $form->{transdate};
+    my $deliverydate;
+    $deliverydate = $form->{reqdate} if any { $_ eq $form->{type} } qw(sales_order request_quotation purchase_order);
+    $transdate = $form->{tax_point} || $deliverydate || $form->{transdate};
   }
 
   if ($transdate eq "") {
index 5c768cf..2663ad6 100644 (file)
--- a/SL/IR.pm
+++ b/SL/IR.pm
@@ -549,7 +549,7 @@ SQL
     if ($form->{currency} ne $defaultcurrency) && !$exchangerate;
 
 # record acc_trans transactions
-  my $taxdate = $form->{deliverydate} ? $form->{deliverydate} : $form->{invdate};
+  my $taxdate = $form->{tax_point} || $form->{deliverydate} || $form->{invdate};
   foreach my $trans_id (keys %{ $form->{amount} }) {
     foreach my $accno (keys %{ $form->{amount}{$trans_id} }) {
       $form->{amount}{$trans_id}{$accno} = $form->round_amount($form->{amount}{$trans_id}{$accno}, 2);
@@ -735,7 +735,7 @@ SQL
                 orddate      = ?, quodate     = ?, vendor_id     = ?, amount       = ?,
                 netamount    = ?, paid        = ?, duedate       = ?, deliverydate = ?,
                 invoice      = ?, taxzone_id  = ?, notes         = ?, taxincluded  = ?,
-                intnotes     = ?, storno_id   = ?, storno        = ?,
+                intnotes     = ?, storno_id   = ?, storno        = ?, tax_point    = ?,
                 cp_id        = ?, employee_id = ?, department_id = ?, delivery_term_id = ?,
                 payment_id   = ?,
                 currency_id = (SELECT id FROM currencies WHERE name = ?),
@@ -746,7 +746,7 @@ SQL
       conv_date($form->{orddate}), conv_date($form->{quodate}),     conv_i($form->{vendor_id}),               $amount,
                 $netamount,                  $form->{paid},        conv_date($form->{duedate}),     conv_date($form->{deliverydate}),
             '1',                             $taxzone_id, $restricter->process($form->{notes}),               $form->{taxincluded} ? 't' : 'f',
-                $form->{intnotes},           conv_i($form->{storno_id}),     $form->{storno}      ? 't' : 'f',
+                $form->{intnotes},           conv_i($form->{storno_id}),     $form->{storno}      ? 't' : 'f', conv_date($form->{tax_point}),
          conv_i($form->{cp_id}),      conv_i($form->{employee_id}), conv_i($form->{department_id}), conv_i($form->{delivery_term_id}),
          conv_i($form->{payment_id}),
                 $form->{"currency"},
@@ -1002,7 +1002,7 @@ sub retrieve_invoice {
 
   # retrieve invoice
   $query = qq|SELECT cp_id, invnumber, transdate AS invdate, duedate,
-                orddate, quodate, deliverydate, globalproject_id,
+                orddate, quodate, deliverydate, tax_point, globalproject_id,
                 ordnumber, quonumber, paid, taxincluded, notes, taxzone_id, storno, gldate,
                 mtime, itime,
                 intnotes, (SELECT cu.name FROM currencies cu WHERE cu.id=ap.currency_id) AS currency, direct_debit,
@@ -1022,7 +1022,7 @@ sub retrieve_invoice {
   delete $ref->{id};
   map { $form->{$_} = $ref->{$_} } keys %$ref;
 
-  my $transdate  = $form->{invdate} ? $dbh->quote($form->{invdate}) : "current_date";
+  my $transdate  = $form->{tax_point} ? $dbh->quote($form->{tax_point}) :$form->{invdate} ? $dbh->quote($form->{invdate}) : "current_date";
 
   my $taxzone_id = $form->{taxzone_id} * 1;
   $taxzone_id = SL::DB::Manager::TaxZone->get_default->id unless SL::DB::Manager::TaxZone->find_by(id => $taxzone_id);
index e9e9144..5fe66cf 100644 (file)
--- a/SL/IS.pm
+++ b/SL/IS.pm
@@ -1037,7 +1037,7 @@ SQL
 
   $project_id = conv_i($form->{"globalproject_id"});
   # entsprechend auch beim Bestimmen des SteuerschlĂĽssels in Taxkey.pm berĂĽcksichtigen
-  my $taxdate = $form->{deliverydate} ? $form->{deliverydate} : $form->{invdate};
+  my $taxdate = $form->{tax_point} ||$form->{deliverydate} || $form->{invdate};
 
   foreach my $trans_id (keys %{ $form->{amount_cogs} }) {
     foreach my $accno (keys %{ $form->{amount_cogs}{$trans_id} }) {
@@ -1312,7 +1312,7 @@ SQL
 
   $query = qq|UPDATE ar set
                 invnumber   = ?, ordnumber     = ?, quonumber     = ?, cusordnumber  = ?,
-                transdate   = ?, orddate       = ?, quodate       = ?, customer_id   = ?,
+                transdate   = ?, orddate       = ?, quodate       = ?, tax_point     = ?, customer_id   = ?,
                 amount      = ?, netamount     = ?, paid          = ?,
                 duedate     = ?, deliverydate  = ?, invoice       = ?, shippingpoint = ?,
                 shipvia     = ?,                    notes         = ?, intnotes      = ?,
@@ -1327,7 +1327,7 @@ SQL
                 delivery_term_id = ?
               WHERE id = ?|;
   @values = (          $form->{"invnumber"},           $form->{"ordnumber"},             $form->{"quonumber"},          $form->{"cusordnumber"},
-             conv_date($form->{"invdate"}),  conv_date($form->{"orddate"}),    conv_date($form->{"quodate"}),    conv_i($form->{"customer_id"}),
+             conv_date($form->{"invdate"}),  conv_date($form->{"orddate"}),    conv_date($form->{"quodate"}), conv_date($form->{tax_point}), conv_i($form->{"customer_id"}),
                        $amount,                        $netamount,                       $form->{"paid"},
              conv_date($form->{"duedate"}),  conv_date($form->{"deliverydate"}),    '1',                                $form->{"shippingpoint"},
                        $form->{"shipvia"},                                $restricter->process($form->{"notes"}),       $form->{"intnotes"},
@@ -2012,7 +2012,7 @@ sub _retrieve_invoice {
       qq|SELECT
            a.invnumber, a.ordnumber, a.quonumber, a.cusordnumber,
            a.orddate, a.quodate, a.globalproject_id,
-           a.transdate AS invdate, a.deliverydate, a.paid, a.storno, a.storno_id, a.gldate,
+           a.transdate AS invdate, a.deliverydate, a.tax_point, a.paid, a.storno, a.storno_id, a.gldate,
            a.shippingpoint, a.shipvia, a.notes, a.intnotes, a.taxzone_id,
            a.duedate, a.taxincluded, (SELECT cu.name FROM currencies cu WHERE cu.id=a.currency_id) AS currency, a.shipto_id, a.cp_id,
            a.employee_id, a.salesman_id, a.payment_id,
@@ -2055,7 +2055,8 @@ sub _retrieve_invoice {
     $sth->finish;
     map { $form->{$_} =~ s/ +$//g } qw(printed emailed queued);
 
-    my $transdate = $form->{deliverydate} ? $dbh->quote($form->{deliverydate})
+    my $transdate = $form->{tax_point}    ? $dbh->quote($form->{tax_point})
+                  : $form->{deliverydate} ? $dbh->quote($form->{deliverydate})
                   : $form->{invdate}      ? $dbh->quote($form->{invdate})
                   :                         "current_date";
 
index 974a1a1..759f962 100644 (file)
--- a/SL/OE.pm
+++ b/SL/OE.pm
@@ -743,7 +743,7 @@ SQL
   $query =
     qq|UPDATE oe SET
          ordnumber = ?, quonumber = ?, cusordnumber = ?, transdate = ?, vendor_id = ?,
-         customer_id = ?, amount = ?, netamount = ?, reqdate = ?, taxincluded = ?,
+         customer_id = ?, amount = ?, netamount = ?, reqdate = ?, tax_point = ?, taxincluded = ?,
          shippingpoint = ?, shipvia = ?, notes = ?, intnotes = ?, currency_id = (SELECT id FROM currencies WHERE name=?), closed = ?,
          delivered = ?, proforma = ?, quotation = ?, department_id = ?, language_id = ?,
          taxzone_id = ?, shipto_id = ?, payment_id = ?, delivery_vendor_id = ?, delivery_customer_id = ?,delivery_term_id = ?,
@@ -754,7 +754,7 @@ SQL
   @values = ($form->{ordnumber} || '', $form->{quonumber},
              $form->{cusordnumber}, conv_date($form->{transdate}),
              conv_i($form->{vendor_id}), conv_i($form->{customer_id}),
-             $amount, $netamount, conv_date($reqdate),
+             $amount, $netamount, conv_date($reqdate), conv_date($form->{tax_point}),
              $form->{taxincluded} ? 't' : 'f', $form->{shippingpoint},
              $form->{shipvia}, $restricter->process($form->{notes}), $form->{intnotes},
              $form->{currency}, $form->{closed} ? 't' : 'f',
@@ -1017,7 +1017,7 @@ sub _retrieve {
            o.taxincluded, o.shippingpoint, o.shipvia, o.notes, o.intnotes,
            (SELECT cu.name FROM currencies cu WHERE cu.id=o.currency_id) AS currency, e.name AS employee, o.employee_id, o.salesman_id,
            o.${vc}_id, cv.name AS ${vc}, o.amount AS invtotal,
-           o.closed, o.reqdate, o.quonumber, o.department_id, o.cusordnumber,
+           o.closed, o.reqdate, o.tax_point, o.quonumber, o.department_id, o.cusordnumber,
            o.mtime, o.itime,
            d.description AS department, o.payment_id, o.language_id, o.taxzone_id,
            o.delivery_customer_id, o.delivery_vendor_id, o.proforma, o.shipto_id,
@@ -1096,7 +1096,7 @@ sub _retrieve {
       map { $form->{$_} =~ s/ +$//g } qw(printed emailed queued);
     }    # if !@ids
 
-    my $transdate = $form->{transdate} ? $dbh->quote($form->{transdate}) : "current_date";
+    my $transdate = $form->{tax_point} ? $dbh->quote($form->{tax_point}) : $form->{transdate} ? $dbh->quote($form->{transdate}) : "current_date";
 
     $form->{taxzone_id} = 0 unless ($form->{taxzone_id});
     unshift @values, ($form->{taxzone_id}) x 2;
index 978b193..9ca15b8 100644 (file)
@@ -1409,7 +1409,7 @@ sub print_form {
 
   # Format dates.
   format_dates($output_dateformat, $output_longdates,
-               qw(invdate orddate quodate pldate duedate reqdate transdate
+               qw(invdate orddate quodate pldate duedate reqdate transdate tax_point
                   shippingdate deliverydate validitydate paymentdate
                   datepaid transdate_oe transdate_do transdate_quo deliverydate_oe dodate
                   employee_startdate employee_enddate
index be1028c..c63bc87 100755 (executable)
@@ -3182,6 +3182,7 @@ $self->{texts} = {
   'Tax deleted!'                => 'Steuer gelöscht!',
   'Tax number'                  => 'Steuernummer',
   'Tax paid'                    => 'Vorsteuer',
+  'Tax point'                   => 'Leistungsdatum',
   'Tax rate'                    => 'Steuersatz',
   'Tax saved!'                  => 'Steuer gespeichert!',
   'Tax zone'                    => 'Steuerzone',
diff --git a/sql/Pg-upgrade2/tax_point.sql b/sql/Pg-upgrade2/tax_point.sql
new file mode 100644 (file)
index 0000000..7fcb65d
--- /dev/null
@@ -0,0 +1,7 @@
+-- @tag: tax_point
+-- @description: Feld Leistungsdatum in Einkaufs- & Verkaufsbelegen
+-- @depends: release_3_5_6_1
+ALTER TABLE ap ADD COLUMN tax_point DATE;
+ALTER TABLE ar ADD COLUMN tax_point DATE;
+ALTER TABLE gl ADD COLUMN tax_point DATE;
+ALTER TABLE oe ADD COLUMN tax_point DATE;
diff --git a/sql/Pg-upgrade2/tax_point2.sql b/sql/Pg-upgrade2/tax_point2.sql
new file mode 100644 (file)
index 0000000..6caf13d
--- /dev/null
@@ -0,0 +1,4 @@
+-- @tag: tax_point2
+-- @description: Feld Leistungsdatum in Lieferscheinen
+-- @depends: tax_point
+ALTER TABLE delivery_orders ADD COLUMN tax_point DATE;
index 6f73fd9..4905645 100644 (file)
                 <th align="right" nowrap>[% 'Due Date' | $T8 %]</th>
                 <td>[% L.date_tag('duedate', duedate) %]</td>
               </tr>
+              <tr>
+                <th align="right" nowrap>[% LxERP.t8('Tax point') %]</th>
+                <td>[% L.date_tag('tax_point', tax_point, id='tax_point') %]</td>
+              </tr>
               <tr>
                 <th align=right nowrap>[% 'Delivery Date' | $T8 %]</th>
                 <td>[% L.date_tag('deliverydate', deliverydate) %]</td>
index c1908a4..755d564 100644 (file)
                 <th align=right nowrap>[% 'Due Date' | $T8 %]</th>
                 <td>[% L.date_tag('duedate', duedate) %]</td>
               </tr>
+              <tr>
+                <th align="right" nowrap>[% LxERP.t8('Tax point') %]</th>
+                <td>[% L.date_tag('tax_point', tax_point, id='tax_point') %]</td>
+              </tr>
               <tr>
                 <th align=right nowrap>[% 'Delivery Date' | $T8 %]</th>
                 <td>[% L.date_tag('deliverydate', deliverydate) %]</td>
index 1cac15b..9ff8e98 100644 (file)
   <input type="hidden" name="type" id="type" value="[% HTML.escape(type) %]">
   <input type="hidden" name="vc" id="vc" value="[% HTML.escape(vc) %]">
   <input type="hidden" name="lastmtime" id="lastmtime" value="[% HTML.escape(lastmtime) %]">
+  <input type="hidden" name="tax_point" id="tax_point" value="[% HTML.escape(tax_point) %]">
 
   <p>
    <table width="100%">
index b021909..ba9036c 100644 (file)
         <tr>
           <th [%- departments_style -%]align="right">[% 'Department' | $T8 %]</th>
           <td [%- departments_style -%]>[% L.select_tag('department_id', ALL_DEPARTMENTS, default = department_id, title_key = 'description', with_empty = 1) %]</td>
-          <th align=right>[% 'Delivery Date' | $T8 %]</th>
-          <td>[% L.date_tag('deliverydate', deliverydate) %]</td>
+          <th align=right>[% 'Tax point' | $T8 %]</th>
+          <td>[% L.date_tag('tax_point', tax_point) %]</td>
         </tr>
         <tr>
           <th align="right">[% 'Description' | $T8 %]</th>
           <td>[% L.areainput_tag('description', description, cols=50, readonly=readonly) %]</td>
-          <th align="right">[% 'MwSt. inkl.' | $T8 %]</th>
-          <td>[% L.checkbox_tag('taxincluded', checked=taxincluded) %]</td>
+          <th align=right>[% 'Delivery Date' | $T8 %]</th>
+          <td>[% L.date_tag('deliverydate', deliverydate) %]</td>
         </tr>
-[%- IF id %]
         <tr>
-          <th align="right">[% 'Mitarbeiter' | $T8 %]</th>
-          <td>[% L.input_tag('employee', employee, size=20, readonly=readonly) %]</td>
+          <th align="right">[%- IF id %][% 'Mitarbeiter' | $T8 %][% END %]</th>
+          <td>[%- IF id %][% L.input_tag('employee', employee, size=20, readonly=readonly) %][% END %]</td>
+          <th align="right">[% 'MwSt. inkl.' | $T8 %]</th>
+          <td>[% L.checkbox_tag('taxincluded', checked=taxincluded) %]</td>
         </tr>
-[%- END %]
 
       <tr>
        <td colspan=4>
index 1c652d8..fac160a 100644 (file)
            <span id="duedate_fixed"[% IF !payment_terms_obj.auto_calculation %] style="display:none"[% END %]>[% HTML.escape(duedate) %]</span>
           </td>
         </tr>
+        <tr>
+          <th align="right" nowrap>[% LxERP.t8('Tax point') %]</th>
+          <td nowrap>[% L.date_tag('tax_point', tax_point, id='tax_point') %]</td>
+        </tr>
         <tr>
           <th align="right">[% 'Delivery Date' | $T8 %]</th>
           <td>[% L.date_tag('deliverydate', deliverydate) %]</td>
index e309740..c23c162 100644 (file)
            <span id="duedate_fixed"[% IF !payment_terms_obj.auto_calculation %] style="display:none"[% END %]>[% HTML.escape(duedate) %]</span>
           </td>
         </tr>
+[%- END %]
+        <tr>
+          <th align="right" nowrap>[% LxERP.t8('Tax point') %]</th>
+          <td nowrap>[% L.date_tag('tax_point', tax_point, id='tax_point') %]</td>
+        </tr>
+[%- IF !is_type_credit_note %]
         <tr>
-        <th align="right" nowrap>[% 'Delivery Order Number' | $T8 %]</th>
+          <th align="right" nowrap>[% 'Delivery Order Number' | $T8 %]</th>
           <td colspan="3"><input size='11' name="donumber" id="donumber" value="[% HTML.escape(donumber) %]"></td>
         </tr>
 [%- END %]
index 5569874..2390718 100644 (file)
                       [% L.date_tag('transdate', transdate, id='transdate') %]
                     </td>
                   </tr>
+                  <tr>
+                    <th align="right" nowrap>[% LxERP.t8('Tax point') %]</th>
+                    <td nowrap>[% L.date_tag('tax_point', tax_point, id='tax_point') %]</td>
+                  </tr>
                   <tr>
                     <th align="right" nowrap>
                      [%- IF is_sales_quo %]
index d7b84ff..975f04b 100644 (file)
             <td>[% L.date_tag('order.transdate_as_date', SELF.order.transdate_as_date) %]</td>
           </tr>
 
+          <tr>
+            <th width="70%" align="right" nowrap>[% 'Tax point' | $T8 %]</th>
+            <td>[% L.date_tag('order.tax_point_as_date', SELF.order.tax_point_as_date, class="recalc") %]</td>
+          </tr>
+
           [%- IF (SELF.type == "sales_order" || SELF.type == "purchase_order") -%]
-            [%- SET reqdate_txt = 'Reqdate' -%]
+            [%- SET reqdate_txt = 'Reqdate'; SET reqdate_class = 'recalc' -%]
           [%- ELSIF SELF.type == "sales_quotation" -%]
-            [%- SET reqdate_txt = 'Valid until' -%]
+            [%- SET reqdate_txt = 'Valid until'; SET reqdate_class = '' -%]
           [%- ELSE -%]
-            [%- SET reqdate_txt = 'Required by' -%]
+            [%- SET reqdate_txt = 'Required by'; SET reqdate_class = 'recalc' -%]
           [%- END -%]
           <tr>
             <th width="70%" align="right" nowrap>[% reqdate_txt | $T8 %]</th>
-            <td>[% L.date_tag('order.reqdate_as_date', SELF.order.reqdate_as_date) %]</td>
+            <td>[% L.date_tag('order.reqdate_as_date', SELF.order.reqdate_as_date, class=reqdate_class) %]</td>
           </tr>
 
           [%- IF SELF.type == "sales_quotation" -%]