Kreditorenbuchungen: Warnung bei vorhandener Rechnungsnummer für diesen Kreditor
authorJan Büren <jan@kivitendo.de>
Mon, 3 Sep 2018 13:34:15 +0000 (15:34 +0200)
committerJan Büren <jan@kivitendo.de>
Mon, 3 Sep 2018 13:34:15 +0000 (15:34 +0200)
Vorbedingung:
AP.js erweitert, sodass der Prüfcode entsprechende Inputs von IR oder AP prüft.

Erweiterungen:
Einkaufsrechnung (IR) mit derselben Prüfung wie Kreditorenbeleg beim Speichern versehen
Prüffunktion auf schon vorhandene Belegnummer zu diesem Kreditor bei
Einkaufs- oder Kreditorenbeleg implementiert.
Generischen Controller für JS-Prüfung (SalesPurchase.pm) mit einer
Funktion hinzugefügt, sowie entsprechend Changelog und locales.

SL/Controller/SalesPurchase.pm [new file with mode: 0644]
bin/mozilla/ap.pl
bin/mozilla/ir.pl
doc/changelog
js/kivi.AP.js
js/locale/de.js
locale/de/all
templates/webpages/ir/form_header.html

diff --git a/SL/Controller/SalesPurchase.pm b/SL/Controller/SalesPurchase.pm
new file mode 100644 (file)
index 0000000..2c045d2
--- /dev/null
@@ -0,0 +1,65 @@
+package SL::Controller::SalesPurchase;
+
+use strict;
+use parent qw(SL::Controller::Base);
+
+use SL::DB::PurchaseInvoice;
+use Carp;
+
+
+sub action_check_duplicate_invnumber {
+  my ($self) = @_;
+
+  croak("no invnumber") unless $::form->{invnumber};
+  croak("no vendor")    unless $::form->{vendor_id};
+
+  my $exists_ap = SL::DB::Manager::PurchaseInvoice->find_by(
+                   invnumber => $::form->{invnumber},
+                   vendor_id => $::form->{vendor_id},
+                 );
+
+  $_[0]->render(\ !!$exists_ap, { type => 'text' });
+}
+
+1;
+
+=pod
+
+=encoding utf8
+
+=head1 NAME
+
+SL::Controller::SalesPurchase - Controller for JS driven actions
+
+=head2 OVERVIEW
+
+Generic Controller Class for validation function
+
+=head1 FUNCTIONS
+
+=over 2
+
+=item C<action_check_duplicate_invnumber>
+
+Needs C<form.invnumber> and C<form.vendor_id>
+
+Returns true if a credit record with this invnumber for this vendor
+already exists.
+
+Example usage (js):
+
+ $.ajax({
+      url: 'controller.pl',
+      data: { action: 'SalesPurchase/check_duplicate_invnumber',
+              vendor_id    : $('#vendor_id').val(),
+              invnumber    : $('#invnumber').val()
+      },
+      method: "GET",
+      async: false,
+      dataType: 'text',
+      success: function(val) {
+        exists_invnumber = val;
+      }
+    });
+
+=back
index 77120a3..fccc684 100644 (file)
@@ -1221,7 +1221,7 @@ sub setup_ap_display_form_action_bar {
         action => [
           t8('Post'),
           submit   => [ '#form', { action => "post" } ],
-          checks   => [ 'kivi.validate_form', 'kivi.AP.check_fields_before_posting' ],
+          checks   => [ 'kivi.validate_form', 'kivi.AP.check_fields_before_posting', 'kivi.AP.check_duplicate_invnumber' ],
           disabled => $is_closed                                  ? t8('The billing period has already been locked.')
                     : $is_storno                                  ? t8('A canceled invoice cannot be posted.')
                     : ($::form->{id} && $change_never)            ? t8('Changing invoices has been disabled in the configuration.')
index 77ad46b..bf96658 100644 (file)
@@ -245,6 +245,8 @@ sub setup_ir_action_bar {
           t8('Post'),
           submit   => [ '#form', { action => "post" } ],
           checks   => [ 'kivi.validate_form' ],
+          checks   => [ 'kivi.validate_form', 'kivi.AP.check_fields_before_posting', 'kivi.AP.check_duplicate_invnumber' ],
+
           disabled => $form->{locked}                           ? t8('The billing period has already been locked.')
                     : $form->{storno}                           ? t8('A canceled invoice cannot be posted.')
                     : ($form->{id} && $change_never)            ? t8('Changing invoices has been disabled in the configuration.')
@@ -325,7 +327,8 @@ sub setup_ir_action_bar {
       ], # end of combobox "more"
     );
   }
-  $::request->layout->add_javascripts('kivi.Validator.js');
+  $::request->layout->add_javascripts('kivi.Validator.js', 'kivi.AP.js');
+
 }
 
 sub form_header {
@@ -392,6 +395,7 @@ sub form_header {
     $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
   }
 
+  # TODO There is no credit_note for vendor invoices (remove template code)
   $TMPL_VAR{is_type_credit_note} = $form->{type}   eq "credit_note";
   $TMPL_VAR{is_format_html}      = $form->{format} eq 'html';
   $TMPL_VAR{dateformat}          = $myconfig{dateformat};
index 46f20ea..693def0 100644 (file)
@@ -29,6 +29,7 @@ Mittelgroße neue Features:
 Kleinere neue Features und Detailverbesserungen:
   - Verknüpfte Belege um die Verknüpfung von Beleg nach E-Mail-Journal erweitert.
   - Filter nach Abteilungen für Lieferplan
+  - Eindeutigkeit bei Rechnungsnummern von Kreditoren. (Es erfolgt eine  Warnung bei Duplikaten (Überprüfung auf Lieferant mit Rechnungsnummer))
 
 Bugfixes:
 - Bugfix #336 Beim Drucken mehrerer Rechnung aus dem Bericht heraus mit aktiviertem DMS bricht mit Fehlermeldung ab
index 55c164f..463334a 100644 (file)
@@ -4,7 +4,9 @@ namespace('kivi.AP', function(ns){
   ns.check_fields_before_posting = function() {
     var errors = [];
 
-    if ($('#transdate').val() === '')
+    // if the element transdate exists, we have a AP form otherwise we have to check the invoice form
+    var invoice_date = ($('#transdate').length === 0) ? $('#transdate').val() : $('#invdate').val();
+    if (invoice_date === '')
       errors.push(kivi.t8('Invoice Date missing!'));
 
     if ($('#duedate').val() === '')
@@ -13,7 +15,7 @@ namespace('kivi.AP', function(ns){
     if ($('#invnumber').val() === '')
       errors.push(kivi.t8('Invoice Number missing!'));
 
-    if ($('#vendor').val() === '')
+    if ($('#vendor_id').val() ===  '')
       errors.push(kivi.t8('Vendor missing!'));
 
     if (errors.length === 0)
@@ -23,4 +25,29 @@ namespace('kivi.AP', function(ns){
 
     return false;
   };
+
+  ns.check_duplicate_invnumber = function() {
+    var exists_invnumber = false;
+
+    $.ajax({
+      url: 'controller.pl',
+      data: { action: 'SalesPurchase/check_duplicate_invnumber',
+              vendor_id    : $('#vendor_id').val(),
+              invnumber    : $('#invnumber').val()
+      },
+      method: "GET",
+      async: false,
+      dataType: 'text',
+      success: function(val) {
+        exists_invnumber = val;
+      }
+    });
+
+    if (exists_invnumber == 1) {
+      return confirm(kivi.t8('This vendor has already a booking with this invoice number, do you really want to add the same invoice number again?'));
+    }
+
+    return true;
+  };
+
 });
index ab6aea2..13218ae 100644 (file)
@@ -127,6 +127,7 @@ namespace("kivi").setupLocale({
 "There is one or more sections for which no part has been assigned yet; therefore creating the new record is not possible yet.":"Es gibt einen oder mehrere Abschnitte ohne Artikelzuweisung; daher kann der neue Beleg noch nicht erstellt werden.",
 "This field must not be empty.":"Dieses Feld darf nicht leer sein.",
 "This sales order has an active configuration for periodic invoices. If you save then all subsequently created invoices will contain those changes as well, but not those that have already been created. Do you want to continue?":"Dieser Auftrag besitzt eine aktive Konfiguration für wiederkehrende Rechnungen. Wenn Sie jetzt speichern, so werden alle zukünftig hieraus erzeugten Rechnungen die Änderungen enthalten, nicht aber die bereits erzeugten Rechnungen. Möchten Sie speichern?",
+"This vendor has already a booking with this invoice number, do you really want to add the same invoice number again?":"Es gibt für diesen Lieferant schon einen Beleg mit dieser Rechnungsnummer. Möchten Sie wirklich eine weitere Buchung mit derselben Rechnungsnummer hinzufügen?",
 "Time/cost estimate actions":"Aktionen für Kosten-/Zeitabschätzung",
 "Title":"Titel",
 "Toggle marker":"Markierung umschalten",
index 093d907..e7c978c 100755 (executable)
@@ -3503,6 +3503,7 @@ $self->{texts} = {
   'This update will change the nature the onhand of goods is tracked.' => 'Dieses update ändert die Art und Weise wie Lagermengen gezält werden.',
   'This user is a member in the following groups' => 'Dieser Benutzer ist Mitglied in den folgenden Gruppen',
   'This user will have access to the following clients' => 'Dieser Benutzer wird Zugriff auf die folgenden Mandanten haben',
+  'This vendor has already a booking with this invoice number, do you really want to add the same invoice number again?' => 'Es gibt für diesen Lieferant schon einen Beleg mit dieser Rechnungsnummer. Möchten Sie wirklich eine weitere Buchung mit derselben Rechnungsnummer hinzufügen?',
   'This vendor has already been added.' => 'Der Lieferant wurde bereits hinzugefügt.',
   'This vendor number is already in use.' => 'Diese Lieferantennummer wird bereits verwendet.',
   'This will apply a 3% reduction to the master data price before entering it into the record item.' => 'Diese Zeile zieht vom Stammdatenpreis 3% ab, und schlägt den resultierenden Preis vor.',
index 775a8b6..4c3d29a 100644 (file)
 [%- ELSE %]
         <tr>
           <th align="right" nowrap>[% 'Invoice Number' | $T8 %]</th>
-          <td colspan="3"><input size='11' name="invnumber" value="[% HTML.escape(invnumber) %]"></td>
+          <td colspan="3">[% L.input_tag("invnumber", invnumber, size="11") %]</td>
         </tr>
         <tr>
           <th align="right">[% 'Invoice Date' | $T8 %]</th>