X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=bin%2Fmozilla%2Foe.pl;h=22784d9fa929bc7675b1af5253a58b4b686bc83e;hb=c45d7eedae611fa7e35d3a8225691fe766e35acb;hp=560ffcd07e7f857055e1a2acbaba5c33307e6738;hpb=87599e477cc6e1df8dded5fda69f21d01278e71e;p=kivitendo-erp.git diff --git a/bin/mozilla/oe.pl b/bin/mozilla/oe.pl index 560ffcd07..22784d9fa 100644 --- a/bin/mozilla/oe.pl +++ b/bin/mozilla/oe.pl @@ -44,13 +44,17 @@ use SL::IR; use SL::IS; use SL::MoreCommon qw(ary_diff restore_form save_form); use SL::ReportGenerator; +use SL::YAML; use List::MoreUtils qw(uniq any none); use List::Util qw(min max reduce sum); use Data::Dumper; +use SL::Controller::Order; + use SL::DB::Customer; use SL::DB::TaxZone; use SL::DB::PaymentTerm; +use SL::DB::Vendor; require "bin/mozilla/common.pl"; require "bin/mozilla/io.pl"; @@ -58,8 +62,6 @@ require "bin/mozilla/reportgenerator.pl"; use strict; -our %TMPL_VAR; - 1; # end of main @@ -185,6 +187,14 @@ sub edit { # editing without stuff to edit? try adding it first if ($form->{rowcount} && !$form->{print_and_save}) { + if ($::instance_conf->get_feature_experimental_order) { + my $c = SL::Controller::Order->new; + $c->action_edit_collective(); + + $main::lxdebug->leave_sub(); + $::dispatcher->end_request; + } + my $id; map { $id++ if $form->{"multi_id_$_"} } (1 .. $form->{rowcount}); if (!$id) { @@ -293,6 +303,185 @@ sub prepare_order { $main::lxdebug->leave_sub(); } +sub setup_oe_action_bar { + my %params = @_; + my $form = $::form; + + my $has_active_periodic_invoice; + if ($params{oe_obj}) { + $has_active_periodic_invoice = + $params{oe_obj}->is_type('sales_order') + && $params{oe_obj}->periodic_invoices_config + && $params{oe_obj}->periodic_invoices_config->active + && ( !$params{oe_obj}->periodic_invoices_config->end_date + || ($params{oe_obj}->periodic_invoices_config->end_date > DateTime->today_local)) + && $params{oe_obj}->periodic_invoices_config->get_previous_billed_period_start_date; + } + + my $allow_invoice = $params{is_req_quo} + || $params{is_pur_ord} + || ($params{is_sales_quo} && $::instance_conf->get_allow_sales_invoice_from_sales_quotation) + || ($params{is_sales_ord} && $::instance_conf->get_allow_sales_invoice_from_sales_order); + my @req_trans_cost_art = qw(kivi.SalesPurchase.check_transport_cost_article_presence) x!!$::instance_conf->get_transport_cost_reminder_article_number_id; + my @warn_p_invoice = qw(kivi.SalesPurchase.oe_warn_save_active_periodic_invoice) x!!$has_active_periodic_invoice; + + for my $bar ($::request->layout->get('actionbar')) { + $bar->add( + action => [ + t8('Update'), + submit => [ '#form', { action => "update" } ], + id => 'update_button', + accesskey => 'enter', + ], + + combobox => [ + action => [ + t8('Save'), + submit => [ '#form', { action => "save" } ], + checks => [ 'kivi.validate_form', @req_trans_cost_art, @warn_p_invoice ], + ], + action => [ + t8('Save as new'), + submit => [ '#form', { action => "save_as_new" } ], + checks => [ 'kivi.validate_form', @req_trans_cost_art ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + ], + action => [ + t8('Save and Close'), + submit => [ '#form', { action => "save_and_close" } ], + checks => [ 'kivi.validate_form', @req_trans_cost_art, @warn_p_invoice ], + ], + action => [ + t8('Delete'), + submit => [ '#form', { action => "delete" } ], + confirm => t8('Do you really want to delete this object?'), + disabled => !$form->{id} ? t8('This record has not been saved yet.') + : ( ($params{is_sales_ord} && !$::instance_conf->get_sales_order_show_delete) + || ($params{is_pur_ord} && !$::instance_conf->get_purchase_order_show_delete)) ? t8('Deleting this type of record has been disabled in the configuration.') + : undef, + ], + ], # end of combobox "Save" + + 'separator', + + combobox => [ + action => [ t8('Workflow') ], + action => [ + t8('Sales Order'), + submit => [ '#form', { action => "sales_order" } ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + checks => [ 'kivi.validate_form' ], + only_if => $params{is_sales_quo} || $params{is_pur_ord}, + ], + action => [ + t8('Purchase Order'), + submit => [ '#form', { action => "purchase_order" } ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + checks => [ 'kivi.validate_form' ], + only_if => $params{is_sales_ord} || $params{is_req_quo}, + ], + action => [ + t8('Delivery Order'), + submit => [ '#form', { action => "delivery_order" } ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + checks => [ 'kivi.validate_form' ], + only_if => $params{is_sales_ord} || $params{is_pur_ord}, + ], + action => [ + t8('Invoice'), + submit => [ '#form', { action => "invoice" } ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + checks => [ 'kivi.validate_form' ], + only_if => $allow_invoice, + ], + action => [ + t8('Quotation'), + submit => [ '#form', { action => "quotation" } ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + checks => [ 'kivi.validate_form' ], + only_if => $params{is_sales_ord}, + ], + action => [ + t8('Request for Quotation'), + submit => [ '#form', { action => "request_for_quotation" } ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + checks => [ 'kivi.validate_form' ], + only_if => $params{is_pur_ord}, + ], + ], # end of combobox "Workflow" + + combobox => [ + action => [ t8('Export') ], + action => [ + t8('Print'), + call => [ 'kivi.SalesPurchase.show_print_dialog' ], + checks => [ 'kivi.validate_form' ], + ], + action => [ + t8('E Mail'), + call => [ 'kivi.SalesPurchase.show_email_dialog' ], + checks => [ 'kivi.validate_form' ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + ], + action => [ + t8('Download attachments of all parts'), + call => [ 'kivi.File.downloadOrderitemsFiles', $::form->{type}, $::form->{id} ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + only_if => $::instance_conf->get_doc_storage, + ], + ], #end of combobox "Export" + + combobox => [ + action => [ t8('more') ], + action => [ + t8('History'), + call => [ 'set_history_window', $form->{id} * 1, 'id' ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + ], + action => [ + t8('Follow-Up'), + call => [ 'follow_up_window' ], + disabled => !$form->{id} ? t8('This record has not been saved yet.') : undef, + ], + ], # end of combobox "more" + ); + } + $::request->layout->add_javascripts('kivi.Validator.js'); +} + +sub setup_oe_search_action_bar { + my %params = @_; + + for my $bar ($::request->layout->get('actionbar')) { + $bar->add( + action => [ + t8('Search'), + submit => [ '#form' ], + accesskey => 'enter', + checks => [ 'kivi.validate_form' ], + ], + ); + } + $::request->layout->add_javascripts('kivi.Validator.js'); +} + +sub setup_oe_orders_action_bar { + my %params = @_; + + return unless $::form->{type} eq 'sales_order'; + + for my $bar ($::request->layout->get('actionbar')) { + $bar->add( + action => [ + t8('New sales order'), + submit => [ '#form', { action => 'edit' } ], + checks => [ [ 'kivi.check_if_entries_selected', '[name^=multi_id_]' ] ], + accesskey => 'enter', + ], + ); + } +} + sub form_header { $main::lxdebug->enter_sub(); my @custom_hiddens; @@ -306,24 +495,20 @@ sub form_header { # Container for template variables. Unfortunately this has to be # visible in form_footer too, so package local level and not my here. - %TMPL_VAR = (); + my $TMPL_VAR = $::request->cache('tmpl_var', {}); if ($form->{id}) { - my $obj = SL::DB::Order->new(id => $form->{id})->load; - $TMPL_VAR{warn_save_active_periodic_invoice} = - $obj->is_type('sales_order') - && $obj->periodic_invoices_config - && $obj->periodic_invoices_config->active - && ( !$obj->periodic_invoices_config->end_date - || ($obj->periodic_invoices_config->end_date > DateTime->today_local)) - && $obj->periodic_invoices_config->get_previous_billed_period_start_date; - - $TMPL_VAR{oe_obj} = $obj; + $TMPL_VAR->{oe_obj} = SL::DB::Order->new(id => $form->{id})->load; } + $TMPL_VAR->{vc_obj} = SL::DB::Customer->new(id => $form->{customer_id})->load if $form->{customer_id}; + $TMPL_VAR->{vc_obj} = SL::DB::Vendor->new(id => $form->{vendor_id})->load if $form->{vendor_id}; $form->{defaultcurrency} = $form->get_default_currency(\%myconfig); - $form->{employee_id} = $form->{old_employee_id} if $form->{old_employee_id}; - $form->{salesman_id} = $form->{old_salesman_id} if $form->{old_salesman_id}; + my $current_employee = SL::DB::Manager::Employee->current; + $form->{employee_id} = $form->{old_employee_id} if $form->{old_employee_id}; + $form->{salesman_id} = $form->{old_salesman_id} if $form->{old_salesman_id}; + $form->{employee_id} ||= $current_employee->id; + $form->{salesman_id} ||= $current_employee->id; # openclosed checkboxes my @tmp; @@ -331,7 +516,7 @@ sub form_header { $form->{"delivered"} ? "checked" : "", $locale->text('Delivery Order(s) for full qty created') if $form->{"type"} =~ /_order$/; push @tmp, sprintf qq||, $form->{"closed"} ? "checked" : "", $locale->text('Closed') if $form->{id}; - $TMPL_VAR{openclosed} = sprintf qq|%s\n|, 2 * scalar @tmp, join "\n", @tmp if @tmp; + $TMPL_VAR->{openclosed} = sprintf qq|%s\n|, 2 * scalar @tmp, join "\n", @tmp if @tmp; my $vc = $form->{vc} eq "customer" ? "customers" : "vendors"; @@ -359,17 +544,17 @@ sub form_header { @old_ids_cond, ]); - $TMPL_VAR{ALL_PROJECTS} = SL::DB::Manager::Project->get_all_sorted(query => \@conditions); - $form->{ALL_PROJECTS} = $TMPL_VAR{ALL_PROJECTS}; # make projects available for second row drop-down in io.pl + $TMPL_VAR->{ALL_PROJECTS} = SL::DB::Manager::Project->get_all_sorted(query => \@conditions); + $form->{ALL_PROJECTS} = $TMPL_VAR->{ALL_PROJECTS}; # make projects available for second row drop-down in io.pl # label subs my $employee_list_query_gen = sub { $::form->{$_[0]} ? [ or => [ id => $::form->{$_[0]}, deleted => 0 ] ] : [ deleted => 0 ] }; - $TMPL_VAR{ALL_EMPLOYEES} = SL::DB::Manager::Employee->get_all_sorted(query => $employee_list_query_gen->('employee_id')); - $TMPL_VAR{ALL_SALESMEN} = SL::DB::Manager::Employee->get_all_sorted(query => $employee_list_query_gen->('salesman_id')); - $TMPL_VAR{ALL_SHIPTO} = SL::DB::Manager::Shipto->get_all_sorted(query => [ + $TMPL_VAR->{ALL_EMPLOYEES} = SL::DB::Manager::Employee->get_all_sorted(query => $employee_list_query_gen->('employee_id')); + $TMPL_VAR->{ALL_SALESMEN} = SL::DB::Manager::Employee->get_all_sorted(query => $employee_list_query_gen->('salesman_id')); + $TMPL_VAR->{ALL_SHIPTO} = SL::DB::Manager::Shipto->get_all_sorted(query => [ or => [ trans_id => $::form->{"$::form->{vc}_id"} * 1, and => [ shipto_id => $::form->{shipto_id} * 1, trans_id => undef ] ] ]); - $TMPL_VAR{ALL_CONTACTS} = SL::DB::Manager::Contact->get_all_sorted(query => [ + $TMPL_VAR->{ALL_CONTACTS} = SL::DB::Manager::Contact->get_all_sorted(query => [ or => [ cp_cv_id => $::form->{"$::form->{vc}_id"} * 1, and => [ @@ -378,20 +563,20 @@ sub form_header { ] ] ]); - $TMPL_VAR{sales_employee_labels} = sub { $_[0]->{name} || $_[0]->{login} }; + $TMPL_VAR->{sales_employee_labels} = sub { $_[0]->{name} || $_[0]->{login} }; # currencies and exchangerate $form->{currency} = $form->{defaultcurrency} unless $form->{currency}; - $TMPL_VAR{show_exchangerate} = $form->{currency} ne $form->{defaultcurrency}; + $TMPL_VAR->{show_exchangerate} = $form->{currency} ne $form->{defaultcurrency}; push @custom_hiddens, "forex"; push @custom_hiddens, "exchangerate" if $form->{forex}; # credit remaining my $creditwarning = (($form->{creditlimit} != 0) && ($form->{creditremaining} < 0) && !$form->{update}) ? 1 : 0; - $TMPL_VAR{is_credit_remaining_negativ} = ($form->{creditremaining} =~ /-/) ? "0" : "1"; + $TMPL_VAR->{is_credit_remaining_negativ} = ($form->{creditremaining} =~ /-/) ? "0" : "1"; # business - $TMPL_VAR{business_label} = ($form->{vc} eq "customer" ? $locale->text('Customer type') : $locale->text('Vendor type')); + $TMPL_VAR->{business_label} = ($form->{vc} eq "customer" ? $locale->text('Customer type') : $locale->text('Vendor type')); push @custom_hiddens, "customer_pricegroup_id" if $form->{vc} eq 'customer'; @@ -399,14 +584,14 @@ sub form_header { my $follow_up_vc = $form->{ $form->{vc} eq 'customer' ? 'customer' : 'vendor' }; $follow_up_vc =~ s/--\d*\s*$//; - $TMPL_VAR{follow_up_trans_info} = ($form->{type} =~ /_quotation$/ ? $form->{quonumber} : $form->{ordnumber}) . " ($follow_up_vc)"; + $TMPL_VAR->{follow_up_trans_info} = ($form->{type} =~ /_quotation$/ ? $form->{quonumber} : $form->{ordnumber}) . " ($follow_up_vc)"; if ($form->{id}) { my $follow_ups = FU->follow_ups('trans_id' => $form->{id}, 'not_done' => 1); if (scalar @{ $follow_ups }) { - $TMPL_VAR{num_follow_ups} = scalar @{ $follow_ups }; - $TMPL_VAR{num_due_follow_ups} = sum map { $_->{due} * 1 } @{ $follow_ups }; + $TMPL_VAR->{num_follow_ups} = scalar @{ $follow_ups }; + $TMPL_VAR->{num_due_follow_ups} = sum map { $_->{due} * 1 } @{ $follow_ups }; } } @@ -414,145 +599,73 @@ sub form_header { if ($form->{resubmit} && ($form->{format} eq "html")) { $dispatch_to_popup = "window.open('about:blank','Beleg'); document.oe.target = 'Beleg';"; $dispatch_to_popup .= "document.do.submit();"; - } elsif ($form->{resubmit}) { + } elsif ($form->{resubmit} && $form->{action_print}) { # emulate click for resubmitting actions - $dispatch_to_popup = "document.oe.${_}.click(); " for grep { /^action_/ } keys %$form; + $dispatch_to_popup = "kivi.SalesPurchase.show_print_dialog(); kivi.SalesPurchase.print_record();"; } elsif ($creditwarning) { $::request->{layout}->add_javascripts_inline("alert('$credittext');"); } $::request->{layout}->add_javascripts_inline("\$(function(){$dispatch_to_popup});"); - $TMPL_VAR{dateformat} = $myconfig{dateformat}; - $TMPL_VAR{numberformat} = $myconfig{numberformat}; + $TMPL_VAR->{dateformat} = $myconfig{dateformat}; + $TMPL_VAR->{numberformat} = $myconfig{numberformat}; if ($form->{type} eq 'sales_order') { if (!$form->{periodic_invoices_config}) { $form->{periodic_invoices_status} = $locale->text('not configured'); } else { - my $config = YAML::Load($form->{periodic_invoices_config}); + my $config = SL::YAML::Load($form->{periodic_invoices_config}); $form->{periodic_invoices_status} = $config->{active} ? $locale->text('active') : $locale->text('inactive'); } } - $::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.SalesPurchase kivi.File kivi.Part show_form_details show_history show_vc_details ckeditor/ckeditor ckeditor/adapters/jquery kivi.io autocomplete_customer)); + $::request->{layout}->use_javascript(map { "${_}.js" } qw(kivi.SalesPurchase kivi.File kivi.Part kivi.CustomerVendor kivi.Validator show_form_details show_history show_vc_details ckeditor/ckeditor ckeditor/adapters/jquery kivi.io)); # original snippets: - # 'data-require-transaction-description'=INSTANCE_CONF.get_require_transaction_description_ps - # data-warn-save-active-periodic-invoice="1" if warn_save_active_periodic_invoice - # tpca_reminder - my $is_sales = scalar ($form->{type} =~ /^sales_/); # these vars are exported, so that the template - my $is_order = scalar ($form->{type} =~ /_order$/); # may determine what to show - my $is_sales_quo = scalar ($form->{type} =~ /sales_quotation$/); - my $is_req_quo = scalar ($form->{type} =~ /request_quotation$/); - my $is_sales_ord = scalar ($form->{type} =~ /sales_order$/); - my $is_pur_ord = scalar ($form->{type} =~ /purchase_order$/); - my $allow_invoice = $is_req_quo || $is_pur_ord || ($is_sales_quo && $::instance_conf->get_allow_sales_invoice_from_sales_quotation) || ($is_sales_ord && $::instance_conf->get_allow_sales_invoice_from_sales_order); - - my $tpca_remainder = 0; + my %type_check_vars = ( + is_sales => scalar($form->{type} =~ /^sales_/), + is_order => scalar($form->{type} =~ /_order$/), + is_sales_quo => scalar($form->{type} =~ /sales_quotation$/), + is_req_quo => scalar($form->{type} =~ /request_quotation$/), + is_sales_ord => scalar($form->{type} =~ /sales_order$/), + is_pur_ord => scalar($form->{type} =~ /purchase_order$/), + ); - for my $bar ($::request->layout->get('actionbar')) { - $bar->add_actions([ t8('Update'), - submit => [ '#form', { action_update => 1 } ], - ]); - $bar->add_actions([ t8('Ship to'), - submit => [ '#form', { action_ship_to => 1 } ], - ]); - $bar->add_actions([ t8('Print'), - submit => [ '#form', { action_print => 1 } ], - checks => [ qw(kivi.SalesPurchase.check_transaction_description) ], - ]); - $bar->add_actions([ t8('E Mail'), - submit => [ '#form', { action_print => 1 } ], - checks => [ qw(kivi.SalesPurchase.check_transaction_description) ], - ]); - $bar->add_actions([ t8('Save'), - submit => [ '#form', { action_save => 1 } ], - checks => [ qw(kivi.SalesPurchase.check_transaction_description) ], - confirm => t8('Missing transport cost: #1 Are you sure?', $tpca_remainder), - # optional warn_save_active_periodic_invoice, - ]); - $bar->add_actions([ t8('Save and Close'), - submit => [ '#form', { action_save_and_close => 1 } ], - checks => [ qw(kivi.SalesPurchase.check_transaction_description) ], - confirm => t8('Missing transport cost: #1 Are you sure?', $tpca_remainder), - # always, optional warn_save_active_periodic_invoice, - ]); - $bar->add_actions([ t8('Follow-Up'), - function => [ 'follow_up_window' ], - disabled => !$::form->{id}, - ]); - $bar->add_actions([ t8('History'), - function => [ 'set_history_window', $::form->{id} * 1, 'id' ], - disabled => !$::form->{id}, - ]); - $bar->add_actions([ t8('Save as new'), - submit => [ '#form', { action_save_as_new => 1 } ], - checks => [ qw(kivi.SalesPurchase.check_transaction_description) ], - disabled => !$::form->{id}, - ]); - $bar->add_actions([ t8('Delete'), - submit => [ '#form', { action_delete => 1 } ], - disabled => !$::form->{id}, - ]) if $::form->{id} && (!$is_sales_ord || $::instance_conf->get_sales_order_show_delete) && (!$is_pur_ord || $::instance_conf->get_purchase_order_show_delete); - $bar->add_actions([ t8('Sales Order'), - submit => [ '#form', { action_sales_order => 1 } ], - disabled => !$::form->{id}, - ]) if $is_sales_quo; - $bar->add_actions([ t8('Purchase Order'), - submit => [ '#form', { action_sales_order => 1 } ], - disabled => !$::form->{id}, - ]) if $is_req_quo; - $bar->add_actions([ t8('Delivery Order'), - submit => [ '#form', { action_delivery_order => 1 } ], - disabled => !$::form->{id}, - ]) if $is_sales_ord || $is_pur_ord; - $bar->add_actions([ t8('Invoice'), - submit => [ '#form', { action_invoice => 1 } ], - disabled => !$::form->{id}, - ]) if $allow_invoice; - $bar->add_actions([ t8('Quotation'), - submit => [ '#form', { action_quotation => 1 } ], - disabled => !$::form->{id}, - ]); - $bar->add_actions([ t8('Request for Quotation'), - submit => [ '#form', { action_reqest_for_quotation => 1 } ], - disabled => !$::form->{id} - ]); - } + setup_oe_action_bar( + %type_check_vars, + oe_obj => $TMPL_VAR->{oe_obj}, + vc_obj => $TMPL_VAR->{vc_obj}, + ); $form->header; if ($form->{CFDD_shipto} && $form->{CFDD_shipto_id} ) { $form->{shipto_id} = $form->{CFDD_shipto_id}; } - push @custom_hiddens, map { "shiptocvar_" . $_->name } @{ SL::DB::Manager::CustomVariableConfig->get_all(where => [ module => 'ShipTo' ]) }; - - $TMPL_VAR{HIDDENS} = [ map { name => $_, value => $form->{$_} }, - qw(id action type vc formname media format proforma queued printed emailed + $TMPL_VAR->{HIDDENS} = [ map { name => $_, value => $form->{$_} }, + qw(id type vc proforma queued printed emailed title creditlimit creditremaining tradediscount business - max_dunning_level dunning_amount shiptoname shiptostreet shiptozipcode - CFDD_shipto CFDD_shipto_id shiptocity shiptocountry shiptogln shiptocontact shiptophone shiptofax - shiptodepartment_1 shiptodepartment_2 shiptoemail shiptocp_gender - message email subject cc bcc taxpart taxservice taxaccounts cursor_fokus + max_dunning_level dunning_amount + CFDD_shipto CFDD_shipto_id + taxpart taxservice taxaccounts cursor_fokus show_details useasnew), @custom_hiddens, map { $_.'_rate', $_.'_description', $_.'_taxnumber' } split / /, $form->{taxaccounts} ]; # deleted: discount - %TMPL_VAR = ( - %TMPL_VAR, - is_sales => $is_sales, - is_order => $is_order, - is_sales_quo => $is_sales_quo, - is_req_quo => $is_req_quo, - is_sales_ord => $is_sales_ord, - is_pur_ord => $is_pur_ord, - ); + $TMPL_VAR->{$_} = $type_check_vars{$_} for keys %type_check_vars; - $TMPL_VAR{ORDER_PROBABILITIES} = [ map { { title => ($_ * 10) . '%', id => $_ * 10 } } (0..10) ]; + $TMPL_VAR->{ORDER_PROBABILITIES} = [ map { { title => ($_ * 10) . '%', id => $_ * 10 } } (0..10) ]; - print $form->parse_html_template("oe/form_header", { %TMPL_VAR }); + if ($type_check_vars{is_sales} && $::instance_conf->get_transport_cost_reminder_article_number_id) { + $TMPL_VAR->{transport_cost_reminder_article} = SL::DB::Part->new(id => $::instance_conf->get_transport_cost_reminder_article_number_id)->load; + } + + print $form->parse_html_template("oe/form_header", { + %$TMPL_VAR, + %type_check_vars, + }); $main::lxdebug->leave_sub(); } @@ -568,10 +681,7 @@ sub form_footer { $form->{invtotal} = $form->{invsubtotal}; - my $introws = max 5, $form->numtextrows($form->{intnotes}, 35, 8); - - $TMPL_VAR{notes} = qq||; - $TMPL_VAR{intnotes} = qq||; + my $TMPL_VAR = $::request->cache('tmpl_var', {}); if( $form->{customer_id} && !$form->{taxincluded_changed_by_user} ) { my $customer = SL::DB::Customer->new(id => $form->{customer_id})->load(); @@ -585,7 +695,7 @@ sub form_footer { $form->{invtotal} += $form->{"${item}_total"} = $form->round_amount( $form->{"${item}_base"} * $form->{"${item}_rate"}, 2); $form->{"${item}_total"} = $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2); - $TMPL_VAR{tax} .= qq| + $TMPL_VAR->{tax} .= qq| $form->{"${item}_description"} | . $form->{"${item}_rate"} * 100 .qq|% $form->{"${item}_total"} @@ -600,7 +710,7 @@ sub form_footer { $form->{"${item}_total"} = $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2); $form->{"${item}_netto"} = $form->format_amount(\%myconfig, $form->{"${item}_netto"}, 2); - $TMPL_VAR{tax} .= qq| + $TMPL_VAR->{tax} .= qq| Enthaltene $form->{"${item}_description"} | . $form->{"${item}_rate"} * 100 .qq|% $form->{"${item}_total"} @@ -621,22 +731,26 @@ sub form_footer { ); $form->{oldinvtotal} = $form->{invtotal}; - $TMPL_VAR{ALL_DELIVERY_TERMS} = SL::DB::Manager::DeliveryTerm->get_all_sorted(); + $TMPL_VAR->{ALL_DELIVERY_TERMS} = SL::DB::Manager::DeliveryTerm->get_all_sorted(); + + my $print_options_html = setup_sales_purchase_print_options(); + + my $shipto_cvars = SL::DB::Shipto->new->cvars_by_config; + foreach my $var (@{ $shipto_cvars }) { + my $name = "shiptocvar_" . $var->config->name; + $var->value($form->{$name}) if exists $form->{$name}; + } - my $tpca_reminder; - $tpca_reminder = check_transport_cost_reminder_article_number() if $::instance_conf->get_transport_cost_reminder_article_number_id; print $form->parse_html_template("oe/form_footer", { - %TMPL_VAR, - tpca_reminder => $tpca_reminder, - print_options => print_options(inline => 1), - label_edit => $locale->text("Edit the $form->{type}"), - label_workflow => $locale->text("Workflow $form->{type}"), + %$TMPL_VAR, + print_options => $print_options_html, is_sales => scalar ($form->{type} =~ /^sales_/), # these vars are exported, so that the template is_order => scalar ($form->{type} =~ /_order$/), # may determine what to show is_sales_quo => scalar ($form->{type} =~ /sales_quotation$/), is_req_quo => scalar ($form->{type} =~ /request_quotation$/), is_sales_ord => scalar ($form->{type} =~ /sales_order$/), is_pur_ord => scalar ($form->{type} =~ /purchase_order$/), + shipto_cvars => $shipto_cvars, }); $main::lxdebug->leave_sub(); @@ -851,6 +965,8 @@ sub search { $::request->{layout}->use_javascript(map { "${_}.js" } qw(autocomplete_project)); + setup_oe_search_action_bar(); + $form->header(); print $form->parse_html_template('oe/search', { @@ -903,7 +1019,7 @@ sub orders { my @columns = ( "transdate", "reqdate", - "id", $ordnumber, "edit_exp", + "id", $ordnumber, "cusordnumber", "customernumber", "name", "netamount", "tax", "amount", @@ -911,7 +1027,7 @@ sub orders { "curr", "employee", "salesman", "shipvia", "globalprojectnumber", - "transaction_description", "open", + "transaction_description", "department", "open", "delivered", "periodic_invoices", "marge_total", "marge_percent", "vcnumber", "ustid", @@ -930,7 +1046,6 @@ sub orders { $form->{l_open} = $form->{l_closed} = "Y" if ($form->{open} && $form->{closed}); $form->{l_delivered} = "Y" if ($form->{delivered} && $form->{notdelivered}); $form->{l_periodic_invoices} = "Y" if ($form->{periodic_invoices_active} && $form->{periodic_invoices_inactive}); - $form->{l_edit_exp} = "Y" if (any { $form->{type} eq $_ } qw(sales_order purchase_order)); map { $form->{"l_${_}"} = 'Y' } qw(order_probability expected_billing_date expected_netamount) if $form->{l_order_probability_expected_billing_date}; my $attachment_basename; @@ -997,6 +1112,7 @@ sub orders { 'shipvia' => { 'text' => $locale->text('Ship via'), }, 'globalprojectnumber' => { 'text' => $locale->text('Project Number'), }, 'transaction_description' => { 'text' => $locale->text('Transaction description'), }, + 'department' => { 'text' => $locale->text('Department'), }, 'open' => { 'text' => $locale->text('Open'), }, 'delivered' => { 'text' => $locale->text('Delivery Order created'), }, 'marge_total' => { 'text' => $locale->text('Ertrag'), }, @@ -1012,11 +1128,10 @@ sub orders { 'expected_billing_date' => { 'text' => $locale->text('Exp. bill. date'), }, 'expected_netamount' => { 'text' => $locale->text('Exp. netamount'), }, 'payment_terms' => { 'text' => $locale->text('Payment Terms'), }, - 'edit_exp' => { 'text' => $locale->text('Edit (experimental)'), }, %column_defs_cvars, ); - foreach my $name (qw(id transdate reqdate quonumber ordnumber cusordnumber name employee salesman shipvia transaction_description shippingpoint taxzone insertdate payment_terms)) { + foreach my $name (qw(id transdate reqdate quonumber ordnumber cusordnumber name employee salesman shipvia transaction_description shippingpoint taxzone insertdate payment_terms department)) { my $sortdir = $form->{sort} eq $name ? 1 - $form->{sortdir} : $form->{sortdir}; $column_defs{$name}->{link} = $href . "&sort=$name&sortdir=$sortdir"; } @@ -1098,7 +1213,7 @@ sub orders { $report->set_options('top_info_text' => join("\n", @options), 'raw_top_info_text' => $form->parse_html_template('oe/orders_top'), - 'raw_bottom_info_text' => $form->parse_html_template('oe/orders_bottom', { 'SHOW_CONTINUE_BUTTON' => $allow_multiple_orders }), + 'raw_bottom_info_text' => $form->parse_html_template('oe/orders_bottom'), 'output_format' => 'HTML', 'title' => $form->{title}, 'attachment_basename' => $attachment_basename . strftime('_%Y%m%d', localtime time), @@ -1120,7 +1235,9 @@ sub orders { my $idx = 1; - my $edit_url = build_std_url('action=edit', 'type', 'vc'); + my $edit_url = ($::instance_conf->get_feature_experimental_order) + ? build_std_url('script=controller.pl', 'action=Order/edit', 'type') + : build_std_url('action=edit', 'type', 'vc'); foreach my $oe (@{ $form->{OE} }) { map { $oe->{$_} *= $oe->{exchangerate} } @subtotal_columns; @@ -1144,7 +1261,6 @@ sub orders { foreach my $column (@columns) { next if ($column eq 'ids'); - next if ($column eq 'edit_exp'); $row->{$column} = { 'data' => $oe->{$column}, 'align' => $column_alignment{$column}, @@ -1160,9 +1276,6 @@ sub orders { $row->{$ordnumber}->{link} = $edit_url . "&id=" . E($oe->{id}) . "&callback=${callback}"; - $row->{edit_exp}->{data} = $oe->{ordnumber}; - $row->{edit_exp}->{link} = build_std_url('script=controller.pl', 'action=Order/edit', "type=$form->{type}", 'id=' . E($oe->{id})); - my $row_set = [ $row ]; if (($form->{l_subtotal} eq 'Y') @@ -1179,6 +1292,7 @@ sub orders { $report->add_separator(); $report->add_data(create_subtotal_row(\%totals, \@columns, \%column_alignment, \@subtotal_columns, 'listtotal')); + setup_oe_orders_action_bar(); $report->generate_with_headers(); $main::lxdebug->leave_sub(); @@ -1201,6 +1315,8 @@ sub check_delivered_flag { foreach my $i (1 .. $form->{rowcount}) { next if (!$form->{"id_$i"}); + $form->{"ship_$i"} = 0 if $form->{saveasnew}; + if ($form->parse_amount(\%myconfig, $form->{"qty_$i"}) == $form->parse_amount(\%myconfig, $form->{"ship_$i"})) { $all_delivered = 1; next; @@ -1211,6 +1327,7 @@ sub check_delivered_flag { } $form->{delivered} = 1 if $all_delivered; + $form->{delivered} = 0 if $form->{saveasnew}; $main::lxdebug->leave_sub(); } @@ -1659,7 +1776,8 @@ sub save_as_new { if ( $form->{reqdate} && $form->{id} ) { my $saved_order = OE->retrieve_simple(id => $form->{id}); if ( $saved_order && $saved_order->{reqdate} eq $form->{reqdate} && $saved_order->{transdate} eq $form->{transdate} ) { - my $extra_days = $form->{type} eq 'sales_quotation' ? $::instance_conf->get_reqdate_interval : 1; + my $extra_days = $form->{type} eq 'sales_quotation' ? $::instance_conf->get_reqdate_interval : + $form->{type} eq 'sales_order' ? $::instance_conf->get_delivery_date_interval : 1; $form->{reqdate} = DateTime->today_local->next_workday(extra_days => $extra_days)->to_kivitendo; $form->{transdate} = DateTime->today_local->to_kivitendo; } @@ -1832,7 +1950,8 @@ sub poso { $form->{old_salesman_id} = $form->{salesman_id}; # reset - map { delete $form->{$_} } qw(id subject message cc bcc printed emailed queued customer vendor creditlimit creditremaining discount tradediscount oldinvtotal delivered ordnumber); + map { delete $form->{$_} } qw(id subject message cc bcc printed emailed queued customer vendor creditlimit creditremaining discount tradediscount oldinvtotal delivered ordnumber + taxzone_id currency); # this converted variable is also used for sales_order to purchase order and vice versa $form->{"converted_from_orderitems_id_$_"} = delete $form->{"orderitems_id_$_"} for 1 .. $form->{"rowcount"}; @@ -1937,31 +2056,39 @@ sub oe_delivery_order_from_order { my $order = SL::DB::Order->new(id => $::form->{id})->load; $order->flatten_to_form($::form, format_amounts => 1); + # hack: add partsgroup for first row if it does not exists, + # because _remove_billed_or_delivered_rows and _remove_full_delivered_rows + # determine fields to handled by existing fields for the first row. If partsgroup + # is missing there, for deleted rows the partsgroup_field is not emptied and in + # update_delivery_order it will not considered an empty row ... + $::form->{partsgroup_1} = '' if !exists $::form->{partsgroup_1}; + # fake last empty row $::form->{rowcount}++; + _update_ship(); delivery_order(); } -sub e_mail { - $main::lxdebug->enter_sub(); - - my $form = $main::form; - - check_oe_access(); - - $form->mtime_ischanged('oe','mail'); - $form->{print_and_save} = 1; +sub oe_invoice_from_order { - my $saved_form = save_form(); + return if !$::form->{id}; - save(); + my $order = SL::DB::Order->new(id => $::form->{id})->load; + $order->flatten_to_form($::form, format_amounts => 1); - restore_form($saved_form, 0, qw(id ordnumber quonumber)); + # hack: add partsgroup for first row if it does not exists, + # because _remove_billed_or_delivered_rows and _remove_full_delivered_rows + # determine fields to handled by existing fields for the first row. If partsgroup + # is missing there, for deleted rows the partsgroup_field is not emptied and in + # update_delivery_order it will not considered an empty row ... + $::form->{partsgroup_1} = '' if !exists $::form->{partsgroup_1}; - edit_e_mail(); + # fake last empty row + $::form->{rowcount}++; - $main::lxdebug->leave_sub(); + _update_ship(); + invoice(); } sub yes { @@ -2020,7 +2147,9 @@ sub report_for_todo_list { my $content; if (@{ $quotations }) { - my $edit_url = build_std_url('script=oe.pl', 'action=edit'); + my $edit_url = ($::instance_conf->get_feature_experimental_order) + ? build_std_url('script=controller.pl', 'action=Order/edit') + : build_std_url('script=oe.pl', 'action=edit'); $content = $form->parse_html_template('oe/report_for_todo_list', { 'QUOTATIONS' => $quotations, 'edit_url' => $edit_url }); @@ -2039,14 +2168,19 @@ sub edit_periodic_invoices_config { check_oe_access(); my $config; - $config = YAML::Load($::form->{periodic_invoices_config}) if $::form->{periodic_invoices_config}; + $config = SL::YAML::Load($::form->{periodic_invoices_config}) if $::form->{periodic_invoices_config}; if ('HASH' ne ref $config) { + my $lang_id = $::form->{language_id}; $config = { periodicity => 'm', order_value_periodicity => 'p', # = same as periodicity start_date_as_date => $::form->{transdate} || $::form->current_date, extend_automatically_by => 12, active => 1, + email_subject => GenericTranslations->get(language_id => $lang_id, + translation_type =>"preset_text_periodic_invoices_email_subject"), + email_body => GenericTranslations->get(language_id => $lang_id, + translation_type =>"preset_text_periodic_invoices_email_body"), }; } @@ -2065,7 +2199,7 @@ sub edit_periodic_invoices_config { } $::form->header(no_layout => 1); - print $::form->parse_html_template('oe/edit_periodic_invoices_config', $config); + print $::form->parse_html_template('oe/edit_periodic_invoices_config', {config => $config}); $::lxdebug->leave_sub(); } @@ -2100,7 +2234,7 @@ sub save_periodic_invoices_config { email_body => $::form->{email_body}, }; - $::form->{periodic_invoices_config} = YAML::Dump($config); + $::form->{periodic_invoices_config} = SL::YAML::Dump($config); $::form->{title} = $::locale->text('Edit the configuration for periodic invoices'); $::form->header; @@ -2178,26 +2312,8 @@ sub _oe_remove_delivered_or_billed_rows { _remove_billed_or_delivered_rows(quantities => \%handled_base_qtys); } -# iterate all positions and match articlenumber -sub check_transport_cost_reminder_article_number { - $main::lxdebug->enter_sub(); - - my $form = $main::form; - - check_oe_access(); - - my $transport_article_id = $::instance_conf->get_transport_cost_reminder_article_number_id; - for my $i (1 .. $form->{rowcount}) { - return if $form->{"id_${i}"} eq $transport_article_id; - } - - # simply return the name of the part - return SL::DB::Part->new(id => $transport_article_id)->load()->partnumber; - - $main::lxdebug->leave_sub(); -} sub dispatcher { - foreach my $action (qw(delete delivery_order e_mail invoice print purchase_order quotation + foreach my $action (qw(delete delivery_order invoice print purchase_order quotation request_for_quotation sales_order save save_and_close save_as_new ship_to update)) { if ($::form->{"action_${action}"}) { call_sub($action);