]> wagnertech.de Git - mfinanz.git/blobdiff - SL/Template/OpenDocument.pm
kivitendo 3.9.2-0.2
[mfinanz.git] / SL / Template / OpenDocument.pm
index 66d8f83ac3f5bbae8924020e4bb1f64cf5eeba41..06dd6d9733ad7962eaa340a405ed07faaf876977 100644 (file)
@@ -7,20 +7,22 @@ use Encode;
 use HTML::Entities;
 use POSIX 'setsid';
 use XML::LibXML;
+use File::Basename;
 
 use SL::Iconv;
 use SL::Template::OpenDocument::Styles;
 
-use SL::DB::BankAccount;
 use SL::Helper::QrBill;
-use SL::Helper::ISO3166;
+use SL::Helper::QrBillFunctions qw(
+  get_ref_number_formatted get_iban_formatted get_amount_formatted
+  get_street_name_from_address_line get_building_number_from_address_line
+);
 
 use Cwd;
 # use File::Copy;
 # use File::Spec;
 # use File::Temp qw(:mktemp);
 use IO::File;
-use List::Util qw(first);
 
 use strict;
 
@@ -200,7 +202,7 @@ sub find_end {
 
     } elsif ((substr($text, $pos + 4, 4) eq 'else') && (1 == $depth)) {
       if (!$var) {
-        $self->{"error"} = '<%else%> outside of <%if%> / <%ifnot%>.';
+        $self->{error} = '<%else%> outside of <%if%> / <%ifnot%>.';
         return undef;
       }
 
@@ -256,7 +258,7 @@ sub parse_block {
 
           ($table_row, $contents) = $self->find_end($contents, length($1));
           if (!$table_row) {
-            $self->{"error"} = "Unclosed <\%foreachrow\%>." unless ($self->{"error"});
+            $self->{error} = "Unclosed <\%foreachrow\%>." unless ($self->{"error"});
             $main::lxdebug->leave_sub();
             return undef;
           }
@@ -311,7 +313,7 @@ sub parse_block {
         substr($contents, 0, $pos_foreach) = "";
 
         if ($contents !~ m|^(\&lt;\%foreach (.*?)\%\&gt;)|) {
-          $self->{"error"} = "Malformed <\%foreach\%>.";
+          $self->{error} = "Malformed <\%foreach\%>.";
           $main::lxdebug->leave_sub();
           return undef;
         }
@@ -323,7 +325,7 @@ sub parse_block {
         my $block;
         ($block, $contents) = $self->find_end($contents);
         if (!$block) {
-          $self->{"error"} = "Unclosed <\%foreach\%>." unless ($self->{"error"});
+          $self->{error} = "Unclosed <\%foreach\%>." unless ($self->{error});
           $main::lxdebug->leave_sub();
           return undef;
         }
@@ -354,12 +356,18 @@ sub parse {
   my $self = $_[0];
 
   local *OUT = $_[1];
-  my $form = $self->{"form"};
+  my $form = $self->{form};
 
   close(OUT);
 
+  my $is_qr_bill = $::instance_conf->get_create_qrbill_invoices &&
+                   ($form->{formname} eq 'invoice' ||
+                    $form->{formname} eq 'invoice_for_advance_payment') &&
+                   $form->{template_meta}->{printer}->{template_code} =~ m/qr/ ?
+                   1 : 0;
+
   my $qr_image_path;
-  if ($::instance_conf->get_create_qrbill_invoices && $form->{formname} eq 'invoice') {
+  if ($is_qr_bill) {
     # the biller account information, biller address and the reference number,
     # are needed in the template aswell as in the qr-code generation, therefore
     # assemble these and add to $::form
@@ -367,22 +375,22 @@ sub parse {
   }
 
   my $file_name;
-  if ($form->{"IN"} =~ m|^/|) {
-    $file_name = $form->{"IN"};
+  if ($form->{IN} =~ m|^/|) {
+    $file_name = $form->{IN};
   } else {
-    $file_name = $form->{"templates"} . "/" . $form->{"IN"};
+    $file_name = $form->{templates} . "/" . $form->{IN};
   }
 
   my $zip = Archive::Zip->new();
   if (Archive::Zip->AZ_OK != $zip->read($file_name)) {
-    $self->{"error"} = "File not found/is not a OpenDocument file.";
+    $self->{error} = "File not found/is not a OpenDocument file.";
     $main::lxdebug->leave_sub();
     return 0;
   }
 
   my $contents = Encode::decode('utf-8-strict', $zip->contents("content.xml"));
   if (!$contents) {
-    $self->{"error"} = "File is not a OpenDocument file.";
+    $self->{error} = "File is not a OpenDocument file.";
     $main::lxdebug->leave_sub();
     return 0;
   }
@@ -435,7 +443,7 @@ sub parse {
     $zip->contents("styles.xml", Encode::encode('utf-8-strict', $new_styles));
   }
 
-  if ($::instance_conf->get_create_qrbill_invoices && $form->{formname} eq 'invoice') {
+  if ($is_qr_bill) {
     # get placeholder path from odt XML
     my $qr_placeholder_path;
     my $dom = XML::LibXML->load_xml(string => $contents);
@@ -457,10 +465,10 @@ sub parse {
     );
   }
 
-  $zip->writeToFileNamed($form->{"tmpfile"}, 1);
+  $zip->writeToFileNamed($form->{tmpfile}, 1);
 
   my $res = 1;
-  if ($form->{"format"} =~ /pdf/) {
+  if ($form->{format} =~ /pdf/) {
     $res = $self->convert_to_pdf();
   }
 
@@ -468,256 +476,125 @@ sub parse {
   return $res;
 }
 
-sub get_qrbill_account {
-  $main::lxdebug->enter_sub();
-  my ($self) = @_;
-
-  my $qr_account;
-
-  my $bank_accounts     = SL::DB::Manager::BankAccount->get_all;
-  $qr_account = scalar(@{ $bank_accounts }) == 1 ?
-    $bank_accounts->[0] :
-    first { $_->use_for_qrbill } @{ $bank_accounts };
-
-  if (!$qr_account) {
-    $::form->error($::locale->text('No bank account flagged for QRBill usage was found.'));
-  }
-
-  $main::lxdebug->leave_sub();
-  return $qr_account;
-}
-
-sub remove_letters_prefix {
-  my $s = $_[0];
-  $s =~ s/^[a-zA-Z]+//;
-  return $s;
-}
-
-sub check_digits_and_max_length {
-  my $s = $_[0];
-  my $length = $_[1];
-
-  return 0 if (!($s =~ /^\d*$/) || length($s) > $length);
-  return 1;
-}
-
-sub calculate_check_digit {
-  # calculate ESR check digit using algorithm: "modulo 10, recursive"
-  my $ref_number_str = $_[0];
-
-  my @m = (0, 9, 4, 6, 8, 2, 7, 1, 3, 5);
-  my $carry = 0;
-
-  my @ref_number_split = map int($_), split(//, $ref_number_str);
-
-  for my $v (@ref_number_split) {
-    $carry = @m[($carry + $v) % 10];
-  }
-
-  return (10 - $carry) % 10;
-}
-
-sub assemble_ref_number {
-  $main::lxdebug->enter_sub();
-
-  my $bank_id = $_[0];
-  my $customer_number = $_[1];
-  my $order_number = $_[2] // "0";
-  my $invoice_number = $_[3] // "0";
-
-  # check values (analog to checks in makro)
-  # - bank_id
-  #     input: 6 digits, only numbers
-  #     output: 6 digits, only numbers
-  if (!($bank_id =~ /^\d*$/) || length($bank_id) != 6) {
-    $::form->error($::locale->text('Bank account id number invalid. Must be 6 digits.'));
-  }
-
-  # - customer_number
-  #     input: prefix (letters) + up to 6 digits (numbers)
-  #     output: prefix removed, 6 digits, filled with leading zeros
-  $customer_number = remove_letters_prefix($customer_number);
-  if (!check_digits_and_max_length($customer_number, 6)) {
-    $::form->error($::locale->text('Customer number invalid. Must be less then or equal to 6 digits after prefix.'));
-  }
-  # fill with zeros
-  $customer_number = sprintf "%06d", $customer_number;
-
-  # - order_number
-  #     input: prefix (letters) + up to 7 digits, may be zero
-  #     output: prefix removed, 7 digits, filled with leading zeros
-  $order_number = remove_letters_prefix($order_number);
-  if (!check_digits_and_max_length($order_number, 7)) {
-    $::form->error($::locale->text('Order number invalid. Must be less then or equal to 7 digits after prefix.'));
-  }
-  # fill with zeros
-  $order_number = sprintf "%07d", $order_number;
-
-  # - invoice_number
-  #     input: prefix (letters) + up to 7 digits, may be zero
-  #     output: prefix removed, 7 digits, filled with leading zeros
-  $invoice_number = remove_letters_prefix($invoice_number);
-  if (!check_digits_and_max_length($invoice_number, 7)) {
-    $::form->error($::locale->text('Invoice number invalid. Must be less then or equal to 7 digits after prefix.'));
-  }
-  # fill with zeros
-  $invoice_number = sprintf "%07d", $invoice_number;
-
-  # assemble ref. number
-  my $ref_number = $bank_id . $customer_number . $order_number . $invoice_number;
-
-  # calculate check digit
-  my $ref_number_cpl = $ref_number . calculate_check_digit($ref_number);
-
-  $main::lxdebug->leave_sub();
-  return $ref_number_cpl;
-}
-
-sub get_ref_number_formatted {
-  $main::lxdebug->enter_sub();
-
-  my $ref_number = $_[0];
-
-  # create ref. number in format:
-  # 'XX XXXXX XXXXX XXXXX XXXXX XXXXX' (2 digits + 5 x 5 digits)
-  my $ref_number_spaced = substr($ref_number, 0, 2) . ' ' .
-                          substr($ref_number, 2, 5) . ' ' .
-                          substr($ref_number, 7, 5) . ' ' .
-                          substr($ref_number, 12, 5) . ' ' .
-                          substr($ref_number, 17, 5) . ' ' .
-                          substr($ref_number, 22, 5);
-
-  $main::lxdebug->leave_sub();
-  return $ref_number_spaced;
-}
-
-sub get_iban_formatted {
-  $main::lxdebug->enter_sub();
-
-  my $iban = $_[0];
-
-  # create iban number in format:
-  # 'XXXX XXXX XXXX XXXX XXXX X' (5 x 4 + 1digits)
-  my $iban_spaced = substr($iban, 0, 4) . ' ' .
-                    substr($iban, 4, 4) . ' ' .
-                    substr($iban, 8, 4) . ' ' .
-                    substr($iban, 12, 4) . ' ' .
-                    substr($iban, 16, 4) . ' ' .
-                    substr($iban, 20, 1);
-
-  $main::lxdebug->leave_sub();
-  return $iban_spaced;
-}
-
-sub get_amount_formatted {
-  $main::lxdebug->enter_sub();
-
-  unless ($_[0] =~ /^\d+\.\d{2}$/) {
-    $::form->error($::locale->text('Amount has wrong format.'));
-  }
-
-  local $_ = shift;
-  $_ = reverse split //;
-  m/^\d{2}\./g;
-  s/\G(\d{3})(?=\d)/$1 /g;
-
-  $main::lxdebug->leave_sub();
-  return scalar reverse split //;
-}
-
 sub generate_qr_code {
   $main::lxdebug->enter_sub();
   my $self = $_[0];
-  my $form = $self->{"form"};
+  my $form = $self->{form};
 
   # assemble data for QR-Code
 
-  # get qr-account data
-  my $qr_account = $self->get_qrbill_account();
+  if (!$form->{qrbill_iban}) {
+    $::form->error($::locale->text('No bank account flagged for QRBill usage was found.'));
+  }
 
   my %biller_information = (
-    'iban' => $qr_account->{'iban'}
+    iban => $form->{qrbill_iban}
   );
 
-  my $biller_countrycode = SL::Helper::ISO3166::map_name_to_alpha_2_code(
-    $::instance_conf->get_address_country()
-  );
-  if (!$biller_countrycode) {
+  if (!$form->{qrbill_biller_countrycode}) {
     $::form->error($::locale->text('Error mapping biller countrycode.'));
   }
   my %biller_data = (
-    'address_type' => 'K',
-    'company' => $::instance_conf->get_company(),
-    'address_row1' => $::instance_conf->get_address_street1(),
-    'address_row2' => $::instance_conf->get_address_zipcode() . ' ' . $::instance_conf->get_address_city(),
-    'countrycode' => $biller_countrycode,
+    address_type => 'S',
+    company => $::instance_conf->get_company(),
+    street => get_street_name_from_address_line($::instance_conf->get_address_street1()),
+    street_no => get_building_number_from_address_line($::instance_conf->get_address_street1()),
+    postalcode => $::instance_conf->get_address_zipcode(),
+    city => $::instance_conf->get_address_city(),
+    countrycode => $form->{qrbill_biller_countrycode},
   );
 
-  my $amount;
-  if ($form->{'qrbill_without_amount'}) {
+  my ($amount, $amount_formatted);
+  if ($form->{qrbill_without_amount}) {
     $amount = '';
+    $amount_formatted = '';
   } else {
-    $amount = sprintf("%.2f", $form->parse_amount(\%::myconfig, $form->{'total'}));
+    $amount = $form->{qrbill_amount};
+
+    # format amount for template
+    $amount_formatted = get_amount_formatted($amount);
+    if (!$amount_formatted) {
+      $::form->error($::locale->text('Amount has wrong format.'));
+    }
   }
 
   my %payment_information = (
-    'amount' => $amount,
-    'currency' => $form->{'currency'},
+    amount => $amount,
+    currency => $form->{currency},
   );
 
-  my $customer_countrycode = SL::Helper::ISO3166::map_name_to_alpha_2_code($form->{'country'});
-  if (!$customer_countrycode) {
+  # get address data from billing address if given, otherwise from invoice
+  my $street_name = get_street_name_from_address_line($form->{billing_address_id} ?
+      $form->{billing_address_street} :
+      $form->{street});
+  my $building_number = get_building_number_from_address_line($form->{billing_address_id} ?
+      $form->{billing_address_street} :
+      $form->{street});
+  my $postalcode = $form->{billing_address_id} ?
+      $form->{billing_address_zipcode} :
+      $form->{zipcode};
+  my $city = $form->{billing_address_id} ?
+      $form->{billing_address_city} :
+      $form->{city};
+
+  # validate address data
+  if ($postalcode !~ m/^\d{4,}$/) {
+    $::form->error($::locale->text('Zipcode missing or wrong format.'));
+  }
+  if (!$city) {
+    $::form->error($::locale->text('No city given.'));
+  }
+  if (!$form->{qrbill_customer_countrycode}) {
     $::form->error($::locale->text('Error mapping customer countrycode.'));
   }
+
   my %invoice_recipient_data = (
-    'address_type' => 'K',
-    'name' => $form->{'name'},
-    'address_row1' => $form->{'street'},
-    'address_row2' => $form->{'zipcode'} . ' ' . $form->{'city'},
-    'countrycode' => $customer_countrycode,
+    address_type => 'S',
+    name => $form->{billing_address_id} ?
+              $form->{billing_address_name} :
+              $form->{name},
+    street => $street_name,
+    street_no => $building_number,
+    postalcode => $postalcode,
+    city => $city,
+    countrycode => $form->{qrbill_customer_countrycode},
   );
 
   my %ref_nr_data;
   if ($::instance_conf->get_create_qrbill_invoices == 1) {
-    # generate ref.-no. with check digit
-    my $ref_number = assemble_ref_number(
-      $qr_account->{'bank_account_id'},
-      $form->{'customernumber'},
-      $form->{'ordnumber'},
-      $form->{'invnumber'},
-    );
+    # fill reference number with zeros when printing preview (before booking)
+    my $reference_number = $form->{id} ? $form->{qr_reference} : '0' x 27;
+
     %ref_nr_data = (
-      'type' => 'QRR',
-      'ref_number' => $ref_number,
+      type => 'QRR',
+      ref_number => $reference_number,
     );
     # 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} = $reference_number;
+    $form->{ref_number_formatted} = get_ref_number_formatted($reference_number);
   } elsif ($::instance_conf->get_create_qrbill_invoices == 2) {
     %ref_nr_data = (
-      'type' => 'NON',
-      'ref_number' => '',
+      type => 'NON',
+      ref_number => '',
     );
   } else {
     $::form->error($::locale->text('Error getting QR-Bill type.'));
   }
 
-  # set into form for template processing
-  $form->{'biller_information'} = \%biller_information;
-  $form->{'biller_data'} = \%biller_data;
-  $form->{'iban_formatted'} = get_iban_formatted($qr_account->{'iban'});
-
-  # format amount for template
-  $form->{'amount_formatted'} = get_amount_formatted(
-    sprintf(
-      "%.2f",
-      $form->parse_amount(\%::myconfig, $form->{'total'})
-    )
+  my %additional_information = (
+    unstructured_message => $form->{qr_unstructured_message}
   );
 
+  # set into form for template processing
+  $form->{biller_information} = \%biller_information;
+  $form->{biller_data} = \%biller_data;
+  $form->{iban_formatted} = get_iban_formatted($form->{qrbill_iban});
+  $form->{amount_formatted} = $amount_formatted;
+  $form->{unstructured_message} = $form->{qr_unstructured_message};
+
   # set outfile
-  my $outfile = $form->{"tmpdir"} . '/' . 'qr-code.png';
+  my $outfile = $form->{tmpdir} . '/' . 'qr-code.png';
 
   # generate QR-Code Image
   eval {
@@ -727,6 +604,7 @@ sub generate_qr_code {
      \%payment_information,
      \%invoice_recipient_data,
      \%ref_nr_data,
+     \%additional_information
    );
    $qr_image->generate($outfile);
   } or do {
@@ -738,133 +616,6 @@ sub generate_qr_code {
   return $outfile;
 }
 
-sub is_xvfb_running {
-  $main::lxdebug->enter_sub();
-
-  my ($self) = @_;
-
-  local *IN;
-  my $dfname = $self->{"userspath"} . "/xvfb_display";
-  my $display;
-
-  $main::lxdebug->message(LXDebug->DEBUG2(), "    Looking for $dfname\n");
-  if ((-f $dfname) && open(IN, $dfname)) {
-    my $pid = <IN>;
-    chomp($pid);
-    $display = <IN>;
-    chomp($display);
-    my $xauthority = <IN>;
-    chomp($xauthority);
-    close(IN);
-
-    $main::lxdebug->message(LXDebug->DEBUG2(), "      found with $pid and $display\n");
-
-    if ((! -d "/proc/$pid") || !open(IN, "/proc/$pid/cmdline")) {
-      $main::lxdebug->message(LXDebug->DEBUG2(), "  no/wrong process #1\n");
-      unlink($dfname, $xauthority);
-      $main::lxdebug->leave_sub();
-      return undef;
-    }
-    my $line = <IN>;
-    close(IN);
-    if ($line !~ /xvfb/i) {
-      $main::lxdebug->message(LXDebug->DEBUG2(), "      no/wrong process #2\n");
-      unlink($dfname, $xauthority);
-      $main::lxdebug->leave_sub();
-      return undef;
-    }
-
-    $ENV{"XAUTHORITY"} = $xauthority;
-    $ENV{"DISPLAY"} = $display;
-  } else {
-    $main::lxdebug->message(LXDebug->DEBUG2(), "      not found\n");
-  }
-
-  $main::lxdebug->leave_sub();
-
-  return $display;
-}
-
-sub spawn_xvfb {
-  $main::lxdebug->enter_sub();
-
-  my ($self) = @_;
-
-  $main::lxdebug->message(LXDebug->DEBUG2, "spawn_xvfb()\n");
-
-  my $display = $self->is_xvfb_running();
-
-  if ($display) {
-    $main::lxdebug->leave_sub();
-    return $display;
-  }
-
-  $display = 99;
-  while ( -f "/tmp/.X${display}-lock") {
-    $display++;
-  }
-  $display = ":${display}";
-  $main::lxdebug->message(LXDebug->DEBUG2(), "  display $display\n");
-
-  my $mcookie = `mcookie`;
-  die("Installation error: mcookie not found.") if ($? != 0);
-  chomp($mcookie);
-
-  $main::lxdebug->message(LXDebug->DEBUG2(), "  mcookie $mcookie\n");
-
-  my $xauthority = "/tmp/.Xauthority-" . $$ . "-" . time() . "-" . int(rand(9999999));
-  $ENV{"XAUTHORITY"} = $xauthority;
-
-  $main::lxdebug->message(LXDebug->DEBUG2(), "  xauthority $xauthority\n");
-
-  if (system("xauth add \"${display}\" . \"${mcookie}\"") == -1) {
-    die "system call to xauth failed: $!";
-  }
-  if ($? != 0) {
-    $self->{"error"} = "Conversion to PDF failed because OpenOffice could not be started (xauth: $!)";
-    $main::lxdebug->leave_sub();
-    return undef;
-  }
-
-  $main::lxdebug->message(LXDebug->DEBUG2(), "  about to fork()\n");
-
-  my $pid = fork();
-  if (0 == $pid) {
-    $main::lxdebug->message(LXDebug->DEBUG2(), "  Child execing\n");
-    exec($::lx_office_conf{applications}->{xvfb}, $display, "-screen", "0", "640x480x8", "-nolisten", "tcp");
-  }
-  sleep(3);
-  $main::lxdebug->message(LXDebug->DEBUG2(), "  parent dont sleeping\n");
-
-  local *OUT;
-  my $dfname = $self->{"userspath"} . "/xvfb_display";
-  if (!open(OUT, ">", $dfname)) {
-    $self->{"error"} = "Conversion to PDF failed because OpenOffice could not be started ($dfname: $!)";
-    unlink($xauthority);
-    kill($pid);
-    $main::lxdebug->leave_sub();
-    return undef;
-  }
-  print(OUT "$pid\n$display\n$xauthority\n");
-  close(OUT);
-
-  $main::lxdebug->message(LXDebug->DEBUG2(), "  parent re-testing\n");
-
-  if (!$self->is_xvfb_running()) {
-    $self->{"error"} = "Conversion to PDF failed because OpenOffice could not be started.";
-    unlink($xauthority, $dfname);
-    kill($pid);
-    $main::lxdebug->leave_sub();
-    return undef;
-  }
-
-  $main::lxdebug->message(LXDebug->DEBUG2(), "  spawn OK\n");
-
-  $main::lxdebug->leave_sub();
-
-  return $display;
-}
-
 sub _run_python_uno {
   my ($self, @args) = @_;
 
@@ -927,9 +678,9 @@ sub spawn_openoffice {
         my $ssres = setsid();
         $main::lxdebug->message(LXDebug->DEBUG2(), "  Child execing\n");
         my @cmdline = ($::lx_office_conf{applications}->{openofficeorg_writer},
-                       "-minimized", "-norestore", "-nologo", "-nolockcheck",
-                       "-headless",
-                       "-accept=socket,host=localhost,port=" .
+                       "--minimized", "--norestore", "--nologo", "--nolockcheck",
+                       "--headless",
+                       "--accept=socket,host=localhost,port=" .
                        $::lx_office_conf{print_templates}->{openofficeorg_daemon_port} . ";urp;");
         exec(@cmdline);
       } else {
@@ -948,7 +699,7 @@ sub spawn_openoffice {
   }
 
   if (!$res) {
-    $self->{"error"} = "Conversion from OpenDocument to PDF failed because " .
+    $self->{error} = "Conversion from OpenDocument to PDF failed because " .
       "OpenOffice could not be started.";
   }
 
@@ -962,30 +713,27 @@ sub convert_to_pdf {
 
   my ($self) = @_;
 
-  my $form = $self->{"form"};
+  my $form = $self->{form};
 
-  my $filename = $form->{"tmpfile"};
+  my $filename = $form->{tmpfile};
   $filename =~ s/.odt$//;
   if (substr($filename, 0, 1) ne "/") {
     $filename = getcwd() . "/${filename}";
   }
 
-  if (substr($self->{"userspath"}, 0, 1) eq "/") {
-    $ENV{'HOME'} = $self->{"userspath"};
+  if (substr($self->{userspath}, 0, 1) eq "/") {
+    $ENV{HOME} = $self->{userspath};
   } else {
-    $ENV{'HOME'} = getcwd() . "/" . $self->{"userspath"};
+    $ENV{HOME} = getcwd() . "/" . $self->{userspath};
   }
 
-  if (!$self->spawn_xvfb()) {
-    $main::lxdebug->leave_sub();
-    return 0;
-  }
+  my $outdir = dirname($filename);
 
   if (!$::lx_office_conf{print_templates}->{openofficeorg_daemon}) {
     if (system($::lx_office_conf{applications}->{openofficeorg_writer},
-               "-minimized", "-norestore", "-nologo", "-nolockcheck", "-headless",
-               "file:${filename}.odt",
-               "macro://" . (split('/', $filename))[-1] . "/Standard.Conversion.ConvertSelfToPDF()") == -1) {
+               "--minimized", "--norestore", "--nologo", "--nolockcheck", "--headless",
+               "--convert-to", "pdf", "--outdir", $outdir,
+               "file:${filename}.odt") == -1) {
       die "system call to $::lx_office_conf{applications}->{openofficeorg_writer} failed: $!";
     }
   } else {
@@ -999,7 +747,7 @@ sub convert_to_pdf {
 
   my $res = $?;
   if ((0 == $?) || (-f "${filename}.pdf" && -s "${filename}.pdf")) {
-    $form->{"tmpfile"} =~ s/odt$/pdf/;
+    $form->{tmpfile} =~ s/odt$/pdf/;
 
     unlink($filename . ".odt");
 
@@ -1009,7 +757,7 @@ sub convert_to_pdf {
   }
 
   unlink($filename . ".odt", $filename . ".pdf");
-  $self->{"error"} = "Conversion from OpenDocument to PDF failed. " .
+  $self->{error} = "Conversion from OpenDocument to PDF failed. " .
     "Exit code: $res";
 
   $main::lxdebug->leave_sub();
@@ -1030,7 +778,7 @@ sub format_string {
 sub get_mime_type() {
   my ($self) = @_;
 
-  if ($self->{"form"}->{"format"} =~ /pdf/) {
+  if ($self->{form}->{format} =~ /pdf/) {
     return "application/pdf";
   } else {
     return "application/vnd.oasis.opendocument.text";