X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FController%2FProject.pm;h=601b245b7cd7cf2d004816ceab81b3bb82b2313d;hb=161082b04bdd3320fe94ff448e80a0b4d19bc29b;hp=f028b9e6ccdf698d357797ed0ce4fcd08adcdca5;hpb=f1ed2dc0cb936826fb8fa21bab7ad73e9d4de3d9;p=kivitendo-erp.git diff --git a/SL/Controller/Project.pm b/SL/Controller/Project.pm index f028b9e6c..601b245b7 100644 --- a/SL/Controller/Project.pm +++ b/SL/Controller/Project.pm @@ -22,16 +22,18 @@ use SL::DB::ProjectType; use SL::Helper::Flash; use SL::Locale::String; +use Data::Dumper; +use JSON; +use Rose::DB::Object::Helpers qw(as_tree); + use Rose::Object::MakeMethods::Generic ( - scalar => [ qw(project linked_records) ], - 'scalar --get_set_init' => [ qw(models) ], + scalar => [ qw(project) ], + 'scalar --get_set_init' => [ qw(models customers project_types project_statuses projects linked_records) ], ); -__PACKAGE__->run_before('check_auth'); -__PACKAGE__->run_before('load_project', only => [ qw(edit update destroy) ]); -__PACKAGE__->run_before('load_project_types', only => [ qw(search edit new list) ]); -__PACKAGE__->run_before('load_project_status', only => [ qw(search edit new list) ]); +__PACKAGE__->run_before('check_auth', except => [ qw(ajax_autocomplete) ]); +__PACKAGE__->run_before('load_project', only => [ qw(edit update destroy) ]); # # actions @@ -43,24 +45,27 @@ sub action_search { my %params; $params{CUSTOM_VARIABLES} = CVar->get_configs(module => 'Projects'); + ($params{CUSTOM_VARIABLES_FILTER_CODE}, $params{CUSTOM_VARIABLES_INCLUSION_CODE}) = CVar->render_search_options(variables => $params{CUSTOM_VARIABLES}, include_prefix => 'l_', include_value => 'Y'); + $self->setup_search_action_bar; + $self->render('project/search', %params); } sub action_list { my ($self) = @_; - $self->make_filter_summary; + $self->setup_search_action_bar; - my $projects = $self->models->get; + $self->make_filter_summary; $self->prepare_report; - $self->report_generator_list_objects(report => $self->{report}, objects => $projects); + $self->report_generator_list_objects(report => $self->{report}, objects => $self->models->get); } sub action_new { @@ -68,15 +73,14 @@ sub action_new { $self->project(SL::DB::Project->new); $self->display_form(title => $::locale->text('Create a new project'), - callback => $::form->{callback} || $self->url_for(action => 'new')); + callback => $::form->{callback} || $self->url_for(action => 'list')); } sub action_edit { my ($self) = @_; - $self->get_linked_records; $self->display_form(title => $::locale->text('Edit project #1', $self->project->projectnumber), - callback => $::form->{callback} || $self->url_for(action => 'edit', id => $self->project->id)); + callback => $::form->{callback} || $self->url_for(action => 'list')); } sub action_create { @@ -103,6 +107,51 @@ sub action_destroy { $self->redirect_to(action => 'search'); } +sub action_ajax_autocomplete { + my ($self, %params) = @_; + + $::form->{filter}{'all:substr:multi::ilike'} =~ s{[\(\)]+}{}g; + + # if someone types something, and hits enter, assume he entered the full name. + # if something matches, treat that as sole match + # unfortunately get_models can't do more than one per package atm, so we d it + # the oldfashioned way. + if ($::form->{prefer_exact}) { + my $exact_matches; + if (1 == scalar @{ $exact_matches = SL::DB::Manager::Project->get_all( + query => [ + valid => 1, + or => [ + description => { ilike => $::form->{filter}{'all:substr:multi::ilike'} }, + projectnumber => { ilike => $::form->{filter}{'all:substr:multi::ilike'} }, + ] + ], + limit => 2, + ) }) { + $self->projects($exact_matches); + } + } + + $::form->{sort_by} = 'customer_and_description'; + + my @hashes = map { + +{ + value => $_->full_description(style => 'full'), + label => $_->full_description(style => 'full'), + id => $_->id, + projectnumber => $_->projectnumber, + description => $_->description, + cvars => { map { ($_->config->name => { value => $_->value_as_text, is_valid => $_->is_valid }) } @{ $_->cvars_by_config } }, + } + } @{ $self->projects }; # neato: if exact match triggers we don't even need the init_projects + + $self->render(\ SL::JSON::to_json(\@hashes), { layout => 0, type => 'json', process => 0 }); +} + +sub action_test_page { + $_[0]->render('project/test_page'); +} + # # filters # @@ -115,10 +164,68 @@ sub check_auth { # helpers # +sub init_project_statuses { SL::DB::Manager::ProjectStatus->get_all_sorted } +sub init_project_types { SL::DB::Manager::ProjectType->get_all_sorted } + +sub init_linked_records { + my ($self) = @_; + return [ + map { @{ $_ } } + grep { $_ } ( + SL::DB::Manager::Invoice-> get_all(where => [ invoice => 1, or => [ globalproject_id => $self->project->id, 'invoiceitems.project_id' => $self->project->id ] ], + with_objects => [ 'invoiceitems', 'customer' ], + distinct => [ 'customer' ], + sort_by => 'transdate ASC'), + SL::DB::Manager::Invoice-> get_all(where => [ invoice => 0, or => [ globalproject_id => $self->project->id, 'transactions.project_id' => $self->project->id ] ], + with_objects => [ 'transactions', 'customer' ], + distinct => [ 'customer' ], + sort_by => 'transdate ASC'), + SL::DB::Manager::PurchaseInvoice->get_all(where => [ invoice => 1, + or => [ globalproject_id => $self->project->id, 'invoiceitems.project_id' => $self->project->id ] + ], + with_objects => [ 'invoiceitems', 'vendor' ], + distinct => [ 'customer' ], + sort_by => 'transdate ASC'), + SL::DB::Manager::PurchaseInvoice->get_all(where => [ invoice => 0, + or => [ globalproject_id => $self->project->id, 'transactions.project_id' => $self->project->id ] + ], + with_objects => [ 'transactions', 'vendor' ], + distinct => [ 'customer' ], + sort_by => 'transdate ASC'), + SL::DB::Manager::GLTransaction-> get_all(where => [ 'transactions.project_id' => $self->project->id ], + with_objects => [ 'transactions' ], + distinct => 1, + sort_by => 'transdate ASC'), + SL::DB::Manager::Order-> get_all(where => [ or => [ globalproject_id => $self->project->id, 'orderitems.project_id' => $self->project->id ] ], + with_objects => [ 'orderitems', 'customer', 'vendor' ], + distinct => [ 'customer', 'vendor' ], + sort_by => 'transdate ASC' ), + SL::DB::Manager::DeliveryOrder-> get_all(where => [ or => [ globalproject_id => $self->project->id, 'orderitems.project_id' => $self->project->id ] ], + with_objects => [ 'orderitems', 'customer', 'vendor' ], + distinct => [ 'customer', 'vendor' ], + sort_by => 'transdate ASC'), + )]; +} + + +sub init_projects { + if ($::form->{no_paginate}) { + $_[0]->models->disable_plugin('paginated'); + } + + $_[0]->models->get; +} + +sub init_customers { + my ($self) = @_; + my @customer_id = $self->project && $self->project->customer_id ? (id => $self->project->customer_id) : (); + + return SL::DB::Manager::Customer->get_all_sorted(where => [ or => [ obsolete => 0, obsolete => undef, @customer_id ]]); +} + sub display_form { my ($self, %params) = @_; - $params{ALL_CUSTOMERS} = SL::DB::Manager::Customer->get_all_sorted(where => [ or => [ obsolete => 0, obsolete => undef, id => $self->project->customer_id ]]); $params{CUSTOM_VARIABLES} = CVar->get_custom_variables(module => 'Projects', trans_id => $self->project->id); if ($params{keep_cvars}) { @@ -129,6 +236,8 @@ sub display_form { CVar->render_inputs(variables => $params{CUSTOM_VARIABLES}) if @{ $params{CUSTOM_VARIABLES} }; + $self->setup_edit_action_bar(callback => $params{callback}); + $self->render('project/form', %params); } @@ -170,18 +279,6 @@ sub load_project { $self->project(SL::DB::Project->new(id => $::form->{id})->load); } -sub get_linked_records { - my ($self) = @_; - - $self->linked_records([ - map { @{ $_ } } - grep { $_ } ( - SL::DB::Manager::Order-> get_all(where => [ globalproject_id => $self->project->id ], with_objects => [ 'customer', 'vendor' ], sort_by => 'transdate ASC'), - SL::DB::Manager::DeliveryOrder-> get_all(where => [ globalproject_id => $self->project->id ], with_objects => [ 'customer', 'vendor' ], sort_by => 'transdate ASC'), - SL::DB::Manager::Invoice-> get_all(where => [ globalproject_id => $self->project->id ], with_objects => [ 'customer' ], sort_by => 'transdate ASC'), - SL::DB::Manager::PurchaseInvoice->get_all(where => [ globalproject_id => $self->project->id ], with_objects => [ 'vendor' ], sort_by => 'transdate ASC'), - )]); -} sub prepare_report { my ($self) = @_; @@ -199,7 +296,8 @@ sub prepare_report { description => { obj_link => sub { $self->url_for(action => 'edit', id => $_[0]->id, callback => $callback) } }, project_type => { sub => sub { $_[0]->project_type->description } }, project_status => { sub => sub { $_[0]->project_status->description }, text => t8('Status') }, - customer => { raw_data => sub { $self->presenter->customer($_[0]->customer, display => 'table-cell', callback => $callback) } }, + customer => { sub => sub { !$_[0]->customer_id ? '' : $_[0]->customer->name }, + raw_data => sub { !$_[0]->customer_id ? '' : $_[0]->customer->presenter->customer(display => 'table-cell', callback => $callback) } }, active => { sub => sub { $_[0]->active ? $::locale->text('Active') : $::locale->text('Inactive') }, text => $::locale->text('Active') }, valid => { sub => sub { $_[0]->valid ? $::locale->text('Valid') : $::locale->text('Invalid') }, @@ -208,15 +306,10 @@ sub prepare_report { map { $column_defs{$_}->{text} ||= $::locale->text( $self->models->get_sort_spec->{$_}->{title} ) } keys %column_defs; - if ( $report->{options}{output_format} =~ /^(pdf|csv)$/i ) { - $self->models->disable_plugin('paginated'); - } $report->set_options( std_column_visibility => 1, controller_class => 'Project', output_format => 'HTML', - raw_top_info_text => $self->render('project/report_top', { output => 0 }), - raw_bottom_info_text => $self->render('project/report_bottom', { output => 0 }), title => $::locale->text('Projects'), allow_pdf_export => 1, allow_csv_export => 1, @@ -225,8 +318,10 @@ sub prepare_report { $report->set_column_order(@columns); $report->set_export_options(qw(list filter)); $report->set_options_from_form; + $self->models->disable_plugin('paginated') if $report->{options}{output_format} =~ /^(pdf|csv)$/i; $self->models->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable); $report->set_options( + raw_top_info_text => $self->render('project/report_top', { output => 0 }), raw_bottom_info_text => $self->render('project/report_bottom', { output => 0 }), ); } @@ -241,12 +336,14 @@ sub init_models { by => 'projectnumber', dir => 1, }, - customer => t8('Customer'), - description => t8('Description'), - projectnumber => t8('Project Number'), - project_type => t8('Project Type'), + customer => t8('Customer'), + description => t8('Description'), + projectnumber => t8('Project Number'), + project_type => t8('Project Type'), + project_status => t8('Project Status'), + customer_and_description => 1, }, - with_objects => [ 'customer' ], + with_objects => [ 'customer', 'project_status', 'project_type' ], ); } @@ -282,12 +379,59 @@ sub make_filter_summary { $self->{filter_summary} = join ', ', @filter_strings; } -sub load_project_types { - $_[0]{ALL_PROJECT_TYPES} = SL::DB::Manager::ProjectType->get_all_sorted; +sub setup_edit_action_bar { + my ($self, %params) = @_; + + my $is_new = !$self->project->id; + + for my $bar ($::request->layout->get('actionbar')) { + $bar->add( + combobox => [ + action => [ + t8('Save'), + submit => [ '#form', { action => 'Project/' . ($is_new ? 'create' : 'update') } ], + accesskey => 'enter', + ], + action => [ + t8('Save as new'), + submit => [ '#form', { action => 'Project/create' }], + disabled => $is_new ? t8('The object has not been saved yet.') : undef, + ], + ], # end of combobox "Save" + + action => [ + t8('Delete'), + submit => [ '#form', { action => 'Project/destroy' } ], + confirm => $::locale->text('Do you really want to delete this object?'), + disabled => $is_new ? t8('This object has not been saved yet.') + : $self->project->is_used ? t8('This object has already been used.') + : undef, + ], + + link => [ + t8('Abort'), + link => $params{callback} || $self->url_for(action => 'list'), + ], + ); + } } -sub load_project_status { - $_[0]{ALL_PROJECT_STATUS} = SL::DB::Manager::ProjectStatus->get_all_sorted; +sub setup_search_action_bar { + my ($self, %params) = @_; + + for my $bar ($::request->layout->get('actionbar')) { + $bar->add( + action => [ + t8('Update'), + submit => [ '#search_form', { action => 'Project/list' } ], + accesskey => 'enter', + ], + link => [ + t8('Add'), + link => $self->url_for(action => 'new'), + ], + ); + } } 1;