]> wagnertech.de Git - kivitendo-erp.git/commitdiff
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 07ad5b11de1bdb94765f37a7d0281d1de86f146a..fca37f59b0ea02273b5216085cc848dec45a43f9 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 76c890abcbc91c41ca77107436644992059de650..d4789d640ffa5a551e01d7500c5d81c28e003a8d 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 7cd853ec23e243941bdf7a6a955078b9a806a970..26ce472f9c9a69ebc09fbbd08e5ece0181aa3ace 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 85bf5bee6d8fa100eeb3d8f011993465881e0259..2bd6bf54239ffcadd25dd4f77ec0fef814856ab8 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 89f2d92b60d26cc7a7f06769813efac5f3a3ec37..a37e516f171b798685edc94cab9ae4d02ab91f6c 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 29886a5bb189dead2d78f47b1733585434fe3cb1..5c156a67506cffad6af381ec7373323de8d75add 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 faaaa3383a9dda526bd95f2961bbca597b78a1a6..506db6bdc873271122cd5fa0adc7f4b77672703e 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 b25cdadb496570f8473a996b3551b8b55ca1abff..1bda974ab48e9ab021f49207702544a692a658a0 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 7ff034702805b0e6ec17aad77db1be8b1cddf50b..a1098020d82e5b00cc061a97dab5f862a2458593 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 5a17d680abc7d0333420e4eb990808e784900b25..e9fbad82a12c9c06aa3b8478fffaac068f7c4d3e 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 d2408ffff3a28f4c05b841888bf2265947450b80..fa97118d991c9ff914a753df1c01b248aaf4b36c 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 ad5406c90699d7e252bd5ddcea0e46fdb971492e..b9abb0f160c1592caf9397677716588fc81abd9b 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 4c2c0b7e537f495a7f7c672b8cad2917213d335a..a70f7917624f9aa038e64dc84c50712a0909ca28 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 f8db6ba8268c9d85c50bee15bf705724bcce32ce..91f0a56c664fab08ad4515abe8f138dfed0533fd 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>