Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision a279fb60

Von Tamino Steinert vor 12 Monaten hinzugefügt

  • ID a279fb605ba2ca165beedaaf906ad811dd070ddb
  • Vorgänger 89821947
  • Nachfolger e2cc408f

Varianten: Stammartikel anlegen und Varianten erstellen

Unterschiede anzeigen:

SL/Controller/Part.pm
$self->add;
};
sub action_add_parent_variant {
my ($self, %params) = @_;
$self->part( SL::DB::Part->new_parent_variant );
$self->add;
}
sub action_add_from_record {
my ($self) = @_;
......
check_has_valid_part_type($::form->{part_type});
$self->action_add_part if $::form->{part_type} eq 'part';
$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_part if $::form->{part_type} eq 'part';
$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 {
......
}
}
sub action_create_variants {
my ($self) = @_;
my @variant_property_ids = sort keys %{$::form->{variant_properties}};
my $part = $self->part;
my $variant_properties = $part->variant_properties();
my @needed_variant_property_ids = sort map {$_->id} @$variant_properties;
if (@variant_property_ids != @needed_variant_property_ids) {
return $self->js->error(
t8('No property value selected for variant properties: #1.',
join(", ",
map {$_->name_translated}
grep {!defined $::form->{variant_properties}->{$_->id}->{selected_property_values}}
@$variant_properties
)
)
)->render();
}
my @grouped_variant_property_values = ();
push @grouped_variant_property_values,
SL::DB::Manager::VariantPropertyValue->get_all(
where => [ id => $::form->{variant_properties}->{$_}->{selected_property_values} ]
)
for @variant_property_ids;
my @variant_property_values_lists = ();
foreach my $variant_property_values (@grouped_variant_property_values) {
my @new_lists = ();
foreach my $variant_property_value (@$variant_property_values) {
unless (scalar @variant_property_values_lists) {
push @new_lists, [$variant_property_value];
}
foreach my $variant_property_values_list (@variant_property_values_lists) {
push @new_lists, [@$variant_property_values_list, $variant_property_value];
}
}
@variant_property_values_lists = @new_lists;
}
my @new_variants = ();
SL::DB->client->with_transaction(sub {
push @new_variants, $part->create_new_variant($_)
for @variant_property_values_lists;
1;
}) or do {
return $self->js->error(t8('Error while creating variants: ' . @_))->render();
};
$self->redirect_to(
controller => 'Part',
action => 'edit',
'part.id' => $self->part->id
);
}
sub action_delete {
my ($self) = @_;
......
@{ $params{CUSTOM_VARIABLES_FIRST_TAB} } = extract_by { $_->{first_tab} == 1 } @{ $params{CUSTOM_VARIABLES} };
}
my %title_hash = ( part => t8('Edit Part'),
assembly => t8('Edit Assembly'),
service => t8('Edit Service'),
assortment => t8('Edit Assortment'),
my %title_hash = ( part => t8('Edit Part'),
assembly => t8('Edit Assembly'),
service => t8('Edit Service'),
assortment => t8('Edit Assortment'),
parent_variant => t8('Edit Parent Variant'),
variant => t8('Edit Variant'),
);
$self->part->prices([]) unless $self->part->prices;
......
$self->_set_javascript;
$self->_setup_form_action_bar;
my %title_hash = ( part => t8('Add Part'),
assembly => t8('Add Assembly'),
service => t8('Add Service'),
assortment => t8('Add Assortment'),
my %title_hash = ( part => t8('Add Part'),
assembly => t8('Add Assembly'),
service => t8('Add Service'),
assortment => t8('Add Assortment'),
parent_variant => t8('Add Parent Variant'),
variant => t8('Add Variant'),
);
$self->render(
......
sub _set_javascript {
my ($self) = @_;
$::request->layout->use_javascript("${_}.js") for qw(kivi.Part kivi.File kivi.PriceRule kivi.ShopPart kivi.Validator);
$::request->layout->use_javascript("${_}.js") for qw(kivi.Part kivi.File kivi.PriceRule kivi.ShopPart kivi.Validator jquery.selectboxes jquery.multiselect2side);
$::request->layout->add_javascripts_inline("\$(function(){kivi.PriceRule.load_price_rules_for_part(@{[ $self->part->id ]})});") if $self->part->id;
}
......
}
sub check_has_valid_part_type {
die "invalid part_type" unless $_[0] =~ /^(part|service|assembly|assortment)$/;
die "invalid part_type" unless $_[0] =~ /^(part|service|assembly|assortment|parent_variant|variant)$/;
}
SL/DB/Part.pm
$class->new(%params, part_type => 'parent_variant');
}
sub new_variant {
my ($class, %params) = @_;
$class->new(%params, part_type => 'variant');
}
sub last_modification {
my ($self) = @_;
return $self->mtime // $self->itime;
......
return \@sorted;
}
sub create_new_variant {
my ($self, $variant_property_values) = @_;
die "only callable on parts of type parent_variant" unless $self->is_parent_variant;
die "only callable on saved objects" unless $self->id;
my @selected_variant_property_ids = sort map {$_->variant_property_id} @$variant_property_values;
my @variant_property_ids = sort map {$_->id} @{$self->variant_properties};
if (@variant_property_ids != @selected_variant_property_ids) {
die "Given variant_property_values dosn't match the variant_properties of parent_variant part";
}
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;
return $new_variant;
}
sub clone_and_reset_deep {
my ($self) = @_;
SL/DB/VariantProperty.pm
map_to => 'part',
type => 'many to many',
},
property_values => {
class => 'SL::DB::VariantPropertyValue',
column_map => { id => 'variant_property_id' },
type => 'one to many',
}
);
__PACKAGE__->meta->initialize;
......
return @errors;
}
sub name_translated {goto &name} # TODO
1;
SL/DB/VariantPropertyValue.pm
__PACKAGE__->meta->initialize;
sub value_translated {goto &value} # TODO
1;
js/kivi.Part.js
$.post("controller.pl", { action: 'Part/warehouse_changed', warehouse_id: function(){ return $('#part_warehouse_id').val(); } }, kivi.eval_json_result);
};
ns.create_variants = function() {
var data = $('#ic').serializeArray();
data.push({ name: 'action', value: 'Part/create_variants' });
$.post("controller.pl", data, kivi.eval_json_result);
};
var KEY = {
TAB: 9,
ENTER: 13,
locale/de/all
'Add Invoice' => 'Rechnung erfassen',
'Add Invoice for Advance Payment' => 'Anzahlungsrechnung erfassen',
'Add Letter' => 'Brief hinzufügen',
'Add Parent Variant' => 'Stammartikel erfassen',
'Add Part' => 'Ware erfassen',
'Add Parts here!' => 'Artikel hier hinzufügen!',
'Add Price Factor' => 'Preisfaktor erfassen',
......
'Add Transaction' => 'Dialogbuchen',
'Add User' => 'Neuer Benutzer',
'Add User Group' => 'Neue Benutzergruppe',
'Add Variant' => 'Variante erfassen',
'Add Vendor' => 'Lieferant erfassen',
'Add Vendor Invoice' => 'Einkaufsrechnung erfassen',
'Add Warehouse' => 'Lager erfassen',
......
'All' => 'Alle',
'All Accounts' => 'Alle Konten',
'All Data' => 'Alle Daten',
'All Property Values' => 'Alle Ausprägunen',
'All as list' => 'Alle als Liste',
'All changes in that file have been reverted.' => 'Alle Änderungen in dieser Datei wurden rückgängig gemacht.',
'All clients' => 'Alle Mandanten',
......
'Create PDF' => 'PDF erzeugen',
'Create Reclamation' => 'Reklamation erstellen',
'Create Sub-Version' => 'Unterversion erzeugen',
'Create Variants with selected Values' => 'Varianten mit ausgewählten Ausprägungen erstellen',
'Create a new background job' => 'Einen neuen Hintergrund-Job anlegen',
'Create a new client' => 'Einen neuen Mandanten anlegen',
'Create a new delivery term' => 'Neue Lieferbedingungen anlegen',
......
'Create invoice' => 'Buchung erstellen',
'Create invoice?' => 'Rechnung erstellen?',
'Create new' => 'Neu erfassen',
'Create new Variants' => 'Neue Varianten erstellen',
'Create new client #1' => 'Neuen Mandanten #1 anlegen',
'Create new quotation or order' => 'Neues Angebot oder neuen Auftrag anlegen',
'Create new quotation/order' => 'Neues Angebot/neuen Auftrag anlegen',
......
'Edit Invoice' => 'Rechnung bearbeiten',
'Edit Invoice for Advance Payment' => 'Anzahlungsrechnung bearbeiten',
'Edit Letter' => 'Brief bearbeiten',
'Edit Parent Variant' => 'Stammartikel bearbeiten',
'Edit Part' => 'Ware bearbeiten',
'Edit Preferences for #1' => 'Einstellungen von #1 bearbeiten',
'Edit Price Factor' => 'Preisfaktor bearbeiten',
......
'Edit Supplier Delivery Order' => 'Beistell-Lieferschein bearbeiten',
'Edit User' => 'Benutzerdaten bearbeiten',
'Edit User Group' => 'Benutzergruppe bearbeiten',
'Edit Variant' => 'Variante bearbeiten',
'Edit Vendor' => 'Lieferant editieren',
'Edit Vendor Invoice' => 'Einkaufsrechnung bearbeiten',
'Edit Warehouse' => 'Lager bearbeiten',
......
'Last Dunning' => 'Letzte Mahnung',
'Last Invoice Number' => 'Letzte Rechnungsnummer',
'Last Numbers / Prefixes' => 'Letzte Nummern / Präfixe',
'Last Parent Variant Number' => 'Letzte Stammartikelnummer',
'Last Purchase Delivery Order Number' => 'Letzte Lieferscheinnummer (Einkauf)',
'Last Purchase Order Confirmation Number' => 'Letzte Lieferantenauftragsbestätigungs-Nummer',
'Last Purchase Order Number' => 'Letzte Lieferantenauftragsnummer',
......
'Last Service Number' => 'Letzte Dienstleistungsnr.',
'Last Supplier Delivery Order Number' => 'Letzte Beistell-Lieferscheinnummer',
'Last Transaction' => 'Letzte Buchung',
'Last Variant Number' => 'Letzte Variantennummer',
'Last Vendor Number' => 'Letzte Lieferantennummer',
'Last command output' => 'Ausgabe des letzten Befehls',
'Last modification' => 'Letzte Änderung',
......
'Paid' => 'bezahlt',
'Paid amount' => 'Bezahlter Betrag',
'Parameter module must be given.' => 'Der Parameter "module" miss angegeben werden.',
'Parent Variant' => 'Stammartikel',
'Parsing the XML data failed: #1' => 'Parsen der XML-Daten fehlgeschlagen: #1',
'Parsing the XMP metadata failed.' => 'Parsen der XMP-Metadaten schlug fehl.',
'Part' => 'Ware',
......
'Select/Deselect' => 'Aus-/Abwählen',
'Select/Deselect all' => 'Alle Aus-/Abwählen',
'Selected' => 'Ausgewählt',
'Selected Property Values' => 'Ausgewählte Ausprägunen',
'Selected items deleted' => 'Ausgewählte Positionen gelöscht',
'Selection' => 'Auswahlbox',
'Selection fields: The option field must contain the available options for the selection. Options are separated by \'##\', for example \'Early##Normal##Late\'.' => 'Auswahlboxen: Das Optionenfeld muss die für die Auswahl verfügbaren Einträge enthalten. Die Einträge werden mit \'##\' voneinander getrennt. Beispiel: \'Früh##Normal##Spät\'.',
......
'Variable' => 'Variable',
'Variable Description' => 'Datenfeldbezeichnung',
'Variable Name' => 'Datenfeldname (intern)',
'Variant' => 'Variante',
'Variants' => 'Varianten',
'Vendor' => 'Lieferant',
'Vendor & Order' => 'Lieferant & Bestellung',
'Vendor & Transaction' => 'Lieferant & Buchung',
locale/en/all
'Add Invoice' => '',
'Add Invoice for Advance Payment' => '',
'Add Letter' => '',
'Add Parent Variant' => '',
'Add Part' => '',
'Add Parts here!' => '',
'Add Price Factor' => '',
......
'Add Transaction' => '',
'Add User' => '',
'Add User Group' => '',
'Add Variant' => '',
'Add Vendor' => '',
'Add Vendor Invoice' => '',
'Add Warehouse' => '',
......
'All' => '',
'All Accounts' => '',
'All Data' => '',
'All Property Values' => '',
'All as list' => '',
'All changes in that file have been reverted.' => '',
'All clients' => '',
......
'Create PDF' => '',
'Create Reclamation' => '',
'Create Sub-Version' => '',
'Create Variants with selected Values' => '',
'Create a new background job' => '',
'Create a new client' => '',
'Create a new delivery term' => '',
......
'Create invoice' => '',
'Create invoice?' => '',
'Create new' => '',
'Create new Variants' => '',
'Create new client #1' => '',
'Create new quotation or order' => '',
'Create new quotation/order' => '',
......
'Edit Invoice' => '',
'Edit Invoice for Advance Payment' => '',
'Edit Letter' => '',
'Edit Parent Variant' => '',
'Edit Part' => '',
'Edit Preferences for #1' => '',
'Edit Price Factor' => '',
......
'Edit Supplier Delivery Order' => '',
'Edit User' => '',
'Edit User Group' => '',
'Edit Variant' => '',
'Edit Vendor' => '',
'Edit Vendor Invoice' => '',
'Edit Warehouse' => '',
......
'Last Dunning' => '',
'Last Invoice Number' => '',
'Last Numbers / Prefixes' => '',
'Last Parent Variant Number' => '',
'Last Purchase Delivery Order Number' => '',
'Last Purchase Order Confirmation Number' => '',
'Last Purchase Order Number' => '',
......
'Last Service Number' => '',
'Last Supplier Delivery Order Number' => '',
'Last Transaction' => '',
'Last Variant Number' => '',
'Last Vendor Number' => '',
'Last command output' => '',
'Last modification' => '',
......
'Paid' => '',
'Paid amount' => '',
'Parameter module must be given.' => '',
'Parent Variant' => '',
'Parsing the XML data failed: #1' => '',
'Parsing the XMP metadata failed.' => '',
'Part' => '',
......
'Select/Deselect' => '',
'Select/Deselect all' => '',
'Selected' => '',
'Selected Property Values' => '',
'Selected items deleted' => '',
'Selection' => '',
'Selection fields: The option field must contain the available options for the selection. Options are separated by \'##\', for example \'Early##Normal##Late\'.' => '',
......
'Variable' => '',
'Variable Description' => '',
'Variable Name' => '',
'Variant' => '',
'Variants' => '',
'Vendor' => '',
'Vendor & Order' => '',
'Vendor & Transaction' => '',
menus/user/00-erp.yaml
access: part_service_assembly_edit & client/feature_experimental_assortment
params:
action: Part/add_assortment
- parent: master_data
id: master_data_add_parent_variant
name: Add Parent Variant
order: 575
access: part_service_assembly_edit
params:
action: Part/add_parent_variant
- parent: master_data
id: master_data_add_project
name: Add Project
templates/design40_webpages/part/_variants.html
[% USE T8 %]
[% USE HTML %]
[% USE LxERP %]
[% USE L %]
[% USE P %]
<div class="wrapper input-panel">
<h3> [% LxERP.t8("Create new Variants") %] </h3>
<div class="wrapper">
[% FOREACH variant_property = SELF.part.variant_properties %]
<div class="col input-panel" style="min-width:fit-content;">
<h4>[% variant_property.name_translated | html %]</h4>
[% L.select_tag("variant_properties." _ variant_property.id _ ".selected_property_values[]",
variant_property.property_values,
title_key='value_translated', value_key='id',
id="selected_property_values_" _ variant_property.id,
multiple=1,
) %]
[% L.multiselect2side(
"selected_property_values_" _ variant_property.id,
labelsx=LxERP.t8("All Property Values"),
labeldx=LxERP.t8("Selected Property Values")
) %]
</div>
[% END %]
</div>
[% L.button_tag('kivi.Part.create_variants();', LxERP.t8("Create Variants with selected Values")) %]
</div>
<br>
variants:
[% FOREACH variant = SELF.part.variants %]
[% variant.partnumber %]:[% variant.description %]
[% END %]
templates/design40_webpages/part/form.html
<ul class="ui-tabs">
<li><a href="#basic_data">[% 'Basic Data' | $T8 %]</a></li>
[% IF SELF.part.is_parent_variant && SELF.part.id %]
<li><a href="#variants_tab">[% 'Variants' | $T8 %]</a></li>
[% END %]
[% IF SELF.part.is_assortment %]
<li><a href="#assortment_tab">[% 'Assortment items' | $T8 %]</a></li>
[% END %]
......
[% PROCESS 'part/_basic_data.html' %]
</div>
[% IF SELF.part.is_parent_variant && SELF.part.id %]
<div id="variants_tab" class="ui-tabs-panel">
[% PROCESS 'part/_variants.html' id=part.id %]
</div>
[% END %]
[% IF SELF.part.is_assortment %]
<div id="assortment_tab" class="ui-tabs-panel">
[% PROCESS 'part/_assortment.html' id=part.id assortment_id=SELF.part.id %]

Auch abrufbar als: Unified diff