commit db101cc6810a2250cac479b6f653bf084c625adf
Author: Cem Aydin <cem.aydin@gmx.ch>
Date:   Thu Sep 1 12:07:55 2022 +0200

    Swiss QR-Bill: QR-Referenz soll in der jeweiligen Rechnung gespeichert werden

diff --git a/SL/IS.pm b/SL/IS.pm
index fdc70ab3a..e85fc695c 100644
--- a/SL/IS.pm
+++ b/SL/IS.pm
@@ -53,6 +53,7 @@ use SL::IC;
 use SL::IO;
 use SL::TransNumber;
 use SL::DB::Chart;
+use SL::DB::Customer;
 use SL::DB::Default;
 use SL::DB::Draft;
 use SL::DB::Tax;
@@ -60,6 +61,7 @@ use SL::DB::TaxZone;
 use SL::TransNumber;
 use SL::DB;
 use SL::Presenter::Part qw(type_abbreviation classification_abbreviation);
+use SL::Helper::QrBillFunctions qw(get_qrbill_account assemble_ref_number);
 use Data::Dumper;
 
 use strict;
@@ -1467,6 +1469,33 @@ SQL
 
   $amount = $form->round_amount( $netamount + $tax, 2, 1);
 
+  # qr reference
+  my $qr_reference;
+  if ($form->{has_qr_reference}) {
+    # (re-)generate reference number
+
+    # get qr-account data
+    my ($qr_account, $error) = get_qrbill_account();
+    die $error if !$qr_account;
+
+    # get customer object
+    my $customer_obj = SL::DB::Customer->load_cached(conv_i($form->{customer_id}));
+
+    # assemble reference number with check digit
+    ($qr_reference, $error) = assemble_ref_number($qr_account->{bank_account_id},
+                                                  $customer_obj->{customernumber},
+                                                  $form->{ordnumber},
+                                                  $form->{invnumber});
+    die $error if !$qr_reference;
+  } else {
+    # if the reference number has been previously defined keep it
+    if (defined $form->{qr_reference}) {
+      $qr_reference = $form->{qr_reference};
+    } else {
+      $qr_reference = undef;
+    }
+  }
+
   # save AR record
   #erweiterung fuer lieferscheinnummer (donumber) 12.02.09 jb
 
@@ -1484,7 +1513,7 @@ SQL
                 globalproject_id               = ?, delivery_customer_id             = ?,
                 transaction_description        = ?, delivery_vendor_id               = ?,
                 donumber    = ?, invnumber_for_credit_note = ?,        direct_debit  = ?, qrbill_without_amount = ?,
-                delivery_term_id = ?
+                qr_reference = ?, 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_date($form->{tax_point}), conv_i($form->{"customer_id"}),
@@ -1498,7 +1527,7 @@ SQL
                 conv_i($form->{"globalproject_id"}),                              conv_i($form->{"delivery_customer_id"}),
                        $form->{transaction_description},                          conv_i($form->{"delivery_vendor_id"}),
                        $form->{"donumber"}, $form->{"invnumber_for_credit_note"},        $form->{direct_debit} ? 't' : 'f', $form->{qrbill_without_amount} ? 't' : 'f',
-                conv_i($form->{delivery_term_id}),
+                $qr_reference, conv_i($form->{delivery_term_id}),
                 conv_i($form->{"id"}));
   do_query($form, $dbh, $query, @values);
 
@@ -2251,7 +2280,7 @@ sub _retrieve_invoice {
            a.mtime, a.itime,
            a.language_id, a.delivery_customer_id, a.delivery_vendor_id, a.type,
            a.transaction_description, a.donumber, a.invnumber_for_credit_note,
-           a.marge_total, a.marge_percent, a.direct_debit, a.qrbill_without_amount, a.delivery_term_id,
+           a.marge_total, a.marge_percent, a.direct_debit, a.qrbill_without_amount, a.qr_reference, a.delivery_term_id,
            dc.dunning_description,
            e.name AS employee
          FROM ar a
diff --git a/SL/Template/OpenDocument.pm b/SL/Template/OpenDocument.pm
index 01612852c..d9cec5e28 100644
--- a/SL/Template/OpenDocument.pm
+++ b/SL/Template/OpenDocument.pm
@@ -13,8 +13,8 @@ use SL::Template::OpenDocument::Styles;
 
 use SL::DB::BankAccount;
 use SL::Helper::QrBill;
-use SL::Helper::QrBillFunctions qw(get_qrbill_account assemble_ref_number
-  get_ref_number_formatted get_iban_formatted get_amount_formatted);
+use SL::Helper::QrBillFunctions qw(get_qrbill_account get_ref_number_formatted
+  get_iban_formatted get_amount_formatted);
 use SL::Helper::ISO3166;
 
 use Cwd;
@@ -538,24 +538,14 @@ sub generate_qr_code {
 
   my %ref_nr_data;
   if ($::instance_conf->get_create_qrbill_invoices == 1) {
-    # generate ref.-no. with check digit
-    my ($ref_number, $error) = assemble_ref_number(
-      $qr_account->{'bank_account_id'},
-      $form->{'customernumber'},
-      $form->{'ordnumber'},
-      $form->{'invnumber'},
-    );
-    if (!$ref_number) {
-      $::form->error($error);
-    }
     %ref_nr_data = (
       'type' => 'QRR',
-      'ref_number' => $ref_number,
+      'ref_number' => $form->{'qr_reference'},
     );
     # get ref. number/iban formatted with spaces and set into form for template
     # processing
-    $form->{'ref_number'} = $ref_number;
-    $form->{'ref_number_formatted'} = get_ref_number_formatted($ref_number);
+    $form->{'ref_number'} = $form->{'qr_reference'};
+    $form->{'ref_number_formatted'} = get_ref_number_formatted($form->{'qr_reference'});
   } elsif ($::instance_conf->get_create_qrbill_invoices == 2) {
     %ref_nr_data = (
       'type' => 'NON',
diff --git a/bin/mozilla/is.pl b/bin/mozilla/is.pl
index 698054ffe..b8a4f61bf 100644
--- a/bin/mozilla/is.pl
+++ b/bin/mozilla/is.pl
@@ -53,6 +53,7 @@ use SL::DB::Department;
 use SL::DB::Invoice;
 use SL::DB::PaymentTerm;
 use SL::DB::ValidityToken;
+use SL::Helper::QrBillFunctions qw(get_ref_number_formatted);
 
 require "bin/mozilla/common.pl";
 require "bin/mozilla/io.pl";
@@ -624,6 +625,15 @@ sub form_header {
   $TMPL_VAR{creditwarning} = ($form->{creditlimit} != 0) && ($form->{creditremaining} < 0) && !$form->{update};
   $TMPL_VAR{is_credit_remaining_negativ} = $form->{creditremaining} =~ /-/;
 
+# qr reference
+my $has_qr_reference = $::instance_conf->get_create_qrbill_invoices == 1 &&
+                       $form->{formname} eq 'invoice' ? 1 : 0;
+$TMPL_VAR{has_qr_reference} = $has_qr_reference;
+
+if ($has_qr_reference && defined $form->{qr_reference}) {
+  $TMPL_VAR{qr_reference_formatted} = get_ref_number_formatted($form->{qr_reference});
+}
+
 # set option selected
   foreach my $item (qw(AR)) {
     $form->{"select$item"} =~ s/ selected//;
diff --git a/locale/de/all b/locale/de/all
index e8b10fa7d..1863b9029 100755
--- a/locale/de/all
+++ b/locale/de/all
@@ -2781,6 +2781,7 @@ $self->{texts} = {
   'Purpose (if field names purpose, purpose1, purpose2 ... exist they will all combined into the field "purpose")' => 'Verwendungszweck (wenn die Spalten purpose, purpose1, purpose2 ... existieren werden diese zum Feld "purpose" zusammengefügt)',
   'Purpose/Reference'           => 'Verwendungszweck und Referenz',
   'QR bill without amount'      => 'QR-Rechnung ohne Betrag',
+  'QR reference'                => 'QR-Referenz',
   'QR-Code placeholder image: QRCodePlaceholder not found in template.' => 'QR-Code Platzhalter Bild: QRCodePlaceholder nicht in Druckvorlage gefunden.',
   'QR-Image generation failed: ' => 'QR-Code Erzeugung fehlgeschlagen: ',
   'QUEUED'                      => 'In Warteschlange',
diff --git a/locale/en/all b/locale/en/all
index cb1152fd4..9879fb8ab 100644
--- a/locale/en/all
+++ b/locale/en/all
@@ -2781,6 +2781,7 @@ $self->{texts} = {
   'Purpose (if field names purpose, purpose1, purpose2 ... exist they will all combined into the field "purpose")' => '',
   'Purpose/Reference'           => '',
   'QR bill without amount'      => '',
+  'QR reference'                => '',
   'QR-Code placeholder image: QRCodePlaceholder not found in template.' => '',
   'QR-Image generation failed: ' => '',
   'QUEUED'                      => '',
diff --git a/templates/webpages/is/form_header.html b/templates/webpages/is/form_header.html
index db192777e..71b38617d 100644
--- a/templates/webpages/is/form_header.html
+++ b/templates/webpages/is/form_header.html
@@ -19,6 +19,10 @@
 <input type="hidden" name="follow_up_rowcount" id="follow_up_rowcount" value="1">
 <input type="hidden" name="lastmtime" id="lastmtime" value="[% HTML.escape(lastmtime) %]">
 <input type="hidden" name="already_printed_flag" id="already_printed_flag" value="0">
+<input type="hidden" name="has_qr_reference" id="has_qr_reference" value="[% has_qr_reference %]">
+[%- IF qr_reference %]
+[%   L.hidden_tag("qr_reference", qr_reference) %]
+[%- END %]
 [% IF !id %]
 [%   L.hidden_tag('form_validity_token', form_validity_token) %]
 [% END %]
@@ -313,6 +317,18 @@
             [%- L.select_tag('globalproject_id', ALL_PROJECTS, title_key = 'projectnumber', default = globalproject_id, with_empty = '1', onChange = "document.getElementById('update_button').click();") %]
           </td>
         </tr>
+        [%- IF has_qr_reference %]
+        <tr>
+          <th align="right" nowrap>[% 'QR reference' | $T8 %]</th>
+          <td>
+            [%- IF qr_reference %]
+              [% HTML.escape(qr_reference_formatted) %]
+            [%- ELSE %]
+              [% LxERP.t8("will be set upon posting") %]
+            [%- END %]
+          </td>
+        </tr>
+        [%- END %]
       </table>
     </td>
   </tr>
