Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 7e6e1bcf

Von Cem Aydin vor fast 3 Jahren hinzugefügt

  • ID 7e6e1bcf72dfb323d9759abdbe072bc9a53b841a
  • Vorgänger 3a2209c2
  • Nachfolger dd4d801e

Swiss QR-Bill: In Druckablauf OpenDocument/OASIS integrieren

- Feature in Mandantenkonfiguration einschaltbar
- Aufruf zum Erzeugen von QR-Code PNG (Steven Schubiger)
- Vorlage hinzugefügt (rev-odt/invoice_qr.odt)
- PNG Bild CH-Kreuz hinzugefügt
- Übersetzungen hinzugefügt, locales Script ausgeführt de/en
- changelog eintrag

Unterschiede anzeigen:

SL/Template/OpenDocument.pm
6 6
use Encode;
7 7
use HTML::Entities;
8 8
use POSIX 'setsid';
9
use XML::LibXML;
9 10

  
10 11
use SL::Iconv;
11 12
use SL::Template::OpenDocument::Styles;
12 13

  
14
use SL::DB::BankAccount;
15
use SL::Helper::QrBill;
16
use SL::Helper::ISO3166;
17

  
13 18
use Cwd;
14 19
# use File::Copy;
15 20
# use File::Spec;
16 21
# use File::Temp qw(:mktemp);
17 22
use IO::File;
23
use List::Util qw(first);
18 24

  
19 25
use strict;
20 26

  
......
346 352
sub parse {
347 353
  $main::lxdebug->enter_sub();
348 354
  my $self = $_[0];
355

  
349 356
  local *OUT = $_[1];
350 357
  my $form = $self->{"form"};
351 358

  
352 359
  close(OUT);
353 360

  
361
  my $qr_image_path;
362
  if ($::instance_conf->get_create_qrbill_invoices) {
363
    # the biller account information, biller address and the reference number,
364
    # are needed in the template aswell as in the qr-code generation, therefore
365
    # assemble these and add to $::form
366
    $qr_image_path = $self->generate_qr_code;
367
  }
368

  
354 369
  my $file_name;
355 370
  if ($form->{"IN"} =~ m|^/|) {
356 371
    $file_name = $form->{"IN"};
......
420 435
    $zip->contents("styles.xml", Encode::encode('utf-8-strict', $new_styles));
421 436
  }
422 437

  
438
  if ($::instance_conf->get_create_qrbill_invoices) {
439
    # get placeholder path from odt XML
440
    my $qr_placeholder_path;
441
    my $dom = XML::LibXML->load_xml(string => $contents);
442
    my @nodelist = $dom->getElementsByTagName("draw:frame");
443
    for my $node (@nodelist) {
444
      my $attr = $node->getAttribute('draw:name');
445
      if ($attr eq 'QRCodePlaceholder') {
446
        my @children = $node->getChildrenByTagName('draw:image');
447
        $qr_placeholder_path = $children[0]->getAttribute('xlink:href');
448
      }
449
    }
450
    if (!defined($qr_placeholder_path)) {
451
      $::form->error($::locale->text('QR-Code placeholder image: QRCodePlaceholder not found in template.'));
452
    }
453
    # replace QR-Code Placeholder Image in zip file (odt) with generated one
454
    $zip->updateMember(
455
     $qr_placeholder_path,
456
     $qr_image_path
457
    );
458
  }
459

  
423 460
  $zip->writeToFileNamed($form->{"tmpfile"}, 1);
424 461

  
425 462
  my $res = 1;
......
431 468
  return $res;
432 469
}
433 470

  
471
sub get_qrbill_account {
472
  $main::lxdebug->enter_sub();
473
  my ($self) = @_;
474

  
475
  my $qr_account;
476

  
477
  my $bank_accounts     = SL::DB::Manager::BankAccount->get_all;
478
  $qr_account = scalar(@{ $bank_accounts }) == 1 ?
479
    $bank_accounts->[0] :
480
    first { $_->use_for_qrbill } @{ $bank_accounts };
481

  
482
  if (!$qr_account) {
483
    $::form->error($::locale->text('No bank account flagged for QRBill usage was found.'));
484
  }
485

  
486
  $main::lxdebug->leave_sub();
487
  return $qr_account;
488
}
489

  
490
sub remove_letters_prefix {
491
  my $s = $_[0];
492
  $s =~ s/^[a-zA-Z]+//;
493
  return $s;
494
}
495

  
496
sub check_digits_and_max_length {
497
  my $s = $_[0];
498
  my $length = $_[1];
499

  
500
  return 0 if (!($s =~ /^\d*$/) || length($s) > $length);
501
  return 1;
502
}
503

  
504
sub calculate_check_digit {
505
  # calculate ESR check digit using algorithm: "modulo 10, recursive"
506
  my $ref_number_str = $_[0];
507

  
508
  my @m = (0, 9, 4, 6, 8, 2, 7, 1, 3, 5);
509
  my $carry = 0;
510

  
511
  my @ref_number_split = map int($_), split(//, $ref_number_str);
512

  
513
  for my $v (@ref_number_split) {
514
    $carry = @m[($carry + $v) % 10];
515
  }
516

  
517
  return (10 - $carry) % 10;
518
}
519

  
520
sub assemble_ref_number {
521
  $main::lxdebug->enter_sub();
522

  
523
  my $bank_id = $_[0];
524
  my $customer_number = $_[1];
525
  my $order_number = $_[2] // "0";
526
  my $invoice_number = $_[3] // "0";
527

  
528
  # check values (analog to checks in makro)
529
  # - bank_id
530
  #     input: 6 digits, only numbers
531
  #     output: 6 digits, only numbers
532
  if (!($bank_id =~ /^\d*$/) || length($bank_id) != 6) {
533
    $::form->error($::locale->text('Bank account id number invalid. Must be 6 digits.'));
534
  }
535

  
536
  # - customer_number
537
  #     input: prefix (letters) + up to 6 digits (numbers)
538
  #     output: prefix removed, 6 digits, filled with leading zeros
539
  $customer_number = remove_letters_prefix($customer_number);
540
  if (!check_digits_and_max_length($customer_number, 6)) {
541
    $::form->error($::locale->text('Customer number invalid. Must be less then or equal to 6 digits after prefix.'));
542
  }
543
  # fill with zeros
544
  $customer_number = sprintf "%06d", $customer_number;
545

  
546
  # - order_number
547
  #     input: prefix (letters) + up to 7 digits, may be zero
548
  #     output: prefix removed, 7 digits, filled with leading zeros
549
  $order_number = remove_letters_prefix($order_number);
550
  if (!check_digits_and_max_length($order_number, 7)) {
551
    $::form->error($::locale->text('Order number invalid. Must be less then or equal to 7 digits after prefix.'));
552
  }
553
  # fill with zeros
554
  $order_number = sprintf "%07d", $order_number;
555

  
556
  # - invoice_number
557
  #     input: prefix (letters) + up to 7 digits, may be zero
558
  #     output: prefix removed, 7 digits, filled with leading zeros
559
  $invoice_number = remove_letters_prefix($invoice_number);
560
  if (!check_digits_and_max_length($invoice_number, 7)) {
561
    $::form->error($::locale->text('Invoice number invalid. Must be less then or equal to 7 digits after prefix.'));
562
  }
563
  # fill with zeros
564
  $invoice_number = sprintf "%07d", $invoice_number;
565

  
566
  # assemble ref. number
567
  my $ref_number = $bank_id . $customer_number . $order_number . $invoice_number;
568

  
569
  # calculate check digit
570
  my $ref_number_cpl = $ref_number . calculate_check_digit($ref_number);
571

  
572
  $main::lxdebug->leave_sub();
573
  return $ref_number_cpl;
574
}
575

  
576
sub get_ref_number_formatted {
577
  $main::lxdebug->enter_sub();
578

  
579
  my $ref_number = $_[0];
580

  
581
  # create ref. number in format:
582
  # 'XX XXXXX XXXXX XXXXX XXXXX XXXXX' (2 digits + 5 x 5 digits)
583
  my $ref_number_spaced = substr($ref_number, 0, 2) . ' ' .
584
                          substr($ref_number, 2, 5) . ' ' .
585
                          substr($ref_number, 7, 5) . ' ' .
586
                          substr($ref_number, 12, 5) . ' ' .
587
                          substr($ref_number, 17, 5) . ' ' .
588
                          substr($ref_number, 22, 5);
589

  
590
  $main::lxdebug->leave_sub();
591
  return $ref_number_spaced;
592
}
593

  
594
sub get_iban_formatted {
595
  $main::lxdebug->enter_sub();
596

  
597
  my $iban = $_[0];
598

  
599
  # create iban number in format:
600
  # 'XXXX XXXX XXXX XXXX XXXX X' (5 x 4 + 1digits)
601
  my $iban_spaced = substr($iban, 0, 4) . ' ' .
602
                    substr($iban, 4, 4) . ' ' .
603
                    substr($iban, 8, 4) . ' ' .
604
                    substr($iban, 12, 4) . ' ' .
605
                    substr($iban, 16, 4) . ' ' .
606
                    substr($iban, 20, 1);
607

  
608
  $main::lxdebug->leave_sub();
609
  return $iban_spaced;
610
}
611

  
612
sub get_amount_formatted {
613
  $main::lxdebug->enter_sub();
614

  
615
  unless ($_[0] =~ /^\d+\.\d{2}$/) {
616
    $::form->error($::locale->text('Amount has wrong format.'));
617
  }
618

  
619
  local $_ = shift;
620
  $_ = reverse split //;
621
  m/^\d{2}\./g;
622
  s/\G(\d{3})(?=\d)/$1 /g;
623

  
624
  $main::lxdebug->leave_sub();
625
  return scalar reverse split //;
626
}
627

  
628
sub generate_qr_code {
629
  $main::lxdebug->enter_sub();
630
  my $self = $_[0];
631
  my $form = $self->{"form"};
632

  
633
  # assemble data for QR-Code
634

  
635
  # get qr-account data
636
  my $qr_account = $self->get_qrbill_account();
637

  
638
  my %biller_information = (
639
    'iban' => $qr_account->{'iban'}
640
  );
641

  
642
  my $biller_countrycode = SL::Helper::ISO3166::map_name_to_alpha_2_code(
643
    $::instance_conf->get_address_country()
644
  );
645
  if (!$biller_countrycode) {
646
    $::form->error($::locale->text('Error mapping biller countrycode.'));
647
  }
648
  my %biller_data = (
649
    'address_type' => 'K',
650
    'company' => $::instance_conf->get_company(),
651
    'address_row1' => $::instance_conf->get_address_street1(),
652
    'address_row2' => $::instance_conf->get_address_zipcode() . ' ' . $::instance_conf->get_address_city(),
653
    'countrycode' => $biller_countrycode,
654
  );
655

  
656
  my %payment_information = (
657
    'amount' => sprintf("%.2f", $form->parse_amount(\%::myconfig, $form->{'total'})),
658
    'currency' => $form->{'currency'},
659
  );
660

  
661
  my $customer_countrycode = SL::Helper::ISO3166::map_name_to_alpha_2_code($form->{'country'});
662
  if (!$customer_countrycode) {
663
    $::form->error($::locale->text('Error mapping customer countrycode.'));
664
  }
665
  my %invoice_recipient_data = (
666
    'address_type' => 'K',
667
    'name' => $form->{'name'},
668
    'address_row1' => $form->{'street'},
669
    'address_row2' => $form->{'zipcode'} . ' ' . $form->{'city'},
670
    'countrycode' => $customer_countrycode,
671
  );
672

  
673
  # generate ref.-no. with check digit
674
  my $ref_number = assemble_ref_number(
675
    $qr_account->{'bank_account_id'},
676
    $form->{'customernumber'},
677
    $form->{'ordnumber'},
678
    $form->{'invnumber'},
679
  );
680

  
681
  my %ref_nr_data = (
682
    'type' => 'QRR',
683
    'ref_number' => $ref_number,
684
  );
685

  
686
  # set into form for template processing
687
  $form->{'biller_information'} = \%biller_information;
688
  $form->{'biller_data'} = \%biller_data;
689
  $form->{'ref_number'} = $ref_number;
690

  
691
  # get ref. number/iban formatted with spaces
692
  $form->{'ref_number_formatted'} = get_ref_number_formatted($ref_number);
693
  $form->{'iban_formatted'} = get_iban_formatted($qr_account->{'iban'});
694

  
695
  # format amount for template
696
  $form->{'amount_formatted'} = get_amount_formatted(
697
    sprintf(
698
      "%.2f",
699
      $form->parse_amount(\%::myconfig, $form->{'total'})
700
    )
701
  );
702

  
703
  # set outfile
704
  my $outfile = $form->{"tmpdir"} . '/' . 'qr-code.png';
705

  
706
  # generate QR-Code Image
707
  eval {
708
   my $qr_image = SL::Helper::QrBill->new(
709
     \%biller_information,
710
     \%biller_data,
711
     \%payment_information,
712
     \%invoice_recipient_data,
713
     \%ref_nr_data,
714
   );
715
   $qr_image->generate($outfile);
716
  } or do {
717
   local $_ = $@; chomp; my $error = $_;
718
   $::form->error($::locale->text('QR-Image generation failed: ' . $error));
719
  };
720

  
721
  $main::lxdebug->leave_sub();
722
  return $outfile;
723
}
724

  
434 725
sub is_xvfb_running {
435 726
  $main::lxdebug->enter_sub();
436 727

  
doc/changelog
15 15

  
16 16
Mittelgroße neue Features:
17 17

  
18
In Kundenstammdaten können nun abweichende Rechnungsadressen analog zu
19
Lieferadressen verwaltet werden. Diese können in Verkaufsbelegen
20
ausgewählt werden. Sie stehen den Druckvorlagen als eigene Variablen
21
zur Verfügung.
22

  
18
- In Kundenstammdaten können nun abweichende Rechnungsadressen analog zu
19
  Lieferadressen verwaltet werden. Diese können in Verkaufsbelegen
20
  ausgewählt werden. Sie stehen den Druckvorlagen als eigene Variablen
21
  zur Verfügung.
22
- Unterstützung für Schweizer QR-Rechnung mit OpenDocument Vorlagen.
23
  Variante: QR-IBAN mit QR-Referenz
23 24

  
24 25
Kleinere neue Features und Detailverbesserungen:
25 26

  
locale/de/all
311 311
  'Amount BT'                   => 'Betrag Bank',
312 312
  'Amount Due'                  => 'Betrag fällig',
313 313
  'Amount and net amount are calculated by kivitendo. "verify_amount" and "verify_netamount" can be used for sanity checks.' => 'Betrag und Nettobetrag werden von kivitendo berechnet. "verify_amount" und "verify_netamount" können für Plausibilitätsprüfungen angegeben werden.',
314
  'Amount has wrong format.'    => 'Betrag hat falsches Format.',
314 315
  'Amount less skonto'          => 'Betrag abzgl. Skonto',
315 316
  'Amount payable'              => 'Noch zu bezahlender Betrag',
316 317
  'Amount payable less discount' => 'Noch zu bezahlender Betrag abzüglich Skonto',
......
429 430
  'Balances'                    => 'Salden',
430 431
  'Balancing'                   => 'Bilanzierung',
431 432
  'Bank'                        => 'Bank',
433
  'Bank Account Id Number (Swiss)' => 'Bankkonto Identifikationsnummer (Schweiz)',
432 434
  'Bank Code'                   => 'BLZ',
433 435
  'Bank Code (long)'            => 'Bankleitzahl (BLZ)',
434 436
  'Bank Code Number'            => 'Bankleitzahl',
......
438 440
  'Bank Transaction'            => 'Bankkonto',
439 441
  'Bank Transaction is in a closed period.' => 'Die Bankbewegung befindet sich innerhalb eines geschlossenen Zeitraums.',
440 442
  'Bank account'                => 'Bankkonto',
443
  'Bank account id number invalid. Must be 6 digits.' => 'Bank Identifikationsnummer ungültig. (6-stellig)',
441 444
  'Bank accounts'               => 'Bankkonten',
442 445
  'Bank code'                   => 'Bankleitzahl',
443 446
  'Bank code of the goal/source' => 'Bankleitzahl von Ziel- oder Quellkonto',
......
812 815
  'Create one from the context menu by right-clicking on this text.' => 'Erstellen Sie einen aus dem Kontextmenü, indem Sie auf diesen Text rechtsklicken.',
813 816
  'Create order'                => 'Auftrag erstellen',
814 817
  'Create sales invoices with Factur-X/ZUGFeRD data' => 'Verkaufsrechnungen mit Factur-X-/ZUGFeRD-Daten erzeugen',
818
  'Create sales invoices with Swiss QR-Bill' => 'Verkaufsrechnungen mit schweizer QR-Rechnung erzeugen',
815 819
  'Create tables'               => 'Tabellen anlegen',
816 820
  'Create with profile \'Factur-X 1.0.05/ZUGFeRD 2.1.1 extended\'' => 'Mit Profil »Factur-X 1.0.05/ZUGFeRD 2.1.1 extended«',
817 821
  'Create with profile \'Factur-X 1.0.05/ZUGFeRD 2.1.1 extended\' (test mode)' => 'Mit Profil »Factur-X 1.0.05/ZUGFeRD 2.1.1 extended« (Test-Modus)',
......
886 890
  'Customer missing!'           => 'Kundenname fehlt!',
887 891
  'Customer must not be empty.' => 'Kunden darf nicht leer sein.',
888 892
  'Customer not found'          => 'Kunde nicht gefunden',
893
  'Customer number invalid. Must be less then or equal to 6 digits after prefix.' => 'Kundennummer ungültig. (kleiner/gleich 6 Stellen nach Prefix)',
889 894
  'Customer of assigned order must match customer.' => 'Kunde des zugeordneten Auftrags muss mit dem gewählten Kunden übereinstimmen.',
890 895
  'Customer of assigned project must match customer.' => 'Kunde des zugeordneten Projekts muss mit dem gewählten Kunden übereinstimmen.',
891 896
  'Customer saved'              => 'Kunde gespeichert',
......
1356 1361
  'Error in position #1: You must either assign no stock at all or the full quantity of #2 #3.' => 'Fehler in Position #1: Sie müssen einer Position entweder gar keinen Lagereingang oder die vollständige im Lieferschein vermerkte Menge von #2 #3 zuweisen.',
1357 1362
  'Error in position #1: You must either assign no transfer at all or the full quantity of #2 #3.' => 'Fehler in Position #1: Sie müssen einer Position entweder gar keinen Lagerausgang oder die vollständige im Lieferschein vermerkte Menge von #2 #3 zuweisen.',
1358 1363
  'Error in row #1: The quantity you entered is bigger than the stocked quantity.' => 'Fehler in Zeile #1: Die angegebene Menge ist größer als die vorhandene Menge.',
1364
  'Error mapping biller countrycode.' => 'Fehler beim erzeugen des Ländercode für Rechnungssteller.',
1365
  'Error mapping customer countrycode.' => 'Fehler beim erzeugen des Ländercode für Kunden.',
1359 1366
  'Error message from the database driver:' => 'Fehlermeldung des Datenbanktreibers:',
1360 1367
  'Error message from the database: #1' => 'Fehlermeldung der Datenbank: #1',
1361 1368
  'Error message from the webshop api:' => 'Fehlermeldung der Webshop Api',
......
1714 1721
  'If enabled a warning will be shown in sales delivery orders on workflow to invoices if positions are not stocked out.' => 'Falls aktiviert, wird eine Warnung beim Workflow von Verkaufslieferscheinen zu Rechnungen ausgegeben, wenn die Positionen noch nicht ausgelagert sind.',
1715 1722
  'If enabled only those projects that are assigned to the currently selected customer are offered for selection in sales records.' => 'Wenn eingeschaltet, so werden in Verkaufsbelegen nur diejenigen Projekte zur Auswahl angeboten, die dem aktuell ausgewählten Kunden zugewiesen wurden.',
1716 1723
  'If enabled purchase and sales records cannot be saved if no transaction description has been entered.' => 'Wenn angeschaltet, so können Einkaufs- und Verkaufsbelege nicht gespeichert werden, solange keine Vorgangsbezeichnung eingegeben wurde.',
1724
  'If enabled sales invoices created using OpenDocument/OASIS format will include data for Swiss QR-Bill creation.' => 'Falls aktiviert, enthalten Rechnungen im OpenDocument/OASIS Format, Daten zur schweizer QR-Rechnung.',
1717 1725
  'If enabled the record links view starts always from the sales order including all sublevels' => 'Falls aktiv, werden die verknüpften Belege immer vom Verkaufsauftrag inkl. aller darunterliegenden Belege angezeigt',
1718 1726
  'If item not found, allow creation of new item' => 'Falls Artikel nicht gefunden, erlaube Erfassen eines Neuen',
1719 1727
  'If left empty the default sender from the kivitendo configuration will be used (key \'email_from\' in section \'periodic_invoices\'; current value: #1).' => 'Falls leer, so wird der Standardabsender aus der kivitendo-Konfiguration genutzt (Schlüssel »email_from« in Abschnitt »periodic_invoices«; aktueller Wert: #1).',
......
1857 1865
  'Invoice for fees'            => 'Rechnung über Gebühren',
1858 1866
  'Invoice has already been storno\'d!' => 'Diese Rechnung wurde bereits storniert.',
1859 1867
  'Invoice number'              => 'Rechnungsnummer',
1868
  'Invoice number invalid. Must be less then or equal to 7 digits after prefix.' => 'Rechnungsnummer ungültig. (kleiner/gleich 7 Stellen nach Prefix)',
1860 1869
  'Invoice to:'                 => 'Rechnung an:',
1861 1870
  'Invoice total'               => 'Die Rechnungssumme',
1862 1871
  'Invoice total less discount' => 'Rechnungssumme abzüglich Skonto',
......
2163 2172
  'No bank account chosen!'     => 'Kein Bankkonto ausgewählt!',
2164 2173
  'No bank account configured for bank code/BIC #1, account number/IBAN #2.' => 'Kein Bankkonto für BLZ/BIC #1, Kontonummer/IBAN #2 konfiguriert.',
2165 2174
  'No bank account flagged for Factur-X/ZUGFeRD usage was found.' => 'Es wurde kein Bankkonto gefunden, das für Nutzung mit Factur-X/ZUGFeRD markiert ist.',
2175
  'No bank account flagged for QRBill usage was found.' => 'Kein Bankkonto markiert für QR-Rechnung gefunden.',
2166 2176
  'No bank information has been entered in this customer\'s master data entry. You cannot create bank collections unless you enter bank information.' => 'Für diesen Kunden wurden in seinen Stammdaten keine Kontodaten hinterlegt. Solange dies nicht geschehen ist, können Sie keine Überweisungen für den Lieferanten anlegen.',
2167 2177
  'No bank information has been entered in this vendor\'s master data entry. You cannot create bank transfers unless you enter bank information.' => 'Für diesen Lieferanten wurden in seinen Stammdaten keine Kontodaten hinterlegt. Solange dies nicht geschehen ist, können Sie keine Überweisungen für den Lieferanten anlegen.',
2168 2178
  'No bins have been added to this warehouse yet.' => 'Es wurden zu diesem Lager noch keine Lagerplätze angelegt.',
......
2339 2349
  'Order amount'                => 'Auftragswert',
2340 2350
  'Order deleted!'              => 'Auftrag gelöscht!',
2341 2351
  'Order item search'           => 'Auftragsartikelsuche',
2352
  'Order number invalid. Must be less then or equal to 7 digits after prefix.' => 'Auftragsnummer ungültig. (kleiner/gleich 7 Stellen nach Prefix)',
2342 2353
  'Order probability'           => 'Auftragswahrscheinlichkeit',
2343 2354
  'Order probability & expected billing date' => 'Auftragswahrscheinlichkeit & vorrauss. Abrechnungsdatum',
2344 2355
  'Order value periodicity'     => 'Auftragswert basiert auf Periodizität',
......
2695 2706
  'Purpose'                     => 'Verwendungszweck',
2696 2707
  '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)',
2697 2708
  'Purpose/Reference'           => 'Verwendungszweck und Referenz',
2709
  'QR-Code placeholder image: QRCodePlaceholder not found in template.' => 'QR-Code Platzhalter Bild: QRCodePlaceholder nicht gefunden.',
2710
  'QR-Image generation failed: ' => 'QR-Code Erzeugung fehlgeschlagen: ',
2698 2711
  'QUEUED'                      => 'In Warteschlange',
2699 2712
  'Qty'                         => 'Menge',
2700 2713
  'Qty according to delivery order' => 'Menge laut Lieferschein',
......
4056 4069
  'Use default booking group because wanted is missing' => 'Fehlende Buchungsgruppe, deshalb Standardbuchungsgruppe',
4057 4070
  'Use existing templates'      => 'Vorhandene Druckvorlagen verwenden',
4058 4071
  'Use for Factur-X/ZUGFeRD'    => 'Nutzung mit Factur-X/ZUGFeRD',
4072
  'Use for Swiss QR-Bill'       => 'Nutzung mit schweizer QR-Rechnung',
4059 4073
  'Use master default bin for Default Transfer, if no default bin for the part is configured' => 'Standardlagerplatz für Ein- / Auslagern über Standard-Lagerplatz, falls für die Ware kein expliziter Lagerplatz konfiguriert ist',
4060 4074
  'Use settings from client configuration' => 'Einstellungen aus Mandantenkonfiguration folgen',
4061 4075
  'Use text field for department of contacts' => 'Textfeld für Abteilungen von Ansprechpersonen verwenden',
locale/en/all
311 311
  'Amount BT'                   => '',
312 312
  'Amount Due'                  => '',
313 313
  'Amount and net amount are calculated by kivitendo. "verify_amount" and "verify_netamount" can be used for sanity checks.' => '',
314
  'Amount has wrong format.'    => '',
314 315
  'Amount less skonto'          => '',
315 316
  'Amount payable'              => '',
316 317
  'Amount payable less discount' => '',
......
429 430
  'Balances'                    => '',
430 431
  'Balancing'                   => '',
431 432
  'Bank'                        => '',
433
  'Bank Account Id Number (Swiss)' => '',
432 434
  'Bank Code'                   => '',
433 435
  'Bank Code (long)'            => '',
434 436
  'Bank Code Number'            => '',
......
438 440
  'Bank Transaction'            => '',
439 441
  'Bank Transaction is in a closed period.' => '',
440 442
  'Bank account'                => '',
443
  'Bank account id number invalid. Must be 6 digits.' => '',
441 444
  'Bank accounts'               => '',
442 445
  'Bank code'                   => '',
443 446
  'Bank code of the goal/source' => '',
......
812 815
  'Create one from the context menu by right-clicking on this text.' => '',
813 816
  'Create order'                => '',
814 817
  'Create sales invoices with Factur-X/ZUGFeRD data' => '',
818
  'Create sales invoices with Swiss QR-Bill' => '',
815 819
  'Create tables'               => '',
816 820
  'Create with profile \'Factur-X 1.0.05/ZUGFeRD 2.1.1 extended\'' => '',
817 821
  'Create with profile \'Factur-X 1.0.05/ZUGFeRD 2.1.1 extended\' (test mode)' => '',
......
886 890
  'Customer missing!'           => '',
887 891
  'Customer must not be empty.' => '',
888 892
  'Customer not found'          => '',
893
  'Customer number invalid. Must be less then or equal to 6 digits after prefix.' => '',
889 894
  'Customer of assigned order must match customer.' => '',
890 895
  'Customer of assigned project must match customer.' => '',
891 896
  'Customer saved'              => '',
......
1356 1361
  'Error in position #1: You must either assign no stock at all or the full quantity of #2 #3.' => '',
1357 1362
  'Error in position #1: You must either assign no transfer at all or the full quantity of #2 #3.' => '',
1358 1363
  'Error in row #1: The quantity you entered is bigger than the stocked quantity.' => '',
1364
  'Error mapping biller countrycode.' => '',
1365
  'Error mapping customer countrycode.' => '',
1359 1366
  'Error message from the database driver:' => '',
1360 1367
  'Error message from the database: #1' => '',
1361 1368
  'Error message from the webshop api:' => '',
......
1714 1721
  'If enabled a warning will be shown in sales delivery orders on workflow to invoices if positions are not stocked out.' => '',
1715 1722
  'If enabled only those projects that are assigned to the currently selected customer are offered for selection in sales records.' => '',
1716 1723
  'If enabled purchase and sales records cannot be saved if no transaction description has been entered.' => '',
1724
  'If enabled sales invoices created using OpenDocument/OASIS format will include data for Swiss QR-Bill creation.' => '',
1717 1725
  'If enabled the record links view starts always from the sales order including all sublevels' => '',
1718 1726
  'If item not found, allow creation of new item' => '',
1719 1727
  'If left empty the default sender from the kivitendo configuration will be used (key \'email_from\' in section \'periodic_invoices\'; current value: #1).' => '',
......
1857 1865
  'Invoice for fees'            => '',
1858 1866
  'Invoice has already been storno\'d!' => '',
1859 1867
  'Invoice number'              => '',
1868
  'Invoice number invalid. Must be less then or equal to 7 digits after prefix.' => '',
1860 1869
  'Invoice to:'                 => '',
1861 1870
  'Invoice total'               => '',
1862 1871
  'Invoice total less discount' => '',
......
2163 2172
  'No bank account chosen!'     => '',
2164 2173
  'No bank account configured for bank code/BIC #1, account number/IBAN #2.' => '',
2165 2174
  'No bank account flagged for Factur-X/ZUGFeRD usage was found.' => '',
2175
  'No bank account flagged for QRBill usage was found.' => '',
2166 2176
  'No bank information has been entered in this customer\'s master data entry. You cannot create bank collections unless you enter bank information.' => '',
2167 2177
  'No bank information has been entered in this vendor\'s master data entry. You cannot create bank transfers unless you enter bank information.' => '',
2168 2178
  'No bins have been added to this warehouse yet.' => '',
......
2339 2349
  'Order amount'                => '',
2340 2350
  'Order deleted!'              => '',
2341 2351
  'Order item search'           => '',
2352
  'Order number invalid. Must be less then or equal to 7 digits after prefix.' => '',
2342 2353
  'Order probability'           => '',
2343 2354
  'Order probability & expected billing date' => '',
2344 2355
  'Order value periodicity'     => '',
......
2695 2706
  'Purpose'                     => '',
2696 2707
  'Purpose (if field names purpose, purpose1, purpose2 ... exist they will all combined into the field "purpose")' => '',
2697 2708
  'Purpose/Reference'           => '',
2709
  'QR-Code placeholder image: QRCodePlaceholder not found in template.' => '',
2710
  'QR-Image generation failed: ' => '',
2698 2711
  'QUEUED'                      => '',
2699 2712
  'Qty'                         => '',
2700 2713
  'Qty according to delivery order' => '',
......
4055 4068
  'Use default booking group because wanted is missing' => '',
4056 4069
  'Use existing templates'      => '',
4057 4070
  'Use for Factur-X/ZUGFeRD'    => '',
4071
  'Use for Swiss QR-Bill'       => '',
4058 4072
  'Use master default bin for Default Transfer, if no default bin for the part is configured' => '',
4059 4073
  'Use settings from client configuration' => '',
4060 4074
  'Use text field for department of contacts' => '',
templates/webpages/client_config/_features.html
277 277
     [% LxERP.t8("If the test mode is enabled, the Factur-X/ZUGFeRD invoices will be flagged so that they're only fit to be used for testing purposes.") %]
278 278
   </td>
279 279
  </tr>
280
  <tr>
281
   <td align="right">[% LxERP.t8("Create sales invoices with Swiss QR-Bill") %]</td>
282
   <td>[% L.yes_no_tag("defaults.create_qrbill_invoices", SELF.defaults.create_qrbill_invoices) %]</td>
283
   <td>[% LxERP.t8("If enabled sales invoices created using OpenDocument/OASIS format will include data for Swiss QR-Bill creation.") %]</td>
284
  </tr>
280 285

  
281 286
  <tr><td class="listheading" colspan="4">[% LxERP.t8("E-mail") %]</td></tr>
282 287

  

Auch abrufbar als: Unified diff