}
sub init_all_partsgroups {
- SL::DB::Manager::PartsGroup->get_all_sorted;
+ my ($self) = @_;
+ SL::DB::Manager::PartsGroup->get_all_sorted(query => [ or => [ id => $self->part->partsgroup_id, obsolete => 0 ] ]);
}
sub init_all_buchungsgruppen {
--- /dev/null
+package SL::Controller::PartsGroup;
+
+use strict;
+
+use parent qw(SL::Controller::Base);
+
+use SL::Helper::Flash;
+use SL::Locale::String;
+use SL::DB::Default;
+use SL::DB::Manager::PartsGroup;
+
+use Rose::Object::MakeMethods::Generic (
+ scalar => [ qw(partsgroup) ],
+ 'scalar --get_set_init' => [ qw(all_partsgroups) ],
+);
+
+__PACKAGE__->run_before('check_auth');
+__PACKAGE__->run_before('load_partsgroup', only => [ qw(edit update delete) ]);
+
+#
+# actions
+#
+
+sub action_list {
+ my ($self) = @_;
+
+ $self->render('partsgroup/list',
+ title => t8('Partsgroups'),
+ );
+}
+
+sub action_new {
+ my ($self) = @_;
+
+ $self->partsgroup( SL::DB::PartsGroup->new );
+ $self->render('partsgroup/form',
+ title => t8('Add partsgroup'),
+ );
+}
+
+sub action_edit {
+ my ($self) = @_;
+
+ $self->render('partsgroup/form',
+ title => t8('Edit partsgroup'),
+ );
+}
+
+sub action_create {
+ my ($self) = @_;
+
+ $self->partsgroup( SL::DB::PartsGroup->new );
+ $self->create_or_update;
+}
+
+sub action_update {
+ my ($self) = @_;
+ $self->create_or_update;
+}
+
+sub action_delete {
+ my ($self) = @_;
+
+ if ( !$self->partsgroup->orphaned ) {
+ flash_later('error', $::locale->text('The partsgroup has been used and cannot be deleted.'));
+ } elsif ( eval { $self->partsgroup->delete; 1; } ) {
+ flash_later('info', $::locale->text('The partsgroup has been deleted.'));
+ } else {
+ flash_later('error', $::locale->text('The partsgroup has been used and cannot be deleted.'));
+ };
+ $self->redirect_to(action => 'list');
+}
+
+sub action_reorder {
+ my ($self) = @_;
+
+ SL::DB::PartsGroup->reorder_list(@{ $::form->{partsgroup_id} || [] });
+ $self->render(\'', { type => 'json' });
+}
+
+#
+# filters
+#
+
+sub check_auth {
+ $::auth->assert('config');
+}
+
+sub load_partsgroup {
+ my ($self) = @_;
+
+ $self->partsgroup( SL::DB::PartsGroup->new(id => $::form->{id})->load );
+}
+
+sub init_all_partsgroups { SL::DB::Manager::PartsGroup->get_all_sorted }
+
+#
+# helpers
+#
+
+sub create_or_update {
+ my ($self) = @_;
+ my $is_new = !$self->partsgroup->id;
+
+ my $params = delete($::form->{partsgroup}) || { };
+
+ $self->partsgroup->assign_attributes(%{ $params });
+
+ my @errors = $self->partsgroup->validate;
+
+ if (@errors) {
+ flash('error', @errors);
+ $self->render('partsgroup/form',
+ title => $is_new ? t8('Add partsgroup') : t8('Edit partsgroup'),
+ );
+ return;
+ }
+
+ $self->partsgroup->save;
+
+ flash_later('info', $is_new ? t8('The partsgroup has been created.') : t8('The partsgroup has been saved.'));
+ $self->redirect_to(action => 'list');
+}
+
+1;
+
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+SL::Controller::PartsGroup - CRUD controller for partsgroups
+
+=head1 SYNOPSIS
+
+A new controller to create / edit / delete partsgroups.
+
+Partsgroups can only be deleted if they haven't been used anywhere.
+
+=head1 OBSOLETE PARTSGROUPS
+
+A partsgroup can be deleted if it hasn't been used anywhere / is orphaned.
+
+A partsgroup can be set to obsolete, which means new items can't be assigned
+that partsgroup, but old items with that partsgroup can keep it. And you can
+also still filter for these obsolete partsgroups in reports.
+
+=head1 ISSUES
+
+Unlike the old version (pe.pl/PE.pm), there is no way to filter/search the
+partsgroups in the overview page, it always shows the complete (ordered) list,
+ordered by sortkey.
+
+=head1 AUTHOR
+
+G. Richardson E<lt>grichardson@kivitendo-premium.deE<gt>
+
+=cut
__PACKAGE__->make_manager_methods;
sub _sort_spec {
- return ( default => [ 'partsgroup', 1 ],
+ return ( default => [ 'sortkey', 1 ],
columns => { SIMPLE => 'ALL' });
}
id => { type => 'integer', not_null => 1, sequence => 'id' },
itime => { type => 'timestamp', default => 'now()' },
mtime => { type => 'timestamp' },
+ obsolete => { type => 'boolean', default => 'false' },
partsgroup => { type => 'text' },
+ sortkey => { type => 'integer', not_null => 1 },
);
__PACKAGE__->meta->primary_key_columns([ 'id' ]);
use SL::DB::MetaSetup::PartsGroup;
use SL::DB::Manager::PartsGroup;
+use SL::DB::Helper::ActsAsList;
__PACKAGE__->meta->add_relationship(
custom_variable_configs => {
return join ' ', grep $_, $self->id, $self->partsgroup;
}
+sub validate {
+ my ($self) = @_;
+ require SL::DB::Customer;
+
+ my @errors;
+
+ push @errors, $::locale->text('The description is missing.') if $self->id and !$self->partsgroup;
+
+ return @errors;
+}
+
+sub orphaned {
+ my ($self) = @_;
+ die 'not an accessor' if @_ > 1;
+
+ return 1 unless $self->id;
+
+ my @relations = qw(
+ SL::DB::Part
+ SL::DB::CustomVariableConfigPartsgroup
+ );
+
+ for my $class (@relations) {
+ eval "require $class";
+ return 0 if $class->_get_manager_class->get_all_count(query => [ partsgroup_id => $self->id ]);
+ }
+
+ return 1;
+}
+
1;
'Add new price rule item' => 'Neue Bedingung hinzufügen',
'Add note' => 'Notiz erfassen',
'Add part' => 'Artikel hinzufügen',
+ 'Add partsgroup' => 'Warengruppe hinzufügen',
'Add picture' => 'Bild hinzufügen',
'Add picture to text block' => 'Bild dem Textblock hinzufügen',
'Add pricegroup' => 'Preisgruppe hinzufügen',
'Edit general settings' => 'Grundeinstellungen bearbeiten',
'Edit greetings' => 'Anreden bearbeiten',
'Edit note' => 'Notiz bearbeiten',
+ 'Edit partsgroup' => 'Warengruppe bearbeiten',
'Edit payment term' => 'Zahlungsbedingungen bearbeiten',
'Edit picture' => 'Bild bearbeiten',
'Edit predefined text' => 'Vordefinierten Textblock bearbeiten',
'Parts, services and assemblies' => 'Waren, Dienstleistungen und Erzeugnisse',
'Partsgroup (database ID)' => 'Warengruppe (Datenbank-ID)',
'Partsgroup (name)' => 'Warengruppe (Name)',
+ 'Partsgroups' => 'Warengruppen',
'Partsgroups where variables are shown' => 'Warengruppen, bei denen Variablen angezeigt werden',
'Password' => 'Passwort',
'Paste' => 'Einfügen',
'The parts have been removed.' => 'Die Waren wurden aus dem Lager entnommen.',
'The parts have been stocked.' => 'Die Artikel wurden eingelagert.',
'The parts have been transferred.' => 'Die Waren wurden umgelagert.',
+ 'The partsgroup has been created.' => 'Die Warengruppe wurde erstellt.',
+ 'The partsgroup has been deleted.' => 'Die Warengruppe wurde gelöscht.',
+ 'The partsgroup has been saved.' => 'Die Warengruppe wurde gespeichert.',
+ 'The partsgroup has been used and cannot be deleted.' => 'Die Warengruppe wurde bereits verwendet und kann nicht gelöscht werden.',
'The password is too long (maximum length: #1).' => 'Das Passwort ist zu lang (maximale Länge: #1).',
'The password is too short (minimum length: #1).' => 'Das Password ist zu kurz (minimale Länge: #1).',
'The password is weak (e.g. it can be found in a dictionary).' => 'Das Passwort ist schwach (z.B. wenn es in einem Wörterbuch steht).',
'Add Follow-Up' => '',
'Add Follow-Up for #1' => '',
'Add General Ledger Transaction' => '',
- 'Add Group' => '',
'Add Language' => '',
'Add Lead' => '',
'Add Letter' => '',
'Add new price rule item' => '',
'Add note' => '',
'Add part' => '',
+ 'Add partsgroup' => '',
'Add picture' => '',
'Add picture to text block' => '',
'Add pricegroup' => '',
'Edit general settings' => '',
'Edit greetings' => '',
'Edit note' => '',
+ 'Edit partsgroup' => '',
'Edit payment term' => '',
'Edit picture' => '',
'Edit predefined text' => '',
'Parts Master Data' => '',
'Parts with existing part numbers' => '',
'Parts, services and assemblies' => '',
+ 'Partsgroup' => '',
'Partsgroup (database ID)' => '',
'Partsgroup (name)' => '',
+ 'Partsgroups' => '',
'Partsgroups where variables are shown' => '',
'Password' => '',
'Paste' => '',
'The parts have been removed.' => '',
'The parts have been stocked.' => '',
'The parts have been transferred.' => '',
+ 'The partsgroup has been created.' => '',
+ 'The partsgroup has been deleted.' => '',
+ 'The partsgroup has been saved.' => '',
+ 'The partsgroup has been used and cannot be deleted.' => '',
'The password is too long (maximum length: #1).' => '',
'The password is too short (minimum length: #1).' => '',
'The password is weak (e.g. it can be found in a dictionary).' => '',
params:
action: BankAccount/list
- parent: system
- id: system_groups
- name: Groups
+ id: system_partsgroups
+ name: Partsgroups
order: 900
- module: pe.pl
params:
- action: search
- type: partsgroup
+ action: PartsGroup/list
- parent: system
id: system_pricegroups
name: Pricegroups
--- /dev/null
+-- @tag: partsgroup_sortkey_obsolete
+-- @description: Sortierreihenfolge und ungültig für Warengruppen
+-- @charset: UTF-8
+-- @depends: release_3_4_1
+-- @ignore: 0
+
+ALTER TABLE partsgroup ADD COLUMN obsolete BOOLEAN DEFAULT FALSE;
+ALTER TABLE partsgroup ADD COLUMN sortkey INTEGER;
+
+CREATE SEQUENCE tmp_counter;
+UPDATE partsgroup SET sortkey = nextval('tmp_counter');
+DROP SEQUENCE tmp_counter;
+ALTER TABLE partsgroup ALTER COLUMN sortkey SET NOT NULL;
--- /dev/null
+[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%]
+
+[% SET style="width: 400px" %]
+[% SET size=15 %]
+
+<h1>[% HTML.escape(title) %]</h1>
+
+<form action="controller.pl" method="post">
+
+[%- INCLUDE 'common/flash.html' %]
+
+[%- L.hidden_tag("id", SELF.partsgroup.id) %]
+
+<table>
+ <tr>
+ <th align="right">[% 'Description' | $T8 %]</th>
+ <td>
+ [%- L.input_tag("partsgroup.partsgroup", SELF.partsgroup.partsgroup) %]
+ </td>
+ [% IF SELF.partsgroup.id %]
+ <tr>
+ <th align="right">[% 'Obsolete' | $T8 %]</th>
+ <td>[% L.checkbox_tag('partsgroup.obsolete', checked = SELF.partsgroup.obsolete, for_submit=1) %]</td>
+ </tr>
+ </tr>
+ [% END %]
+</table>
+
+ <p>
+ [% L.hidden_tag("action", "PartsGroup/dispatch") %]
+ [% L.submit_tag("action_" _ (SELF.partsgroup.id ? "update" : "create"), LxERP.t8('Save'), onclick="return check_prerequisites();") %]
+ [%- IF SELF.partsgroup.id AND SELF.partsgroup.orphaned -%]
+ [% L.submit_tag("action_delete", LxERP.t8('Delete')) %]
+ [%- END %]
+ <a href="[% SELF.url_for(action='list') %]">[%- LxERP.t8("Cancel") %]</a>
+ </p>
+
+ <hr>
+
+<script type="text/javascript">
+<!--
+function check_prerequisites() {
+ if ($('#partsgroup_partsgroup').val() === "") {
+ alert(kivi.t8('The description is missing.'));
+ return false;
+ }
+ return true;
+}
+-->
+</script>