1 package SL::BackgroundJob::MassRecordCreationAndPrinting;
 
   6 use parent qw(SL::BackgroundJob::Base);
 
   8 use SL::DB::DeliveryOrder;
 
   9 use SL::DB::Order;  # origin order to delivery_order
 
  14 use SL::Locale::String qw(t8);
 
  17 use constant WAITING_FOR_EXECUTION       => 0;
 
  18 use constant CONVERTING_DELIVERY_ORDERS  => 1;
 
  19 use constant PRINTING_INVOICES           => 2;
 
  20 use constant DONE                        => 3;
 
  23 #   record_ids          => [ 123, 124, 127, ],
 
  27 #   invoice_ids        => [ 234, 235, ],
 
  28 #   conversion_errors  => [ { id => 124, number => 'A981723', message => "Stuff went boom" }, ],
 
  29 #   print_errors       => [ { id => 234, number => 'L87123123', message => "Printer is out of coffee" }, ],
 
  30 #   pdf_file_name      => 'qweqwe.pdf',
 
  36   my $job_obj = $self->{job_obj};
 
  37   my $db      = $job_obj->db;
 
  39   $job_obj->set_data(status => CONVERTING_DELIVERY_ORDERS())->save;
 
  41   foreach my $delivery_order_id (@{ $job_obj->data_as_hash->{record_ids} }) {
 
  42     my $number = $delivery_order_id;
 
  43     my $data   = $job_obj->data_as_hash;
 
  47       my $sales_delivery_order = SL::DB::DeliveryOrder->new(id => $delivery_order_id)->load;
 
  48       $number                  = $sales_delivery_order->donumber;
 
  50       if (!$db->do_transaction(sub {
 
  51         $invoice = $sales_delivery_order->convert_to_invoice(item_filter => \&delivery_order_item_filter, queue_sort => 1) || die $db->error;
 
  52         # $delivery_order->post_save_sanity_check; # just a hint at e8521eee (#90 od)
 
  58       $data->{num_created}++;
 
  59       push @{ $data->{invoice_ids} }, $invoice->id;
 
  60       push @{ $self->{invoices}    }, $invoice;
 
  64       push @{ $data->{conversion_errors} }, { id => $delivery_order_id, number => $number, message => $@ };
 
  67     $job_obj->update_attributes(data_as_hash => $data);
 
  71 sub convert_invoices_to_pdf {
 
  74   return if !@{ $self->{invoices} };
 
  76   my $job_obj = $self->{job_obj};
 
  77   my $db      = $job_obj->db;
 
  79   $job_obj->set_data(status => PRINTING_INVOICES())->save;
 
  81   require SL::Controller::MassInvoiceCreatePrint;
 
  83   my $printer_id = $job_obj->data_as_hash->{printer_id};
 
  84   my $ctrl       = SL::Controller::MassInvoiceCreatePrint->new;
 
  87     formname     => 'invoice',
 
  89     media        => $printer_id ? 'printer' : 'file',
 
  94   foreach my $invoice (@{ $self->{invoices} }) {
 
  95     my $data = $job_obj->data_as_hash;
 
  99         template  => $ctrl->find_template(name => 'invoice', printer_id => $printer_id),
 
 100         variables => Form->new(''),
 
 101         return    => 'file_name',
 
 104       $create_params{variables}->{$_} = $variables{$_} for keys %variables;
 
 106       $invoice->flatten_to_form($create_params{variables}, format_amounts => 1);
 
 107       $create_params{variables}->prepare_for_printing;
 
 109       push @pdf_file_names, $ctrl->create_pdf(%create_params);
 
 111       # copy file to webdav folder
 
 112       if ($::instance_conf->get_webdav_documents) {
 
 113         my $webdav = SL::Webdav->new(
 
 115           number   => $invoice->invnumber,
 
 117         my $webdav_file = SL::Webdav::File->new(
 
 119           filename => t8('Invoice') . '_' . $invoice->invnumber . '.pdf',
 
 122           $webdav_file->store(file => $pdf_file_names[-1]);
 
 125           push @{ $data->{print_errors} }, { id => $invoice->id, number => $invoice->invnumber, message => $@ };
 
 129       $data->{num_printed}++;
 
 134       push @{ $data->{print_errors} }, { id => $invoice->id, number => $invoice->invnumber, message => $@ };
 
 137     $job_obj->update_attributes(data_as_hash => $data);
 
 140   if (@pdf_file_names) {
 
 141     my $data = $job_obj->data_as_hash;
 
 144       $self->{merged_pdf} = $ctrl->merge_pdfs(file_names => \@pdf_file_names);
 
 145       unlink @pdf_file_names;
 
 148         my $file_name = 'mass_invoice' . $job_obj->id . '.pdf';
 
 149         my $sfile     = SL::SessionFile->new($file_name, mode => 'w');
 
 150         $sfile->fh->print($self->{merged_pdf});
 
 153         $data->{pdf_file_name} = $file_name;
 
 159       push @{ $data->{print_errors} }, { message => $@ };
 
 162     $job_obj->update_attributes(data_as_hash => $data);
 
 169   my $job_obj    = $self->{job_obj};
 
 170   my $data       = $job_obj->data_as_hash;
 
 171   my $printer_id = $data->{printer_id};
 
 173   return if !$printer_id;
 
 175   my $printer = SL::DB::Printer->new(id => $printer_id)->load;
 
 176   my $command = SL::Template::create(type => 'ShellCommand', form => Form->new(''))->parse($printer->printer_command);
 
 179   if (!open $out, '|-', $command) {
 
 180     push @{ $data->{print_errors} }, { message => $::locale->text('Could not execute printer command: #1', $!) };
 
 181     $job_obj->update_attributes(data_as_hash => $data);
 
 186   print $out $self->{merged_pdf};
 
 191   my ($self, $job_obj) = @_;
 
 193   $self->{job_obj}         = $job_obj;
 
 194   $self->{invoices} = [];
 
 196   $self->create_invoices;
 
 197   $self->convert_invoices_to_pdf;
 
 200   $job_obj->set_data(status => DONE())->save;
 
 215 SL::BackgroundJob::MassRecordCreationAndPrinting
 
 221 use SL::BackgroundJob::MassRecordCreationAndPrinting
 
 223 my $job              = SL::DB::BackgroundJob->new(
 
 226     package_name       => 'MassRecordCreationAndPrinting',
 
 229     record_ids         => [ map { $_->id } @records[0..$num - 1] ],
 
 230     printer_id         => $::form->{printer_id},
 
 231     status             => SL::BackgroundJob::MassRecordCreationAndPrinting->WAITING_FOR_EXECUTION(),
 
 235     conversion_errors  => [ ],
 
 238   )->update_next_run_at;
 
 239   SL::System::TaskServer->new->wake_up;
 
 243 This background job has 4 states which are described by the four constants above.
 
 247 =item * WAITING_FOR_EXECUTION
 
 248   Background has been initialised and needs to be picked up by the task_server
 
 250 =item * CONVERTING_DELIVERY_ORDERS
 
 253 =item * PRINTING_INVOICES
 
 254   Printing, if done via print command
 
 257   To release the process and for the user information
 
 265 =item C<create_invoices>
 
 267 Converts the source objects (DeliveryOrder) to destination objects (Invoice).
 
 268 On success objects will be saved.
 
 270 =item C<convert_invoices_to_pdf>
 
 272 Takes the new destination objects and merges them via print template in one pdf.
 
 276 Sent the pdf to the printer command (if checked).
 
 282 Currently the calculation from the gui (form) differs from the calculation via convert (PTC).
 
 283 Furthermore mass conversion with foreign currencies could lead to problems (daily rate check).
 
 287 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
 
 289 Jan Büren E<lt>jan@kivitendo-premium.deE<gt>