X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/mfinanz.git/blobdiff_plain/eae5f8bdbca22f1f8c7ba4439dafbe3b89b6a143..5a55ac869e35f61a8ae018d0e54b4fe6dc89c6a7:/SL/Controller/Part.pm diff --git a/SL/Controller/Part.pm b/SL/Controller/Part.pm index 1c8db0e5d..f152e0844 100644 --- a/SL/Controller/Part.pm +++ b/SL/Controller/Part.pm @@ -6,6 +6,7 @@ use parent qw(SL::Controller::Base); use Clone qw(clone); use SL::DB::Part; use SL::DB::PartsGroup; +use SL::DB::Shop; use SL::Controller::Helper::GetModels; use SL::Locale::String qw(t8); use SL::JSON; @@ -16,15 +17,17 @@ use DateTime; use SL::DB::History; use SL::DB::Helper::ValidateAssembly qw(validate_assembly); use SL::CVar; +use SL::MoreCommon qw(save_form); use Carp; use Rose::Object::MakeMethods::Generic ( 'scalar --get_set_init' => [ qw(parts models part p warehouses multi_items_models - makemodels + makemodels shops_not_assigned orphaned assortment assortment_items assembly assembly_items all_pricegroups all_translations all_partsgroups all_units all_buchungsgruppen all_payment_terms all_warehouses + parts_classification_filter all_languages all_units all_price_factors) ], 'scalar' => [ qw(warehouse bin) ], ); @@ -40,7 +43,6 @@ __PACKAGE__->run_before('check_part_id', only => [ qw(edit delete) ]); sub action_add_part { my ($self, %params) = @_; - $::form->{callback} = $self->url_for(action => 'add_part') unless $::form->{callback}; $self->part( SL::DB::Part->new_part ); $self->add; }; @@ -48,7 +50,6 @@ sub action_add_part { sub action_add_service { my ($self, %params) = @_; - $::form->{callback} = $self->url_for(action => 'add_service') unless $::form->{callback}; $self->part( SL::DB::Part->new_service ); $self->add; }; @@ -56,7 +57,6 @@ sub action_add_service { sub action_add_assembly { my ($self, %params) = @_; - $::form->{callback} = $self->url_for(action => 'add_assembly') unless $::form->{callback}; $self->part( SL::DB::Part->new_assembly ); $self->add; }; @@ -64,11 +64,22 @@ sub action_add_assembly { sub action_add_assortment { my ($self, %params) = @_; - $::form->{callback} = $self->url_for(action => 'add_assortment') unless $::form->{callback}; $self->part( SL::DB::Part->new_assortment ); $self->add; }; +sub action_add_from_record { + my ($self) = @_; + + check_has_valid_part_type($::form->{part}{part_type}); + + die 'parts_classification_type must be "sales" or "purchases"' + unless $::form->{parts_classification_type} =~ m/^(sales|purchases)$/; + + $self->parse_form; + $self->add; +} + sub action_add { my ($self) = @_; @@ -94,8 +105,11 @@ sub action_save { return $self->js->error(t8('The document has been changed by another user. Please reopen it in another window and copy the changes to the new window'))->render; } - if ( $is_new and !$::form->{part}{partnumber} ) { - $self->check_next_transnumber_is_free or return $self->js->error(t8('The next partnumber in the number range already exists!'))->render; + if ( $is_new + && $::form->{part}{partnumber} + && SL::DB::Manager::Part->find_by(partnumber => $::form->{part}{partnumber}) + ) { + return $self->js->error(t8('The partnumber is already being used'))->render; } $self->parse_form; @@ -132,10 +146,12 @@ sub action_save { 1; }) or return $self->js->error(t8('The item couldn\'t be saved!') . " " . $self->part->db->error )->render; - flash_later('info', $is_new ? t8('The item has been created.') : t8('The item has been saved.')); + ; + flash_later('info', $is_new ? t8('The item has been created.') . " " . $self->part->displayable_name : t8('The item has been saved.')); if ( $::form->{callback} ) { - $self->redirect_to($::form->unescape($::form->{callback})); + $self->redirect_to($::form->unescape($::form->{callback}) . '&new_parts_id=' . $self->part->id); + } else { # default behaviour after save: reload item, this also resets last_modification! $self->redirect_to(controller => 'Part', action => 'edit', 'part.id' => $self->part->id); @@ -175,11 +191,7 @@ sub action_delete { if ( $::form->{callback} ) { $self->redirect_to($::form->unescape($::form->{callback})); } else { - my @redirect_params = ( - controller => 'controller.pl', - action => 'LoginScreen/user_login' - ); - $self->redirect_to(@redirect_params); + $self->redirect_to(controller => 'ic.pl', action => 'search', searchitems => 'article'); } } @@ -625,7 +637,7 @@ sub add { sub _set_javascript { my ($self) = @_; - $::request->layout->use_javascript("${_}.js") for qw(kivi.Part kivi.File kivi.PriceRule ckeditor/ckeditor ckeditor/adapters/jquery); + $::request->layout->use_javascript("${_}.js") for qw(kivi.Part kivi.File kivi.PriceRule ckeditor/ckeditor ckeditor/adapters/jquery kivi.ShopPart); $::request->layout->add_javascripts_inline("\$(function(){kivi.PriceRule.load_price_rules_for_part(@{[ $self->part->id ]})});") if $self->part->id; } @@ -677,8 +689,6 @@ sub parse_form { my $params = delete($::form->{part}) || { }; delete $params->{id}; - # never overwrite existing partnumber for parts in use, should be a read-only field in that case anyway - delete $params->{partnumber} if $self->part->partnumber and not $self->orphaned; $self->part->assign_attributes(%{ $params}); $self->part->bin_id(undef) unless $self->part->warehouse_id; @@ -794,7 +804,7 @@ sub init_part { # used by edit, save, delete and add if ( $::form->{part}{id} ) { - return SL::DB::Part->new(id => $::form->{part}{id})->load(with => [ qw(makemodels prices translations partsgroup) ]); + return SL::DB::Part->new(id => $::form->{part}{id})->load(with => [ qw(makemodels prices translations partsgroup shop_parts shop_parts.shop) ]); } else { die "part_type missing" unless $::form->{part}{part_type}; return SL::DB::Part->new(part_type => $::form->{part}{part_type}); @@ -915,6 +925,18 @@ sub init_all_buchungsgruppen { } } +sub init_shops_not_assigned { + my ($self) = @_; + + my @used_shop_ids = map { $_->shop->id } @{ $self->part->shop_parts }; + if ( @used_shop_ids ) { + return SL::DB::Manager::Shop->get_all( query => [ obsolete => 0, '!id' => \@used_shop_ids ], sort_by => 'sortkey' ); + } + else { + return SL::DB::Manager::Shop->get_all( query => [ obsolete => 0 ], sort_by => 'sortkey' ); + } +} + sub init_all_units { my ($self) = @_; if ( $self->part->orphaned ) { @@ -955,6 +977,15 @@ sub init_multi_items_models { ); } +sub init_parts_classification_filter { + return [] unless $::form->{parts_classification_type}; + + return [ used_for_sale => 't' ] if $::form->{parts_classification_type} eq 'sales'; + return [ used_for_purchase => 't' ] if $::form->{parts_classification_type} eq 'purchases'; + + die "no query rules for parts_classification_type " . $::form->{parts_classification_type}; +} + # simple checks to run on $::form before saving sub form_check_part_description_exists { @@ -1036,17 +1067,6 @@ sub form_check_partnumber_is_unique { } # general checking functions -sub check_next_transnumber_is_free { - my ($self) = @_; - - my ($next_transnumber, $count); - $self->part->db->with_transaction(sub { - $next_transnumber = $self->part->get_next_trans_number; - $count = SL::DB::Manager::Part->get_all_count(where => [ partnumber => $next_transnumber ]); - return 1; - }) or die $@; - $count ? return 0 : return 1; -} sub check_part_id { die t8("Can't load item without a valid part.id") . "\n" unless $::form->{part}{id}; @@ -1284,6 +1304,17 @@ parameter part_type as an action. Example: controller.pl?action=Part/add&part_type=service +=item C + +When adding new items to records they can be created on the fly if the entered +partnumber or description doesn't exist yet. After being asked what part type +the new item should have the user is redirected to the correct edit page. + +Depending on whether the item was added from a sales or a purchase record, only +the relevant part classifications should be selectable for new item, so this +parameter is passed on via a hidden parts_classification_type in the new_item +template. + =item C Saves the current part and then reloads the edit page for the part.