Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 8a0d2996

Von Tamino Steinert vor 9 Monaten hinzugefügt

  • ID 8a0d29968757bfba2f0a06dfa07b650eaffc4ef7
  • Vorgänger bc8ddcc1
  • Nachfolger e4982f5b

Varianten: einfachen Artikel in Variante umwandeln

Unterschiede anzeigen:

SL/Controller/Part.pm
10 10
use File::Temp;
11 11
use List::Util qw(sum);
12 12
use List::UtilsBy qw(extract_by);
13
use List::MoreUtils qw(any pairwise);
13 14
use POSIX qw(strftime);
14 15
use Text::CSV_XS;
15 16

  
......
294 295

  
295 296
  my $part = $self->part;
296 297
  my $variant_properties = $part->variant_properties();
297
  my @needed_variant_property_ids = sort map {$_->id} @$variant_properties;
298 298

  
299
  if (@variant_property_ids != @needed_variant_property_ids) {
299
  if (any {$_} grep {
300
      !defined $::form->{variant_properties}->{$_->id}->{selected_property_value_ids}
301
    } @$variant_properties
302
    ) {
300 303
    return $self->js->error(
301 304
      t8('No property value selected for variant properties: #1.',
302 305
        join(", ",
303 306
          map {$_->displayable_name}
304
          grep {!defined $::form->{variant_properties}->{$_->id}->{selected_property_values}}
307
          grep {!defined $::form->{variant_properties}->{$_->id}->{selected_property_value_ids}}
305 308
          @$variant_properties
306 309
        )
307 310
      )
......
311 314
  my @grouped_variant_property_values = ();
312 315
  push @grouped_variant_property_values,
313 316
    SL::DB::Manager::VariantPropertyValue->get_all(
314
      where => [ id => $::form->{variant_properties}->{$_}->{selected_property_values} ]
317
      where => [ id => $::form->{variant_properties}->{$_}->{selected_property_value_ids} ]
315 318
    )
316 319
    for @variant_property_ids;
317 320

  
318 321

  
319
  my @variant_property_values_lists = ();
322
  my @variant_property_value_lists = ();
320 323
  foreach my $variant_property_values (@grouped_variant_property_values) {
321 324
    my @new_lists = ();
322 325
    foreach my $variant_property_value (@$variant_property_values) {
323
      unless (scalar @variant_property_values_lists) {
326
      unless (scalar @variant_property_value_lists) {
324 327
        push @new_lists, [$variant_property_value];
325 328
      }
326
      foreach my $variant_property_values_list (@variant_property_values_lists) {
329
      foreach my $variant_property_values_list (@variant_property_value_lists) {
327 330
        push @new_lists, [@$variant_property_values_list, $variant_property_value];
328 331
      }
329 332
    }
330
    @variant_property_values_lists = @new_lists;
333
    @variant_property_value_lists = @new_lists;
331 334
  }
332 335

  
333
  my @new_variants = ();
336
  _check_variant_property_values_not_taken($part, \@variant_property_value_lists);
334 337
  SL::DB->client->with_transaction(sub {
335
    push @new_variants, $part->create_new_variant($_)
336
      for @variant_property_values_lists;
338
    $part->create_new_variant($_) for @variant_property_value_lists;
337 339
    1;
338 340
  }) or do {
339
    die t8('Error while creating variants: '), $@;
341
    die t8('Error while creating variants: '), SL::DB->client->error;
342
  };
343

  
344
  $self->redirect_to(
345
    controller => 'Part',
346
    action     => 'edit',
347
    'part.id'  => $self->part->id
348
  );
349
}
350

  
351
sub action_convert_part_to_variant {
352
  my ($self) = @_;
353

  
354
  my $convert_part_id = $::form->{convert_part}->{id};
355
  die t8("Please select a part to convert.") unless $convert_part_id;
356

  
357
  my @variant_property_ids = sort keys %{$::form->{convert_part}->{variant_properties}};
358

  
359
  my $part = $self->part;
360
  my $variant_properties = $part->variant_properties();
361
  my @needed_variant_property_ids = sort map {$_->id} @$variant_properties;
362

  
363
  if (@variant_property_ids != @needed_variant_property_ids) {
364
    return $self->js->error(
365
      t8('No property value selected for variant properties: #1.',
366
        join(", ",
367
          map {$_->displayable_name}
368
          grep {!defined $::form->{convert_part}->{variant_properties}->{$_->id}->{selected_property_value_id}}
369
          @$variant_properties
370
        )
371
      )
372
    )->render();
373
  }
374

  
375
  my @variant_property_values = map {
376
      SL::DB::VariantPropertyValue->new(
377
        id => $::form->{convert_part}->{variant_properties}->{$_}->{selected_property_value_id}
378
      )->load()
379
    } @variant_property_ids;
380

  
381
  _check_variant_property_values_not_taken($part, [\@variant_property_values]);
382
  SL::DB->client->with_transaction(sub {
383
    my $part_to_convert = SL::DB::Part->new(id => $convert_part_id)->load;
384
    $part_to_convert->variant_type('variant');
385
    $part_to_convert->variant_property_values(\@variant_property_values);
386
    $part_to_convert->parent_variant($part);
387
    $part_to_convert->save;
388
    1;
389
  }) or do {
390
    die t8('Error while converting part to variant: '), SL::DB->Client->error;
340 391
  };
341 392

  
342 393
  $self->redirect_to(
......
1748 1799
  Carp::confess "invalid part_type" unless $_[0] =~ /^(part|service|assembly|assortment)$/;
1749 1800
}
1750 1801

  
1802
sub _check_variant_property_values_not_taken {
1803
  my ($parent_variant, $variant_property_value_lists) = @_;
1804

  
1805
  my @double_lists;
1806
  my $variants = $parent_variant->variants;
1807
  foreach my $variant (@$variants) {
1808
    my @property_value_ids = sort map {$_->id} $variant->variant_property_values;
1809
    foreach my $test_property_values (@$variant_property_value_lists) {
1810
      my @test_property_value_ids = sort map {$_->id} @$test_property_values;
1811
      if (@test_property_value_ids == @property_value_ids
1812
        && not any {$_} pairwise {$a != $b} @test_property_value_ids, @property_value_ids
1813
      ) {
1814
        push @double_lists, join(', ', map {$_->displayable_name} @$test_property_values);
1815
      }
1816
    }
1817
  }
1818

  
1819
  if (@double_lists) {
1820
    die t8("There is already a variant with the property values: #1.", join("; ", @double_lists));
1821
  }
1822
}
1751 1823

  
1752 1824
sub normalize_text_blocks {
1753 1825
  my ($self) = @_;
SL/DB/Part.pm
3 3
use strict;
4 4

  
5 5
use Carp;
6
use List::MoreUtils qw(any uniq);
6
use List::MoreUtils qw(any uniq pairwise);
7 7
use List::Util qw(sum max);
8 8
use Rose::DB::Object::Helpers qw(as_tree);
9 9

  
......
133 133

  
134 134
__PACKAGE__->before_save('_before_save_set_partnumber');
135 135
__PACKAGE__->before_save('_before_save_set_assembly_weight');
136
__PACKAGE__->before_save('_before_check_variant_property_values');
136 137

  
137 138
sub _before_save_set_partnumber {
138 139
  my ($self) = @_;
......
151 152
  return 1;
152 153
}
153 154

  
155
sub _before_check_variant_property_values {
156
  my ($self) = @_;
157
  if ($self->is_variant) {
158
    my @property_value_ids = sort map {$_->id} $self->variant_property_values;
159
    my ($parent_variant) = $self->parent_variant;
160
    my $other_variants = $parent_variant->variants;
161
    foreach my $variant (@$other_variants) {
162
      next if $variant->id == $self->id;
163
      my @other_property_value_ids = sort map {$_->id} $variant->variant_property_values;
164
      if (@other_property_value_ids == @property_value_ids
165
        && not any {$_} pairwise {$a != $b} @other_property_value_ids, @property_value_ids
166
      ) {
167
        die t8("There is already a variant with the property values: "),
168
          join(' ,', map {$_->displayable_name} $self->variant_property_values);
169
      }
170
    }
171
  }
172
  return 1;
173
}
174

  
154 175
sub items {
155 176
  my ($self) = @_;
156 177

  
......
513 534
    die "Given variant_property_values dosn't match the variant_properties of parent_variant part";
514 535
  }
515 536

  
516
  my $separator = '.'; # TODO: make configurable
537
  my $new_variant = $self->clone_and_reset;
538
  $new_variant->partnumber($self->_next_variant_partnumber);
539
  $new_variant->variant_type('variant');
540
  $new_variant->add_assemblies(map {$_->clone_and_reset} $self->assemblies) if ($self->is_assembly);
541
  $new_variant->add_variant_property_values(@$variant_property_values);
542
  $new_variant->parent_variant($self);
543
  $new_variant->save;
544

  
545
  $self->add_variants($new_variant);
546
  return $new_variant;
547
}
517 548

  
549
sub _next_variant_partnumber {
550
  my ($self) = @_;
551
  die "only callable on parts of type parent_variant" unless $self->is_parent_variant;
552

  
553
  my $separator = '.'; # TODO: make configurable
518 554
  my $last_variant_number =
519 555
    max
520 556
    map {
......
524 560
    }
525 561
    $self->variants;
526 562

  
527
  my $new_variant = $self->clone_and_reset;
528
  $new_variant->partnumber($self->partnumber . $separator . ($last_variant_number + 1));
529
  $new_variant->variant_type('variant');
530
  $new_variant->add_assemblies(map {$_->clone_and_reset} $self->assemblies) if ($self->is_assembly);
531
  $new_variant->add_variant_property_values(@$variant_property_values);
532

  
533
  $self->add_variants($new_variant);
534
  $self->save;
535
  return $new_variant;
563
  return $self->partnumber . $separator . ($last_variant_number + 1);
536 564
}
537 565

  
538 566
sub clone_and_reset_deep {
SL/Presenter/Part.pm
294 294
for autocompletion. You may comma separate multiple types as in
295 295
C<part,assembly>.
296 296

  
297
If C<%params> contains C<variant_type> only parts of this variant type will be
298
used for autocompletion. You may comma separate multiple variant types as in
299
C<single,variant>.
300

  
297 301
If C<%params> contains C<status> only parts of this status will be used
298 302
for autocompletion. C<status> can be one of the following strings:
299 303
C<active>, C<obsolete> or C<all>. C<active> is the default if C<status> is
js/kivi.Part.js
337 337
    $.post("controller.pl", data, kivi.eval_json_result);
338 338
  };
339 339

  
340
  ns.convert_part_to_variant = function() {
341
    var data = $('#ic').serializeArray();
342
    data.push({ name: 'action', value: 'Part/convert_part_to_variant' });
343
    $.post("controller.pl", data, kivi.eval_json_result);
344
  };
345

  
340 346
  ns.update_variant_property_value_options = function() {
341 347
    var data = $('#ic').serializeArray();
342 348
    data.push({ name: 'action', value: 'Part/update_variant_property_value_options' });
......
403 409
      if (this.o.part_type)
404 410
        data['filter.part_type'] = this.o.part_type.split(',');
405 411

  
412
      if (this.o.variant_type)
413
        data['filter.variant_type'] = this.o.variant_type.split(',');
414

  
406 415
      if (this.o.status) {
407 416
        if (this.o.status == 'active')   data['filter.obsolete'] = 0;
408 417
        if (this.o.status == 'obsolete') data['filter.obsolete'] = 1;
templates/design40_webpages/part/_parent_variant.html
53 53
    <div class="wrapper">
54 54
    [% FOREACH variant_property = SELF.part.variant_properties %]
55 55
      <div class="col input-panel" style="min-width:fit-content;">
56
        <h4>[% variant_property.name_translated | html %]</h4>
57
        [% L.select_tag("variant_properties." _ variant_property.id _ ".selected_property_values[]",
56
        <h4>[% variant_property.displayable_name | html %]</h4>
57
        [% L.select_tag("variant_properties." _ variant_property.id _ ".selected_property_value_ids[]",
58 58
          variant_property.property_values,
59 59
          title_key='displayable_name', value_key='id',
60
          id="selected_property_values_" _ variant_property.id,
60
          id="selected_property_value_ids_" _ variant_property.id,
61 61
          multiple=1,
62 62
        ) %]
63 63
        [% L.multiselect2side(
64
          "selected_property_values_" _ variant_property.id,
64
          "selected_property_value_ids_" _ variant_property.id,
65 65
          labelsx=LxERP.t8("All Property Values"),
66 66
          labeldx=LxERP.t8("Selected Property Values")
67 67
        ) %]
......
70 70
    </div>
71 71
    [% L.button_tag('kivi.Part.create_variants();', LxERP.t8("Create Variants with selected Values")) %]
72 72
  </div>
73

  
74
  <div class="wrapper input-panel">
75
    <h3> [% LxERP.t8("Convert part to Variant") %] </h3>
76
    <table class="tbl-list">
77
      <caption>
78
        [% 'Variant Properties' | $T8 %]
79
      </caption>
80
      <thead>
81
        <tr>
82
          <th>[% 'Name' | $T8 %]</th>
83
          <th>[% 'Value' | $T8 %]</th>
84
        </tr>
85
      </thead>
86
      <tbody>
87
        [% FOREACH variant_property = SELF.part.variant_properties %]
88
        <tr>
89
          <td>[% variant_property.displayable_name | html %]</td>
90
          <td>
91
          [% L.select_tag("convert_part.variant_properties." _ variant_property.id _ ".selected_property_value_id",
92
            variant_property.property_values,
93
            title_key='displayable_name', value_key='id',
94
            size=variant_property.property_values.size,
95
          ) %]
96
        </tr>
97
        [% END %]
98
      </tbody>
99
    </table>
100
    <label for="convert_part.id">[% 'Part to convert:' | $T8 %]</label>
101
    [% P.part.picker('convert_part.id', undef,
102
      part_type=SELF.part.part_type, variant_type='single',
103
      placeholder=(LxERP.t8('Type:') _ ' ' _ LxERP.t8(SELF.part.part_type)),
104
      class="wi-wide"
105
    ) %]
106
    <br>
107
    <br>
108
    [% L.button_tag('kivi.Part.convert_part_to_variant();', LxERP.t8("Convert")) %]
109
  </div>
73 110
</div>
74 111

  
75 112

  

Auch abrufbar als: Unified diff