Revision 86650875
Von Tamino Steinert vor etwa 1 Jahr hinzugefügt
SL/Controller/Part.pm | ||
---|---|---|
my ($self, %params) = @_;
|
||
|
||
$self->part( SL::DB::Part->new_parent_variant );
|
||
$self->part->part_type($::form->{part_type});
|
||
$self->add;
|
||
}
|
||
|
||
... | ... | |
$self->action_add_service if $::form->{part_type} eq 'service';
|
||
$self->action_add_assembly if $::form->{part_type} eq 'assembly';
|
||
$self->action_add_assortment if $::form->{part_type} eq 'assortment';
|
||
$self->action_add_parent_variant if $::form->{part_type} eq 'parent_variant';
|
||
$self->action_add_variant if $::form->{part_type} eq 'variant';
|
||
};
|
||
|
||
sub action_save {
|
||
... | ... | |
for @variant_property_values_lists;
|
||
1;
|
||
}) or do {
|
||
return $self->js->error(t8('Error while creating variants: ' . @_))->render();
|
||
die t8('Error while creating variants: '), $@;
|
||
};
|
||
|
||
$self->redirect_to(
|
||
... | ... | |
assembly => t8('Edit Assembly'),
|
||
service => t8('Edit Service'),
|
||
assortment => t8('Edit Assortment'),
|
||
parent_variant => t8('Edit Parent Variant'),
|
||
variant => t8('Edit Variant'),
|
||
);
|
||
my $title = $title_hash{$self->part->part_type};
|
||
$title .=
|
||
' (' . SL::Presenter::Part::variant_type_abbreviation($self->part->variant_type) . ')'
|
||
if $self->part->variant_type;
|
||
|
||
$self->part->prices([]) unless $self->part->prices;
|
||
$self->part->translations([]) unless $self->part->translations;
|
||
|
||
$self->render(
|
||
'part/form',
|
||
title => $title_hash{$self->part->part_type},
|
||
title => $title,
|
||
%assortment_vars,
|
||
%assembly_vars,
|
||
%parent_variant_vars,
|
||
... | ... | |
assembly => t8('Add Assembly'),
|
||
service => t8('Add Service'),
|
||
assortment => t8('Add Assortment'),
|
||
parent_variant => t8('Add Parent Variant'),
|
||
variant => t8('Add Variant'),
|
||
);
|
||
my $title = $title_hash{$self->part->part_type};
|
||
$title .=
|
||
' (' . SL::Presenter::Part::variant_type_abbreviation($self->part->variant_type) . ')'
|
||
if $self->part->variant_type;
|
||
|
||
$self->render(
|
||
'part/form',
|
||
title => $title_hash{$self->part->part_type},
|
||
title => $title,
|
||
);
|
||
}
|
||
|
||
... | ... | |
}
|
||
|
||
sub check_has_valid_part_type {
|
||
die "invalid part_type" unless $_[0] =~ /^(part|service|assembly|assortment|parent_variant|variant)$/;
|
||
Carp::confess "invalid part_type" unless $_[0] =~ /^(part|service|assembly|assortment)$/;
|
||
}
|
||
|
||
|
SL/DB/Helper/TransNumberGenerator.pm | ||
---|---|---|
service => { number_column => 'partnumber', number_range_column => 'servicenumber', },
|
||
assembly => { number_column => 'partnumber', number_range_column => 'assemblynumber', },
|
||
assortment => { number_column => 'partnumber', number_range_column => 'assortmentnumber', },
|
||
parent_variant => { number_column => 'partnumber', number_range_column => 'parent_variant_number', },
|
||
variant => { number_column => 'partnumber', number_range_column => 'variant_number', },
|
||
);
|
||
|
||
sub get_next_trans_number {
|
SL/DB/MetaSetup/Default.pm | ||
---|---|---|
order_warn_no_cusordnumber => { type => 'boolean', default => 'false' },
|
||
order_warn_no_deliverydate => { type => 'boolean', default => 'true' },
|
||
p_reclamation_record_number => { type => 'text', default => '0', not_null => 1 },
|
||
parent_variant_number => { type => 'text' },
|
||
parts_image_css => { type => 'text', default => 'border:0;float:left;max-width:250px;margin-top:20px:margin-right:10px;margin-left:10px;' },
|
||
parts_listing_image => { type => 'boolean', default => 'true' },
|
||
parts_show_image => { type => 'boolean', default => 'true' },
|
||
... | ... | |
transit_items_chart_id => { type => 'integer' },
|
||
transport_cost_reminder_article_number_id => { type => 'integer' },
|
||
undo_transfer_interval => { type => 'integer', default => 7 },
|
||
variant_number => { type => 'text' },
|
||
vc_greetings_use_textfield => { type => 'boolean' },
|
||
vendor_ustid_taxnummer_unique => { type => 'boolean', default => 'false' },
|
||
vendornumber => { type => 'text' },
|
SL/DB/MetaSetup/Part.pm | ||
---|---|---|
onhand => { type => 'numeric', default => '0', precision => 25, scale => 5 },
|
||
order_locked => { type => 'boolean', default => 'false' },
|
||
order_qty => { type => 'numeric', default => '0', not_null => 1, precision => 15, scale => 5 },
|
||
part_type => { type => 'enum', check_in => [ 'part', 'service', 'assembly', 'assortment', 'parent_variant', 'variant' ], db_type => 'part_type_enum', not_null => 1 },
|
||
part_type => { type => 'enum', check_in => [ 'part', 'service', 'assembly', 'assortment' ], db_type => 'part_type_enum', not_null => 1 },
|
||
partnumber => { type => 'text', not_null => 1 },
|
||
partsgroup_id => { type => 'integer' },
|
||
payment_id => { type => 'integer' },
|
||
... | ... | |
stockable => { type => 'boolean', default => 'false' },
|
||
tariff_code => { type => 'text' },
|
||
unit => { type => 'varchar', length => 20, not_null => 1 },
|
||
variant_type => { type => 'enum', check_in => [ 'single', 'parent_variant', 'variant' ], db_type => 'part_variant_type', default => 'single', not_null => 1 },
|
||
ve => { type => 'integer' },
|
||
warehouse_id => { type => 'integer' },
|
||
weight => { type => 'float', precision => 4, scale => 4 },
|
SL/DB/MetaSetup/VariantPropertyValue.pm | ||
---|---|---|
id => { type => 'serial', not_null => 1 },
|
||
itime => { type => 'timestamp', default => 'now()' },
|
||
mtime => { type => 'timestamp' },
|
||
sortkey => { type => 'integer', not_null => 1 },
|
||
sortkey => { type => 'integer' },
|
||
value => { type => 'text', not_null => 1 },
|
||
variant_property_id => { type => 'integer', not_null => 1 },
|
||
);
|
SL/DB/Part.pm | ||
---|---|---|
|
||
use Carp;
|
||
use List::MoreUtils qw(any uniq);
|
||
use List::Util qw(sum);
|
||
use List::Util qw(sum max);
|
||
use Rose::DB::Object::Helpers qw(as_tree);
|
||
|
||
use SL::Locale::String qw(t8);
|
||
... | ... | |
sub is_assembly { $_[0]->part_type eq 'assembly' }
|
||
sub is_service { $_[0]->part_type eq 'service' }
|
||
sub is_assortment { $_[0]->part_type eq 'assortment' }
|
||
sub is_parent_variant { $_[0]->part_type eq 'parent_variant' }
|
||
sub is_variant { $_[0]->part_type eq 'variant' }
|
||
|
||
sub is_parent_variant { $_[0]->variant_type eq 'parent_variant' }
|
||
sub is_variant { $_[0]->variant_type eq 'variant' }
|
||
|
||
sub type { return $_[0]->part_type; }
|
||
|
||
... | ... | |
|
||
sub new_parent_variant {
|
||
my ($class, %params) = @_;
|
||
$class->new(%params, part_type => 'parent_variant');
|
||
$class->new(%params, variant_type => 'parent_variant');
|
||
}
|
||
|
||
sub last_modification {
|
||
... | ... | |
die "Given variant_property_values dosn't match the variant_properties of parent_variant part";
|
||
}
|
||
|
||
my $separator = '.'; # TODO: make configurable
|
||
|
||
my $last_variant_number =
|
||
max
|
||
map {
|
||
my $partnumber = $_->partnumber;
|
||
$partnumber =~ s/.*\Q$separator\E([0-9]*)/$1/; # escape chars between \Q \E
|
||
$partnumber;
|
||
}
|
||
$self->variants;
|
||
|
||
my $new_variant = $self->clone_and_reset;
|
||
# TODO set partnumber
|
||
$new_variant->part_type('variant');
|
||
$new_variant->save;
|
||
SL::DB::VariantPropertyValuePart->new(
|
||
part_id => $new_variant->id,
|
||
variant_property_value_id => $_->id,
|
||
)->save for @$variant_property_values;
|
||
SL::DB::PartParentVariantPartVariant->new(
|
||
variant_id => $new_variant->id,
|
||
parent_variant_id => $self->id,
|
||
)->save;
|
||
$new_variant->partnumber($self->partnumber . $separator . ($last_variant_number + 1));
|
||
$new_variant->variant_type('variant');
|
||
$new_variant->add_assemblies(map {$_->clone_and_reset} $self->assemblies) if ($self->is_assembly);
|
||
$new_variant->add_variant_property_values(@$variant_property_values);
|
||
|
||
$self->add_variants($new_variant);
|
||
$self->save;
|
||
return $new_variant;
|
||
}
|
||
|
||
... | ... | |
|
||
sub variant_value {
|
||
my ($self, $variant_property) = @_;
|
||
die "only callable on parts of type parent_variant" unless $self->is_variant;
|
||
die "only callable with SL::DB::VariantProperty object" unless ref $variant_property eq 'SL::DB::VariantProperty';
|
||
|
||
my %property_id_to_values =
|
||
map {$_->variant_property_id => $_}
|
SL/IC.pm | ||
---|---|---|
$form->{l_assembly} = 1 if $form->{searchitems} eq 'assembly' || $form->{searchitems} eq '';
|
||
$form->{l_part} = 1 if $form->{searchitems} eq 'part' || $form->{searchitems} eq '';
|
||
$form->{l_assortment} = 1 if $form->{searchitems} eq 'assortment' || $form->{searchitems} eq '';
|
||
$form->{l_parent_variant} = 1 if $form->{searchitems} eq 'parent_variant' || $form->{searchitems} eq '';
|
||
$form->{l_variant} = 1 if $form->{searchitems} eq 'variant' || $form->{searchitems} eq '';
|
||
push @where_tokens, "p.partnumber ILIKE ? OR p.description ILIKE ?";
|
||
push @bind_vars, (like($form->{all})) x 2;
|
||
}
|
||
... | ... | |
# Oder Bedingungen fuer Ware Dienstleistung Erzeugnis:
|
||
if ( $form->{l_part} || $form->{l_assembly}
|
||
|| $form->{l_service} || $form->{l_assortment}
|
||
|| $form->{l_parent_variant} || $form->{l_variant}
|
||
) {
|
||
my @or_tokens = ();
|
||
push @or_tokens, "p.part_type = 'service'" if $form->{l_service};
|
||
push @or_tokens, "p.part_type = 'assembly'" if $form->{l_assembly};
|
||
push @or_tokens, "p.part_type = 'part'" if $form->{l_part};
|
||
push @or_tokens, "p.part_type = 'assortment'" if $form->{l_assortment};
|
||
push @or_tokens, "p.part_type = 'parent_variant'" if $form->{l_parent_variant};
|
||
push @or_tokens, "p.part_type = 'variant'" if $form->{l_variant};
|
||
push @where_tokens, join ' OR ', map { "($_)" } @or_tokens;
|
||
}
|
||
else {
|
SL/Presenter/Part.pm | ||
---|---|---|
assembly => t8('Assembly (typeabbreviation)'),
|
||
assortment => t8('Assortment (typeabbreviation)'),
|
||
service => t8('Service (typeabbreviation)'),
|
||
);
|
||
|
||
return $part_type_abbr{$part_type} || '';
|
||
}
|
||
|
||
sub variant_type_abbreviation {
|
||
my ($variant_type) = @_;
|
||
|
||
my %variant_type_abbr = (
|
||
parent_variant => t8('Parent Variant (typeabbreviation)'),
|
||
variant => t8('Variant (typeabbreviation)'),
|
||
);
|
||
|
||
return $part_type_abbr{$part_type} || '';
|
||
return $variant_type_abbr{$variant_type} || '';
|
||
}
|
||
|
||
#
|
SL/TransNumber.pm | ||
---|---|---|
$filters{table} = "oe";
|
||
$filters{where} = 'COALESCE(quotation, FALSE) AND (vendor_id IS NOT NULL)';
|
||
|
||
} elsif ($type =~ /^(part|service|assembly|assortment|parent_variant|variant)$/) {
|
||
} elsif ($type =~ /^(part|service|assembly|assortment)$/) {
|
||
$filters{trans_number} = "partnumber";
|
||
my %numberfield_hash = ( service => 'servicenumber',
|
||
assembly => 'assemblynumber',
|
||
assortment => 'assortmentnumber',
|
||
parent_variant => 'parent_variant_number',
|
||
variant => 'variant_number',
|
||
part => 'articlenumber'
|
||
);
|
||
$filters{numberfield} = $numberfield_hash{$type};
|
menus/user/00-erp.yaml | ||
---|---|---|
name: Add Parent Variant
|
||
order: 575
|
||
access: part_service_assembly_edit
|
||
- parent: master_data_add_parent_variant
|
||
id: master_data_add_parent_variant_part
|
||
name: Add Parent Variant Part
|
||
order: 100
|
||
params:
|
||
action: Part/add_parent_variant
|
||
part_type: part
|
||
- parent: master_data_add_parent_variant
|
||
id: master_data_add_parent_variant_service
|
||
name: Add Parent Variant Service
|
||
order: 200
|
||
params:
|
||
action: Part/add_parent_variant
|
||
part_type: service
|
||
- parent: master_data_add_parent_variant
|
||
id: master_data_add_parent_variant_assembly
|
||
name: Add Parent Variant Assembly
|
||
order: 300
|
||
params:
|
||
action: Part/add_parent_variant
|
||
part_type: assembly
|
||
- parent: master_data
|
||
id: master_data_add_project
|
||
name: Add Project
|
sql/Pg-upgrade2/add_variants.sql | ||
---|---|---|
-- @depends: release_3_8_0
|
||
-- @ignore: 0
|
||
|
||
ALTER TYPE part_type_enum ADD VALUE 'parent_variant';
|
||
ALTER TYPE part_type_enum ADD VALUE 'variant';
|
||
|
||
ALTER TABLE defaults ADD parent_variant_number TEXT;
|
||
ALTER TABLE defaults ADD variant_number TEXT;
|
||
CREATE TYPE part_variant_type AS ENUM ('single', 'parent_variant', 'variant');
|
||
ALTER TABLE parts ADD COLUMN variant_type part_variant_type DEFAULT 'single' NOT NULL;
|
||
|
||
CREATE TABLE parts_parent_variant_id_parts_variant_id (
|
||
parent_variant_id INTEGER NOT NULL REFERENCES parts(id),
|
||
... | ... | |
name TEXT NOT NULL,
|
||
unique_name TEXT NOT NULL UNIQUE,
|
||
abbreviation VARCHAR(4) NOT NULL,
|
||
sortkey INTEGER,
|
||
itime TIMESTAMP DEFAULT now(),
|
||
mtime TIMESTAMP
|
||
);
|
||
... | ... | |
variant_property_id INTEGER NOT NULL REFERENCES variant_properties(id),
|
||
value TEXT NOT NULL,
|
||
abbreviation VARCHAR(4) NOT NULL,
|
||
sortkey INTEGER NOT NULL,
|
||
sortkey INTEGER,
|
||
itime TIMESTAMP DEFAULT now(),
|
||
mtime TIMESTAMP
|
||
);
|
sql/Pg-upgrade2/variant_properties_add_column_sortkey.sql | ||
---|---|---|
-- @tag: variants_add_column_sortkey
|
||
-- @description: Sortierung für Varianteneigenschaften
|
||
-- @depends: add_variants
|
||
-- @ignore: 0
|
||
|
||
ALTER TABLE variant_properties ADD COLUMN sortkey INTEGER;
|
sql/Pg-upgrade2/variant_property_values_alter_column_sortkey.sql | ||
---|---|---|
-- @tag: variant_values_alter_column_sortkey
|
||
-- @description: sortkey für Varianteneigenschaftswert darf NULL sein
|
||
-- @depends: add_variants
|
||
-- @ignore: 0
|
||
|
||
ALTER TABLE variant_property_values ALTER COLUMN sortkey DROP NOT NULL;
|
templates/design40_webpages/client_config/_ranges_of_numbers.html | ||
---|---|---|
<td>[% L.input_tag("defaults.assortmentnumber", SELF.defaults.assortmentnumber, size="15", class="wi-normal") %]</td>
|
||
[% END %]
|
||
</tr>
|
||
<tr>
|
||
<th>[% LxERP.t8('Parent Variant') %]</th>
|
||
<td>[% L.input_tag("defaults.parent_variant_number", SELF.defaults.parent_variant_number, size="15", class="wi-normal") %]</td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% LxERP.t8('Variant') %]</th>
|
||
<td>[% L.input_tag("defaults.variant_number", SELF.defaults.variant_number, size="15", class="wi-normal") %]</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
templates/design40_webpages/ic/search.html | ||
---|---|---|
<input name="l_assortment" id="l_assortment" type="checkbox" value="Y" checked>
|
||
<label for="l_assortment"> [% 'Assortment' | $T8 %] </label>
|
||
[% END %]
|
||
<input name="l_parent_variant" id="l_parent_variant" type="checkbox" value="Y" checked>
|
||
<label for="l_parent_variant"> [% 'Parent Variant' | $T8 %] </label>
|
||
<input name="l_variant" id="l_variant" type="checkbox" value="Y" checked>
|
||
<label for="l_variant"> [% 'Variant' | $T8 %] </label>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
templates/design40_webpages/part/form.html | ||
---|---|---|
|
||
[% INCLUDE 'common/flash.html' %]
|
||
|
||
[% L.hidden_tag('part.part_type' , SELF.part.part_type) %]
|
||
[% L.hidden_tag('part.id' , SELF.part.id) %]
|
||
[% L.hidden_tag('part.part_type' , SELF.part.part_type) %]
|
||
[% L.hidden_tag('part.variant_type', SELF.part.variant_type) %]
|
||
[% L.hidden_tag('last_modification', SELF.part.last_modification) %]
|
||
[% L.hidden_tag('callback' , FORM.callback) %]
|
||
|
templates/webpages/client_config/_ranges_of_numbers.html | ||
---|---|---|
<tr>
|
||
<td align="right" nowrap>[% LxERP.t8('Last Purchase Delivery Order Number') %]</td>
|
||
<td>[% L.input_tag("defaults.pdonumber", SELF.defaults.pdonumber, size="15") %]</td>
|
||
<td align="right" nowrap>[% LxERP.t8('Last Parent Variant Number') %]</td>
|
||
<td>[% L.input_tag("defaults.parent_variant_number", SELF.defaults.parent_variant_number, size="15") %]</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td align="right" nowrap>[% LxERP.t8('Last Supplier Delivery Order Number') %]</td>
|
||
<td>[% L.input_tag("defaults.sudonumber", SELF.defaults.sudonumber, size="15") %]</td>
|
||
<td align="right" nowrap>[% LxERP.t8('Last Variant Number') %]</td>
|
||
<td>[% L.input_tag("defaults.variant_number", SELF.defaults.variant_number, size="15") %]</td>
|
||
</tr>
|
||
|
||
<tr>
|
templates/webpages/part/form.html | ||
---|---|---|
|
||
<form method="post" id="ic" name="ic" action="controller.pl">
|
||
|
||
[% L.hidden_tag('part.part_type' , SELF.part.part_type) %]
|
||
[% L.hidden_tag('part.id' , SELF.part.id) %]
|
||
[% L.hidden_tag('part.part_type' , SELF.part.part_type) %]
|
||
[% L.hidden_tag('part.variant_type', SELF.part.variant_type) %]
|
||
[% L.hidden_tag('last_modification', SELF.part.last_modification) %]
|
||
[% L.hidden_tag('callback' , FORM.callback) %]
|
||
|
Auch abrufbar als: Unified diff
Varianten: alle Artikeltypen ermöglichen