+ IS->invoice_details(\%myconfig, \%$form, $locale);
+ }
+
+ $form->get_employee_data('prefix' => 'employee', 'id' => $form->{employee_id});
+ $form->get_employee_data('prefix' => 'salesman', 'id' => $salesman_id_saved);
+
+ if ($form->{shipto_id}) {
+ $form->get_shipto(\%myconfig);
+ }
+
+ my @a = qw(name street zipcode city country contact);
+
+ my $shipto = 1;
+
+ # if there is no shipto fill it in from billto
+ foreach my $item (@a) {
+ if ($form->{"shipto$item"}) {
+ $shipto = 0;
+ last;
+ }
+ }
+
+ if ($shipto) {
+ if ( $form->{formname} eq 'purchase_order'
+ || $form->{formname} eq 'request_quotation') {
+ $form->{shiptoname} = $myconfig{company};
+ $form->{shiptostreet} = $myconfig{address};
+ } else {
+ map { $form->{"shipto$_"} = $form->{$_} } @a;
+ }
+ }
+
+ $form->{notes} =~ s/^\s+//g;
+
+ $form->{templates} = "$myconfig{templates}";
+
+ delete $form->{printer_command};
+
+ $form->{language} = $form->get_template_language(\%myconfig);
+
+ my $printer_code;
+ if ($form->{media} ne 'email') {
+ $printer_code = $form->get_printer_code(\%myconfig);
+ if ($printer_code ne "") {
+ $printer_code = "_" . $printer_code;
+ }
+ }
+
+ if ($form->{language} ne "") {
+ my $template_arrays = $form->{TEMPLATE_ARRAYS} || $form;
+ map { $template_arrays->{unit}->[$_] = AM->translate_units($form, $form->{language}, $template_arrays->{unit}->[$_], $template_arrays->{qty}->[$_]); } (0..scalar(@{ $template_arrays->{unit} }) - 1);
+
+ $form->{language} = "_" . $form->{language};
+ }
+
+ # Format dates.
+ format_dates($output_dateformat, $output_longdates,
+ qw(invdate orddate quodate pldate duedate reqdate transdate
+ shippingdate deliverydate validitydate paymentdate
+ datepaid transdate_oe deliverydate_oe
+ employee_startdate employee_enddate
+ ),
+ grep({ /^datepaid_\d+$/ ||
+ /^transdate_oe_\d+$/ ||
+ /^deliverydate_oe_\d+$/ ||
+ /^reqdate_\d+$/ ||
+ /^deliverydate_\d+$/ ||
+ /^transdate_\d+$/
+ } keys(%{$form})));
+
+ reformat_numbers($output_numberformat, 2,
+ qw(invtotal ordtotal quototal subtotal linetotal
+ listprice sellprice netprice discount
+ tax taxbase total paid),
+ grep({ /^(?:linetotal|nodiscount_linetotal|listprice|sellprice|netprice|taxbase|discount|p_discount|discount_sub|nodiscount_sub|paid|subtotal|total|tax)_\d+$/ } keys(%{$form})));
+
+ reformat_numbers($output_numberformat, undef,
+ qw(qty price_factor),
+ grep({ /^qty_\d+$/
+ } keys(%{$form})));
+
+ my ($cvar_date_fields, $cvar_number_fields) = CVar->get_field_format_list('module' => 'CT', 'prefix' => 'vc_');
+
+ if (scalar @{ $cvar_date_fields }) {
+ format_dates($output_dateformat, $output_longdates, @{ $cvar_date_fields });
+ }
+
+ while (my ($precision, $field_list) = each %{ $cvar_number_fields }) {
+ reformat_numbers($output_numberformat, $precision, @{ $field_list });
+ }
+
+ my $extension = 'html';
+ if ($form->{format} eq 'postscript') {
+ $form->{postscript} = 1;
+ $extension = 'tex';
+
+ } elsif ($form->{"format"} =~ /pdf/) {
+ $form->{pdf} = 1;
+ $extension = $form->{'format'} =~ m/opendocument/i ? 'odt' : 'tex';
+
+ } elsif ($form->{"format"} =~ /opendocument/) {
+ $form->{opendocument} = 1;
+ $extension = 'odt';
+ } elsif ($form->{"format"} =~ /excel/) {
+ $form->{excel} = 1;
+ $extension = 'xls';
+ }
+
+ # search for the template
+ my @template_files;
+ push @template_files, "$form->{formname}_email$form->{language}$printer_code.$extension" if $form->{media} eq 'email';
+ push @template_files, "$form->{formname}$form->{language}$printer_code.$extension";
+ push @template_files, "$form->{formname}.$extension";
+ push @template_files, "default.$extension";
+
+ $form->{IN} = undef;
+ for my $filename (@template_files) {
+ if (-f "$myconfig{templates}/$filename") {
+ $form->{IN} = $filename;
+ last;
+ }
+ }
+
+ if (!defined $form->{IN}) {
+ $::form->error($::locale->text('Cannot find matching template for this print request. Please contact your template maintainer. I tried these: #1.', join ', ', map { "'$_'"} @template_files));
+ }
+
+ delete $form->{OUT};
+
+ if ($form->{media} eq 'printer') {
+ #$form->{OUT} = "| $form->{printer_command} &>/dev/null";
+ $form->{OUT} = $form->{printer_command};
+ $form->{OUT_MODE} = '|-';
+ $form->{printed} .= " $form->{formname}";
+ $form->{printed} =~ s/^ //;
+ }
+ my $printed = $form->{printed};
+
+ if ($form->{media} eq 'email') {
+ $form->{subject} = qq|$form->{label} $form->{"${inv}number"}|
+ unless $form->{subject};
+
+ $form->{emailed} .= " $form->{formname}";
+ $form->{emailed} =~ s/^ //;
+ }
+ my $emailed = $form->{emailed};
+
+ if ($form->{media} eq 'queue') {
+ my %queued = map { s|.*/|| } split / /, $form->{queued};
+
+ my $filename;
+ if ($filename = $queued{ $form->{formname} }) {
+ $form->{queued} =~ s/\Q$form->{formname} $filename\E//;
+ unlink $::lx_office_conf{paths}->{spool} . "/$filename";
+ $filename =~ s/\..*$//g;
+ } else {
+ $filename = time;
+ $filename .= $$;
+ }
+
+ $filename .= ($form->{postscript}) ? '.ps' : '.pdf';
+ $form->{OUT} = $::lx_office_conf{paths}->{spool} . "/$filename";
+ $form->{OUT_MODE} = '>';
+
+ # add type
+ $form->{queued} .= " $form->{formname} $filename";
+
+ $form->{queued} =~ s/^ //;
+ }
+ my $queued = $form->{queued};
+
+# saving the history
+ if(!exists $form->{addition}) {
+ $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
+ if($form->{media} =~ /printer/) {
+ $form->{addition} = "PRINTED";
+ }
+ elsif($form->{media} =~ /email/) {
+ $form->{addition} = "MAILED";
+ }
+ elsif($form->{media} =~ /queue/) {
+ $form->{addition} = "QUEUED";
+ }
+ elsif($form->{media} =~ /screen/) {
+ $form->{addition} = "SCREENED";
+ }
+ $form->save_history;
+ }
+ # /saving the history
+
+ # prepare meta information for template introspection
+ $form->{template_meta} = {
+ formname => $form->{formname},
+ language => SL::DB::Manager::Language->find_by_or_create(id => $form->{language_id}),
+ format => $form->{format},
+ media => $form->{media},
+ extension => $extension,
+ printer => SL::DB::Manager::Printer->find_by_or_create(id => $form->{printer_id}),
+ };
+
+ $form->parse_template(\%myconfig);
+
+ $form->{callback} = "";
+
+ if ($form->{media} eq 'email') {
+ $form->{message} = $locale->text('sent') unless $form->{message};
+ }
+ my $message = $form->{message};
+
+ # if we got back here restore the previous form
+ if ($form->{media} =~ /(printer|email|queue)/) {
+
+ $form->update_status(\%myconfig)
+ if ($form->{media} eq 'queue' && $form->{id});
+
+ return $main::lxdebug->leave_sub() if ($old_form eq "return");
+
+ if ($old_form) {
+
+ $old_form->{"${inv}number"} = $form->{"${inv}number"};
+
+ # restore and display form
+ map { $form->{$_} = $old_form->{$_} } keys %$old_form;
+
+ $form->{queued} = $queued;
+ $form->{printed} = $printed;
+ $form->{emailed} = $emailed;
+ $form->{message} = $message;
+
+ $form->{rowcount}--;
+ map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) }
+ qw(exchangerate creditlimit creditremaining);
+
+ for my $i (1 .. $form->{paidaccounts}) {
+ map {
+ $form->{"${_}_$i"} =
+ $form->parse_amount(\%myconfig, $form->{"${_}_$i"})
+ } qw(paid exchangerate);
+ }
+
+ call_sub($display_form);
+ ::end_of_request();
+ }
+
+ my $msg =
+ ($form->{media} eq 'printer')
+ ? $locale->text('sent to printer')
+ : $locale->text('emailed to') . " $form->{email}";
+ $form->redirect(qq|$form->{label} $form->{"${inv}number"} $msg|);
+ }
+ if ($form->{printing}) {
+ call_sub($display_form);
+ ::end_of_request();
+ }
+
+ $main::lxdebug->leave_sub();
+}
+
+sub customer_details {
+ $main::lxdebug->enter_sub();
+
+ my $form = $main::form;
+ my %myconfig = %main::myconfig;
+
+ IS->customer_details(\%myconfig, \%$form, @_);
+
+ $main::lxdebug->leave_sub();
+}
+
+sub vendor_details {
+ $main::lxdebug->enter_sub();
+
+ my $form = $main::form;
+ my %myconfig = %main::myconfig;
+
+ IR->vendor_details(\%myconfig, \%$form, @_);
+
+ $main::lxdebug->leave_sub();
+}
+
+sub post_as_new {
+ $main::lxdebug->enter_sub();
+
+ my $form = $main::form;
+
+ _check_io_auth();
+
+ $form->{postasnew} = 1;
+ map { delete $form->{$_} } qw(printed emailed queued);
+
+ &post;
+
+ $main::lxdebug->leave_sub();
+}
+
+sub ship_to {
+ $main::lxdebug->enter_sub();
+
+ _check_io_auth();
+
+ $::form->{print_and_post} = 0 if $::form->{second_run};
+
+ map { $::form->{$_} = $::form->parse_amount(\%::myconfig, $::form->{$_}) } qw(exchangerate creditlimit creditremaining);
+
+ # get details for customer/vendor
+ call_sub($::form->{vc} . "_details", qw(name department_1 department_2 street zipcode city country contact email phone fax), $::form->{vc} . "number");
+
+ # get pricegroups for parts
+ IS->get_pricegroups_for_parts(\%::myconfig, \%$::form);
+
+ # build up html code for prices_$i
+ set_pricegroup($::form->{rowcount});
+
+ $::form->{rowcount}--;
+
+ my @shipto_vars = qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry
+ shiptocontact shiptocp_gender shiptophone shiptofax shiptoemail
+ shiptodepartment_1 shiptodepartment_2);
+ my $previous_form = $::auth->save_form_in_session(skip_keys => [ @shipto_vars, qw(header shipto_id) ]);
+ $::form->{title} = $::locale->text('Ship to');
+ $::form->header;
+
+ print $::form->parse_html_template('io/ship_to', { previousform => $previous_form,
+ nextsub => $::form->{display_form} || 'display_form',
+ });
+
+ $main::lxdebug->leave_sub();
+}
+
+sub ship_to_entered {
+ $::auth->restore_form_from_session(delete $::form->{previousform});
+ call_sub($::form->{nextsub});
+}
+
+sub relink_accounts {
+ $main::lxdebug->enter_sub();
+
+ my $form = $main::form;
+ my %myconfig = %main::myconfig;
+
+ _check_io_auth();
+
+ $form->{"taxaccounts"} =~ s/\s*$//;
+ $form->{"taxaccounts"} =~ s/^\s*//;
+ foreach my $accno (split(/\s*/, $form->{"taxaccounts"})) {
+ map({ delete($form->{"${accno}_${_}"}); } qw(rate description taxnumber));
+ }
+ $form->{"taxaccounts"} = "";
+
+ IC->retrieve_accounts(\%myconfig, $form, map { $_ => $form->{"id_$_"} } 1 .. $form->{rowcount});
+
+ $main::lxdebug->leave_sub();
+}
+
+sub set_duedate {
+ $main::lxdebug->enter_sub();
+
+ my $form = $main::form;
+ my %myconfig = %main::myconfig;
+
+ _check_io_auth();
+
+ my $invdate = $form->{invdate} eq 'undefined' ? undef : $form->{invdate};
+ my $duedate = $form->get_duedate(\%myconfig, $invdate);
+
+ print $form->ajax_response_header() . $duedate;
+
+ $main::lxdebug->leave_sub();
+}
+
+sub _update_part_information {
+ $main::lxdebug->enter_sub();
+
+ my $form = $main::form;
+
+ my %part_information = IC->get_basic_part_info('id' => [ grep { $_ } map { $form->{"id_${_}"} } (1..$form->{rowcount}) ],
+ 'vendor_id' => $form->{vendor_id});
+
+ $form->{PART_INFORMATION} = \%part_information;
+
+ foreach my $i (1..$form->{rowcount}) {
+ next unless ($form->{"id_${i}"});
+
+ my $info = $form->{PART_INFORMATION}->{$form->{"id_${i}"}} || { };
+ $form->{"partunit_${i}"} = $info->{unit};
+ }
+
+ $main::lxdebug->leave_sub();
+}
+
+sub _update_ship {
+ $main::lxdebug->enter_sub();
+
+ my $form = $main::form;
+ my %myconfig = %main::myconfig;
+
+ if (!$form->{ordnumber} || !$form->{id}) {
+ map { $form->{"ship_$_"} = 0 } (1..$form->{rowcount});
+ $main::lxdebug->leave_sub();
+ return;
+ }
+
+ my $all_units = AM->retrieve_all_units();
+
+ my %ship = DO->get_shipped_qty('type' => ($form->{type} eq 'purchase_order') ? 'purchase' : 'sales',
+ 'oe_id' => $form->{id},);
+
+ foreach my $i (1..$form->{rowcount}) {
+ next unless ($form->{"id_${i}"});
+
+ $form->{"ship_$i"} = 0;
+
+ my $ship_entry = $ship{$form->{"id_$i"}};
+
+ next if (!$ship_entry || ($ship_entry->{qty} <= 0));
+
+ my $rowqty =
+ ($form->{simple_save} ? $form->{"qty_$i"} : $form->parse_amount(\%myconfig, $form->{"qty_$i"}))
+ * $all_units->{$form->{"unit_$i"}}->{factor}
+ / $all_units->{$form->{"partunit_$i"}}->{factor};
+
+ $form->{"ship_$i"} = min($rowqty, $ship_entry->{qty});
+ $ship_entry->{qty} -= $form->{"ship_$i"};
+ }
+
+ foreach my $i (1..$form->{rowcount}) {
+ next unless ($form->{"id_${i}"});
+
+ my $ship_entry = $ship{$form->{"id_$i"}};
+
+ next if (!$ship_entry || ($ship_entry->{qty} <= 0.01));
+
+ $form->{"ship_$i"} += $ship_entry->{qty};
+ $ship_entry->{qty} = 0;
+ }
+
+ $main::lxdebug->leave_sub();
+}
+
+sub _update_custom_variables {
+ $main::lxdebug->enter_sub();
+
+ my $form = $main::form;
+
+ $form->{CVAR_CONFIGS} = { } unless ref $form->{CVAR_CONFIGS} eq 'HASH';
+ $form->{CVAR_CONFIGS}->{IC} ||= CVar->get_configs(module => 'IC');
+
+ $main::lxdebug->leave_sub();
+}
+
+sub _render_custom_variables_inputs {
+ $main::lxdebug->enter_sub(2);
+
+ my $form = $main::form;
+
+ my %params = @_;
+
+ if (!$form->{CVAR_CONFIGS}->{IC}) {
+ $main::lxdebug->leave_sub();
+ return;
+ }
+
+ my $valid = CVar->custom_variables_validity_by_trans_id(trans_id => $params{part_id});
+
+ my $num_visible_cvars = 0;
+ foreach my $cvar (@{ $form->{CVAR_CONFIGS}->{IC} }) {
+ $cvar->{valid} = $params{part_id} && $valid->($cvar->{id});
+
+ my $description = '';
+ if ($cvar->{flag_editable} && $cvar->{valid}) {
+ $num_visible_cvars++;
+ $description = $cvar->{description} . ' ';
+ }
+
+ my $form_key = "ic_cvar_" . $cvar->{name} . "_$params{row}";
+
+ push @{ $params{ROW2} }, {
+ line_break => $num_visible_cvars == 1,
+ description => $description,
+ cvar => 1,
+ render_options => {
+ hide_non_editable => 1,
+ var => $cvar,
+ name_prefix => 'ic_',
+ name_postfix => "_$params{row}",
+ valid => $cvar->{valid},
+ value => CVar->parse($::form->{$form_key}, $cvar),
+ }
+ };
+ }
+
+ $main::lxdebug->leave_sub(2);
+}