Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision a279fb60

Von Tamino Steinert vor 9 Monaten hinzugefügt

  • ID a279fb605ba2ca165beedaaf906ad811dd070ddb
  • Vorgänger 89821947
  • Nachfolger e2cc408f

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;
......
504 499
  return \@sorted;
505 500
}
506 501

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

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

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

  
526
  return $new_variant;
527
}
528

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

  
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
203 203
  'Add Invoice'                 => 'Rechnung erfassen',
204 204
  'Add Invoice for Advance Payment' => 'Anzahlungsrechnung erfassen',
205 205
  'Add Letter'                  => 'Brief hinzufügen',
206
  'Add Parent Variant'          => 'Stammartikel erfassen',
206 207
  'Add Part'                    => 'Ware erfassen',
207 208
  'Add Parts here!'             => 'Artikel hier hinzufügen!',
208 209
  'Add Price Factor'            => 'Preisfaktor erfassen',
......
235 236
  'Add Transaction'             => 'Dialogbuchen',
236 237
  'Add User'                    => 'Neuer Benutzer',
237 238
  'Add User Group'              => 'Neue Benutzergruppe',
239
  'Add Variant'                 => 'Variante erfassen',
238 240
  'Add Vendor'                  => 'Lieferant erfassen',
239 241
  'Add Vendor Invoice'          => 'Einkaufsrechnung erfassen',
240 242
  'Add Warehouse'               => 'Lager erfassen',
......
315 317
  'All'                         => 'Alle',
316 318
  'All Accounts'                => 'Alle Konten',
317 319
  'All Data'                    => 'Alle Daten',
320
  'All Property Values'         => 'Alle Ausprägunen',
318 321
  'All as list'                 => 'Alle als Liste',
319 322
  'All changes in that file have been reverted.' => 'Alle Änderungen in dieser Datei wurden rückgängig gemacht.',
320 323
  'All clients'                 => 'Alle Mandanten',
......
879 882
  'Create PDF'                  => 'PDF erzeugen',
880 883
  'Create Reclamation'          => 'Reklamation erstellen',
881 884
  'Create Sub-Version'          => 'Unterversion erzeugen',
885
  'Create Variants with selected Values' => 'Varianten mit ausgewählten Ausprägungen erstellen',
882 886
  'Create a new background job' => 'Einen neuen Hintergrund-Job anlegen',
883 887
  'Create a new client'         => 'Einen neuen Mandanten anlegen',
884 888
  'Create a new delivery term'  => 'Neue Lieferbedingungen anlegen',
......
930 934
  'Create invoice'              => 'Buchung erstellen',
931 935
  'Create invoice?'             => 'Rechnung erstellen?',
932 936
  'Create new'                  => 'Neu erfassen',
937
  'Create new Variants'         => 'Neue Varianten erstellen',
933 938
  'Create new client #1'        => 'Neuen Mandanten #1 anlegen',
934 939
  'Create new quotation or order' => 'Neues Angebot oder neuen Auftrag anlegen',
935 940
  'Create new quotation/order'  => 'Neues Angebot/neuen Auftrag anlegen',
......
1418 1423
  'Edit Invoice'                => 'Rechnung bearbeiten',
1419 1424
  'Edit Invoice for Advance Payment' => 'Anzahlungsrechnung bearbeiten',
1420 1425
  'Edit Letter'                 => 'Brief bearbeiten',
1426
  'Edit Parent Variant'         => 'Stammartikel bearbeiten',
1421 1427
  'Edit Part'                   => 'Ware bearbeiten',
1422 1428
  'Edit Preferences for #1'     => 'Einstellungen von #1 bearbeiten',
1423 1429
  'Edit Price Factor'           => 'Preisfaktor bearbeiten',
......
1445 1451
  'Edit Supplier Delivery Order' => 'Beistell-Lieferschein bearbeiten',
1446 1452
  'Edit User'                   => 'Benutzerdaten bearbeiten',
1447 1453
  'Edit User Group'             => 'Benutzergruppe bearbeiten',
1454
  'Edit Variant'                => 'Variante bearbeiten',
1448 1455
  'Edit Vendor'                 => 'Lieferant editieren',
1449 1456
  'Edit Vendor Invoice'         => 'Einkaufsrechnung bearbeiten',
1450 1457
  'Edit Warehouse'              => 'Lager bearbeiten',
......
2204 2211
  'Last Dunning'                => 'Letzte Mahnung',
2205 2212
  'Last Invoice Number'         => 'Letzte Rechnungsnummer',
2206 2213
  'Last Numbers / Prefixes'     => 'Letzte Nummern / Präfixe',
2214
  'Last Parent Variant Number'  => 'Letzte Stammartikelnummer',
2207 2215
  'Last Purchase Delivery Order Number' => 'Letzte Lieferscheinnummer (Einkauf)',
2208 2216
  'Last Purchase Order Confirmation Number' => 'Letzte Lieferantenauftragsbestätigungs-Nummer',
2209 2217
  'Last Purchase Order Number'  => 'Letzte Lieferantenauftragsnummer',
......
2219 2227
  'Last Service Number'         => 'Letzte Dienstleistungsnr.',
2220 2228
  'Last Supplier Delivery Order Number' => 'Letzte Beistell-Lieferscheinnummer',
2221 2229
  'Last Transaction'            => 'Letzte Buchung',
2230
  'Last Variant Number'         => 'Letzte Variantennummer',
2222 2231
  'Last Vendor Number'          => 'Letzte Lieferantennummer',
2223 2232
  'Last command output'         => 'Ausgabe des letzten Befehls',
2224 2233
  'Last modification'           => 'Letzte Änderung',
......
2777 2786
  'Paid'                        => 'bezahlt',
2778 2787
  'Paid amount'                 => 'Bezahlter Betrag',
2779 2788
  'Parameter module must be given.' => 'Der Parameter "module" miss angegeben werden.',
2789
  'Parent Variant'              => 'Stammartikel',
2780 2790
  'Parsing the XML data failed: #1' => 'Parsen der XML-Daten fehlgeschlagen: #1',
2781 2791
  'Parsing the XMP metadata failed.' => 'Parsen der XMP-Metadaten schlug fehl.',
2782 2792
  'Part'                        => 'Ware',
......
3523 3533
  'Select/Deselect'             => 'Aus-/Abwählen',
3524 3534
  'Select/Deselect all'         => 'Alle Aus-/Abwählen',
3525 3535
  'Selected'                    => 'Ausgewählt',
3536
  'Selected Property Values'    => 'Ausgewählte Ausprägunen',
3526 3537
  'Selected items deleted'      => 'Ausgewählte Positionen gelöscht',
3527 3538
  'Selection'                   => 'Auswahlbox',
3528 3539
  '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\'.',
......
4738 4749
  'Variable'                    => 'Variable',
4739 4750
  'Variable Description'        => 'Datenfeldbezeichnung',
4740 4751
  'Variable Name'               => 'Datenfeldname (intern)',
4752
  'Variant'                     => 'Variante',
4753
  'Variants'                    => 'Varianten',
4741 4754
  'Vendor'                      => 'Lieferant',
4742 4755
  'Vendor & Order'              => 'Lieferant & Bestellung',
4743 4756
  'Vendor & Transaction'        => 'Lieferant & Buchung',
locale/en/all
203 203
  'Add Invoice'                 => '',
204 204
  'Add Invoice for Advance Payment' => '',
205 205
  'Add Letter'                  => '',
206
  'Add Parent Variant'          => '',
206 207
  'Add Part'                    => '',
207 208
  'Add Parts here!'             => '',
208 209
  'Add Price Factor'            => '',
......
235 236
  'Add Transaction'             => '',
236 237
  'Add User'                    => '',
237 238
  'Add User Group'              => '',
239
  'Add Variant'                 => '',
238 240
  'Add Vendor'                  => '',
239 241
  'Add Vendor Invoice'          => '',
240 242
  'Add Warehouse'               => '',
......
315 317
  'All'                         => '',
316 318
  'All Accounts'                => '',
317 319
  'All Data'                    => '',
320
  'All Property Values'         => '',
318 321
  'All as list'                 => '',
319 322
  'All changes in that file have been reverted.' => '',
320 323
  'All clients'                 => '',
......
879 882
  'Create PDF'                  => '',
880 883
  'Create Reclamation'          => '',
881 884
  'Create Sub-Version'          => '',
885
  'Create Variants with selected Values' => '',
882 886
  'Create a new background job' => '',
883 887
  'Create a new client'         => '',
884 888
  'Create a new delivery term'  => '',
......
930 934
  'Create invoice'              => '',
931 935
  'Create invoice?'             => '',
932 936
  'Create new'                  => '',
937
  'Create new Variants'         => '',
933 938
  'Create new client #1'        => '',
934 939
  'Create new quotation or order' => '',
935 940
  'Create new quotation/order'  => '',
......
1418 1423
  'Edit Invoice'                => '',
1419 1424
  'Edit Invoice for Advance Payment' => '',
1420 1425
  'Edit Letter'                 => '',
1426
  'Edit Parent Variant'         => '',
1421 1427
  'Edit Part'                   => '',
1422 1428
  'Edit Preferences for #1'     => '',
1423 1429
  'Edit Price Factor'           => '',
......
1445 1451
  'Edit Supplier Delivery Order' => '',
1446 1452
  'Edit User'                   => '',
1447 1453
  'Edit User Group'             => '',
1454
  'Edit Variant'                => '',
1448 1455
  'Edit Vendor'                 => '',
1449 1456
  'Edit Vendor Invoice'         => '',
1450 1457
  'Edit Warehouse'              => '',
......
2203 2210
  'Last Dunning'                => '',
2204 2211
  'Last Invoice Number'         => '',
2205 2212
  'Last Numbers / Prefixes'     => '',
2213
  'Last Parent Variant Number'  => '',
2206 2214
  'Last Purchase Delivery Order Number' => '',
2207 2215
  'Last Purchase Order Confirmation Number' => '',
2208 2216
  'Last Purchase Order Number'  => '',
......
2218 2226
  'Last Service Number'         => '',
2219 2227
  'Last Supplier Delivery Order Number' => '',
2220 2228
  'Last Transaction'            => '',
2229
  'Last Variant Number'         => '',
2221 2230
  'Last Vendor Number'          => '',
2222 2231
  'Last command output'         => '',
2223 2232
  'Last modification'           => '',
......
2776 2785
  'Paid'                        => '',
2777 2786
  'Paid amount'                 => '',
2778 2787
  'Parameter module must be given.' => '',
2788
  'Parent Variant'              => '',
2779 2789
  'Parsing the XML data failed: #1' => '',
2780 2790
  'Parsing the XMP metadata failed.' => '',
2781 2791
  'Part'                        => '',
......
3522 3532
  'Select/Deselect'             => '',
3523 3533
  'Select/Deselect all'         => '',
3524 3534
  'Selected'                    => '',
3535
  'Selected Property Values'    => '',
3525 3536
  'Selected items deleted'      => '',
3526 3537
  'Selection'                   => '',
3527 3538
  'Selection fields: The option field must contain the available options for the selection. Options are separated by \'##\', for example \'Early##Normal##Late\'.' => '',
......
4736 4747
  'Variable'                    => '',
4737 4748
  'Variable Description'        => '',
4738 4749
  'Variable Name'               => '',
4750
  'Variant'                     => '',
4751
  'Variants'                    => '',
4739 4752
  'Vendor'                      => '',
4740 4753
  'Vendor & Order'              => '',
4741 4754
  '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