Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 1861cb74

Von Tamino Steinert vor 6 Tagen hinzugefügt

  • ID 1861cb749f71d74f0fb4f041f7c714362c37224a
  • Vorgänger 4d65e27a
  • Nachfolger daa95513

Varianten: alle Artikeltypen ermöglichen

Unterschiede anzeigen:

SL/Controller/Part.pm
94 94
  my ($self, %params) = @_;
95 95

  
96 96
  $self->part( SL::DB::Part->new_parent_variant );
97
  $self->part->part_type($::form->{part_type});
97 98
  $self->add;
98 99
}
99 100

  
......
118 119
  $self->action_add_service        if $::form->{part_type} eq 'service';
119 120
  $self->action_add_assembly       if $::form->{part_type} eq 'assembly';
120 121
  $self->action_add_assortment     if $::form->{part_type} eq 'assortment';
121
  $self->action_add_parent_variant if $::form->{part_type} eq 'parent_variant';
122
  $self->action_add_variant        if $::form->{part_type} eq 'variant';
123 122
};
124 123

  
125 124
sub action_save {
......
338 337
      for @variant_property_values_lists;
339 338
    1;
340 339
  }) or do {
341
    return $self->js->error(t8('Error while creating variants: ' . @_))->render();
340
    die t8('Error while creating variants: '), $@;
342 341
  };
343 342

  
344 343
  $self->redirect_to(
......
454 453
                     assembly       => t8('Edit Assembly'),
455 454
                     service        => t8('Edit Service'),
456 455
                     assortment     => t8('Edit Assortment'),
457
                     parent_variant => t8('Edit Parent Variant'),
458
                     variant        => t8('Edit Variant'),
459 456
                   );
457
  my $title = $title_hash{$self->part->part_type};
458
  $title .=
459
    ' (' . SL::Presenter::Part::variant_type_abbreviation($self->part->variant_type) . ')'
460
    if $self->part->variant_type;
460 461

  
461 462
  $self->part->prices([])       unless $self->part->prices;
462 463
  $self->part->translations([]) unless $self->part->translations;
463 464

  
464 465
  $self->render(
465 466
    'part/form',
466
    title             => $title_hash{$self->part->part_type},
467
    title             => $title,
467 468
    %assortment_vars,
468 469
    %assembly_vars,
469 470
    %parent_variant_vars,
......
1123 1124
                     assembly       => t8('Add Assembly'),
1124 1125
                     service        => t8('Add Service'),
1125 1126
                     assortment     => t8('Add Assortment'),
1126
                     parent_variant => t8('Add Parent Variant'),
1127
                     variant        => t8('Add Variant'),
1128 1127
                   );
1128
  my $title = $title_hash{$self->part->part_type};
1129
  $title .=
1130
    ' (' . SL::Presenter::Part::variant_type_abbreviation($self->part->variant_type) . ')'
1131
    if $self->part->variant_type;
1129 1132

  
1130 1133
  $self->render(
1131 1134
    'part/form',
1132
    title => $title_hash{$self->part->part_type},
1135
    title => $title,
1133 1136
  );
1134 1137
}
1135 1138

  
......
1776 1779
}
1777 1780

  
1778 1781
sub check_has_valid_part_type {
1779
  die "invalid part_type" unless $_[0] =~ /^(part|service|assembly|assortment|parent_variant|variant)$/;
1782
  Carp::confess "invalid part_type" unless $_[0] =~ /^(part|service|assembly|assortment)$/;
1780 1783
}
1781 1784

  
1782 1785

  
SL/DB/Helper/TransNumberGenerator.pm
47 47
              service                     => { number_column => 'partnumber',     number_range_column => 'servicenumber',                              },
48 48
              assembly                    => { number_column => 'partnumber',     number_range_column => 'assemblynumber',                             },
49 49
              assortment                  => { number_column => 'partnumber',     number_range_column => 'assortmentnumber',                           },
50
              parent_variant              => { number_column => 'partnumber',     number_range_column => 'parent_variant_number',                      },
51
              variant                     => { number_column => 'partnumber',     number_range_column => 'variant_number',                             },
52 50
            );
53 51

  
54 52
sub get_next_trans_number {
SL/DB/MetaSetup/Default.pm
147 147
  order_warn_no_cusordnumber                => { type => 'boolean', default => 'false' },
148 148
  order_warn_no_deliverydate                => { type => 'boolean', default => 'true' },
149 149
  p_reclamation_record_number               => { type => 'text', default => '0', not_null => 1 },
150
  parent_variant_number                     => { type => 'text' },
151 150
  parts_image_css                           => { type => 'text', default => 'border:0;float:left;max-width:250px;margin-top:20px:margin-right:10px;margin-left:10px;' },
152 151
  parts_listing_image                       => { type => 'boolean', default => 'true' },
153 152
  parts_show_image                          => { type => 'boolean', default => 'true' },
......
231 230
  transit_items_chart_id                    => { type => 'integer' },
232 231
  transport_cost_reminder_article_number_id => { type => 'integer' },
233 232
  undo_transfer_interval                    => { type => 'integer', default => 7 },
234
  variant_number                            => { type => 'text' },
235 233
  vc_greetings_use_textfield                => { type => 'boolean' },
236 234
  vendor_ustid_taxnummer_unique             => { type => 'boolean', default => 'false' },
237 235
  vendornumber                              => { type => 'text' },
SL/DB/MetaSetup/Part.pm
33 33
  onhand             => { type => 'numeric', default => '0', precision => 25, scale => 5 },
34 34
  order_locked       => { type => 'boolean', default => 'false' },
35 35
  order_qty          => { type => 'numeric', default => '0', not_null => 1, precision => 15, scale => 5 },
36
  part_type          => { type => 'enum', check_in => [ 'part', 'service', 'assembly', 'assortment', 'parent_variant', 'variant' ], db_type => 'part_type_enum', not_null => 1 },
36
  part_type          => { type => 'enum', check_in => [ 'part', 'service', 'assembly', 'assortment' ], db_type => 'part_type_enum', not_null => 1 },
37 37
  partnumber         => { type => 'text', not_null => 1 },
38 38
  partsgroup_id      => { type => 'integer' },
39 39
  payment_id         => { type => 'integer' },
......
45 45
  stockable          => { type => 'boolean', default => 'false' },
46 46
  tariff_code        => { type => 'text' },
47 47
  unit               => { type => 'varchar', length => 20, not_null => 1 },
48
  variant_type       => { type => 'enum', check_in => [ 'single', 'parent_variant', 'variant' ], db_type => 'part_variant_type', default => 'single', not_null => 1 },
48 49
  ve                 => { type => 'integer' },
49 50
  warehouse_id       => { type => 'integer' },
50 51
  weight             => { type => 'float', precision => 4, scale => 4 },
SL/DB/MetaSetup/VariantPropertyValue.pm
13 13
  id                  => { type => 'serial', not_null => 1 },
14 14
  itime               => { type => 'timestamp', default => 'now()' },
15 15
  mtime               => { type => 'timestamp' },
16
  sortkey             => { type => 'integer', not_null => 1 },
16
  sortkey             => { type => 'integer' },
17 17
  value               => { type => 'text', not_null => 1 },
18 18
  variant_property_id => { type => 'integer', not_null => 1 },
19 19
);
SL/DB/Part.pm
4 4

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

  
10 10
use SL::Locale::String qw(t8);
......
215 215
sub is_assembly       { $_[0]->part_type eq 'assembly'   }
216 216
sub is_service        { $_[0]->part_type eq 'service'    }
217 217
sub is_assortment     { $_[0]->part_type eq 'assortment' }
218
sub is_parent_variant { $_[0]->part_type eq 'parent_variant' }
219
sub is_variant        { $_[0]->part_type eq 'variant' }
218

  
219
sub is_parent_variant { $_[0]->variant_type eq 'parent_variant' }
220
sub is_variant        { $_[0]->variant_type eq 'variant' }
220 221

  
221 222
sub type { return $_[0]->part_type; }
222 223

  
......
242 243

  
243 244
sub new_parent_variant {
244 245
  my ($class, %params) = @_;
245
  $class->new(%params, part_type => 'parent_variant');
246
  $class->new(%params, variant_type => 'parent_variant');
246 247
}
247 248

  
248 249
sub last_modification {
......
513 514
    die "Given variant_property_values dosn't match the variant_properties of parent_variant part";
514 515
  }
515 516

  
517
  my $separator = '.'; # TODO: make configurable
518

  
519
  my $last_variant_number =
520
    max
521
    map {
522
      my $partnumber = $_->partnumber;
523
      $partnumber =~ s/.*\Q$separator\E([0-9]*)/$1/; # escape chars between \Q \E
524
      $partnumber;
525
    }
526
    $self->variants;
527

  
516 528
  my $new_variant = $self->clone_and_reset;
517
  # TODO set partnumber
518
  $new_variant->part_type('variant');
519
  $new_variant->save;
520
  SL::DB::VariantPropertyValuePart->new(
521
    part_id                   => $new_variant->id,
522
    variant_property_value_id => $_->id,
523
  )->save for @$variant_property_values;
524
  SL::DB::PartParentVariantPartVariant->new(
525
    variant_id        => $new_variant->id,
526
    parent_variant_id => $self->id,
527
  )->save;
529
  $new_variant->partnumber($self->partnumber . $separator . ($last_variant_number + 1));
530
  $new_variant->variant_type('variant');
531
  $new_variant->add_assemblies(map {$_->clone_and_reset} $self->assemblies) if ($self->is_assembly);
532
  $new_variant->add_variant_property_values(@$variant_property_values);
528 533

  
534
  $self->add_variants($new_variant);
535
  $self->save;
529 536
  return $new_variant;
530 537
}
531 538

  
......
645 652

  
646 653
sub variant_value {
647 654
  my ($self, $variant_property) = @_;
655
  die "only callable on parts of type parent_variant"     unless $self->is_variant;
656
  die "only callable with SL::DB::VariantProperty object" unless ref $variant_property eq 'SL::DB::VariantProperty';
648 657

  
649 658
  my %property_id_to_values =
650 659
    map {$_->variant_property_id => $_}
SL/IC.pm
319 319
    $form->{l_assembly}       = 1 if $form->{searchitems} eq 'assembly'       || $form->{searchitems} eq '';
320 320
    $form->{l_part}           = 1 if $form->{searchitems} eq 'part'           || $form->{searchitems} eq '';
321 321
    $form->{l_assortment}     = 1 if $form->{searchitems} eq 'assortment'     || $form->{searchitems} eq '';
322
    $form->{l_parent_variant} = 1 if $form->{searchitems} eq 'parent_variant' || $form->{searchitems} eq '';
323
    $form->{l_variant}        = 1 if $form->{searchitems} eq 'variant'        || $form->{searchitems} eq '';
324 322
    push @where_tokens, "p.partnumber ILIKE ? OR p.description ILIKE ?";
325 323
    push @bind_vars,    (like($form->{all})) x 2;
326 324
  }
......
372 370
  # Oder Bedingungen fuer Ware Dienstleistung Erzeugnis:
373 371
  if (   $form->{l_part}           || $form->{l_assembly}
374 372
      || $form->{l_service}        || $form->{l_assortment}
375
      || $form->{l_parent_variant} || $form->{l_variant}
376 373
    ) {
377 374
    my @or_tokens = ();
378 375
    push @or_tokens, "p.part_type = 'service'"        if $form->{l_service};
379 376
    push @or_tokens, "p.part_type = 'assembly'"       if $form->{l_assembly};
380 377
    push @or_tokens, "p.part_type = 'part'"           if $form->{l_part};
381 378
    push @or_tokens, "p.part_type = 'assortment'"     if $form->{l_assortment};
382
    push @or_tokens, "p.part_type = 'parent_variant'" if $form->{l_parent_variant};
383
    push @or_tokens, "p.part_type = 'variant'"        if $form->{l_variant};
384 379
    push @where_tokens, join ' OR ', map { "($_)" } @or_tokens;
385 380
  }
386 381
  else {
SL/Presenter/Part.pm
76 76
    assembly       => t8('Assembly (typeabbreviation)'),
77 77
    assortment     => t8('Assortment (typeabbreviation)'),
78 78
    service        => t8('Service (typeabbreviation)'),
79
  );
80

  
81
  return $part_type_abbr{$part_type} || '';
82
}
83

  
84
sub variant_type_abbreviation {
85
  my ($variant_type) = @_;
86

  
87
  my %variant_type_abbr = (
79 88
    parent_variant => t8('Parent Variant (typeabbreviation)'),
80 89
    variant        => t8('Variant (typeabbreviation)'),
81 90
  );
82 91

  
83
  return $part_type_abbr{$part_type} || '';
92
  return $variant_type_abbr{$variant_type} || '';
84 93
}
85 94

  
86 95
#
SL/TransNumber.pm
92 92
    $filters{table}         = "oe";
93 93
    $filters{where}         = 'COALESCE(quotation, FALSE) AND (vendor_id IS NOT NULL)';
94 94

  
95
  } elsif ($type =~ /^(part|service|assembly|assortment|parent_variant|variant)$/) {
95
  } elsif ($type =~ /^(part|service|assembly|assortment)$/) {
96 96
    $filters{trans_number}  = "partnumber";
97 97
    my %numberfield_hash = ( service        => 'servicenumber',
98 98
                             assembly       => 'assemblynumber',
99 99
                             assortment     => 'assortmentnumber',
100
                             parent_variant => 'parent_variant_number',
101
                             variant        => 'variant_number',
102 100
                             part           => 'articlenumber'
103 101
                           );
104 102
    $filters{numberfield}   = $numberfield_hash{$type};
menus/user/00-erp.yaml
84 84
  name: Add Parent Variant
85 85
  order: 575
86 86
  access: part_service_assembly_edit
87
- parent: master_data_add_parent_variant
88
  id: master_data_add_parent_variant_part
89
  name: Add Parent Variant Part
90
  order: 100
91
  params:
92
    action: Part/add_parent_variant
93
    part_type: part
94
- parent: master_data_add_parent_variant
95
  id: master_data_add_parent_variant_service
96
  name: Add Parent Variant Service
97
  order: 200
98
  params:
99
    action: Part/add_parent_variant
100
    part_type: service
101
- parent: master_data_add_parent_variant
102
  id: master_data_add_parent_variant_assembly
103
  name: Add Parent Variant Assembly
104
  order: 300
87 105
  params:
88 106
    action: Part/add_parent_variant
107
    part_type: assembly
89 108
- parent: master_data
90 109
  id: master_data_add_project
91 110
  name: Add Project
sql/Pg-upgrade2/add_variants.sql
3 3
-- @depends: release_3_8_0
4 4
-- @ignore: 0
5 5

  
6
ALTER TYPE part_type_enum ADD VALUE 'parent_variant';
7
ALTER TYPE part_type_enum ADD VALUE 'variant';
8

  
9
ALTER TABLE defaults ADD parent_variant_number TEXT;
10
ALTER TABLE defaults ADD variant_number TEXT;
6
CREATE TYPE part_variant_type AS ENUM ('single', 'parent_variant', 'variant');
7
ALTER TABLE parts ADD COLUMN variant_type part_variant_type DEFAULT 'single' NOT NULL;
11 8

  
12 9
CREATE TABLE parts_parent_variant_id_parts_variant_id (
13 10
  parent_variant_id INTEGER NOT NULL        REFERENCES parts(id),
......
20 17
  name         TEXT       NOT NULL,
21 18
  unique_name  TEXT       NOT NULL UNIQUE,
22 19
  abbreviation VARCHAR(4) NOT NULL,
20
  sortkey      INTEGER,
23 21
  itime        TIMESTAMP DEFAULT now(),
24 22
  mtime        TIMESTAMP
25 23
);
......
50 48
  variant_property_id INTEGER NOT NULL REFERENCES variant_properties(id),
51 49
  value               TEXT    NOT NULL,
52 50
  abbreviation        VARCHAR(4) NOT NULL,
53
  sortkey             INTEGER NOT NULL,
51
  sortkey             INTEGER,
54 52
  itime               TIMESTAMP DEFAULT now(),
55 53
  mtime               TIMESTAMP
56 54
);
sql/Pg-upgrade2/variant_properties_add_column_sortkey.sql
1
-- @tag: variants_add_column_sortkey
2
-- @description: Sortierung für Varianteneigenschaften
3
-- @depends: add_variants
4
-- @ignore: 0
5

  
6
ALTER TABLE variant_properties ADD COLUMN sortkey INTEGER;
sql/Pg-upgrade2/variant_property_values_alter_column_sortkey.sql
1
-- @tag: variant_values_alter_column_sortkey
2
-- @description: sortkey für Varianteneigenschaftswert darf NULL sein
3
-- @depends: add_variants
4
-- @ignore: 0
5

  
6
ALTER TABLE variant_property_values ALTER COLUMN sortkey DROP NOT NULL;
templates/design40_webpages/client_config/_ranges_of_numbers.html
104 104
      <td>[% L.input_tag("defaults.assortmentnumber", SELF.defaults.assortmentnumber, size="15", class="wi-normal") %]</td>
105 105
      [% END %]
106 106
    </tr>
107
    <tr>
108
      <th>[% LxERP.t8('Parent Variant') %]</th>
109
      <td>[% L.input_tag("defaults.parent_variant_number", SELF.defaults.parent_variant_number, size="15", class="wi-normal") %]</td>
110
    </tr>
111
    <tr>
112
      <th>[% LxERP.t8('Variant') %]</th>
113
      <td>[% L.input_tag("defaults.variant_number", SELF.defaults.variant_number, size="15", class="wi-normal") %]</td>
114
    </tr>
115 107
  </tbody>
116 108
</table>
117 109

  
templates/design40_webpages/ic/search.html
36 36
            <input name="l_assortment" id="l_assortment" type="checkbox" value="Y" checked>
37 37
            <label for="l_assortment"> [% 'Assortment' | $T8 %] </label>
38 38
          [% END %]
39
          <input name="l_parent_variant" id="l_parent_variant" type="checkbox" value="Y" checked>
40
          <label for="l_parent_variant"> [% 'Parent Variant' | $T8 %] </label>
41
          <input name="l_variant" id="l_variant" type="checkbox" value="Y" checked>
42
          <label for="l_variant"> [% 'Variant' | $T8 %] </label>
43 39
        </td>
44 40
      </tr>
45 41
      <tr>
templates/design40_webpages/part/form.html
10 10

  
11 11
[% INCLUDE 'common/flash.html' %]
12 12

  
13
[% L.hidden_tag('part.part_type'   , SELF.part.part_type) %]
14 13
[% L.hidden_tag('part.id'          , SELF.part.id) %]
14
[% L.hidden_tag('part.part_type'   , SELF.part.part_type) %]
15
[% L.hidden_tag('part.variant_type', SELF.part.variant_type) %]
15 16
[% L.hidden_tag('last_modification', SELF.part.last_modification) %]
16 17
[% L.hidden_tag('callback'         , FORM.callback) %]
17 18

  
templates/webpages/client_config/_ranges_of_numbers.html
72 72
  <tr>
73 73
   <td align="right" nowrap>[% LxERP.t8('Last Purchase Delivery Order Number') %]</td>
74 74
   <td>[% L.input_tag("defaults.pdonumber", SELF.defaults.pdonumber, size="15") %]</td>
75
   <td align="right" nowrap>[% LxERP.t8('Last Parent Variant Number') %]</td>
76
   <td>[% L.input_tag("defaults.parent_variant_number", SELF.defaults.parent_variant_number, size="15") %]</td>
77 75
  </tr>
78 76

  
79 77
  <tr>
80 78
   <td align="right" nowrap>[% LxERP.t8('Last Supplier Delivery Order Number') %]</td>
81 79
   <td>[% L.input_tag("defaults.sudonumber", SELF.defaults.sudonumber, size="15") %]</td>
82
   <td align="right" nowrap>[% LxERP.t8('Last Variant Number') %]</td>
83
   <td>[% L.input_tag("defaults.variant_number", SELF.defaults.variant_number, size="15") %]</td>
84 80
  </tr>
85 81

  
86 82
  <tr>
templates/webpages/part/form.html
9 9

  
10 10
 <form method="post" id="ic" name="ic" action="controller.pl">
11 11

  
12
  [% L.hidden_tag('part.part_type'   , SELF.part.part_type) %]
13 12
  [% L.hidden_tag('part.id'          , SELF.part.id) %]
13
  [% L.hidden_tag('part.part_type'   , SELF.part.part_type) %]
14
  [% L.hidden_tag('part.variant_type', SELF.part.variant_type) %]
14 15
  [% L.hidden_tag('last_modification', SELF.part.last_modification) %]
15 16
  [% L.hidden_tag('callback'         , FORM.callback) %]
16 17

  

Auch abrufbar als: Unified diff