Revision 7e6e1bcf
Von Cem Aydin vor fast 3 Jahren hinzugefügt
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
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