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, ],
 
  25 #   copy_printer_id    => 4711,
 
  26 #   transdate          => $today || $custom_transdate,
 
  29 #   invoice_ids        => [ 234, 235, ],
 
  30 #   conversion_errors  => [ { id => 124, number => 'A981723', message => "Stuff went boom" }, ],
 
  31 #   print_errors       => [ { id => 234, number => 'L87123123', message => "Printer is out of coffee" }, ],
 
  32 #   pdf_file_name      => 'qweqwe.pdf',
 
  38   my $job_obj = $self->{job_obj};
 
  39   my $db      = $job_obj->db;
 
  41   $job_obj->set_data(status => CONVERTING_DELIVERY_ORDERS())->save;
 
  43   foreach my $delivery_order_id (@{ $job_obj->data_as_hash->{record_ids} }) {
 
  44     my $number = $delivery_order_id;
 
  45     my $data   = $job_obj->data_as_hash;
 
  49       my $sales_delivery_order = SL::DB::DeliveryOrder->new(id => $delivery_order_id)->load;
 
  50       $number                  = $sales_delivery_order->donumber;
 
  52       if (!$db->do_transaction(sub {
 
  53         $invoice = $sales_delivery_order->convert_to_invoice(sub { $data->{transdate} ? ('attributes' => { transdate => $data->{transdate} }) :
 
  54                                                                          undef }->() ) || die $db->error;
 
  60       $data->{num_created}++;
 
  61       push @{ $data->{invoice_ids} }, $invoice->id;
 
  62       push @{ $self->{invoices}    }, $invoice;
 
  66       push @{ $data->{conversion_errors} }, { id => $delivery_order_id, number => $number, message => $@ };
 
  69     $job_obj->update_attributes(data_as_hash => $data);
 
  73 sub convert_invoices_to_pdf {
 
  76   return if !@{ $self->{invoices} };
 
  78   my $job_obj = $self->{job_obj};
 
  79   my $db      = $job_obj->db;
 
  81   $job_obj->set_data(status => PRINTING_INVOICES())->save;
 
  83   require SL::Controller::MassInvoiceCreatePrint;
 
  85   my $printer_id = $job_obj->data_as_hash->{printer_id};
 
  86   my $ctrl       = SL::Controller::MassInvoiceCreatePrint->new;
 
  89     formname     => 'invoice',
 
  91     media        => $printer_id ? 'printer' : 'file',
 
  96   foreach my $invoice (@{ $self->{invoices} }) {
 
  97     my $data = $job_obj->data_as_hash;
 
 100       my %create_params = (
 
 101         template  => $ctrl->find_template(name => 'invoice', printer_id => $printer_id),
 
 102         variables => Form->new(''),
 
 103         return    => 'file_name',
 
 104         variable_content_types => { longdescription => 'html',
 
 111       $create_params{variables}->{$_} = $variables{$_} for keys %variables;
 
 113       $invoice->flatten_to_form($create_params{variables}, format_amounts => 1);
 
 114       $create_params{variables}->prepare_for_printing;
 
 116       push @pdf_file_names, $ctrl->create_pdf(%create_params);
 
 118       # copy file to webdav folder
 
 119       if ($::instance_conf->get_webdav_documents) {
 
 120         my $webdav = SL::Webdav->new(
 
 122           number   => $invoice->invnumber,
 
 124         my $webdav_file = SL::Webdav::File->new(
 
 126           filename => t8('Invoice') . '_' . $invoice->invnumber . '.pdf',
 
 129           $webdav_file->store(file => $pdf_file_names[-1]);
 
 132           push @{ $data->{print_errors} }, { id => $invoice->id, number => $invoice->invnumber, message => $@ };
 
 136       $data->{num_printed}++;
 
 141       push @{ $data->{print_errors} }, { id => $invoice->id, number => $invoice->invnumber, message => $@ };
 
 144     $job_obj->update_attributes(data_as_hash => $data);
 
 147   if (@pdf_file_names) {
 
 148     my $data = $job_obj->data_as_hash;
 
 151       $self->{merged_pdf} = $ctrl->merge_pdfs(file_names => \@pdf_file_names);
 
 152       unlink @pdf_file_names;
 
 155         my $file_name = 'mass_invoice' . $job_obj->id . '.pdf';
 
 156         my $sfile     = SL::SessionFile->new($file_name, mode => 'w');
 
 157         $sfile->fh->print($self->{merged_pdf});
 
 160         $data->{pdf_file_name} = $file_name;
 
 166       push @{ $data->{print_errors} }, { message => $@ };
 
 169     $job_obj->update_attributes(data_as_hash => $data);
 
 176   my $job_obj         = $self->{job_obj};
 
 177   my $data            = $job_obj->data_as_hash;
 
 178   my $printer_id      = $data->{printer_id};
 
 179   my $copy_printer_id = $data->{copy_printer_id};
 
 181   return if !$printer_id;
 
 185   foreach  my $local_printer_id ($printer_id, $copy_printer_id) {
 
 186     next unless $local_printer_id;
 
 187     my $printer = SL::DB::Printer->new(id => $local_printer_id)->load;
 
 188     my $command = SL::Template::create(type => 'ShellCommand', form => Form->new(''))->parse($printer->printer_command);
 
 189     if (!open $out, '|-', $command) {
 
 190       push @{ $data->{print_errors} }, { message => $::locale->text('Could not execute printer command: #1', $!) };
 
 191       $job_obj->update_attributes(data_as_hash => $data);
 
 195     print $out $self->{merged_pdf};
 
 202   my ($self, $job_obj) = @_;
 
 204   $self->{job_obj}         = $job_obj;
 
 205   $self->{invoices} = [];
 
 207   $self->create_invoices;
 
 208   $self->convert_invoices_to_pdf;
 
 211   $job_obj->set_data(status => DONE())->save;
 
 226 SL::BackgroundJob::MassRecordCreationAndPrinting
 
 232 use SL::BackgroundJob::MassRecordCreationAndPrinting
 
 234 my $job              = SL::DB::BackgroundJob->new(
 
 237     package_name       => 'MassRecordCreationAndPrinting',
 
 240     record_ids         => [ map { $_->id } @records[0..$num - 1] ],
 
 241     printer_id         => $::form->{printer_id},
 
 242     copy_printer_id    => $::form->{copy_printer_id},
 
 243     transdate          => $::form->{transdate} || undef,
 
 244     status             => SL::BackgroundJob::MassRecordCreationAndPrinting->WAITING_FOR_EXECUTION(),
 
 248     conversion_errors  => [ ],
 
 251   )->update_next_run_at;
 
 252   SL::System::TaskServer->new->wake_up;
 
 256 This background job has 4 states which are described by the four constants above.
 
 260 =item * WAITING_FOR_EXECUTION
 
 261   Background has been initialised and needs to be picked up by the task_server
 
 263 =item * CONVERTING_DELIVERY_ORDERS
 
 266 =item * PRINTING_INVOICES
 
 267   Printing, if done via print command
 
 270   To release the process and for the user information
 
 278 =item C<create_invoices>
 
 280 Converts the source objects (DeliveryOrder) to destination objects (Invoice).
 
 281 On success objects will be saved.
 
 282 If param C<data->{transdate}> is set, this will be the transdate. No safety checks are done.
 
 283 The original conversion from order to delivery order had a post_save_sanity_check
 
 284 C<$delivery_order-E<gt>post_save_sanity_check; # just a hint at e8521eee (#90 od)>
 
 285 The params of convert_to_invoice are created on the fly with a anonym sub, as a alternative check
 
 286  perlsecret Enterprise ()x!!
 
 288 =item C<convert_invoices_to_pdf>
 
 290 Takes the new destination objects and merges them via print template in one pdf.
 
 294 Sent the pdf to the printer command.
 
 295 If param C<data->{copy_printer_id}> is set, the pdf will be sent to a second printer command.
 
 301 Currently the calculation from the gui (form) differs from the calculation via convert (PTC).
 
 302 Furthermore mass conversion with foreign currencies could lead to problems (daily rate check).
 
 306 It would be great to extend this Job for general background printing. The original project
 
 307 code converted sales order to delivery orders (84e7c540) this could be merged in unstable.
 
 308 The states should be CONVERTING_SOURCE_RECORDS, PRINTING_DESTINATION_RECORDS etc
 
 312 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
 
 314 Jan Büren E<lt>jan@kivitendo-premium.deE<gt>