Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision eebe8e90

Von Sven Schöling vor etwa 10 Jahren hinzugefügt

  • ID eebe8e90991eacadb6fbd20a648c152017a620c7
  • Vorgänger c21d2acc
  • Nachfolger 0409db7c

PriceSource: Erste Version

- Preisgruppen und Stammdaten sind implementiert
- Persistenz in allen Belegen funktioniert
- Rudimentäre Visualisierung funktioniert
- Klassen sind alle da

- Doku fehlt
- Verkauf/Einkaufweiche fehlt
- best_price ungetestet
- Preisgruppen hängen noch nicht von Verkäufer ab
- dependancy system fehlt
- verhalten bei fehlerhaften sources
- pricegroup -> active_source migration

Unterschiede anzeigen:

bin/mozilla/io.pl
38 38

  
39 39
use Carp;
40 40
use CGI;
41
use List::MoreUtils qw(any uniq);
41
use List::MoreUtils qw(any uniq apply);
42 42
use List::Util qw(min max first);
43 43

  
44 44
use SL::CVar;
......
46 46
use SL::CT;
47 47
use SL::IC;
48 48
use SL::IO;
49
use SL::PriceSource;
49 50

  
50 51
use SL::DB::Customer;
51 52
use SL::DB::Default;
......
149 150
  }
150 151

  
151 152
  # column_index
152
  my @header_sort = qw(runningnumber partnumber description ship qty unit weight sellprice_pg sellprice discount linetotal);
153
  my @header_sort = qw(runningnumber partnumber description ship qty unit weight sellprice discount linetotal);
153 154
  my @HEADER = (
154 155
    {  id => 'runningnumber', width => 5,     value => $locale->text('No.'),                  display => 1, },
155 156
    {  id => 'partnumber',    width => 8,     value => $locale->text('Number'),               display => 1, },
......
162 163
    {  id => 'serialnr',      width => 10,    value => $locale->text('Serial No.'),           display => 0, },
163 164
    {  id => 'projectnr',     width => 10,    value => $locale->text('Project'),              display => 0, },
164 165
    {  id => 'sellprice',     width => 15,    value => $locale->text('Price'),                display => !$is_delivery_order, },
165
    {  id => 'sellprice_pg',  width => 8,     value => $locale->text('Pricegroup'),           display => !$is_delivery_order && !$is_purchase, },
166
    {  id => 'price_source',  width => 5,     value => $locale->text('Price Source'),         display => !$is_delivery_order, },
166 167
    {  id => 'discount',      width => 5,     value => $locale->text('Discount'),             display => !$is_delivery_order, },
167 168
    {  id => 'linetotal',     width => 10,    value => $locale->text('Extended'),             display => !$is_delivery_order, },
168 169
    {  id => 'bin',           width => 10,    value => $locale->text('Bin'),                  display => 0, },
......
196 197
  my $deliverydate  = $locale->text('Required by');
197 198

  
198 199
  # special alignings
199
  my %align  = map { $_ => 'right' } qw(qty ship right sellprice_pg discount linetotal stock_in_out weight);
200
  my %align  = map { $_ => 'right' } qw(qty ship right discount linetotal stock_in_out weight);
200 201
  my %nowrap = map { $_ => 1 }       qw(description unit);
201 202

  
202 203
  $form->{marge_total}           = 0;
......
232 233
      $form->{"sellprice_$i"} = $form->{"price_new_$i"};
233 234
    }
234 235

  
236
    my $record_item = _make_record_item($i);
237

  
235 238
# unit begin
236 239
    $form->{"unit_old_$i"}      ||= $form->{"unit_$i"};
237 240
    $form->{"selected_unit_$i"} ||= $form->{"unit_$i"};
......
240 243
        || !AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units)) { # (z.B. Dimensionseinheit war ausgewaehlt, es handelt sich aber
241 244
      $form->{"unit_old_$i"} = $form->{"selected_unit_$i"} = $form->{"unit_$i"};                 # um eine Dienstleistung). Dann keinerlei Umrechnung vornehmen.
242 245
    }
243
    # adjust prices by unit, ignore if pricegroup changed
244
    if ((!$form->{"prices_$i"}) || ($form->{"new_pricegroup_$i"} == $form->{"old_pricegroup_$i"})) {
245
        $form->{"sellprice_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1;
246
        $form->{"lastcost_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1;
247
        $form->{"unit_old_$i"}   = $form->{"selected_unit_$i"};
248
    }
246

  
247
    $form->{"sellprice_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1;
248
    $form->{"lastcost_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1;
249
    $form->{"unit_old_$i"}   = $form->{"selected_unit_$i"};
250

  
249 251
    my $this_unit = $form->{"unit_$i"};
250 252
    $this_unit    = $form->{"selected_unit_$i"} if AM->convert_unit($this_unit, $form->{"selected_unit_$i"}, $all_units);
251 253

  
......
305 307
      $column_data{ship}  = $form->format_amount(\%myconfig, $form->round_amount($ship_qty, 2) * 1) . ' ' . $form->{"unit_$i"};
306 308
    }
307 309

  
308
    # build in drop down list for pricesgroups
309
    # $sellprice_value setzt den Wert etwas unabhängiger von der Darstellung.
310
    # Hintergrund: Preisgruppen werden hier überprüft und neu berechnet.
311
    # Vorher wurde der ganze cgi->textfield Block zweimal identisch eingebaut, dass passiert
312
    # jetzt nach der Abfrage.
313
    my $sellprice_value;
314
    if ($form->{"prices_$i"}) {
315
      $column_data{sellprice_pg} = qq|<select name="sellprice_pg_$i" style="width: 8em">$form->{"prices_$i"}</select>|;
316
      $sellprice_value           =($form->{"new_pricegroup_$i"} != $form->{"old_pricegroup_$i"})
317
                                      ? $form->format_amount(\%myconfig, $form->{"price_new_$i"}, $decimalplaces)
318
                                      : $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
319
    } else {
320
      # for last row and report
321
      # set pricegroup drop down list from report menu
322
      if ($form->{"sellprice_$i"} != 0) {
323
        # remember the pricegroup_id in pricegroup_old
324
        # but don't overwrite it
325
        $form->{"pricegroup_old_$i"} = $form->{"pricegroup_id_$i"};
326
        my $default_option           = $form->{"sellprice_$i"}.'--'.$form->{"pricegroup_id_$i"};
327
        $column_data{sellprice_pg}   = NTI($cgi->popup_menu("sellprice_pg_$i", [ $default_option ], $default_option, { $default_option => $form->{"pricegroup_$i"} || '' }));
328
      } else {
329
        $column_data{sellprice_pg} = qq|&nbsp;|;
330
      }
331
      $sellprice_value = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
332

  
333
    }
334
    # Falls der Benutzer die Preise nicht anpassen sollte, wird das entsprechende
335
    # Textfield auf readonly gesetzt. Anm. von Sven: Manipulation der Preise ist
336
    # immer noch möglich, konsequenterweise sollten diese NUR aus der Datenbank
337
    # geholt werden.
338
    my $edit_prices = $main::auth->assert('edit_prices', 1);
339
    $column_data{sellprice} = (!$edit_prices)
340
                                ? $cgi->textfield(-readonly => "readonly",
341
                                                  -name => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value)
342
                                : $cgi->textfield(-name => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value);
310
    my $sellprice_value = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
311
    my $edit_prices     = $main::auth->assert('edit_prices', 1) && !$::form->{"active_price_source_$i"};
312
    $column_data{sellprice}   = (!$edit_prices)
313
                                ? $cgi->hidden(   -name => "sellprice_$i", -id => "sellprice_$i", -value => $sellprice_value) . $sellprice_value
314
                                : $cgi->textfield(-name => "sellprice_$i", -id => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value);
343 315
    $column_data{discount}    = (!$edit_prices)
344 316
                                  ? $cgi->textfield(-readonly => "readonly",
345 317
                                                    -name => "discount_$i", -size => 3, -value => $form->format_amount(\%myconfig, $form->{"discount_$i"}))
......
349 321

  
350 322
    $column_data{weight}      = $form->format_amount(\%myconfig, $form->{"qty_$i"} * $form->{"weight_$i"}, 3) . ' ' . $defaults->{weightunit} if $defaults->{show_weight};
351 323

  
324
    if ($form->{"id_${i}"}) {
325
      my $price_source = SL::PriceSource->new(record_item => $record_item);
326
      my $price = $price_source->price_from_source($::form->{"active_price_source_$i"});
327
      $::form->{price_sources}[$i] = $price_source;
328
      $column_data{price_source} .= $cgi->button(-value => $price->full_description, -onClick => "toggle_price_source($i)");
329
    }
330

  
352 331
    if ($is_delivery_order) {
353 332
      $column_data{stock_in_out} =  calculate_stock_in_out($i);
354 333
    }
......
433 412

  
434 413
    if ($is_delivery_order) {
435 414
      map { $form->{"${_}_${i}"} = $form->format_amount(\%myconfig, $form->{"${_}_${i}"}) } qw(sellprice discount lastcost);
436
      $form->{"pricegroup_id_$i"} = $form->{"pricegroup_old_$i"} if $form->{"pricegroup_old_$i"};
437
      $form->{"sellprice_pg_$i"}  = $form->{"hidden_prices_$i"}  if $form->{"hidden_prices_$i"};
438
      push @hidden_vars, grep { defined $form->{"${_}_${i}"} } qw(sellprice discount not_discountable price_factor_id lastcost pricegroup_id sellprice_pg);
415
      push @hidden_vars, grep { defined $form->{"${_}_${i}"} } qw(sellprice discount not_discountable price_factor_id lastcost);
439 416
      push @hidden_vars, "stock_${stock_in_out}_sum_qty", "stock_${stock_in_out}";
440 417
    }
441 418

  
......
443 420
          $cgi->hidden("-name" => "unit_old_$i", "-value" => $form->{"selected_unit_$i"}),
444 421
          $cgi->hidden("-name" => "price_new_$i", "-value" => $form->format_amount(\%myconfig, $form->{"price_new_$i"})),
445 422
          map { ($cgi->hidden("-name" => $_, "-id" => $_, "-value" => $form->{$_})); } map { $_."_$i" }
446
            (qw(orderitems_id bo pricegroup_old price_old id inventory_accno bin partsgroup partnotes
423
            (qw(orderitems_id bo price_old id inventory_accno bin partsgroup partnotes active_price_source
447 424
                income_accno expense_accno listprice assembly taxaccounts ordnumber donumber transdate cusordnumber
448 425
                longdescription basefactor marge_absolut marge_percent marge_price_factor weight), @hidden_vars)
449 426
    );
......
455 432
    # Benutzerdefinierte Variablen für Waren/Dienstleistungen/Erzeugnisse
456 433
    _render_custom_variables_inputs(ROW2 => \@ROW2, row => $i, part_id => $form->{"id_$i"});
457 434

  
458
    push @ROWS, { ROW1 => \@ROW1, ROW2 => \@ROW2, HIDDENS => \@HIDDENS, colspan => $colspan, error => $form->{"row_error_$i"}, };
435
    push @ROWS, { ROW1 => \@ROW1, ROW2 => \@ROW2, HIDDENS => \@HIDDENS, colspan => $colspan, error => $form->{"row_error_$i"}, obj => $record_item };
459 436
  }
460 437

  
461 438
  $form->{totalweight} = $totalweight;
......
471 448
  $main::lxdebug->leave_sub();
472 449
}
473 450

  
474
##################################################
475
# build html-code for pricegroups in variable $form->{prices_$j}
476

  
477
sub set_pricegroup {
478
  $main::lxdebug->enter_sub();
479

  
480
  my $form     = $main::form;
481
  my $locale   = $main::locale;
482
  my $cgi      = $::request->{cgi};
483

  
484
  _check_io_auth();
485

  
486
  my $rowcount = shift;
487
  for my $j (1 .. $rowcount) {
488
    next unless $form->{PRICES}{$j};
489
    # build drop down list for pricegroups
490
    my $option_tmpl = qq|<option value="%s--%s" %s>%s</option>|;
491
    $form->{"prices_$j"}  = join '', map { sprintf $option_tmpl, @$_{qw(price pricegroup_id selected pricegroup)} }
492
                                         (+{ pricegroup => $locale->text("none (pricegroup)") }, @{ $form->{PRICES}{$j} });
493

  
494
    foreach my $item (@{ $form->{PRICES}{$j} }) {
495
      # set new selectedpricegroup_id and prices for "Preis"
496
      $form->{"pricegroup_old_$j"} = $item->{pricegroup_id}   if $item->{selected} &&  $item->{pricegroup_id};
497
      $form->{"sellprice_$j"}      = $item->{price}           if $item->{selected} &&  $item->{pricegroup_id};
498
      $form->{"price_new_$j"}      = $form->{"sellprice_$j"}  if $item->{selected} || !$item->{pricegroup_id};
499
    }
500

  
501
    # save hidden pricegroups for delivery_orders
502
    next unless my @selected_prices = grep { $_->{selected} } @{ $form->{PRICES}{$j} };
503
    $form->{"hidden_prices_$j"} = $selected_prices[-1]{price} . "--" . $selected_prices[-1]{pricegroup_id};
504
  }
505
  $main::lxdebug->leave_sub();
506
}
507

  
508 451
sub select_item {
509 452
  $main::lxdebug->enter_sub();
510 453

  
......
633 576
      $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces)
634 577
  } qw(sellprice listprice lastcost) if $form->{item} ne 'assembly';
635 578

  
636
  # get pricegroups for parts
637
  IS->get_pricegroups_for_parts(\%myconfig, \%$form);
638

  
639
  # build up html code for prices_$i
640
  set_pricegroup($form->{rowcount});
641

  
642 579
  &display_form;
643 580

  
644 581
  $main::lxdebug->leave_sub();
......
733 670
      or (($form->{level} eq undef) and ($form->{type} =~ /invoice/))
734 671
      or ($form->{type} =~ /sales_order/)) {
735 672

  
736
    # get pricegroups for parts
737
    IS->get_pricegroups_for_parts(\%myconfig, \%$form);
738

  
739
    # build up html code for prices_$i
740
    set_pricegroup($form->{rowcount});
741

  
742 673
  }
743 674

  
744 675
  &display_form;
......
757 688
                taxaccounts bin assembly weight projectnumber project_id
758 689
                oldprojectnumber runningnumber serialnumber partsgroup payment_id
759 690
                not_discountable shop ve gv buchungsgruppen_id language_values
760
                sellprice_pg pricegroup_old price_old price_new unit_old ordnumber donumber
691
                price_old price_new unit_old ordnumber donumber
761 692
                transdate longdescription basefactor marge_total marge_percent
762 693
                marge_price_factor lastcost price_factor_id partnotes
763 694
                stock_out stock_in has_sernumber reqdate orderitems_id);
......
1714 1645
  # get details for customer/vendor
1715 1646
  call_sub($::form->{vc} . "_details", qw(name department_1 department_2 street zipcode city country contact email phone fax), $::form->{vc} . "number");
1716 1647

  
1717
  # get pricegroups for parts
1718
  IS->get_pricegroups_for_parts(\%::myconfig, \%$::form);
1719

  
1720
  # build up html code for prices_$i
1721
  set_pricegroup($::form->{rowcount});
1722

  
1723 1648
  $::form->{rowcount}--;
1724 1649

  
1725 1650
  my @shipto_vars   = qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry
......
1964 1889
  $::form->redo_rows(\@fields, \@new_rows, scalar(@new_rows), $::form->{rowcount});
1965 1890
  $::form->{rowcount} -= $removed_rows;
1966 1891
}
1892

  
1893
sub _make_record_item {
1894
  my ($row) = @_;
1895

  
1896
  my $class = {
1897
    sales_order             => 'OrderItem',
1898
    purchase_oder           => 'OrderItem',
1899
    sales_quotation         => 'OrderItem',
1900
    request_quotation       => 'OrderItem',
1901
    invoice                 => 'InvoiceItem',
1902
    purchase_invoice        => 'InvoiceItem',
1903
    purchase_delivery_order => 'DeliveryOrderItem',
1904
    sales_delivery_order    => 'DeliveryOrderItem',
1905
  }->{$::form->{type}};
1906

  
1907
  return unless $class;
1908

  
1909
  $class = 'SL::DB::' . $class;
1910

  
1911
  eval "require $class";
1912

  
1913
  my $obj = $::form->{"orderitems_id_$row"}
1914
          ? $class->meta->convention_manager->auto_manager_class_name->find_by(id => $::form->{"orderitems_id_$row"})
1915
          : $class->new;
1916

  
1917
  for my $method (apply { s/_$row$// } grep { /_$row$/ } keys %$::form) {
1918
    next unless $obj->meta->column($method);
1919
    if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) {
1920
      $obj->${\"$method\_as_date"}($::form->{"$method\_$row"});
1921
    } else {
1922
      $obj->$method($::form->{"$method\_$row"});
1923
    }
1924
  }
1925

  
1926
  if ($::form->{"id_$row"}) {
1927
    $obj->part(SL::DB::Part->load_cached($::form->{"id_$row"}));
1928
  }
1929

  
1930
  return $obj;
1931
}

Auch abrufbar als: Unified diff