Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 66c06a13

Von Tamino Steinert vor etwa 1 Jahr hinzugefügt

  • ID 66c06a13bf892e3346eec50f7f4ea278f8de0318
  • Vorgänger f36c200a
  • Nachfolger b16967fa

Varianten: Stammartikel anlegen und Varianten erstellen

Unterschiede anzeigen:

SL/Controller/Part.pm
86 86
  $self->add;
87 87
};
88 88

  
89
sub action_add_parent_variant {
90
  my ($self, %params) = @_;
91

  
92
  $self->part( SL::DB::Part->new_parent_variant );
93
  $self->add;
94
}
95

  
89 96
sub action_add_from_record {
90 97
  my ($self) = @_;
91 98

  
......
103 110

  
104 111
  check_has_valid_part_type($::form->{part_type});
105 112

  
106
  $self->action_add_part       if $::form->{part_type} eq 'part';
107
  $self->action_add_service    if $::form->{part_type} eq 'service';
108
  $self->action_add_assembly   if $::form->{part_type} eq 'assembly';
109
  $self->action_add_assortment if $::form->{part_type} eq 'assortment';
113
  $self->action_add_part           if $::form->{part_type} eq 'part';
114
  $self->action_add_service        if $::form->{part_type} eq 'service';
115
  $self->action_add_assembly       if $::form->{part_type} eq 'assembly';
116
  $self->action_add_assortment     if $::form->{part_type} eq 'assortment';
117
  $self->action_add_parent_variant if $::form->{part_type} eq 'parent_variant';
118
  $self->action_add_variant        if $::form->{part_type} eq 'variant';
110 119
};
111 120

  
112 121
sub action_save {
......
212 221
  }
213 222
}
214 223

  
224
sub action_create_variants {
225
  my ($self) = @_;
226
  my @variant_property_ids = sort keys %{$::form->{variant_properties}};
227

  
228
  my $part = $self->part;
229
  my $variant_properties = $part->variant_properties();
230
  my @needed_variant_property_ids = sort map {$_->id} @$variant_properties;
231

  
232
  if (@variant_property_ids != @needed_variant_property_ids) {
233
    return $self->js->error(
234
      t8('No property value selected for variant properties: #1.',
235
        join(", ",
236
          map {$_->name_translated}
237
          grep {!defined $::form->{variant_properties}->{$_->id}->{selected_property_values}}
238
          @$variant_properties
239
        )
240
      )
241
    )->render();
242
  }
243

  
244
  my @grouped_variant_property_values = ();
245
  push @grouped_variant_property_values,
246
    SL::DB::Manager::VariantPropertyValue->get_all(
247
      where => [ id => $::form->{variant_properties}->{$_}->{selected_property_values} ]
248
    )
249
    for @variant_property_ids;
250

  
251

  
252
  my @variant_property_values_lists = ();
253
  foreach my $variant_property_values (@grouped_variant_property_values) {
254
    my @new_lists = ();
255
    foreach my $variant_property_value (@$variant_property_values) {
256
      unless (scalar @variant_property_values_lists) {
257
        push @new_lists, [$variant_property_value];
258
      }
259
      foreach my $variant_property_values_list (@variant_property_values_lists) {
260
        push @new_lists, [@$variant_property_values_list, $variant_property_value];
261
      }
262
    }
263
    @variant_property_values_lists = @new_lists;
264
  }
265

  
266
  my @new_variants = ();
267
  SL::DB->client->with_transaction(sub {
268
    push @new_variants, $part->create_new_variant($_)
269
      for @variant_property_values_lists;
270
    1;
271
  }) or do {
272
    return $self->js->error(t8('Error while creating variants: ' . @_))->render();
273
  };
274

  
275
  $self->redirect_to(
276
    controller => 'Part',
277
    action     => 'edit',
278
    'part.id'  => $self->part->id
279
  );
280
}
281

  
215 282
sub action_delete {
216 283
  my ($self) = @_;
217 284

  
......
307 374
    @{ $params{CUSTOM_VARIABLES_FIRST_TAB} }  = extract_by { $_->{first_tab} == 1 } @{ $params{CUSTOM_VARIABLES} };
308 375
  }
309 376

  
310
  my %title_hash = ( part       => t8('Edit Part'),
311
                     assembly   => t8('Edit Assembly'),
312
                     service    => t8('Edit Service'),
313
                     assortment => t8('Edit Assortment'),
377
  my %title_hash = ( part           => t8('Edit Part'),
378
                     assembly       => t8('Edit Assembly'),
379
                     service        => t8('Edit Service'),
380
                     assortment     => t8('Edit Assortment'),
381
                     parent_variant => t8('Edit Parent Variant'),
382
                     variant        => t8('Edit Variant'),
314 383
                   );
315 384

  
316 385
  $self->part->prices([])       unless $self->part->prices;
......
955 1024
  $self->_set_javascript;
956 1025
  $self->_setup_form_action_bar;
957 1026

  
958
  my %title_hash = ( part       => t8('Add Part'),
959
                     assembly   => t8('Add Assembly'),
960
                     service    => t8('Add Service'),
961
                     assortment => t8('Add Assortment'),
1027
  my %title_hash = ( part           => t8('Add Part'),
1028
                     assembly       => t8('Add Assembly'),
1029
                     service        => t8('Add Service'),
1030
                     assortment     => t8('Add Assortment'),
1031
                     parent_variant => t8('Add Parent Variant'),
1032
                     variant        => t8('Add Variant'),
962 1033
                   );
963 1034

  
964 1035
  $self->render(
......
970 1041

  
971 1042
sub _set_javascript {
972 1043
  my ($self) = @_;
973
  $::request->layout->use_javascript("${_}.js")  for qw(kivi.Part kivi.File kivi.PriceRule kivi.ShopPart kivi.Validator);
1044
  $::request->layout->use_javascript("${_}.js")  for qw(kivi.Part kivi.File kivi.PriceRule kivi.ShopPart kivi.Validator jquery.selectboxes jquery.multiselect2side);
974 1045
  $::request->layout->add_javascripts_inline("\$(function(){kivi.PriceRule.load_price_rules_for_part(@{[ $self->part->id ]})});") if $self->part->id;
975 1046
}
976 1047

  
......
1585 1656
}
1586 1657

  
1587 1658
sub check_has_valid_part_type {
1588
  die "invalid part_type" unless $_[0] =~ /^(part|service|assembly|assortment)$/;
1659
  die "invalid part_type" unless $_[0] =~ /^(part|service|assembly|assortment|parent_variant|variant)$/;
1589 1660
}
1590 1661

  
1591 1662

  
SL/DB/Part.pm
242 242
  $class->new(%params, part_type => 'parent_variant');
243 243
}
244 244

  
245
sub new_variant {
246
  my ($class, %params) = @_;
247
  $class->new(%params, part_type => 'variant');
248
}
249

  
250 245
sub last_modification {
251 246
  my ($self) = @_;
252 247
  return $self->mtime // $self->itime;
......
503 498
  return \@sorted;
504 499
}
505 500

  
501
sub create_new_variant {
502
  my ($self, $variant_property_values) = @_;
503
  die "only callable on parts of type parent_variant" unless $self->is_parent_variant;
504
  die "only callable on saved objects"                unless $self->id;
505

  
506
  my @selected_variant_property_ids = sort map {$_->variant_property_id} @$variant_property_values;
507
  my @variant_property_ids = sort map {$_->id} @{$self->variant_properties};
508
  if (@variant_property_ids != @selected_variant_property_ids) {
509
    die "Given variant_property_values dosn't match the variant_properties of parent_variant part";
510
  }
511

  
512
  my $new_variant = $self->clone_and_reset;
513
  # TODO set partnumber
514
  $new_variant->part_type('variant');
515
  $new_variant->save;
516
  SL::DB::VariantPropertyValuePart->new(
517
    part_id                   => $new_variant->id,
518
    variant_property_value_id => $_->id,
519
  )->save for @$variant_property_values;
520
  SL::DB::PartParentVariantPartVariant->new(
521
    variant_id        => $new_variant->id,
522
    parent_variant_id => $self->id,
523
  )->save;
524

  
525
  return $new_variant;
526
}
527

  
506 528
sub clone_and_reset_deep {
507 529
  my ($self) = @_;
508 530

  
SL/DB/VariantProperty.pm
15 15
    map_to    => 'part',
16 16
    type      => 'many to many',
17 17
  },
18
  property_values => {
19
    class => 'SL::DB::VariantPropertyValue',
20
    column_map => { id => 'variant_property_id' },
21
    type => 'one to many',
22
  }
18 23
);
19 24

  
20 25
__PACKAGE__->meta->initialize;
......
30 35
  return @errors;
31 36
}
32 37

  
38
sub name_translated {goto &name} # TODO
39

  
33 40
1;
SL/DB/VariantPropertyValue.pm
19 19

  
20 20
__PACKAGE__->meta->initialize;
21 21

  
22
sub value_translated {goto &value} # TODO
23

  
22 24
1;
js/kivi.Part.js
331 331
    $.post("controller.pl", { action: 'Part/warehouse_changed', warehouse_id: function(){ return $('#part_warehouse_id').val(); } },   kivi.eval_json_result);
332 332
  };
333 333

  
334
  ns.create_variants = function() {
335
    var data = $('#ic').serializeArray();
336
    data.push({ name: 'action', value: 'Part/create_variants' });
337
    $.post("controller.pl", data, kivi.eval_json_result);
338
  };
339

  
334 340
  var KEY = {
335 341
    TAB:       9,
336 342
    ENTER:     13,
locale/de/all
200 200
  'Add General Ledger Transaction' => 'Dialogbuchen',
201 201
  'Add Invoice for Advance Payment' => 'Anzahlungsrechnung erfassen',
202 202
  'Add Letter'                  => 'Brief hinzufügen',
203
  'Add Parent Variant'          => 'Stammartikel erfassen',
203 204
  'Add Part'                    => 'Ware erfassen',
204 205
  'Add Parts here!'             => 'Artikel hier hinzufügen!',
205 206
  'Add Price Factor'            => 'Preisfaktor erfassen',
......
228 229
  'Add Transaction'             => 'Dialogbuchen',
229 230
  'Add User'                    => 'Neuer Benutzer',
230 231
  'Add User Group'              => 'Neue Benutzergruppe',
232
  'Add Variant'                 => 'Variante erfassen',
231 233
  'Add Vendor'                  => 'Lieferant erfassen',
232 234
  'Add Vendor Invoice'          => 'Einkaufsrechnung erfassen',
233 235
  'Add Warehouse'               => 'Lager erfassen',
......
308 310
  'All'                         => 'Alle',
309 311
  'All Accounts'                => 'Alle Konten',
310 312
  'All Data'                    => 'Alle Daten',
313
  'All Property Values'         => 'Alle Ausprägunen',
311 314
  'All as list'                 => 'Alle als Liste',
312 315
  'All changes in that file have been reverted.' => 'Alle Änderungen in dieser Datei wurden rückgängig gemacht.',
313 316
  'All clients'                 => 'Alle Mandanten',
......
867 870
  'Create PDF'                  => 'PDF erzeugen',
868 871
  'Create Reclamation'          => 'Reklamation erstellen',
869 872
  'Create Sub-Version'          => 'Unterversion erzeugen',
873
  'Create Variants with selected Values' => 'Varianten mit ausgewählten Ausprägungen erstellen',
870 874
  'Create a new background job' => 'Einen neuen Hintergrund-Job anlegen',
871 875
  'Create a new client'         => 'Einen neuen Mandanten anlegen',
872 876
  'Create a new delivery term'  => 'Neue Lieferbedingungen anlegen',
......
916 920
  'Create invoice'              => 'Buchung erstellen',
917 921
  'Create invoice?'             => 'Rechnung erstellen?',
918 922
  'Create new'                  => 'Neu erfassen',
923
  'Create new Variants'         => 'Neue Varianten erstellen',
919 924
  'Create new client #1'        => 'Neuen Mandanten #1 anlegen',
920 925
  'Create new quotation or order' => 'Neues Angebot oder neuen Auftrag anlegen',
921 926
  'Create new quotation/order'  => 'Neues Angebot/neuen Auftrag anlegen',
......
1400 1405
  'Edit General Ledger Transaction' => 'Buchung im Hauptbuch bearbeiten',
1401 1406
  'Edit Invoice for Advance Payment' => 'Anzahlungsrechnung bearbeiten',
1402 1407
  'Edit Letter'                 => 'Brief bearbeiten',
1408
  'Edit Parent Variant'         => 'Stammartikel bearbeiten',
1403 1409
  'Edit Part'                   => 'Ware bearbeiten',
1404 1410
  'Edit Preferences for #1'     => 'Einstellungen von #1 bearbeiten',
1405 1411
  'Edit Price Factor'           => 'Preisfaktor bearbeiten',
......
1425 1431
  'Edit Supplier Delivery Order' => 'Beistell-Lieferschein bearbeiten',
1426 1432
  'Edit User'                   => 'Benutzerdaten bearbeiten',
1427 1433
  'Edit User Group'             => 'Benutzergruppe bearbeiten',
1434
  'Edit Variant'                => 'Variante bearbeiten',
1428 1435
  'Edit Vendor'                 => 'Lieferant editieren',
1429 1436
  'Edit Vendor Invoice'         => 'Einkaufsrechnung bearbeiten',
1430 1437
  'Edit Warehouse'              => 'Lager bearbeiten',
......
2171 2178
  'Last Dunning'                => 'Letzte Mahnung',
2172 2179
  'Last Invoice Number'         => 'Letzte Rechnungsnummer',
2173 2180
  'Last Numbers / Prefixes'     => 'Letzte Nummern / Präfixe',
2181
  'Last Parent Variant Number'  => 'Letzte Stammartikelnummer',
2174 2182
  'Last Purchase Delivery Order Number' => 'Letzte Lieferscheinnummer (Einkauf)',
2175 2183
  'Last Purchase Order Confirmation Number' => 'Letzte Lieferantenauftragsbestätigungs-Nummer',
2176 2184
  'Last Purchase Order Number'  => 'Letzte Lieferantenauftragsnummer',
......
2186 2194
  'Last Service Number'         => 'Letzte Dienstleistungsnr.',
2187 2195
  'Last Supplier Delivery Order Number' => 'Letzte Beistell-Lieferscheinnummer',
2188 2196
  'Last Transaction'            => 'Letzte Buchung',
2197
  'Last Variant Number'         => 'Letzte Variantennummer',
2189 2198
  'Last Vendor Number'          => 'Letzte Lieferantennummer',
2190 2199
  'Last command output'         => 'Ausgabe des letzten Befehls',
2191 2200
  'Last modification'           => 'Letzte Änderung',
......
2731 2740
  'Paid'                        => 'bezahlt',
2732 2741
  'Paid amount'                 => 'Bezahlter Betrag',
2733 2742
  'Parameter module must be given.' => 'Der Parameter "module" miss angegeben werden.',
2743
  'Parent Variant'              => 'Stammartikel',
2734 2744
  'Parsing the XML data failed: #1' => 'Parsen der XML-Daten fehlgeschlagen: #1',
2735 2745
  'Parsing the XMP metadata failed.' => 'Parsen der XMP-Metadaten schlug fehl.',
2736 2746
  'Part'                        => 'Ware',
......
3467 3477
  'Select/Deselect'             => 'Aus-/Abwählen',
3468 3478
  'Select/Deselect all'         => 'Alle Aus-/Abwählen',
3469 3479
  'Selected'                    => 'Ausgewählt',
3480
  'Selected Property Values'    => 'Ausgewählte Ausprägunen',
3470 3481
  'Selected items deleted'      => 'Ausgewählte Positionen gelöscht',
3471 3482
  'Selection'                   => 'Auswahlbox',
3472 3483
  '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\'.',
......
4662 4673
  'Variable'                    => 'Variable',
4663 4674
  'Variable Description'        => 'Datenfeldbezeichnung',
4664 4675
  'Variable Name'               => 'Datenfeldname (intern)',
4676
  'Variant'                     => 'Variante',
4677
  'Variants'                    => 'Varianten',
4665 4678
  'Vendor'                      => 'Lieferant',
4666 4679
  'Vendor & Order'              => 'Lieferant & Bestellung',
4667 4680
  'Vendor & Transaction'        => 'Lieferant & Buchung',
locale/en/all
200 200
  'Add General Ledger Transaction' => '',
201 201
  'Add Invoice for Advance Payment' => '',
202 202
  'Add Letter'                  => '',
203
  'Add Parent Variant'          => '',
203 204
  'Add Part'                    => '',
204 205
  'Add Parts here!'             => '',
205 206
  'Add Price Factor'            => '',
......
228 229
  'Add Transaction'             => '',
229 230
  'Add User'                    => '',
230 231
  'Add User Group'              => '',
232
  'Add Variant'                 => '',
231 233
  'Add Vendor'                  => '',
232 234
  'Add Vendor Invoice'          => '',
233 235
  'Add Warehouse'               => '',
......
308 310
  'All'                         => '',
309 311
  'All Accounts'                => '',
310 312
  'All Data'                    => '',
313
  'All Property Values'         => '',
311 314
  'All as list'                 => '',
312 315
  'All changes in that file have been reverted.' => '',
313 316
  'All clients'                 => '',
......
867 870
  'Create PDF'                  => '',
868 871
  'Create Reclamation'          => '',
869 872
  'Create Sub-Version'          => '',
873
  'Create Variants with selected Values' => '',
870 874
  'Create a new background job' => '',
871 875
  'Create a new client'         => '',
872 876
  'Create a new delivery term'  => '',
......
916 920
  'Create invoice'              => '',
917 921
  'Create invoice?'             => '',
918 922
  'Create new'                  => '',
923
  'Create new Variants'         => '',
919 924
  'Create new client #1'        => '',
920 925
  'Create new quotation or order' => '',
921 926
  'Create new quotation/order'  => '',
......
1400 1405
  'Edit General Ledger Transaction' => '',
1401 1406
  'Edit Invoice for Advance Payment' => '',
1402 1407
  'Edit Letter'                 => '',
1408
  'Edit Parent Variant'         => '',
1403 1409
  'Edit Part'                   => '',
1404 1410
  'Edit Preferences for #1'     => '',
1405 1411
  'Edit Price Factor'           => '',
......
1425 1431
  'Edit Supplier Delivery Order' => '',
1426 1432
  'Edit User'                   => '',
1427 1433
  'Edit User Group'             => '',
1434
  'Edit Variant'                => '',
1428 1435
  'Edit Vendor'                 => '',
1429 1436
  'Edit Vendor Invoice'         => '',
1430 1437
  'Edit Warehouse'              => '',
......
2170 2177
  'Last Dunning'                => '',
2171 2178
  'Last Invoice Number'         => '',
2172 2179
  'Last Numbers / Prefixes'     => '',
2180
  'Last Parent Variant Number'  => '',
2173 2181
  'Last Purchase Delivery Order Number' => '',
2174 2182
  'Last Purchase Order Confirmation Number' => '',
2175 2183
  'Last Purchase Order Number'  => '',
......
2185 2193
  'Last Service Number'         => '',
2186 2194
  'Last Supplier Delivery Order Number' => '',
2187 2195
  'Last Transaction'            => '',
2196
  'Last Variant Number'         => '',
2188 2197
  'Last Vendor Number'          => '',
2189 2198
  'Last command output'         => '',
2190 2199
  'Last modification'           => '',
......
2730 2739
  'Paid'                        => '',
2731 2740
  'Paid amount'                 => '',
2732 2741
  'Parameter module must be given.' => '',
2742
  'Parent Variant'              => '',
2733 2743
  'Parsing the XML data failed: #1' => '',
2734 2744
  'Parsing the XMP metadata failed.' => '',
2735 2745
  'Part'                        => '',
......
3466 3476
  'Select/Deselect'             => '',
3467 3477
  'Select/Deselect all'         => '',
3468 3478
  'Selected'                    => '',
3479
  'Selected Property Values'    => '',
3469 3480
  'Selected items deleted'      => '',
3470 3481
  'Selection'                   => '',
3471 3482
  'Selection fields: The option field must contain the available options for the selection. Options are separated by \'##\', for example \'Early##Normal##Late\'.' => '',
......
4660 4671
  'Variable'                    => '',
4661 4672
  'Variable Description'        => '',
4662 4673
  'Variable Name'               => '',
4674
  'Variant'                     => '',
4675
  'Variants'                    => '',
4663 4676
  'Vendor'                      => '',
4664 4677
  'Vendor & Order'              => '',
4665 4678
  'Vendor & Transaction'        => '',
menus/user/00-erp.yaml
79 79
  access: part_service_assembly_edit & client/feature_experimental_assortment
80 80
  params:
81 81
    action: Part/add_assortment
82
- parent: master_data
83
  id: master_data_add_parent_variant
84
  name: Add Parent Variant
85
  order: 575
86
  access: part_service_assembly_edit
87
  params:
88
    action: Part/add_parent_variant
82 89
- parent: master_data
83 90
  id: master_data_add_project
84 91
  name: Add Project
templates/design40_webpages/part/_variants.html
1
[% USE T8 %]
2
[% USE HTML %]
3
[% USE LxERP %]
4
[% USE L %]
5
[% USE P %]
6

  
7
<div class="wrapper input-panel">
8
  <h3> [% LxERP.t8("Create new Variants") %] </h3>
9
  <div class="wrapper">
10
  [% FOREACH variant_property = SELF.part.variant_properties %]
11
    <div class="col input-panel" style="min-width:fit-content;">
12
      <h4>[% variant_property.name_translated | html %]</h4>
13
      [% L.select_tag("variant_properties." _ variant_property.id _ ".selected_property_values[]",
14
        variant_property.property_values,
15
        title_key='value_translated', value_key='id',
16
        id="selected_property_values_" _ variant_property.id,
17
        multiple=1,
18
      ) %]
19
      [% L.multiselect2side(
20
        "selected_property_values_" _ variant_property.id,
21
        labelsx=LxERP.t8("All Property Values"),
22
        labeldx=LxERP.t8("Selected Property Values")
23
      ) %]
24
    </div>
25
  [% END %]
26
  </div>
27
  [% L.button_tag('kivi.Part.create_variants();', LxERP.t8("Create Variants with selected Values")) %]
28
</div>
29

  
30
<br>
31

  
32
variants:
33
[% FOREACH variant = SELF.part.variants %]
34
  [% variant.partnumber %]:[% variant.description %]
35
[% END %]
36

  
37

  
templates/design40_webpages/part/form.html
19 19

  
20 20
  <ul class="ui-tabs">
21 21
    <li><a href="#basic_data">[% 'Basic Data' | $T8 %]</a></li>
22
    [% IF SELF.part.is_parent_variant && SELF.part.id %]
23
      <li><a href="#variants_tab">[% 'Variants' | $T8 %]</a></li>
24
    [% END %]
22 25
    [% IF SELF.part.is_assortment %]
23 26
      <li><a href="#assortment_tab">[% 'Assortment items' | $T8 %]</a></li>
24 27
    [% END %]
......
55 58
    [% PROCESS 'part/_basic_data.html' %]
56 59
  </div>
57 60

  
61
  [% IF SELF.part.is_parent_variant && SELF.part.id %]
62
    <div id="variants_tab" class="ui-tabs-panel">
63
      [% PROCESS 'part/_variants.html' id=part.id %]
64
    </div>
65
  [% END %]
66

  
58 67
  [% IF SELF.part.is_assortment %]
59 68
    <div id="assortment_tab" class="ui-tabs-panel">
60 69
      [% PROCESS 'part/_assortment.html' id=part.id assortment_id=SELF.part.id %]

Auch abrufbar als: Unified diff