PriceSource: Erste Version
authorSven Schöling <s.schoeling@linet-services.de>
Fri, 25 Jul 2014 14:38:00 +0000 (16:38 +0200)
committerSven Schöling <s.schoeling@linet-services.de>
Thu, 18 Dec 2014 15:18:21 +0000 (16:18 +0100)
- 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

22 files changed:
SL/DB/Helper/PriceTaxCalculator.pm
SL/DB/MetaSetup/DeliveryOrderItem.pm
SL/DB/MetaSetup/InvoiceItem.pm
SL/DB/MetaSetup/OrderItem.pm
SL/DO.pm
SL/IS.pm
SL/OE.pm
SL/PriceSource.pm [new file with mode: 0644]
SL/PriceSource/ALL.pm [new file with mode: 0644]
SL/PriceSource/Base.pm [new file with mode: 0644]
SL/PriceSource/MasterData.pm [new file with mode: 0644]
SL/PriceSource/Price.pm [new file with mode: 0644]
SL/PriceSource/Pricegroup.pm [new file with mode: 0644]
bin/mozilla/do.pl
bin/mozilla/invoice_io.pl
bin/mozilla/io.pl
bin/mozilla/is.pl
bin/mozilla/oe.pl
locale/de/all
sql/Pg-upgrade2/recorditem_active_price_source.sql [new file with mode: 0644]
templates/webpages/oe/_price_sources_row.html [new file with mode: 0644]
templates/webpages/oe/sales_order.html

index 07ad5b1..fca37f5 100644 (file)
@@ -3,7 +3,7 @@ package SL::DB::Helper::PriceTaxCalculator;
 use strict;
 
 use parent qw(Exporter);
 use strict;
 
 use parent qw(Exporter);
-our @EXPORT = qw(calculate_prices_and_taxes);
+our @EXPORT = qw(calculate_prices_and_taxes _calculate_item);
 
 use Carp;
 use List::Util qw(sum min max);
 
 use Carp;
 use List::Util qw(sum min max);
@@ -75,6 +75,8 @@ sub _calculate_item {
   my ($self, $item, $idx, $data, %params) = @_;
 
   my $part       = SL::DB::Part->load_cached($item->parts_id);
   my ($self, $item, $idx, $data, %params) = @_;
 
   my $part       = SL::DB::Part->load_cached($item->parts_id);
+  return unless $item->part;
+
   my $part_unit  = $data->{units_by_name}->{ $part->unit };
   my $item_unit  = $data->{units_by_name}->{ $item->unit };
 
   my $part_unit  = $data->{units_by_name}->{ $part->unit };
   my $item_unit  = $data->{units_by_name}->{ $item->unit };
 
index 76c890a..d4789d6 100644 (file)
@@ -9,29 +9,30 @@ use base qw(SL::DB::Object);
 __PACKAGE__->meta->table('delivery_order_items');
 
 __PACKAGE__->meta->columns(
 __PACKAGE__->meta->table('delivery_order_items');
 
 __PACKAGE__->meta->columns(
-  base_qty           => { type => 'float', scale => 4 },
-  cusordnumber       => { type => 'text' },
-  delivery_order_id  => { type => 'integer', not_null => 1 },
-  description        => { type => 'text' },
-  discount           => { type => 'float', scale => 4 },
-  id                 => { type => 'integer', not_null => 1, sequence => 'delivery_order_items_id' },
-  itime              => { type => 'timestamp', default => 'now()' },
-  lastcost           => { type => 'numeric', precision => 15, scale => 5 },
-  longdescription    => { type => 'text' },
-  marge_price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 },
-  mtime              => { type => 'timestamp' },
-  ordnumber          => { type => 'text' },
-  parts_id           => { type => 'integer', not_null => 1 },
-  price_factor       => { type => 'numeric', default => 1, precision => 15, scale => 5 },
-  price_factor_id    => { type => 'integer' },
-  pricegroup_id      => { type => 'integer' },
-  project_id         => { type => 'integer' },
-  qty                => { type => 'numeric', precision => 25, scale => 5 },
-  reqdate            => { type => 'date' },
-  sellprice          => { type => 'numeric', precision => 15, scale => 5 },
-  serialnumber       => { type => 'text' },
-  transdate          => { type => 'text' },
-  unit               => { type => 'varchar', length => 20 },
+  base_qty            => { type => 'float', scale => 4 },
+  cusordnumber        => { type => 'text' },
+  delivery_order_id   => { type => 'integer', not_null => 1 },
+  description         => { type => 'text' },
+  discount            => { type => 'float', scale => 4 },
+  id                  => { type => 'integer', not_null => 1, sequence => 'delivery_order_items_id' },
+  itime               => { type => 'timestamp', default => 'now()' },
+  lastcost            => { type => 'numeric', precision => 15, scale => 5 },
+  longdescription     => { type => 'text' },
+  marge_price_factor  => { type => 'numeric', default => 1, precision => 15, scale => 5 },
+  mtime               => { type => 'timestamp' },
+  ordnumber           => { type => 'text' },
+  parts_id            => { type => 'integer', not_null => 1 },
+  price_factor        => { type => 'numeric', default => 1, precision => 15, scale => 5 },
+  price_factor_id     => { type => 'integer' },
+  pricegroup_id       => { type => 'integer' },
+  project_id          => { type => 'integer' },
+  qty                 => { type => 'numeric', precision => 25, scale => 5 },
+  reqdate             => { type => 'date' },
+  sellprice           => { type => 'numeric', precision => 15, scale => 5 },
+  serialnumber        => { type => 'text' },
+  transdate           => { type => 'text' },
+  unit                => { type => 'varchar', length => 20 },
+  active_price_source => { type => 'text', default => '', not_null => 1 },
 );
 
 __PACKAGE__->meta->primary_key_columns([ 'id' ]);
 );
 
 __PACKAGE__->meta->primary_key_columns([ 'id' ]);
index 7cd853e..26ce472 100644 (file)
@@ -9,36 +9,37 @@ use base qw(SL::DB::Object);
 __PACKAGE__->meta->table('invoice');
 
 __PACKAGE__->meta->columns(
 __PACKAGE__->meta->table('invoice');
 
 __PACKAGE__->meta->columns(
-  allocated          => { type => 'float', scale => 4 },
-  assemblyitem       => { type => 'boolean', default => 'false' },
-  base_qty           => { type => 'float', scale => 4 },
-  cusordnumber       => { type => 'text' },
-  deliverydate       => { type => 'date' },
-  description        => { type => 'text' },
-  discount           => { type => 'float', scale => 4 },
-  donumber           => { type => 'text' },
-  fxsellprice        => { type => 'numeric', precision => 15, scale => 5 },
-  id                 => { type => 'integer', not_null => 1, sequence => 'invoiceid' },
-  itime              => { type => 'timestamp', default => 'now()' },
-  lastcost           => { type => 'numeric', precision => 15, scale => 5 },
-  longdescription    => { type => 'text' },
-  marge_percent      => { type => 'numeric', precision => 15, scale => 5 },
-  marge_price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 },
-  marge_total        => { type => 'numeric', precision => 15, scale => 5 },
-  mtime              => { type => 'timestamp' },
-  ordnumber          => { type => 'text' },
-  parts_id           => { type => 'integer' },
-  price_factor       => { type => 'numeric', default => 1, precision => 15, scale => 5 },
-  price_factor_id    => { type => 'integer' },
-  pricegroup_id      => { type => 'integer' },
-  project_id         => { type => 'integer' },
-  qty                => { type => 'float', scale => 4 },
-  sellprice          => { type => 'numeric', precision => 15, scale => 5 },
-  serialnumber       => { type => 'text' },
-  subtotal           => { type => 'boolean', default => 'false' },
-  trans_id           => { type => 'integer' },
-  transdate          => { type => 'text' },
-  unit               => { type => 'varchar', length => 20 },
+  allocated           => { type => 'float', scale => 4 },
+  assemblyitem        => { type => 'boolean', default => 'false' },
+  base_qty            => { type => 'float', scale => 4 },
+  cusordnumber        => { type => 'text' },
+  deliverydate        => { type => 'date' },
+  description         => { type => 'text' },
+  discount            => { type => 'float', scale => 4 },
+  donumber            => { type => 'text' },
+  fxsellprice         => { type => 'numeric', precision => 15, scale => 5 },
+  id                  => { type => 'integer', not_null => 1, sequence => 'invoiceid' },
+  itime               => { type => 'timestamp', default => 'now()' },
+  lastcost            => { type => 'numeric', precision => 15, scale => 5 },
+  longdescription     => { type => 'text' },
+  marge_percent       => { type => 'numeric', precision => 15, scale => 5 },
+  marge_price_factor  => { type => 'numeric', default => 1, precision => 15, scale => 5 },
+  marge_total         => { type => 'numeric', precision => 15, scale => 5 },
+  mtime               => { type => 'timestamp' },
+  ordnumber           => { type => 'text' },
+  parts_id            => { type => 'integer' },
+  price_factor        => { type => 'numeric', default => 1, precision => 15, scale => 5 },
+  price_factor_id     => { type => 'integer' },
+  pricegroup_id       => { type => 'integer' },
+  project_id          => { type => 'integer' },
+  qty                 => { type => 'float', scale => 4 },
+  sellprice           => { type => 'numeric', precision => 15, scale => 5 },
+  serialnumber        => { type => 'text' },
+  subtotal            => { type => 'boolean', default => 'false' },
+  trans_id            => { type => 'integer' },
+  transdate           => { type => 'text' },
+  unit                => { type => 'varchar', length => 20 },
+  active_price_source => { type => 'text', default => '', not_null => 1 },
 );
 
 __PACKAGE__->meta->primary_key_columns([ 'id' ]);
 );
 
 __PACKAGE__->meta->primary_key_columns([ 'id' ]);
index 85bf5be..2bd6bf5 100644 (file)
@@ -9,33 +9,34 @@ use base qw(SL::DB::Object);
 __PACKAGE__->meta->table('orderitems');
 
 __PACKAGE__->meta->columns(
 __PACKAGE__->meta->table('orderitems');
 
 __PACKAGE__->meta->columns(
-  base_qty           => { type => 'float', scale => 4 },
-  cusordnumber       => { type => 'text' },
-  description        => { type => 'text' },
-  discount           => { type => 'float', scale => 4 },
-  id                 => { type => 'integer', not_null => 1, sequence => 'orderitemsid' },
-  itime              => { type => 'timestamp', default => 'now()' },
-  lastcost           => { type => 'numeric', precision => 15, scale => 5 },
-  longdescription    => { type => 'text' },
-  marge_percent      => { type => 'numeric', precision => 15, scale => 5 },
-  marge_price_factor => { type => 'numeric', default => 1, precision => 15, scale => 5 },
-  marge_total        => { type => 'numeric', precision => 15, scale => 5 },
-  mtime              => { type => 'timestamp' },
-  ordnumber          => { type => 'text' },
-  parts_id           => { type => 'integer' },
-  price_factor       => { type => 'numeric', default => 1, precision => 15, scale => 5 },
-  price_factor_id    => { type => 'integer' },
-  pricegroup_id      => { type => 'integer' },
-  project_id         => { type => 'integer' },
-  qty                => { type => 'float', scale => 4 },
-  reqdate            => { type => 'date' },
-  sellprice          => { type => 'numeric', precision => 15, scale => 5 },
-  serialnumber       => { type => 'text' },
-  ship               => { type => 'float', scale => 4 },
-  subtotal           => { type => 'boolean', default => 'false' },
-  trans_id           => { type => 'integer' },
-  transdate          => { type => 'text' },
-  unit               => { type => 'varchar', length => 20 },
+  base_qty            => { type => 'float', scale => 4 },
+  cusordnumber        => { type => 'text' },
+  description         => { type => 'text' },
+  discount            => { type => 'float', scale => 4 },
+  id                  => { type => 'integer', not_null => 1, sequence => 'orderitemsid' },
+  itime               => { type => 'timestamp', default => 'now()' },
+  lastcost            => { type => 'numeric', precision => 15, scale => 5 },
+  longdescription     => { type => 'text' },
+  marge_percent       => { type => 'numeric', precision => 15, scale => 5 },
+  marge_price_factor  => { type => 'numeric', default => 1, precision => 15, scale => 5 },
+  marge_total         => { type => 'numeric', precision => 15, scale => 5 },
+  mtime               => { type => 'timestamp' },
+  ordnumber           => { type => 'text' },
+  parts_id            => { type => 'integer' },
+  price_factor        => { type => 'numeric', default => 1, precision => 15, scale => 5 },
+  price_factor_id     => { type => 'integer' },
+  pricegroup_id       => { type => 'integer' },
+  project_id          => { type => 'integer' },
+  qty                 => { type => 'float', scale => 4 },
+  reqdate             => { type => 'date' },
+  sellprice           => { type => 'numeric', precision => 15, scale => 5 },
+  serialnumber        => { type => 'text' },
+  ship                => { type => 'float', scale => 4 },
+  subtotal            => { type => 'boolean', default => 'false' },
+  trans_id            => { type => 'integer' },
+  transdate           => { type => 'text' },
+  unit                => { type => 'varchar', length => 20 },
+  active_price_source => { type => 'text', default => '', not_null => 1 },
 );
 
 __PACKAGE__->meta->primary_key_columns([ 'id' ]);
 );
 
 __PACKAGE__->meta->primary_key_columns([ 'id' ]);
index 89f2d92..a37e516 100644 (file)
--- a/SL/DO.pm
+++ b/SL/DO.pm
@@ -284,9 +284,10 @@ sub save {
          id, delivery_order_id, parts_id, description, longdescription, qty, base_qty,
          sellprice, discount, unit, reqdate, project_id, serialnumber,
          ordnumber, transdate, cusordnumber,
          id, delivery_order_id, parts_id, description, longdescription, qty, base_qty,
          sellprice, discount, unit, reqdate, project_id, serialnumber,
          ordnumber, transdate, cusordnumber,
-         lastcost, price_factor_id, price_factor, marge_price_factor, pricegroup_id)
+         lastcost, price_factor_id, price_factor, marge_price_factor, pricegroup_id,
+         active_price_source)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
-         (SELECT factor FROM price_factors WHERE id = ?), ?, ?)|;
+         (SELECT factor FROM price_factors WHERE id = ?), ?, ?, ?)|;
   my $h_item = prepare_query($form, $dbh, $q_item);
 
   my $q_item_stock =
   my $h_item = prepare_query($form, $dbh, $q_item);
 
   my $q_item_stock =
@@ -341,7 +342,8 @@ sub save {
                $form->{"lastcost_$i"},
                conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
                conv_i($form->{"marge_price_factor_$i"}),
                $form->{"lastcost_$i"},
                conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
                conv_i($form->{"marge_price_factor_$i"}),
-               $pricegroup_id);
+               $pricegroup_id,
+               $form->{"active_price_source_$i"});
     do_statement($form, $h_item, $q_item, @values);
 
     my $stock_info = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_$i"});
     do_statement($form, $h_item, $q_item, @values);
 
     my $stock_info = DO->unpack_stock_information('packed' => $form->{"stock_${in_out}_$i"});
@@ -688,6 +690,7 @@ sub retrieve {
          doi.reqdate, doi.project_id, doi.serialnumber, doi.lastcost,
          doi.ordnumber, doi.transdate, doi.cusordnumber, doi.longdescription,
          doi.price_factor_id, doi.price_factor, doi.marge_price_factor, doi.pricegroup_id,
          doi.reqdate, doi.project_id, doi.serialnumber, doi.lastcost,
          doi.ordnumber, doi.transdate, doi.cusordnumber, doi.longdescription,
          doi.price_factor_id, doi.price_factor, doi.marge_price_factor, doi.pricegroup_id,
+         doi.active_price_source,
          pr.projectnumber, dord.transdate AS dord_transdate, dord.donumber,
          pg.partsgroup
        FROM delivery_order_items doi
          pr.projectnumber, dord.transdate AS dord_transdate, dord.donumber,
          pg.partsgroup
        FROM delivery_order_items doi
index 29886a5..5c156a6 100644 (file)
--- a/SL/IS.pm
+++ b/SL/IS.pm
@@ -2131,196 +2131,6 @@ sub retrieve_item {
   $main::lxdebug->leave_sub();
 }
 
   $main::lxdebug->leave_sub();
 }
 
-##########################
-# get pricegroups from database
-# build up selected pricegroup
-# if an exchange rate - change price
-# for each part
-#
-sub get_pricegroups_for_parts {
-
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-
-  my $dbh = $form->get_standard_dbh;
-
-  $form->{"PRICES"} = {};
-
-  my $i  = 1;
-  my $id = 0;
-  my $all_units = AM->retrieve_units($myconfig, $form);
-  while (($form->{"id_$i"}) or ($form->{"new_id_$i"})) {
-    $form->{"PRICES"}{$i} = [];
-
-    $id = $form->{"id_$i"};
-
-    if (!($form->{"id_$i"}) and $form->{"new_id_$i"}) {
-      $id = $form->{"new_id_$i"};
-    }
-
-    my ($price, $selectedpricegroup_id) = split(/--/, $form->{"sellprice_pg_$i"});
-
-    my $pricegroup_old = $form->{"pricegroup_old_$i"};
-
-    # sellprice has format 13,0000 or 0,00000,  can't check for 0 numerically
-    my $sellprice = $form->{"sellprice_$i"};
-    my $pricegroup_id = $form->{"pricegroup_id_$i"};
-    $form->{"new_pricegroup_$i"} = $selectedpricegroup_id;
-    $form->{"old_pricegroup_$i"} = $pricegroup_old;
-
-    my $price_new = $form->{"price_new_$i"};
-    my $price_old = $form->{"price_old_$i"};
-
-    if (!$form->{"unit_old_$i"}) {
-      # Neue Ware aus der Datenbank. In diesem Fall ist unit_$i die
-      # Einheit, wie sie in den Stammdaten hinterlegt wurde.
-      # Es sollte also angenommen werden, dass diese ausgewaehlt war.
-      $form->{"unit_old_$i"} = $form->{"unit_$i"};
-    }
-
-    # Die zuletzt ausgewaehlte mit der aktuell ausgewaehlten Einheit
-    # vergleichen und bei Unterschied den Preis entsprechend umrechnen.
-    $form->{"selected_unit_$i"} = $form->{"unit_$i"} unless ($form->{"selected_unit_$i"});
-
-    if (!$all_units->{$form->{"selected_unit_$i"}} ||
-        ($all_units->{$form->{"selected_unit_$i"}}->{"base_unit"} ne
-         $all_units->{$form->{"unit_old_$i"}}->{"base_unit"})) {
-      # Die ausgewaehlte Einheit ist fuer diesen Artikel nicht gueltig
-      # (z.B. Dimensionseinheit war ausgewaehlt, es handelt sich aber
-      # um eine Dienstleistung). Dann keinerlei Umrechnung vornehmen.
-      $form->{"unit_old_$i"} = $form->{"selected_unit_$i"} = $form->{"unit_$i"};
-    }
-
-    my $basefactor = 1;
-
-    if ($form->{"unit_old_$i"} ne $form->{"selected_unit_$i"}) {
-      if (defined($all_units->{$form->{"unit_old_$i"}}->{"factor"}) &&
-          $all_units->{$form->{"unit_old_$i"}}->{"factor"}) {
-        $basefactor = $all_units->{$form->{"selected_unit_$i"}}->{"factor"} /
-          $all_units->{$form->{"unit_old_$i"}}->{"factor"};
-      }
-    }
-
-    if (!$form->{"basefactor_$i"}) {
-      $form->{"basefactor_$i"} = 1;
-    }
-
-    my $query =
-       qq|SELECT
-            0 as pricegroup_id,
-            sellprice AS default_sellprice,
-            '' AS pricegroup,
-            sellprice AS price,
-            'selected' AS selected
-          FROM parts
-          WHERE id = ?
-          UNION ALL
-          SELECT
-           pricegroup_id,
-           parts.sellprice AS default_sellprice,
-           pricegroup.pricegroup,
-           price,
-           '' AS selected
-          FROM prices
-          LEFT JOIN parts ON parts.id = parts_id
-          LEFT JOIN pricegroup ON pricegroup.id = pricegroup_id
-          WHERE parts_id = ?
-          ORDER BY pricegroup|;
-    my @values = (conv_i($id), conv_i($id));
-    my $pkq = prepare_execute_query($form, $dbh, $query, @values);
-
-    while (my $pkr = $pkq->fetchrow_hashref('NAME_lc')) {
-      $pkr->{id}       = $id;
-      $pkr->{selected} = '';
-
-      # if there is an exchange rate change price
-      if (($form->{exchangerate} * 1) != 0) {
-        $pkr->{price} /= $form->{exchangerate};
-      }
-
-      $pkr->{price} *= $form->{"basefactor_$i"};
-      $pkr->{price} *= $basefactor;
-      $pkr->{price_ufmt} = $pkr->{price};
-      $pkr->{price} = $form->format_amount($myconfig, $pkr->{price}, 5);
-
-      if (!defined $selectedpricegroup_id) {
-        # new entries in article list, either old invoice was loaded (edit) or a new article was added
-        # Case A: open old invoice, no pricegroup selected
-        # Case B: add new article to invoice, no pricegroup selected
-
-        # to distinguish case A and B the variable pricegroup_id_$i is used
-        # for new articles this variable isn't defined, for loaded articles it is
-        # sellprice can't be used, as it already has 0,00 set
-
-        if ($pkr->{pricegroup_id} eq $form->{"pricegroup_id_$i"} and defined $form->{"pricegroup_id_$i"}) {
-          # Case A
-          $pkr->{selected}  = ' selected';
-        } elsif ($pkr->{pricegroup_id} eq $form->{customer_klass}
-                 and not defined $form->{"pricegroup_id_$i"}
-                 and $pkr->{price_ufmt} != 0    # only use customer pricegroup price if it has a value, else use default_sellprice
-                                                # for the case where pricegroup prices haven't been set
-                ) {
-          # Case B: use default pricegroup of customer
-
-          $pkr->{selected}  = ' selected'; # unless $form->{selected};
-          # no customer pricesgroup set
-          if ($pkr->{price_ufmt} == $pkr->{default_sellprice}) {
-
-            $pkr->{price} = $form->{"sellprice_$i"};
-
-          } else {
-
-# this sub should not set anything and only return. --sschoeling, 20090506
-# is this correct? put in again... -- grichardson 20110119
-            $form->{"sellprice_$i"} = $pkr->{price};
-          }
-
-        } elsif ($pkr->{price_ufmt} == $pkr->{default_sellprice} and $pkr->{default_sellprice} != 0) {
-          $pkr->{price}    = $form->{"sellprice_$i"};
-          $pkr->{selected} = ' selected';
-        }
-      }
-
-      # existing article: pricegroup or price changed
-      if ($selectedpricegroup_id or $selectedpricegroup_id == 0) {
-        if ($selectedpricegroup_id ne $pricegroup_old) {
-          # pricegroup has changed
-          if ($pkr->{pricegroup_id} eq $selectedpricegroup_id) {
-            $pkr->{selected}  = ' selected';
-          }
-        } elsif ( ($form->parse_amount($myconfig, $price_new)
-                 != $form->parse_amount($myconfig, $form->{"sellprice_$i"}))
-                  and ($price_new ne 0) and defined $price_new) {
-          # sellprice has changed
-          # when loading existing invoices $price_new is NULL
-          if ($pkr->{pricegroup_id} == 0) {
-            $pkr->{price}     = $form->{"sellprice_$i"};
-            $pkr->{selected}  = ' selected';
-          }
-        } elsif ($pkr->{pricegroup_id} eq $selectedpricegroup_id) {
-          # neither sellprice nor pricegroup changed
-          $pkr->{selected}  = ' selected';
-          if (    ($pkr->{pricegroup_id} == 0) and ($pkr->{price} == $form->{"sellprice_$i"})) {
-            # $pkr->{price}                         = $form->{"sellprice_$i"};
-          } else {
-            $pkr->{price} = $form->{"sellprice_$i"};
-          }
-        }
-      }
-      push @{ $form->{PRICES}{$i} }, $pkr;
-
-    }
-    $form->{"basefactor_$i"} *= $basefactor;
-
-    $i++;
-
-    $pkq->finish;
-  }
-
-  $main::lxdebug->leave_sub();
-}
-
 sub has_storno {
   $main::lxdebug->enter_sub();
 
 sub has_storno {
   $main::lxdebug->enter_sub();
 
index faaaa33..506db6b 100644 (file)
--- a/SL/OE.pm
+++ b/SL/OE.pm
@@ -532,6 +532,7 @@ sub save {
           sellprice = ?, discount = ?, unit = ?, reqdate = ?, project_id = ?, serialnumber = ?, ship = ?,
           pricegroup_id = ?, ordnumber = ?, transdate = ?, cusordnumber = ?, subtotal = ?,
           marge_percent = ?, marge_total = ?, lastcost = ?, price_factor_id = ?,
           sellprice = ?, discount = ?, unit = ?, reqdate = ?, project_id = ?, serialnumber = ?, ship = ?,
           pricegroup_id = ?, ordnumber = ?, transdate = ?, cusordnumber = ?, subtotal = ?,
           marge_percent = ?, marge_total = ?, lastcost = ?, price_factor_id = ?,
+          active_price_source = ?,
           price_factor = (SELECT factor FROM price_factors WHERE id = ?), marge_price_factor = ?
         WHERE id = ?
 SQL
           price_factor = (SELECT factor FROM price_factors WHERE id = ?), marge_price_factor = ?
         WHERE id = ?
 SQL
@@ -546,6 +547,7 @@ SQL
            $form->{"cusordnumber_$i"}, $form->{"subtotal_$i"} ? 't' : 'f',
            $form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"},
            $form->{"lastcost_$i"},
            $form->{"cusordnumber_$i"}, $form->{"subtotal_$i"} ? 't' : 'f',
            $form->{"marge_percent_$i"}, $form->{"marge_absolut_$i"},
            $form->{"lastcost_$i"},
+           $form->{"active_price_source_$i"},
            conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
            conv_i($form->{"marge_price_factor_$i"}),
            conv_i($orderitems_id),
            conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
            conv_i($form->{"marge_price_factor_$i"}),
            conv_i($orderitems_id),
@@ -945,7 +947,7 @@ sub retrieve {
            o.sellprice, o.parts_id AS id, o.unit, o.discount, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id,
            o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost,
            o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription,
            o.sellprice, o.parts_id AS id, o.unit, o.discount, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id,
            o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost,
            o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription,
-           o.price_factor_id, o.price_factor, o.marge_price_factor,
+           o.price_factor_id, o.price_factor, o.marge_price_factor, o.active_price_source,
            pr.projectnumber, p.formel,
            pg.partsgroup, o.pricegroup_id, (SELECT pricegroup FROM pricegroup WHERE id=o.pricegroup_id) as pricegroup
          FROM orderitems o
            pr.projectnumber, p.formel,
            pg.partsgroup, o.pricegroup_id, (SELECT pricegroup FROM pricegroup WHERE id=o.pricegroup_id) as pricegroup
          FROM orderitems o
diff --git a/SL/PriceSource.pm b/SL/PriceSource.pm
new file mode 100644 (file)
index 0000000..9a3a978
--- /dev/null
@@ -0,0 +1,101 @@
+package SL::PriceSource;
+
+use strict;
+use parent 'SL::DB::Object';
+use Rose::Object::MakeMethods::Generic (
+  scalar => [ qw(record_item) ],
+);
+
+use List::UtilsBy qw(min_by);
+use SL::PriceSource::ALL;
+use SL::PriceSource::Price;
+use SL::Locale::String;
+
+sub all_price_sources {
+  my ($self) = @_;
+
+  return map {
+    $_->new(record_item => $self->record_item)
+  } SL::PriceSource::ALL->all_price_sources
+}
+
+sub price_from_source {
+  my ($self, $source) = @_;
+  my ($source_name, $spec) = split m{/}, $source, 2;
+
+  my $class = SL::PriceSource::ALL->price_source_class_by_name($source_name);
+
+  return $class
+    ? $class->new(record_item => $self->record_item)->price_from_source($source, $spec)
+    : empty_price();
+}
+
+sub available_prices {
+  map { $_->available_prices } $_[0]->all_price_sources;
+}
+
+sub best_price {
+  min_by { $_->price } map { $_->best_price } $_[0]->all_price_sources;
+}
+
+sub empty_price {
+  SL::PriceSource::Price->new(
+    source      => '',
+    description => t8('None (PriceSource)'),
+  );
+}
+
+1;
+
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+SL::PriceSource - mixin for price_sources in record items
+
+=head1 SYNOPSIS
+
+  # in record item class
+
+  use SL::PriceSource;
+
+  # later on:
+
+  $record_item->all_price_sources
+  $record_item->price_source      # get
+  $record_item->price_source($c)  # set
+
+  $record_item->update_price_source # set price to calculated
+
+=head1 DESCRIPTION
+
+This mixin provides a way to use price_source objects from within a record item.
+Record items in this contest mean OrderItems, InvoiceItems and
+DeliveryOrderItems.
+
+=head1 FUNCTIONS
+
+price_sources
+
+returns a list of price_source objects which are created with the current record
+item.
+
+active_price_source
+
+returns the object representing the currently chosen price_source method or
+undef if custom price is chosen. Note that this must not necessarily be the
+active price, if something affecting the price_source has changed, the price
+calculated can differ from the price in the record. It is the responsibility of
+the implementing code to decide what to do in this case.
+
+=head1 BUGS
+
+None yet. :)
+
+=head1 AUTHOR
+
+Sven Schoeling E<lt>s.schoeling@linet-services.deE<gt>
+
+=cut
diff --git a/SL/PriceSource/ALL.pm b/SL/PriceSource/ALL.pm
new file mode 100644 (file)
index 0000000..f39df0a
--- /dev/null
@@ -0,0 +1,25 @@
+package SL::PriceSource::ALL;
+
+use strict;
+use SL::PriceSource::Pricegroup;
+use SL::PriceSource::MasterData;
+
+my %price_sources_by_name = (
+  master_data => 'SL::PriceSource::MasterData',
+  pricegroup  => 'SL::PriceSource::Pricegroup',
+);
+
+my @price_sources_order = qw(
+  master_data
+  pricegroup
+);
+
+sub all_price_sources {
+  map { $price_sources_by_name{$_} } @price_sources_order;
+}
+
+sub price_source_class_by_name {
+  $price_sources_by_name{$_[1]};
+}
+
+1;
diff --git a/SL/PriceSource/Base.pm b/SL/PriceSource/Base.pm
new file mode 100644 (file)
index 0000000..618512d
--- /dev/null
@@ -0,0 +1,107 @@
+package SL::PriceSource::Base;
+
+use strict;
+
+use parent qw(SL::DB::Object);
+use Rose::Object::MakeMethods::Generic (
+  scalar => [ qw(record_item record) ],
+);
+
+sub name { die 'name needs to be implemented' }
+
+sub description { die 'description needs to be implemented' }
+
+sub available_prices { die 'available_prices needs to be implemented' }
+
+sub best_price { die 'best_price needs to be implemented' }
+
+sub price_from_source { die 'price_from_source needs to be implemented:' . "@_" }
+
+sub part {
+  $_[0]->record_item->part;
+}
+
+1;
+
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+SL::PriceSource::Base - <oneliner description>
+
+=head1 SYNOPSIS
+
+  # in consuming module
+# TODO: thats bullshit, theres no need to have this pollute the namespace
+# make a manager that handles this
+
+  my @list_of_price_sources = $record_item->price_sources;
+  for (@list_of_price_sources) {
+    my $internal_name   = $_->name;
+    my $translated_name = $_->description;
+    my $price           = $_->price;
+  }
+
+  $record_item->set_active_price_source($price_source)  # equivalent to:
+  $record_item->active_price_source($price_source->name);
+  $record_item->sellprice($price_source->price);
+
+  # for finer control
+  $price_source->needed_params
+  $price_source->supported_params
+
+=head1 DESCRIPTION
+
+PriceSource is an interface that allows generic algorithms to be used, to
+calculate a price for a position in a record.
+
+If any such price_source algorithm is known to the system, a user can chose
+which of them should be used to claculate the price displayed in the record.
+
+The algorithm is saved togetherwith the target price, so that changes in the
+record can recalculate the price accordingly, and otherwise manual changes to
+the price can reset the price_source used to custom (aka no price_source).
+
+=head1 INTERFACE METHODS
+
+=over 4
+
+=item C<name>
+
+Should return a unique internal name. Should be entered in
+L<SL::PriceSource::ALL> so that a name_to_class lookup works.
+
+=item C<description>
+
+Should return a translated name.
+
+=item C<needed_params>
+
+Should return a list of elements that a record_item NEEDS to be used with this calulation.
+
+Both C<needed_params> nad C<supported_params> are purely informational at this point.
+
+=item C<supported_params>
+
+Should return a list of elements that a record_item MAY HAVE to be used with this calulation.
+
+Both C<needed_params> nad C<supported_params> are purely informational at this point.
+
+=item C<price>
+
+Calculate a price and return. Do not mutate the record_item. Should will return
+undef if price is not applicable to the current record_item.
+
+=back
+
+=head1 BUGS
+
+None yet. :)
+
+=head1 AUTHOR
+
+Sven Schoeling E<lt>s.schoeling@linet-services.deE<gt>
+
+=cut
diff --git a/SL/PriceSource/MasterData.pm b/SL/PriceSource/MasterData.pm
new file mode 100644 (file)
index 0000000..56b0265
--- /dev/null
@@ -0,0 +1,43 @@
+package SL::PriceSource::MasterData;
+
+use strict;
+use parent qw(SL::PriceSource::Base);
+
+use SL::PriceSource::Price;
+use SL::Locale::String;
+
+sub name { 'master_data' }
+
+sub description { t8('Master Data') }
+
+sub available_prices {
+  my ($self, %params) = @_;
+
+  my $part = $self->part;
+
+  return () unless $part;
+
+  # TODO: sellprice only in sales, lastcost in purchase
+  return $self->make_sellprice($part);
+}
+
+sub price_from_source {
+  my ($self, $source, $spec) = @_;
+
+  if ($spec eq 'sellprice') {
+    return $self->make_sellprice($self->part);
+  }
+}
+
+sub make_sellprice {
+  my ($self, $part) = @_;
+
+  return SL::PriceSource::Price->new(
+    price        => $part->sellprice,
+    source       => 'master_data/sellprice',
+    description  => t8('Sellprice'),
+    price_source => $self,
+  );
+}
+
+1;
diff --git a/SL/PriceSource/Price.pm b/SL/PriceSource/Price.pm
new file mode 100644 (file)
index 0000000..ccfdb07
--- /dev/null
@@ -0,0 +1,19 @@
+package SL::PriceSource::Price;
+
+use strict;
+
+use parent 'SL::DB::Object';
+use Rose::Object::MakeMethods::Generic (
+  scalar => [ qw(price description source price_source) ],
+  array => [ qw(depends_on) ]
+);
+
+sub full_description {
+  my ($self) = @_;
+
+  $self->price_source
+    ? $self->price_source->description . ': ' . $self->description
+    : $self->description
+}
+
+1;
diff --git a/SL/PriceSource/Pricegroup.pm b/SL/PriceSource/Pricegroup.pm
new file mode 100644 (file)
index 0000000..4b73ac8
--- /dev/null
@@ -0,0 +1,50 @@
+package SL::PriceSource::Pricegroup;
+
+use strict;
+use parent qw(SL::PriceSource::Base);
+
+use SL::PriceSource::Price;
+use SL::Locale::String;
+
+sub name { 'pricegroup' }
+
+sub description { t8('Pricegroup') }
+
+sub available_prices {
+  my ($self, %params) = @_;
+
+  my $item = $self->record_item;
+
+  my $prices = SL::DB::Manager::Price->get_all(
+    query        => [ parts_id => $item->parts_id, price => { gt => 0 } ],
+    with_objects => 'pricegroup',
+    order_by     => 'pricegroun.id',
+  );
+
+  return () unless @$prices;
+
+  return map {
+    $self->make_price($_);
+  } @$prices;
+}
+
+sub price_from_source {
+  my ($self, $source, $spec) = @_;
+
+  my $price = SL::DB::Manager::Price->find_by(id => $spec);
+
+  return $self->make_price($price);
+}
+
+sub make_price {
+  my ($self, $price_obj) = @_;
+
+  SL::PriceSource::Price->new(
+    price        => $price_obj->price,
+    source       => 'pricegroup/' . $price_obj->id,
+    description  => $price_obj->pricegroup->pricegroup,
+    price_source => $self,
+  )
+}
+
+1;
index b25cdad..1bda974 100644 (file)
@@ -390,7 +390,6 @@ sub update_delivery_order {
   #            Kunde mit Rabatt 20 -> Rabatt 5,5 i.O.
   $form->{payment_id} = $payment_id if $form->{payment_id} eq "";
 
   #            Kunde mit Rabatt 20 -> Rabatt 5,5 i.O.
   $form->{payment_id} = $payment_id if $form->{payment_id} eq "";
 
-  # for pricegroups
   my $i = $form->{rowcount};
 
   if (   ($form->{"partnumber_$i"} eq "")
   my $i = $form->{rowcount};
 
   if (   ($form->{"partnumber_$i"} eq "")
@@ -431,12 +430,6 @@ sub update_delivery_order {
         $form->{"sellprice_$i"}          = $form->format_amount(\%myconfig, $form->{"sellprice_$i"} * (1 - $form->{tradediscount}));
         $form->{"lastcost_$i"}          = $form->format_amount(\%myconfig, $form->{"lastcost_$i"});
         $form->{"qty_$i"}                = $form->format_amount(\%myconfig, $form->{"qty_$i"});
         $form->{"sellprice_$i"}          = $form->format_amount(\%myconfig, $form->{"sellprice_$i"} * (1 - $form->{tradediscount}));
         $form->{"lastcost_$i"}          = $form->format_amount(\%myconfig, $form->{"lastcost_$i"});
         $form->{"qty_$i"}                = $form->format_amount(\%myconfig, $form->{"qty_$i"});
-
-        # get pricegroups for parts
-        IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-
-        # build up html code for prices_$i
-        &set_pricegroup($i);
       }
 
       display_form();
       }
 
       display_form();
@@ -849,13 +842,6 @@ sub invoice {
 
   }
 
 
   }
 
-  #  show pricegroup in newly loaded invoice when creating invoice from delivery order
-  for my $i (1 .. $form->{rowcount}) {
-    $form->{"sellprice_pg_$i"} = join '--', $form->{"sellprice_$i"}, $form->{"pricegroup_id_$i"};
-  }
-  IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-  set_pricegroup($form->{rowcount});
-
   display_form();
 
   $main::lxdebug->leave_sub();
   display_form();
 
   $main::lxdebug->leave_sub();
@@ -957,13 +943,6 @@ sub invoice_multi {
   invoice_links();
   prepare_invoice();
 
   invoice_links();
   prepare_invoice();
 
-  #  show pricegroup in newly loaded invoice when creating invoice from delivery order
-  for my $i (1 .. $form->{rowcount}) {
-    $form->{"sellprice_pg_$i"} = join '--', $form->{"sellprice_$i"}, $form->{"pricegroup_id_$i"};
-  }
-  IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-  set_pricegroup($_) for 1 .. $form->{rowcount};
-
   display_form();
 
   $main::lxdebug->leave_sub();
   display_form();
 
   $main::lxdebug->leave_sub();
index 7ff0347..a109802 100644 (file)
@@ -88,56 +88,6 @@ use SL::PE;
 use SL::AM;
 use Data::Dumper;
 
 use SL::AM;
 use Data::Dumper;
 
-sub set_pricegroup {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-  my $locale   = $main::locale;
-
-  my $rowcount = shift;
-  for my $j (1 .. $rowcount) {
-    my $pricegroup_old = $form->{"pricegroup_old_$j"};
-    if ($form->{PRICES}{$j}) {
-      my $len    = 0;
-      my $prices = '<option value="--">' . $locale->text("none (pricegroup)") . '</option>';
-      my $price  = 0;
-      foreach my $item (@{ $form->{PRICES}{$j} }) {
-
-        #$price = $form->round_amount($myconfig,  $item->{price}, 5);
-        #$price = $form->format_amount($myconfig, $item->{price}, 2);
-        my $price         = $item->{price};
-        my $pricegroup_id = $item->{pricegroup_id};
-        my $pricegroup    = $item->{pricegroup};
-
-        # build drop down list for pricegroups
-        $prices .=
-          qq|<option value="$price--$pricegroup_id"$item->{selected}>$pricegroup</option>\n|;
-
-        $len += 1;
-
-        #        map {
-        #               $form->{"${_}_$j"} =
-        #               $form->format_amount(\%myconfig, $form->{"${_}_$j"})
-        #              } qw(sellprice price_new price_old);
-
-        # set new selectedpricegroup_id and prices for "Preis"
-        if ($item->{selected} && ($pricegroup_id != 0)) {
-          $form->{"pricegroup_old_$j"} = $pricegroup_id;
-          $form->{"price_new_$j"}      = $price;
-          # edit: don't change the sellprice here
-          # $form->{"sellprice_$j"}      = $price;   # this must only be updated for existing articles, not new ones
-        }
-        if ($pricegroup_id == 0) {
-          $form->{"price_new_$j"} = $form->{"sellprice_$j"};
-        }
-      }
-      $form->{"prices_$j"} = $prices;
-    }
-  }
-  $main::lxdebug->leave_sub();
-}
-
 sub display_form {
   $main::lxdebug->enter_sub();
 
 sub display_form {
   $main::lxdebug->enter_sub();
 
@@ -188,12 +138,6 @@ sub display_form {
   #     $form->{rowcount}--;
   #     my $rowcount = $form->{rowcount};
   #
   #     $form->{rowcount}--;
   #     my $rowcount = $form->{rowcount};
   #
-  #     # get pricegroups for parts
-  #     IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-  #
-  #     # build up html code for prices_$i
-  #     set_pricegroup($rowcount);
-  #
   #     $form->{resubmit} = 1;
   #
   #   }
   #     $form->{resubmit} = 1;
   #
   #   }
index 5a17d68..e9fbad8 100644 (file)
@@ -38,7 +38,7 @@
 
 use Carp;
 use CGI;
 
 use Carp;
 use CGI;
-use List::MoreUtils qw(any uniq);
+use List::MoreUtils qw(any uniq apply);
 use List::Util qw(min max first);
 
 use SL::CVar;
 use List::Util qw(min max first);
 
 use SL::CVar;
@@ -46,6 +46,7 @@ use SL::Common;
 use SL::CT;
 use SL::IC;
 use SL::IO;
 use SL::CT;
 use SL::IC;
 use SL::IO;
+use SL::PriceSource;
 
 use SL::DB::Customer;
 use SL::DB::Default;
 
 use SL::DB::Customer;
 use SL::DB::Default;
@@ -149,7 +150,7 @@ sub display_row {
   }
 
   # column_index
   }
 
   # column_index
-  my @header_sort = qw(runningnumber partnumber description ship qty unit weight sellprice_pg sellprice discount linetotal);
+  my @header_sort = qw(runningnumber partnumber description ship qty unit weight sellprice discount linetotal);
   my @HEADER = (
     {  id => 'runningnumber', width => 5,     value => $locale->text('No.'),                  display => 1, },
     {  id => 'partnumber',    width => 8,     value => $locale->text('Number'),               display => 1, },
   my @HEADER = (
     {  id => 'runningnumber', width => 5,     value => $locale->text('No.'),                  display => 1, },
     {  id => 'partnumber',    width => 8,     value => $locale->text('Number'),               display => 1, },
@@ -162,7 +163,7 @@ sub display_row {
     {  id => 'serialnr',      width => 10,    value => $locale->text('Serial No.'),           display => 0, },
     {  id => 'projectnr',     width => 10,    value => $locale->text('Project'),              display => 0, },
     {  id => 'sellprice',     width => 15,    value => $locale->text('Price'),                display => !$is_delivery_order, },
     {  id => 'serialnr',      width => 10,    value => $locale->text('Serial No.'),           display => 0, },
     {  id => 'projectnr',     width => 10,    value => $locale->text('Project'),              display => 0, },
     {  id => 'sellprice',     width => 15,    value => $locale->text('Price'),                display => !$is_delivery_order, },
-    {  id => 'sellprice_pg',  width => 8,     value => $locale->text('Pricegroup'),           display => !$is_delivery_order && !$is_purchase, },
+    {  id => 'price_source',  width => 5,     value => $locale->text('Price Source'),         display => !$is_delivery_order, },
     {  id => 'discount',      width => 5,     value => $locale->text('Discount'),             display => !$is_delivery_order, },
     {  id => 'linetotal',     width => 10,    value => $locale->text('Extended'),             display => !$is_delivery_order, },
     {  id => 'bin',           width => 10,    value => $locale->text('Bin'),                  display => 0, },
     {  id => 'discount',      width => 5,     value => $locale->text('Discount'),             display => !$is_delivery_order, },
     {  id => 'linetotal',     width => 10,    value => $locale->text('Extended'),             display => !$is_delivery_order, },
     {  id => 'bin',           width => 10,    value => $locale->text('Bin'),                  display => 0, },
@@ -196,7 +197,7 @@ sub display_row {
   my $deliverydate  = $locale->text('Required by');
 
   # special alignings
   my $deliverydate  = $locale->text('Required by');
 
   # special alignings
-  my %align  = map { $_ => 'right' } qw(qty ship right sellprice_pg discount linetotal stock_in_out weight);
+  my %align  = map { $_ => 'right' } qw(qty ship right discount linetotal stock_in_out weight);
   my %nowrap = map { $_ => 1 }       qw(description unit);
 
   $form->{marge_total}           = 0;
   my %nowrap = map { $_ => 1 }       qw(description unit);
 
   $form->{marge_total}           = 0;
@@ -232,6 +233,8 @@ sub display_row {
       $form->{"sellprice_$i"} = $form->{"price_new_$i"};
     }
 
       $form->{"sellprice_$i"} = $form->{"price_new_$i"};
     }
 
+    my $record_item = _make_record_item($i);
+
 # unit begin
     $form->{"unit_old_$i"}      ||= $form->{"unit_$i"};
     $form->{"selected_unit_$i"} ||= $form->{"unit_$i"};
 # unit begin
     $form->{"unit_old_$i"}      ||= $form->{"unit_$i"};
     $form->{"selected_unit_$i"} ||= $form->{"unit_$i"};
@@ -240,12 +243,11 @@ sub display_row {
         || !AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units)) { # (z.B. Dimensionseinheit war ausgewaehlt, es handelt sich aber
       $form->{"unit_old_$i"} = $form->{"selected_unit_$i"} = $form->{"unit_$i"};                 # um eine Dienstleistung). Dann keinerlei Umrechnung vornehmen.
     }
         || !AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units)) { # (z.B. Dimensionseinheit war ausgewaehlt, es handelt sich aber
       $form->{"unit_old_$i"} = $form->{"selected_unit_$i"} = $form->{"unit_$i"};                 # um eine Dienstleistung). Dann keinerlei Umrechnung vornehmen.
     }
-    # adjust prices by unit, ignore if pricegroup changed
-    if ((!$form->{"prices_$i"}) || ($form->{"new_pricegroup_$i"} == $form->{"old_pricegroup_$i"})) {
-        $form->{"sellprice_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1;
-        $form->{"lastcost_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1;
-        $form->{"unit_old_$i"}   = $form->{"selected_unit_$i"};
-    }
+
+    $form->{"sellprice_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1;
+    $form->{"lastcost_$i"} *= AM->convert_unit($form->{"selected_unit_$i"}, $form->{"unit_old_$i"}, $all_units) || 1;
+    $form->{"unit_old_$i"}   = $form->{"selected_unit_$i"};
+
     my $this_unit = $form->{"unit_$i"};
     $this_unit    = $form->{"selected_unit_$i"} if AM->convert_unit($this_unit, $form->{"selected_unit_$i"}, $all_units);
 
     my $this_unit = $form->{"unit_$i"};
     $this_unit    = $form->{"selected_unit_$i"} if AM->convert_unit($this_unit, $form->{"selected_unit_$i"}, $all_units);
 
@@ -305,41 +307,11 @@ sub display_row {
       $column_data{ship}  = $form->format_amount(\%myconfig, $form->round_amount($ship_qty, 2) * 1) . ' ' . $form->{"unit_$i"};
     }
 
       $column_data{ship}  = $form->format_amount(\%myconfig, $form->round_amount($ship_qty, 2) * 1) . ' ' . $form->{"unit_$i"};
     }
 
-    # build in drop down list for pricesgroups
-    # $sellprice_value setzt den Wert etwas unabhängiger von der Darstellung.
-    # Hintergrund: Preisgruppen werden hier überprüft und neu berechnet.
-    # Vorher wurde der ganze cgi->textfield Block zweimal identisch eingebaut, dass passiert
-    # jetzt nach der Abfrage.
-    my $sellprice_value;
-    if ($form->{"prices_$i"}) {
-      $column_data{sellprice_pg} = qq|<select name="sellprice_pg_$i" style="width: 8em">$form->{"prices_$i"}</select>|;
-      $sellprice_value           =($form->{"new_pricegroup_$i"} != $form->{"old_pricegroup_$i"})
-                                      ? $form->format_amount(\%myconfig, $form->{"price_new_$i"}, $decimalplaces)
-                                      : $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
-    } else {
-      # for last row and report
-      # set pricegroup drop down list from report menu
-      if ($form->{"sellprice_$i"} != 0) {
-        # remember the pricegroup_id in pricegroup_old
-        # but don't overwrite it
-        $form->{"pricegroup_old_$i"} = $form->{"pricegroup_id_$i"};
-        my $default_option           = $form->{"sellprice_$i"}.'--'.$form->{"pricegroup_id_$i"};
-        $column_data{sellprice_pg}   = NTI($cgi->popup_menu("sellprice_pg_$i", [ $default_option ], $default_option, { $default_option => $form->{"pricegroup_$i"} || '' }));
-      } else {
-        $column_data{sellprice_pg} = qq|&nbsp;|;
-      }
-      $sellprice_value = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
-
-    }
-    # Falls der Benutzer die Preise nicht anpassen sollte, wird das entsprechende
-    # Textfield auf readonly gesetzt. Anm. von Sven: Manipulation der Preise ist
-    # immer noch möglich, konsequenterweise sollten diese NUR aus der Datenbank
-    # geholt werden.
-    my $edit_prices = $main::auth->assert('edit_prices', 1);
-    $column_data{sellprice} = (!$edit_prices)
-                                ? $cgi->textfield(-readonly => "readonly",
-                                                  -name => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value)
-                                : $cgi->textfield(-name => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value);
+    my $sellprice_value = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
+    my $edit_prices     = $main::auth->assert('edit_prices', 1) && !$::form->{"active_price_source_$i"};
+    $column_data{sellprice}   = (!$edit_prices)
+                                ? $cgi->hidden(   -name => "sellprice_$i", -id => "sellprice_$i", -value => $sellprice_value) . $sellprice_value
+                                : $cgi->textfield(-name => "sellprice_$i", -id => "sellprice_$i", -size => 10, -onBlur => "check_right_number_format(this)", -value => $sellprice_value);
     $column_data{discount}    = (!$edit_prices)
                                   ? $cgi->textfield(-readonly => "readonly",
                                                     -name => "discount_$i", -size => 3, -value => $form->format_amount(\%myconfig, $form->{"discount_$i"}))
     $column_data{discount}    = (!$edit_prices)
                                   ? $cgi->textfield(-readonly => "readonly",
                                                     -name => "discount_$i", -size => 3, -value => $form->format_amount(\%myconfig, $form->{"discount_$i"}))
@@ -349,6 +321,13 @@ sub display_row {
 
     $column_data{weight}      = $form->format_amount(\%myconfig, $form->{"qty_$i"} * $form->{"weight_$i"}, 3) . ' ' . $defaults->{weightunit} if $defaults->{show_weight};
 
 
     $column_data{weight}      = $form->format_amount(\%myconfig, $form->{"qty_$i"} * $form->{"weight_$i"}, 3) . ' ' . $defaults->{weightunit} if $defaults->{show_weight};
 
+    if ($form->{"id_${i}"}) {
+      my $price_source = SL::PriceSource->new(record_item => $record_item);
+      my $price = $price_source->price_from_source($::form->{"active_price_source_$i"});
+      $::form->{price_sources}[$i] = $price_source;
+      $column_data{price_source} .= $cgi->button(-value => $price->full_description, -onClick => "toggle_price_source($i)");
+    }
+
     if ($is_delivery_order) {
       $column_data{stock_in_out} =  calculate_stock_in_out($i);
     }
     if ($is_delivery_order) {
       $column_data{stock_in_out} =  calculate_stock_in_out($i);
     }
@@ -433,9 +412,7 @@ sub display_row {
 
     if ($is_delivery_order) {
       map { $form->{"${_}_${i}"} = $form->format_amount(\%myconfig, $form->{"${_}_${i}"}) } qw(sellprice discount lastcost);
 
     if ($is_delivery_order) {
       map { $form->{"${_}_${i}"} = $form->format_amount(\%myconfig, $form->{"${_}_${i}"}) } qw(sellprice discount lastcost);
-      $form->{"pricegroup_id_$i"} = $form->{"pricegroup_old_$i"} if $form->{"pricegroup_old_$i"};
-      $form->{"sellprice_pg_$i"}  = $form->{"hidden_prices_$i"}  if $form->{"hidden_prices_$i"};
-      push @hidden_vars, grep { defined $form->{"${_}_${i}"} } qw(sellprice discount not_discountable price_factor_id lastcost pricegroup_id sellprice_pg);
+      push @hidden_vars, grep { defined $form->{"${_}_${i}"} } qw(sellprice discount not_discountable price_factor_id lastcost);
       push @hidden_vars, "stock_${stock_in_out}_sum_qty", "stock_${stock_in_out}";
     }
 
       push @hidden_vars, "stock_${stock_in_out}_sum_qty", "stock_${stock_in_out}";
     }
 
@@ -443,7 +420,7 @@ sub display_row {
           $cgi->hidden("-name" => "unit_old_$i", "-value" => $form->{"selected_unit_$i"}),
           $cgi->hidden("-name" => "price_new_$i", "-value" => $form->format_amount(\%myconfig, $form->{"price_new_$i"})),
           map { ($cgi->hidden("-name" => $_, "-id" => $_, "-value" => $form->{$_})); } map { $_."_$i" }
           $cgi->hidden("-name" => "unit_old_$i", "-value" => $form->{"selected_unit_$i"}),
           $cgi->hidden("-name" => "price_new_$i", "-value" => $form->format_amount(\%myconfig, $form->{"price_new_$i"})),
           map { ($cgi->hidden("-name" => $_, "-id" => $_, "-value" => $form->{$_})); } map { $_."_$i" }
-            (qw(orderitems_id bo pricegroup_old price_old id inventory_accno bin partsgroup partnotes
+            (qw(orderitems_id bo price_old id inventory_accno bin partsgroup partnotes active_price_source
                 income_accno expense_accno listprice assembly taxaccounts ordnumber donumber transdate cusordnumber
                 longdescription basefactor marge_absolut marge_percent marge_price_factor weight), @hidden_vars)
     );
                 income_accno expense_accno listprice assembly taxaccounts ordnumber donumber transdate cusordnumber
                 longdescription basefactor marge_absolut marge_percent marge_price_factor weight), @hidden_vars)
     );
@@ -455,7 +432,7 @@ sub display_row {
     # Benutzerdefinierte Variablen für Waren/Dienstleistungen/Erzeugnisse
     _render_custom_variables_inputs(ROW2 => \@ROW2, row => $i, part_id => $form->{"id_$i"});
 
     # Benutzerdefinierte Variablen für Waren/Dienstleistungen/Erzeugnisse
     _render_custom_variables_inputs(ROW2 => \@ROW2, row => $i, part_id => $form->{"id_$i"});
 
-    push @ROWS, { ROW1 => \@ROW1, ROW2 => \@ROW2, HIDDENS => \@HIDDENS, colspan => $colspan, error => $form->{"row_error_$i"}, };
+    push @ROWS, { ROW1 => \@ROW1, ROW2 => \@ROW2, HIDDENS => \@HIDDENS, colspan => $colspan, error => $form->{"row_error_$i"}, obj => $record_item };
   }
 
   $form->{totalweight} = $totalweight;
   }
 
   $form->{totalweight} = $totalweight;
@@ -471,40 +448,6 @@ sub display_row {
   $main::lxdebug->leave_sub();
 }
 
   $main::lxdebug->leave_sub();
 }
 
-##################################################
-# build html-code for pricegroups in variable $form->{prices_$j}
-
-sub set_pricegroup {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my $locale   = $main::locale;
-  my $cgi      = $::request->{cgi};
-
-  _check_io_auth();
-
-  my $rowcount = shift;
-  for my $j (1 .. $rowcount) {
-    next unless $form->{PRICES}{$j};
-    # build drop down list for pricegroups
-    my $option_tmpl = qq|<option value="%s--%s" %s>%s</option>|;
-    $form->{"prices_$j"}  = join '', map { sprintf $option_tmpl, @$_{qw(price pricegroup_id selected pricegroup)} }
-                                         (+{ pricegroup => $locale->text("none (pricegroup)") }, @{ $form->{PRICES}{$j} });
-
-    foreach my $item (@{ $form->{PRICES}{$j} }) {
-      # set new selectedpricegroup_id and prices for "Preis"
-      $form->{"pricegroup_old_$j"} = $item->{pricegroup_id}   if $item->{selected} &&  $item->{pricegroup_id};
-      $form->{"sellprice_$j"}      = $item->{price}           if $item->{selected} &&  $item->{pricegroup_id};
-      $form->{"price_new_$j"}      = $form->{"sellprice_$j"}  if $item->{selected} || !$item->{pricegroup_id};
-    }
-
-    # save hidden pricegroups for delivery_orders
-    next unless my @selected_prices = grep { $_->{selected} } @{ $form->{PRICES}{$j} };
-    $form->{"hidden_prices_$j"} = $selected_prices[-1]{price} . "--" . $selected_prices[-1]{pricegroup_id};
-  }
-  $main::lxdebug->leave_sub();
-}
-
 sub select_item {
   $main::lxdebug->enter_sub();
 
 sub select_item {
   $main::lxdebug->enter_sub();
 
@@ -633,12 +576,6 @@ sub item_selected {
       $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces)
   } qw(sellprice listprice lastcost) if $form->{item} ne 'assembly';
 
       $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces)
   } qw(sellprice listprice lastcost) if $form->{item} ne 'assembly';
 
-  # get pricegroups for parts
-  IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-
-  # build up html code for prices_$i
-  set_pricegroup($form->{rowcount});
-
   &display_form;
 
   $main::lxdebug->leave_sub();
   &display_form;
 
   $main::lxdebug->leave_sub();
@@ -733,12 +670,6 @@ sub check_form {
       or (($form->{level} eq undef) and ($form->{type} =~ /invoice/))
       or ($form->{type} =~ /sales_order/)) {
 
       or (($form->{level} eq undef) and ($form->{type} =~ /invoice/))
       or ($form->{type} =~ /sales_order/)) {
 
-    # get pricegroups for parts
-    IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-
-    # build up html code for prices_$i
-    set_pricegroup($form->{rowcount});
-
   }
 
   &display_form;
   }
 
   &display_form;
@@ -757,7 +688,7 @@ sub remove_emptied_rows {
                 taxaccounts bin assembly weight projectnumber project_id
                 oldprojectnumber runningnumber serialnumber partsgroup payment_id
                 not_discountable shop ve gv buchungsgruppen_id language_values
                 taxaccounts bin assembly weight projectnumber project_id
                 oldprojectnumber runningnumber serialnumber partsgroup payment_id
                 not_discountable shop ve gv buchungsgruppen_id language_values
-                sellprice_pg pricegroup_old price_old price_new unit_old ordnumber donumber
+                price_old price_new unit_old ordnumber donumber
                 transdate longdescription basefactor marge_total marge_percent
                 marge_price_factor lastcost price_factor_id partnotes
                 stock_out stock_in has_sernumber reqdate orderitems_id);
                 transdate longdescription basefactor marge_total marge_percent
                 marge_price_factor lastcost price_factor_id partnotes
                 stock_out stock_in has_sernumber reqdate orderitems_id);
@@ -1714,12 +1645,6 @@ sub ship_to {
   # get details for customer/vendor
   call_sub($::form->{vc} . "_details", qw(name department_1 department_2 street zipcode city country contact email phone fax), $::form->{vc} . "number");
 
   # get details for customer/vendor
   call_sub($::form->{vc} . "_details", qw(name department_1 department_2 street zipcode city country contact email phone fax), $::form->{vc} . "number");
 
-  # get pricegroups for parts
-  IS->get_pricegroups_for_parts(\%::myconfig, \%$::form);
-
-  # build up html code for prices_$i
-  set_pricegroup($::form->{rowcount});
-
   $::form->{rowcount}--;
 
   my @shipto_vars   = qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry
   $::form->{rowcount}--;
 
   my @shipto_vars   = qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry
@@ -1964,3 +1889,43 @@ sub _remove_billed_or_delivered_rows {
   $::form->redo_rows(\@fields, \@new_rows, scalar(@new_rows), $::form->{rowcount});
   $::form->{rowcount} -= $removed_rows;
 }
   $::form->redo_rows(\@fields, \@new_rows, scalar(@new_rows), $::form->{rowcount});
   $::form->{rowcount} -= $removed_rows;
 }
+
+sub _make_record_item {
+  my ($row) = @_;
+
+  my $class = {
+    sales_order             => 'OrderItem',
+    purchase_oder           => 'OrderItem',
+    sales_quotation         => 'OrderItem',
+    request_quotation       => 'OrderItem',
+    invoice                 => 'InvoiceItem',
+    purchase_invoice        => 'InvoiceItem',
+    purchase_delivery_order => 'DeliveryOrderItem',
+    sales_delivery_order    => 'DeliveryOrderItem',
+  }->{$::form->{type}};
+
+  return unless $class;
+
+  $class = 'SL::DB::' . $class;
+
+  eval "require $class";
+
+  my $obj = $::form->{"orderitems_id_$row"}
+          ? $class->meta->convention_manager->auto_manager_class_name->find_by(id => $::form->{"orderitems_id_$row"})
+          : $class->new;
+
+  for my $method (apply { s/_$row$// } grep { /_$row$/ } keys %$::form) {
+    next unless $obj->meta->column($method);
+    if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) {
+      $obj->${\"$method\_as_date"}($::form->{"$method\_$row"});
+    } else {
+      $obj->$method($::form->{"$method\_$row"});
+    }
+  }
+
+  if ($::form->{"id_$row"}) {
+    $obj->part(SL::DB::Part->load_cached($::form->{"id_$row"}));
+  }
+
+  return $obj;
+}
index d2408ff..fa97118 100644 (file)
@@ -273,16 +273,6 @@ sub prepare_invoice {
       $form->{rowcount}        = $i;
 
     }
       $form->{rowcount}        = $i;
 
     }
-
-    # get pricegroups for parts
-    IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-
-    # Problem: set_pricegroup resets the sellprice of old invoices to the price
-    # currently defined in the pricegroup, which is a problem if the price has
-    # changed, as the old invoice gets the new price
-    # set_pricegroup must never be called, when an old invoice is initially loaded
-
-    # set_pricegroup($_) for 1 .. $form->{rowcount};
   }
   $main::lxdebug->leave_sub();
 }
   }
   $main::lxdebug->leave_sub();
 }
@@ -614,12 +604,6 @@ sub update {
         map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces) } qw(sellprice lastcost);
 
         $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"});
         map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces) } qw(sellprice lastcost);
 
         $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"});
-
-        # get pricegroups for parts
-        IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-
-        # build up html code for prices_$i
-        &set_pricegroup($i);
       }
 
       &display_form;
       }
 
       &display_form;
@@ -837,10 +821,6 @@ sub use_as_new {
   $form->{forex}        = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{invdate}, 'buy');
   $form->{exchangerate} = $form->{forex} if $form->{forex};
 
   $form->{forex}        = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{invdate}, 'buy');
   $form->{exchangerate} = $form->{forex} if $form->{forex};
 
-  # remember pricegroups for "use as new"
-  IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-  set_pricegroup($_) for 1 .. $form->{rowcount};
-
   &display_form;
 
   $main::lxdebug->leave_sub();
   &display_form;
 
   $main::lxdebug->leave_sub();
index ad5406c..b9abb0f 100644 (file)
@@ -594,6 +594,8 @@ sub update {
 
   check_oe_access();
 
 
   check_oe_access();
 
+  my $order = _make_record();
+
   set_headings($form->{"id"} ? "edit" : "add");
 
   $form->{update} = 1;
   set_headings($form->{"id"} ? "edit" : "add");
 
   $form->{update} = 1;
@@ -692,12 +694,6 @@ sub update {
         $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
         $form->{"lastcost_$i"}  = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces);
         $form->{"qty_$i"}       = $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);
         $form->{"sellprice_$i"} = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
         $form->{"lastcost_$i"}  = $form->format_amount(\%myconfig, $form->{"lastcost_$i"}, $decimalplaces);
         $form->{"qty_$i"}       = $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);
-
-        # get pricegroups for parts
-        IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-
-        # build up html code for prices_$i
-        &set_pricegroup($i);
       }
 
       display_form();
       }
 
       display_form();
@@ -1510,10 +1506,6 @@ sub invoice {
       $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);
   }
 
       $form->format_amount(\%myconfig, $form->{"qty_$i"}, $dec_qty);
   }
 
-  #  show pricegroup in newly loaded invoice when creating invoice from quotation/order
-  IS->get_pricegroups_for_parts(\%myconfig, \%$form);
-  set_pricegroup($_) for 1 .. $form->{rowcount};
-
   &display_form;
 
   $main::lxdebug->leave_sub();
   &display_form;
 
   $main::lxdebug->leave_sub();
@@ -2118,3 +2110,29 @@ sub dispatcher {
 
   $::form->error($::locale->text('No action defined.'));
 }
 
   $::form->error($::locale->text('No action defined.'));
 }
+
+sub _make_record {
+  my $obj = SL::DB::Order->new;
+
+  for my $method (keys %$::form) {
+    next unless $obj->can($method);
+    next unless $obj->meta->column($method);
+
+    if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) {
+      $obj->${\"$method\_as_date"}($::form->{$method});
+    } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Integer|Numeric|Float|DoublePrecsion)$/) {
+      $obj->$method($::form->{$method});
+    }
+  }
+
+  my @items;
+  for my $i (1 .. $::form->{rowcount}) {
+    next unless $::form->{"id_$i"};
+    push @items, _make_record_item($i)
+  }
+
+  $obj->orderitems(@items);
+
+  return $obj;
+}
+
index 4c2c0b7..a70f791 100755 (executable)
@@ -1596,6 +1596,7 @@ $self->{texts} = {
   'No.'                         => 'Position',
   'No/individual shipping address' => 'Keine/individuelle Lieferadresse',
   'None'                        => 'Kein',
   'No.'                         => 'Position',
   'No/individual shipping address' => 'Keine/individuelle Lieferadresse',
   'None'                        => 'Kein',
+  'None (PriceSource)'          => 'Freier Preis',
   'Normal users cannot log in.' => 'Normale Benutzer können sich nicht anmelden.',
   'Normalize Customer / Vendor names' => 'Normalisierung Kunden- / Lieferantennamen',
   'Normalize part description and part notes' => 'Normalisierung Artikelbeschreibung und Artikellangtext (Bemerkung)',
   'Normal users cannot log in.' => 'Normale Benutzer können sich nicht anmelden.',
   'Normalize Customer / Vendor names' => 'Normalisierung Kunden- / Lieferantennamen',
   'Normalize part description and part notes' => 'Normalisierung Artikelbeschreibung und Artikellangtext (Bemerkung)',
@@ -1832,6 +1833,7 @@ $self->{texts} = {
   'Price'                       => 'Preis',
   'Price Factor'                => 'Preisfaktor',
   'Price Factors'               => 'Preisfaktoren',
   'Price'                       => 'Preis',
   'Price Factor'                => 'Preisfaktor',
   'Price Factors'               => 'Preisfaktoren',
+  'Price Source'                => 'Preisquelle',
   'Price factor (database ID)'  => 'Preisfaktor (Datenbank-ID)',
   'Price factor (name)'         => 'Preisfaktor (Name)',
   'Price factor deleted!'       => 'Preisfaktor gel&ouml;scht.',
   'Price factor (database ID)'  => 'Preisfaktor (Datenbank-ID)',
   'Price factor (name)'         => 'Preisfaktor (Name)',
   'Price factor deleted!'       => 'Preisfaktor gel&ouml;scht.',
@@ -3051,7 +3053,6 @@ $self->{texts} = {
   'no article assigned yet'     => 'noch kein Artikel zugewiesen',
   'no bestbefore'               => 'keine Mindesthaltbarkeit',
   'no chargenumber'             => 'keine Chargennummer',
   'no article assigned yet'     => 'noch kein Artikel zugewiesen',
   'no bestbefore'               => 'keine Mindesthaltbarkeit',
   'no chargenumber'             => 'keine Chargennummer',
-  'none (pricegroup)'           => 'keine',
   'not configured'              => 'nicht konfiguriert',
   'not delivered'               => 'nicht geliefert',
   'not executed'                => 'nicht ausgeführt',
   'not configured'              => 'nicht konfiguriert',
   'not delivered'               => 'nicht geliefert',
   'not executed'                => 'nicht ausgeführt',
diff --git a/sql/Pg-upgrade2/recorditem_active_price_source.sql b/sql/Pg-upgrade2/recorditem_active_price_source.sql
new file mode 100644 (file)
index 0000000..c391335
--- /dev/null
@@ -0,0 +1,8 @@
+-- @tag: recorditem_active_price_source
+-- @description: Preisquelle in Belegpositionen
+-- @depends: release_2_6_2
+-- @encoding: utf-8
+
+ALTER TABLE orderitems ADD COLUMN active_price_source TEXT NOT NULL DEFAULT '';
+ALTER TABLE delivery_order_items ADD COLUMN active_price_source TEXT NOT NULL DEFAULT '';
+ALTER TABLE invoice ADD COLUMN active_price_source TEXT NOT NULL DEFAULT '';
diff --git a/templates/webpages/oe/_price_sources_row.html b/templates/webpages/oe/_price_sources_row.html
new file mode 100644 (file)
index 0000000..a58e139
--- /dev/null
@@ -0,0 +1,16 @@
+[%- USE T8 %]
+[%- USE HTML %]
+[%- USE L %]
+[%- USE LxERP %]
+<tr class="listrow[% i % 2 %]" id="row[% i %]_3" style='display:none'>
+ <td colspan="[% row.colspan %]">
+   <span class="[% IF !row.obj.active_price_source %]bold[% END %]">
+   [% L.radio_button_tag('active_price_source_' _ i, label=LxERP.t8('None (PriceSource)'), checked=!row.obj.active_price_source, value='', onChange='update_price_source(' _ i _ ', \'\')') %]
+   </span>
+   [%- FOREACH price IN price_sources.$i.available_prices %]
+     <div class="[% IF price.source == row.obj.active_price_source %]bold[% END %]">
+     [% L.radio_button_tag('active_price_source_' _ i, value=price.source, checked=price.source == row.obj.active_price_source, label=LxERP.format_amount(price.price, 2) _ ' (' _ price.full_description _ ')', onChange='update_price_source(' _ i _ ', \'' _ price.source _ '\', \'' _ LxERP.format_amount(price.price, -2) _ '\')' ) %]
+     </div>
+   [%- END %]
+ </td>
+</tr>
index f8db6ba..91f0a56 100644 (file)
@@ -1,6 +1,7 @@
 [%- USE T8 %]
 [%- USE HTML %]
 [%- USE T8 %]
 [%- USE HTML %]
-
+[%- USE L %]
+[%- USE LxERP %]
 [%- PROCESS 'amcvar/render_inputs_block.html' %]
 <tr>
  <td>
 [%- PROCESS 'amcvar/render_inputs_block.html' %]
 <tr>
  <td>
@@ -74,6 +75,7 @@
 
       </td>
      </tr>
 
       </td>
      </tr>
+ [% PROCESS 'oe/_price_sources_row.html' i = loop.count %]
 [%- END %]
 
   </table>
 [%- END %]
 
   </table>
         [% END %]
       }, 1);
     });
         [% END %]
       }, 1);
     });
+    function toggle_price_source(row) {
+      $('#row' + row + '_3').toggle();
+    }
+    function update_price_source(row, source, price_str){
+      $('#active_price_source_' + row).val(source);
+      if (price_str) $('#sellprice_' + row).val(price_str);
+      $('#update_button').click();
+    }
   </script>
 
  </td>
   </script>
 
  </td>