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',
33 # session_id => $::auth->get_session_id,
39 my $job_obj = $self->{job_obj};
40 my $db = $job_obj->db;
42 $job_obj->set_data(status => CONVERTING_DELIVERY_ORDERS())->save;
44 foreach my $delivery_order_id (@{ $job_obj->data_as_hash->{record_ids} }) {
45 my $number = $delivery_order_id;
46 my $data = $job_obj->data_as_hash;
50 my $sales_delivery_order = SL::DB::DeliveryOrder->new(id => $delivery_order_id)->load;
51 $number = $sales_delivery_order->donumber;
53 if (!$db->do_transaction(sub {
54 $invoice = $sales_delivery_order->convert_to_invoice(sub { $data->{transdate} ? ('attributes' => { transdate => $data->{transdate} }) :
55 undef }->() ) || die $db->error;
61 $data->{num_created}++;
62 push @{ $data->{invoice_ids} }, $invoice->id;
63 push @{ $self->{invoices} }, $invoice;
67 push @{ $data->{conversion_errors} }, { id => $delivery_order_id, number => $number, message => $@ };
70 $job_obj->update_attributes(data_as_hash => $data);
74 sub convert_invoices_to_pdf {
77 return if !@{ $self->{invoices} };
79 my $job_obj = $self->{job_obj};
80 my $db = $job_obj->db;
82 $job_obj->set_data(status => PRINTING_INVOICES())->save;
84 require SL::Controller::MassInvoiceCreatePrint;
86 my $printer_id = $job_obj->data_as_hash->{printer_id};
87 my $ctrl = SL::Controller::MassInvoiceCreatePrint->new;
90 formname => 'invoice',
92 media => $printer_id ? 'printer' : 'file',
97 foreach my $invoice (@{ $self->{invoices} }) {
98 my $data = $job_obj->data_as_hash;
101 my %create_params = (
102 template => $ctrl->find_template(name => 'invoice', printer_id => $printer_id),
103 variables => Form->new(''),
104 return => 'file_name',
105 variable_content_types => { longdescription => 'html',
112 $create_params{variables}->{$_} = $variables{$_} for keys %variables;
114 $invoice->flatten_to_form($create_params{variables}, format_amounts => 1);
115 $create_params{variables}->prepare_for_printing;
117 push @pdf_file_names, $ctrl->create_pdf(%create_params);
119 # copy file to webdav folder
120 if ($::instance_conf->get_webdav_documents) {
121 my $webdav = SL::Webdav->new(
123 number => $invoice->invnumber,
125 my $webdav_file = SL::Webdav::File->new(
127 filename => t8('Invoice') . '_' . $invoice->invnumber . '.pdf',
130 $webdav_file->store(file => $pdf_file_names[-1]);
133 push @{ $data->{print_errors} }, { id => $invoice->id, number => $invoice->invnumber, message => $@ };
137 $data->{num_printed}++;
142 push @{ $data->{print_errors} }, { id => $invoice->id, number => $invoice->invnumber, message => $@ };
145 $job_obj->update_attributes(data_as_hash => $data);
148 if (@pdf_file_names) {
149 my $data = $job_obj->data_as_hash;
152 $self->{merged_pdf} = $ctrl->merge_pdfs(file_names => \@pdf_file_names);
153 unlink @pdf_file_names;
156 my $file_name = 'mass_invoice' . $job_obj->id . '.pdf';
157 my $sfile = SL::SessionFile->new($file_name, mode => 'w', session_id => $data->{session_id});
158 $sfile->fh->print($self->{merged_pdf});
161 $data->{pdf_file_name} = $file_name;
167 push @{ $data->{print_errors} }, { message => $@ };
170 $job_obj->update_attributes(data_as_hash => $data);
177 my $job_obj = $self->{job_obj};
178 my $data = $job_obj->data_as_hash;
179 my $printer_id = $data->{printer_id};
180 my $copy_printer_id = $data->{copy_printer_id};
182 return if !$printer_id;
186 foreach my $local_printer_id ($printer_id, $copy_printer_id) {
187 next unless $local_printer_id;
188 my $printer = SL::DB::Printer->new(id => $local_printer_id)->load;
189 my $command = SL::Template::create(type => 'ShellCommand', form => Form->new(''))->parse($printer->printer_command);
190 if (!open $out, '|-', $command) {
191 push @{ $data->{print_errors} }, { message => $::locale->text('Could not execute printer command: #1', $!) };
192 $job_obj->update_attributes(data_as_hash => $data);
196 print $out $self->{merged_pdf};
203 my ($self, $job_obj) = @_;
205 $self->{job_obj} = $job_obj;
206 $self->{invoices} = [];
208 $self->create_invoices;
209 $self->convert_invoices_to_pdf;
212 $job_obj->set_data(status => DONE())->save;
227 SL::BackgroundJob::MassRecordCreationAndPrinting
233 use SL::BackgroundJob::MassRecordCreationAndPrinting
235 my $job = SL::DB::BackgroundJob->new(
238 package_name => 'MassRecordCreationAndPrinting',
241 record_ids => [ map { $_->id } @records[0..$num - 1] ],
242 printer_id => $::form->{printer_id},
243 copy_printer_id => $::form->{copy_printer_id},
244 transdate => $::form->{transdate} || undef,
245 status => SL::BackgroundJob::MassRecordCreationAndPrinting->WAITING_FOR_EXECUTION(),
249 conversion_errors => [ ],
252 )->update_next_run_at;
253 SL::System::TaskServer->new->wake_up;
257 This background job has 4 states which are described by the four constants above.
261 =item * WAITING_FOR_EXECUTION
262 Background has been initialised and needs to be picked up by the task_server
264 =item * CONVERTING_DELIVERY_ORDERS
267 =item * PRINTING_INVOICES
268 Printing, if done via print command
271 To release the process and for the user information
279 =item C<create_invoices>
281 Converts the source objects (DeliveryOrder) to destination objects (Invoice).
282 On success objects will be saved.
283 If param C<data->{transdate}> is set, this will be the transdate. No safety checks are done.
284 The original conversion from order to delivery order had a post_save_sanity_check
285 C<$delivery_order-E<gt>post_save_sanity_check; # just a hint at e8521eee (#90 od)>
286 The params of convert_to_invoice are created on the fly with a anonym sub, as a alternative check
287 perlsecret Enterprise ()x!!
289 =item C<convert_invoices_to_pdf>
291 Takes the new destination objects and merges them via print template in one pdf.
295 Sent the pdf to the printer command.
296 If param C<data->{copy_printer_id}> is set, the pdf will be sent to a second printer command.
302 Currently the calculation from the gui (form) differs from the calculation via convert (PTC).
303 Furthermore mass conversion with foreign currencies could lead to problems (daily rate check).
307 It would be great to extend this Job for general background printing. The original project
308 code converted sales order to delivery orders (84e7c540) this could be merged in unstable.
309 The states should be CONVERTING_SOURCE_RECORDS, PRINTING_DESTINATION_RECORDS etc
313 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
315 Jan Büren E<lt>jan@kivitendo-premium.deE<gt>