Part Controller - ic.pl und IC.pm Funktionen entfernt
authorG. Richardson <information@kivitendo-premium.de>
Thu, 1 Dec 2016 14:08:31 +0000 (15:08 +0100)
committerG. Richardson <information@kivitendo-premium.de>
Thu, 1 Dec 2016 14:43:05 +0000 (15:43 +0100)
SL/IC.pm
bin/mozilla/ic.pl

index 2cf7996..2b3abf6 100644 (file)
--- a/SL/IC.pm
+++ b/SL/IC.pm
@@ -48,138 +48,6 @@ use Carp;
 
 use strict;
 
-sub get_part {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-
-  # connect to db
-  my $dbh = $form->get_standard_dbh;
-
-  my $sth;
-
-  my $query =
-    qq|SELECT p.*,
-         c1.accno AS inventory_accno,
-         c2.accno AS income_accno,
-         c3.accno AS expense_accno,
-         pg.partsgroup
-       FROM parts p
-       LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
-       LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
-       LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
-       LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
-       WHERE p.id = ? |;
-  my $ref = selectfirst_hashref_query($form, $dbh, $query, conv_i($form->{id}));
-
-  # copy to $form variables
-  map { $form->{$_} = $ref->{$_} } (keys %{$ref});
-
-  $form->{mtime} = $form->{itime} if !$form->{mtime};
-  $form->{lastmtime} = $form->{mtime};
-  $form->{onhand} *= 1;
-
-  # part or service item
-  if ($form->{part_type} eq 'assembly') {
-
-    # retrieve assembly items
-    $query =
-      qq|SELECT p.id, p.partnumber, p.description,
-           p.sellprice, p.lastcost, p.weight, a.qty, a.bom, p.unit,
-           pg.partsgroup, p.price_factor_id, pfac.factor AS price_factor
-         FROM parts p
-         JOIN assembly a ON (a.parts_id = p.id)
-         LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
-         LEFT JOIN price_factors pfac ON pfac.id = p.price_factor_id
-         WHERE (a.id = ?)
-         ORDER BY a.oid|;
-    $sth = prepare_execute_query($form, $dbh, $query, conv_i($form->{id}));
-
-    $form->{assembly_rows} = 0;
-    while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
-      $form->{assembly_rows}++;
-      foreach my $key (keys %{$ref}) {
-        $form->{"${key}_$form->{assembly_rows}"} = $ref->{$key};
-      }
-    }
-    $sth->finish;
-
-  }
-
-  # setup accno hash for <option checked> {amount} is used in create_links
-  $form->{amount}{IC}         = $form->{inventory_accno};
-  $form->{amount}{IC_income}  = $form->{income_accno};
-  $form->{amount}{IC_sale}    = $form->{income_accno};
-  $form->{amount}{IC_expense} = $form->{expense_accno};
-  $form->{amount}{IC_cogs}    = $form->{expense_accno};
-
-  # get prices
-  $query = <<SQL;
-    SELECT pg.pricegroup, pg.id AS pricegroup_id, COALESCE(pr.price, 0) AS price
-    FROM pricegroup pg
-    LEFT JOIN prices pr ON (pr.pricegroup_id = pg.id) AND (pr.parts_id = ?)
-    ORDER BY lower(pg.pricegroup)
-SQL
-
-  my $row = 1;
-  foreach $ref (selectall_hashref_query($form, $dbh, $query, conv_i($form->{id}))) {
-    $form->{"${_}_${row}"} = $ref->{$_} for qw(pricegroup_id pricegroup price);
-    $row++;
-  }
-  $form->{price_rows} = $row - 1;
-
-  # get makes
-  if ($form->{makemodel}) {
-  #hli
-    $query = qq|SELECT m.make, m.model,m.lastcost,m.lastcost,m.lastupdate,m.sortorder FROM makemodel m | .
-             qq|WHERE m.parts_id = ? order by m.sortorder asc|;
-    my @values = ($form->{id});
-    $sth = $dbh->prepare($query);
-    $sth->execute(@values) || $form->dberror("$query (" . join(', ', @values) . ")");
-
-    my $i = 1;
-
-    while (($form->{"make_$i"}, $form->{"model_$i"}, $form->{"old_lastcost_$i"},
-              $form->{"lastcost_$i"}, $form->{"lastupdate_$i"}, $form->{"sortorder_$i"}) = $sth->fetchrow_array)
-    {
-      $i++;
-    }
-    $sth->finish;
-    $form->{makemodel_rows} = $i - 1;
-
-  }
-
-  # get translations
-  $query = qq|SELECT language_id, translation, longdescription
-              FROM translation
-              WHERE parts_id = ?|;
-  $form->{translations} = selectall_hashref_query($form, $dbh, $query, conv_i($form->{id}));
-
-  # is it an orphan
-  my @referencing_tables = qw(invoice orderitems inventory);
-  my %column_map         = ( );
-  my $parts_id           = conv_i($form->{id});
-
-  $form->{orphaned}      = 1;
-
-  foreach my $table (@referencing_tables) {
-    my $column  = $column_map{$table} || 'parts_id';
-    $query      = qq|SELECT $column FROM $table WHERE $column = ? LIMIT 1|;
-    my ($found) = selectrow_query($form, $dbh, $query, $parts_id);
-
-    if ($found) {
-      $form->{orphaned} = 0;
-      last;
-    }
-  }
-
-  $form->{"unit_changeable"} = $form->{orphaned};
-
-  Common::webdav_folder($form) if $::lx_office_conf{features}{webdav};
-
-  $main::lxdebug->leave_sub();
-}
-
 sub get_pricegroups {
   $main::lxdebug->enter_sub();
 
@@ -223,328 +91,6 @@ sub retrieve_buchungsgruppen {
   $main::lxdebug->leave_sub();
 }
 
-sub save {
-  my ($self, $myconfig, $form) = @_;
-  $main::lxdebug->enter_sub();
-
-  my $rc = SL::DB->client->with_transaction(\&_save, $self, $myconfig, $form);
-
-  $main::lxdebug->leave_sub();
-  return $rc;
-}
-
-sub _save {
-  my ($self, $myconfig, $form) = @_;
-  my @values;
-
-  my $dbh = SL::DB->client->dbh;
-  my $restricter = SL::HTML::Restrict->create;
-
-  # save the part
-  # make up a unique handle and store in partnumber field
-  # then retrieve the record based on the unique handle to get the id
-  # replace the partnumber field with the actual variable
-  # add records for makemodel
-
-  # if there is a $form->{id} then replace the old entry
-  # delete all makemodel entries and add the new ones
-
-  # undo amount formatting
-  map { $form->{$_} = $form->parse_amount($myconfig, $form->{$_}) }
-    qw(rop weight listprice sellprice gv lastcost);
-
-  my $makemodel = ($form->{make_1} || $form->{model_1} || ($form->{makemodel_rows} > 1)) ? 1 : 0;
-
-
-  my ($query, $sth);
-
-  my $priceupdate = ', priceupdate = current_date';
-
-  if ($form->{id}) {
-    my $trans_number = SL::TransNumber->new(type => $form->{part_type}, dbh => $dbh, number => $form->{partnumber}, id => $form->{id});
-    if (!$trans_number->is_unique) {
-      $::lxdebug->leave_sub;
-      return 3;
-    }
-
-    # get old price
-    $query = qq|SELECT sellprice FROM parts WHERE id = ?|;
-    my ($sellprice) = selectrow_query($form, $dbh, $query, conv_i($form->{id}));
-
-    # delete makemodel records
-    do_query($form, $dbh, qq|DELETE FROM makemodel WHERE parts_id = ?|, conv_i($form->{id}));
-
-    if ($form->{part_type} eq 'assembly') {
-      # delete assembly records
-      do_query($form, $dbh, qq|DELETE FROM assembly WHERE id = ?|, conv_i($form->{id}));
-    }
-
-    # delete translations
-    do_query($form, $dbh, qq|DELETE FROM translation WHERE parts_id = ?|, conv_i($form->{id}));
-
-    # Check whether or not the prices have changed. If they haven't
-    # then 'priceupdate' should not be updated.
-    my $previous_values = selectfirst_hashref_query($form, $dbh, qq|SELECT * FROM parts WHERE id = ?|, conv_i($form->{id})) || {};
-    $priceupdate        = '' if (all { $previous_values->{$_} == $form->{$_} } qw(sellprice lastcost listprice));
-
-  } else {
-    my $trans_number = SL::TransNumber->new(type => $form->{part_type}, dbh => $dbh, number => $form->{partnumber}, save => 1);
-
-    if ($form->{partnumber} && !$trans_number->is_unique) {
-      $::lxdebug->leave_sub;
-      return 3;
-    }
-
-    $form->{partnumber} ||= $trans_number->create_unique;
-
-    ($form->{id}) = selectrow_query($form, $dbh, qq|SELECT nextval('id')|);
-    do_query($form, $dbh, qq|INSERT INTO parts (id, partnumber, unit, part_type) VALUES (?, ?, ?, ?)|, $form->{id}, $form->{partnumber}, $form->{unit}, $form->{part_type});
-
-    $form->{orphaned} = 1;
-  }
-  my $partsgroup_id = undef;
-
-  if ($form->{partsgroup}) {
-    (my $partsgroup, $partsgroup_id) = split(/--/, $form->{partsgroup});
-  }
-
-  my ($subq_inventory, $subq_expense, $subq_income);
-  if ($form->{part_type} eq "part") {
-    $subq_inventory =
-      qq|(SELECT bg.inventory_accno_id
-          FROM buchungsgruppen bg
-          WHERE bg.id = | . conv_i($form->{"buchungsgruppen_id"}, 'NULL') . qq|)|;
-  } else {
-    $subq_inventory = "NULL";
-  }
-
-  if ($form->{part_type} ne "assembly") {
-    $subq_expense =
-      qq|(SELECT tc.expense_accno_id
-          FROM taxzone_charts tc
-          WHERE tc.buchungsgruppen_id = | . conv_i($form->{"buchungsgruppen_id"}, 'NULL') . qq| and tc.taxzone_id = 0)|;
-  } else {
-    $subq_expense = "NULL";
-  }
-
-  normalize_text_blocks();
-
-  $query =
-    qq|UPDATE parts SET
-         partnumber = ?,
-         description = ?,
-         makemodel = ?,
-         listprice = ?,
-         sellprice = ?,
-         lastcost = ?,
-         weight = ?,
-         unit = ?,
-         notes = ?,
-         formel = ?,
-         rop = ?,
-         warehouse_id = ?,
-         bin_id = ?,
-         buchungsgruppen_id = ?,
-         payment_id = ?,
-         inventory_accno_id = $subq_inventory,
-         income_accno_id = (SELECT tc.income_accno_id FROM taxzone_charts tc WHERE tc.taxzone_id = 0 and tc.buchungsgruppen_id = ?),
-         expense_accno_id = $subq_expense,
-         obsolete = ?,
-         image = ?,
-         drawing = ?,
-         shop = ?,
-         ve = ?,
-         gv = ?,
-         ean = ?,
-         has_sernumber = ?,
-         not_discountable = ?,
-         microfiche = ?,
-         part_type = ?,
-         partsgroup_id = ?,
-         price_factor_id = ?
-         $priceupdate
-       WHERE id = ?|;
-  @values = ($form->{partnumber},
-             $form->{description},
-             $makemodel ? 't' : 'f',
-             $form->{listprice},
-             $form->{sellprice},
-             $form->{lastcost},
-             $form->{weight},
-             $form->{unit},
-             $restricter->process($form->{notes}),
-             $form->{formel},
-             $form->{rop},
-             conv_i($form->{warehouse_id}),
-             conv_i($form->{bin_id}),
-             conv_i($form->{buchungsgruppen_id}),
-             conv_i($form->{payment_id}),
-             conv_i($form->{buchungsgruppen_id}),
-             $form->{obsolete} ? 't' : 'f',
-             $form->{image},
-             $form->{drawing},
-             $form->{shop} ? 't' : 'f',
-             conv_i($form->{ve}),
-             conv_i($form->{gv}),
-             $form->{ean},
-             $form->{has_sernumber} ? 't' : 'f',
-             $form->{not_discountable} ? 't' : 'f',
-             $form->{microfiche},
-             $form->{part_type},
-             conv_i($partsgroup_id),
-             conv_i($form->{price_factor_id}),
-             conv_i($form->{id})
-  );
-  do_query($form, $dbh, $query, @values);
-
-  $form->new_lastmtime('parts');
-
-  # delete translation records
-  do_query($form, $dbh, qq|DELETE FROM translation WHERE parts_id = ?|, conv_i($form->{id}));
-
-  my @translations = grep { $_->{language_id} && $_->{translation} } @{ $form->{translations} || [] };
-  if (@translations) {
-    $query = qq|INSERT into translation (parts_id, language_id, translation, longdescription)
-                VALUES ( ?, ?, ?, ? )|;
-    $sth   = $dbh->prepare($query);
-
-    foreach my $translation (@translations) {
-      do_statement($form, $sth, $query, conv_i($form->{id}), conv_i($translation->{language_id}), $translation->{translation}, $restricter->process($translation->{longdescription}));
-    }
-
-    $sth->finish();
-  }
-
-  # delete price records
-  do_query($form, $dbh, qq|DELETE FROM prices WHERE parts_id = ?|, conv_i($form->{id}));
-
-  $query = qq|INSERT INTO prices (parts_id, pricegroup_id, price) VALUES(?, ?, ?)|;
-  $sth   = prepare_query($form, $dbh, $query);
-
-  for my $i (1 .. $form->{price_rows}) {
-    my $price = $form->parse_amount($myconfig, $form->{"price_$i"});
-    next unless $price;
-
-    @values = (conv_i($form->{id}), conv_i($form->{"pricegroup_id_$i"}), $price);
-    do_statement($form, $sth, $query, @values);
-  }
-
-  $sth->finish;
-
-  # insert makemodel records
-    my $lastupdate = '';
-    my $value = 0;
-    for my $i (1 .. $form->{makemodel_rows}) {
-      if (($form->{"make_$i"}) || ($form->{"model_$i"})) {
-        #hli
-        $value = $form->parse_amount($myconfig, $form->{"lastcost_$i"});
-        if ($value == $form->parse_amount($myconfig, $form->{"old_lastcost_$i"}))
-        {
-            if ($form->{"lastupdate_$i"} eq "") {
-                $lastupdate = 'now()';
-            } else {
-                $lastupdate = $dbh->quote($form->{"lastupdate_$i"});
-            }
-        } else {
-            $lastupdate = 'now()';
-        }
-        $query = qq|INSERT INTO makemodel (parts_id, make, model, lastcost, lastupdate, sortorder) | .
-                 qq|VALUES (?, ?, ?, ?, ?, ?)|;
-        @values = (conv_i($form->{id}), conv_i($form->{"make_$i"}), $form->{"model_$i"}, $value, $lastupdate, conv_i($form->{"sortorder_$i"}) );
-
-        do_query($form, $dbh, $query, @values);
-      }
-    }
-
-  # add assembly records
-  if ($form->{part_type} eq 'assembly') {
-    # check additional assembly row
-    my $i = $form->{assembly_rows};
-    # if last row is not empty add them
-    if ($form->{"partnumber_$i"} ne "") {
-      $query = qq|SELECT id FROM parts WHERE partnumber = ?|;
-      my ($partid) = selectrow_query($form, $dbh, $query,$form->{"partnumber_$i"} );
-      if ( $partid ) {
-        $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
-        $form->{"id_$i"} = $partid;
-        $form->{"bom_$i"} = 0;
-        $form->{assembly_rows}++;
-      }
-      else {
-        $::form->error($::locale->text("uncorrect partnumber ").$form->{"partnumber_$i"});
-      }
-    }
-
-    for my $i (1 .. $form->{assembly_rows}) {
-      $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
-
-      if ($form->{"qty_$i"} != 0) {
-        $form->{"bom_$i"} *= 1;
-        $query = qq|INSERT INTO assembly (id, parts_id, qty, bom) | .
-                 qq|VALUES (?, ?, ?, ?)|;
-        @values = (conv_i($form->{id}), conv_i($form->{"id_$i"}), conv_i($form->{"qty_$i"}), $form->{"bom_$i"} ? 't' : 'f');
-        do_query($form, $dbh, $query, @values);
-      }
-    }
-    my @a = localtime;
-    $a[5] += 1900;
-    $a[4]++;
-    my $shippingdate = "$a[5]-$a[4]-$a[3]";
-
-    $form->get_employee($dbh);
-
-  }
-
-  #set expense_accno=inventory_accno if they are different => bilanz
-  my $vendor_accno =
-    ($form->{expense_accno} != $form->{inventory_accno})
-    ? $form->{inventory_accno}
-    : $form->{expense_accno};
-
-  # get tax rates and description
-  my $accno_id =
-    ($form->{vc} eq "customer") ? $form->{income_accno} : $vendor_accno;
-  $query =
-    qq|SELECT c.accno, c.description, t.rate, t.taxnumber
-       FROM chart c, tax t
-       WHERE (c.id = t.chart_id) AND (t.taxkey IN (SELECT taxkey_id FROM chart where accno = ?))
-       ORDER BY c.accno|;
-  my $stw = prepare_execute_query($form, $dbh, $query, $accno_id);
-
-  $form->{taxaccount} = "";
-  while (my $ptr = $stw->fetchrow_hashref("NAME_lc")) {
-    $form->{taxaccount} .= "$ptr->{accno} ";
-    if (!($form->{taxaccount2} =~ /\Q$ptr->{accno}\E/)) {
-      $form->{"$ptr->{accno}_rate"}        = $ptr->{rate};
-      $form->{"$ptr->{accno}_description"} = $ptr->{description};
-      $form->{"$ptr->{accno}_taxnumber"}   = $ptr->{taxnumber};
-      $form->{taxaccount2} .= " $ptr->{accno} ";
-    }
-  }
-
-  CVar->save_custom_variables(dbh           => $dbh,
-                              module        => 'IC',
-                              trans_id      => $form->{id},
-                              variables     => $form,
-                              save_validity => 1);
-
-  # Delete saved custom variable values for configs that have been
-  # marked invalid for this part.
-  $query = <<SQL;
-    DELETE FROM custom_variables
-    WHERE (config_id IN (
-        SELECT val.config_id
-        FROM custom_variables_validity val
-        LEFT JOIN custom_variable_configs val_cfg ON (val.config_id = val_cfg.id)
-        WHERE (val_cfg.module = 'IC')
-          AND (val.trans_id   = ?)))
-      AND (trans_id = ?)
-SQL
-  do_query($form, $dbh, $query, ($form->{id}) x 2);
-
-  return 1;
-}
-
 sub retrieve_assemblies {
   $main::lxdebug->enter_sub();
 
@@ -581,30 +127,6 @@ sub retrieve_assemblies {
   $main::lxdebug->leave_sub();
 }
 
-sub delete {
-  my ($self, $myconfig, $form) = @_;
-  $main::lxdebug->enter_sub();
-
-  my $rc = SL::DB->client->with_transaction(\&_delete, $self, $myconfig, $form);
-
-  $main::lxdebug->leave_sub();
-  return $rc;
-}
-
-sub _delete {
-  my ($self, $myconfig, $form) = @_;
-  my @values = (conv_i($form->{id}));
-
-  my %columns = ( "assembly" => "id", "parts" => "id" );
-
-  for my $table (qw(prices makemodel inventory assembly translation parts)) {
-    my $column = defined($columns{$table}) ? $columns{$table} : "parts_id";
-    do_query($form, SL::DB->client->dbh, qq|DELETE FROM $table WHERE $column = ?|, @values);
-  }
-
-  return 1;
-}
-
 sub assembly_item {
   $main::lxdebug->enter_sub();
 
@@ -1302,71 +824,6 @@ sub _update_prices {
   return $num_updated;
 }
 
-sub create_links {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $module, $myconfig, $form) = @_;
-
-  # connect to database
-  my $dbh = $form->get_standard_dbh;
-
-  my @values = like($module);
-  my $query;
-
-  if ($form->{id}) {
-    $query =
-      qq|SELECT c.accno, c.description, c.link, c.id,
-           p.inventory_accno_id, p.income_accno_id, p.expense_accno_id
-         FROM chart c, parts p
-         WHERE (c.link LIKE ?) AND (p.id = ?)
-         ORDER BY c.accno|;
-    push(@values, conv_i($form->{id}));
-
-  } else {
-    $query =
-      qq|SELECT c.accno, c.description, c.link, c.id,
-           d.inventory_accno_id, d.income_accno_id, d.expense_accno_id
-         FROM chart c, defaults d
-         WHERE c.link LIKE ?
-         ORDER BY c.accno|;
-  }
-
-  my $sth = prepare_execute_query($form, $dbh, $query, @values);
-  while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
-    foreach my $key (split(/:/, $ref->{link})) {
-      if ($key =~ /\Q$module\E/) {
-        if (   ($ref->{id} eq $ref->{inventory_accno_id})
-            || ($ref->{id} eq $ref->{income_accno_id})
-            || ($ref->{id} eq $ref->{expense_accno_id})) {
-          push @{ $form->{"${module}_links"}{$key} },
-            { accno       => $ref->{accno},
-              description => $ref->{description},
-              selected    => "selected" };
-          $form->{"${key}_default"} = "$ref->{accno}--$ref->{description}";
-            } else {
-          push @{ $form->{"${module}_links"}{$key} },
-            { accno       => $ref->{accno},
-              description => $ref->{description},
-              selected    => "" };
-        }
-      }
-    }
-  }
-  $sth->finish;
-
-  # get buchungsgruppen
-  $form->{BUCHUNGSGRUPPEN} = selectall_hashref_query($form, $dbh, qq|SELECT id, description FROM buchungsgruppen|);
-
-  # get payment terms
-  $form->{payment_terms} = selectall_hashref_query($form, $dbh, qq|SELECT id, description FROM payment_terms ORDER BY sortkey|);
-
-  if (!$form->{id}) {
-    ($form->{priceupdate}) = selectrow_query($form, $dbh, qq|SELECT current_date|);
-  }
-
-  $main::lxdebug->leave_sub();
-}
-
 # get partnumber, description, unit, sellprice and soldtotal with choice through $sortorder for Top100
 sub get_parts {
   $main::lxdebug->enter_sub();
@@ -1436,39 +893,6 @@ sub get_soldtotal {
   return $sum;
 }    #end get_soldtotal
 
-sub retrieve_languages {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-
-  # connect to database
-  my $dbh = $form->get_standard_dbh;
-
-  my @values;
-  my $where;
-  my $query;
-
-  if ($form->{language_values} ne "") {
-    $query =
-      qq|SELECT l.id, l.description, tr.translation, tr.longdescription
-         FROM language l
-         LEFT OUTER JOIN translation tr ON (tr.language_id = l.id) AND (tr.parts_id = ?)
-         ORDER BY lower(l.description)|;
-    @values = (conv_i($form->{id}));
-
-  } else {
-    $query = qq|SELECT id, description
-                FROM language
-                ORDER BY lower(description)|;
-  }
-
-  my $languages = selectall_hashref_query($form, $dbh, $query, @values);
-
-  $main::lxdebug->leave_sub();
-
-  return $languages;
-}
-
 sub follow_account_chain {
   $main::lxdebug->enter_sub(2);
 
index d3cd910..47a1983 100644 (file)
@@ -74,23 +74,6 @@ require "bin/mozilla/reportgenerator.pl";
 
 # end of main
 
-sub add {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_edit');
-
-  my $title                = 'Add ' . ucfirst $form->{part_type};
-  $form->{title}           = $locale->text($title);
-  $form->{callback}        = "$form->{script}?action=add&part_type=$form->{part_type}" unless $form->{callback};
-  $form->{unit_changeable} = 1;
-
-  IC->get_pricegroups(\%myconfig, \%$form);
-  &link_part;
-  &display_form;
-
-  $lxdebug->leave_sub();
-}
-
 sub search {
   $lxdebug->enter_sub();
 
@@ -732,630 +715,6 @@ sub parts_subtotal {
   $lxdebug->leave_sub();
 }
 
-sub edit {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_details');
-
-  # show history button
-  $form->{javascript} = qq|<script type="text/javascript" src="js/show_history.js"></script>|;
-  #/show hhistory button
-  IC->get_part(\%myconfig, \%$form);
-
-  $form->{"original_partnumber"} = $form->{"partnumber"};
-
-  my $title      = 'Edit ' . ucfirst $form->{part_type};
-  $form->{title} = $locale->text($title);
-
-  &link_part;
-  &display_form;
-
-  $lxdebug->leave_sub();
-}
-
-sub link_part {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_details');
-
-  IC->create_links("IC", \%myconfig, \%$form);
-
-  # currencies
-  map({ $form->{selectcurrency} .= "<option>$_\n" } $::form->get_all_currencies());
-
-  # parts and assemblies have the same links
-  my $item = $form->{part_type};
-  if ($form->{part_type} eq 'assembly') {
-    $item = 'part';
-  }
-
-  # build the popup menus
-  $form->{taxaccounts} = "";
-  foreach my $key (keys %{ $form->{IC_links} }) {
-    foreach my $ref (@{ $form->{IC_links}{$key} }) {
-
-      # if this is a tax field
-      if ($key =~ /IC_tax/) {
-        if ($key =~ /\Q$item\E/) {
-          $form->{taxaccounts} .= "$ref->{accno} ";
-          $form->{"IC_tax_$ref->{accno}_description"} =
-            "$ref->{accno}--$ref->{description}";
-
-          if ($form->{id}) {
-            if ($form->{amount}{ $ref->{accno} }) {
-              $form->{"IC_tax_$ref->{accno}"} = "checked";
-            }
-          } else {
-            $form->{"IC_tax_$ref->{accno}"} = "checked";
-          }
-        }
-      } else {
-
-        $form->{"select$key"} .=
-          "<option $ref->{selected}>$ref->{accno}--$ref->{description}\n";
-        if ($form->{amount}{$key} eq $ref->{accno}) {
-          $form->{$key} = "$ref->{accno}--$ref->{description}";
-        }
-
-      }
-    }
-  }
-  chop $form->{taxaccounts};
-
-  if (($form->{part_type} eq "part") || ($form->{part_type} eq "assembly")) {
-    $form->{selectIC_income}  = $form->{selectIC_sale};
-    $form->{selectIC_expense} = $form->{selectIC_cogs};
-    $form->{IC_income}        = $form->{IC_sale};
-    $form->{IC_expense}       = $form->{IC_cogs};
-  }
-
-  delete $form->{IC_links};
-  delete $form->{amount};
-
-  $form->get_partsgroup(\%myconfig, { all => 1 });
-
-  $form->{partsgroup} = "$form->{partsgroup}--$form->{partsgroup_id}";
-
-  if (@{ $form->{all_partsgroup} }) {
-    $form->{selectpartsgroup} = qq|<option>\n|;
-    map { $form->{selectpartsgroup} .= qq|<option value="$_->{partsgroup}--$_->{id}">$_->{partsgroup}\n| } @{ $form->{all_partsgroup} };
-  }
-
-  if ($form->{part_type} eq 'assembly') {
-
-    foreach my $i (1 .. $form->{assembly_rows}) {
-      if ($form->{"partsgroup_id_$i"}) {
-        $form->{"partsgroup_$i"} =
-          qq|$form->{"partsgroup_$i"}--$form->{"partsgroup_id_$i"}|;
-      }
-    }
-    $form->get_partsgroup(\%myconfig);
-
-    if (@{ $form->{all_partsgroup} }) {
-      $form->{selectassemblypartsgroup} = qq|<option>\n|;
-
-      map {
-        $form->{selectassemblypartsgroup} .=
-          qq|<option value="$_->{partsgroup}--$_->{id}">$_->{partsgroup}\n|
-      } @{ $form->{all_partsgroup} };
-    }
-  }
-  $lxdebug->leave_sub();
-}
-
-sub form_header {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_details');
-
-  $form->{pg_keys}          = sub { "$_[0]->{partsgroup}--$_[0]->{id}" };
-  $form->{description_area} = ($form->{rows} = $form->numtextrows($form->{description}, 40)) > 1;
-  $form->{notes_rows}       =  max 4, $form->numtextrows($form->{notes}, 40), $form->numtextrows($form->{formel}, 40);
-
-  map { $form->{"is_$_"}  = ($form->{part_type} eq $_) } qw(part service assembly);
-  map { $form->{$_}       =~ s/"/&quot;/g;        } qw(unit);
-
-  $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS',
-                   'partsgroup'    => 'all_partsgroup',
-                   'vendors'       => 'ALL_VENDORS',
-                   'warehouses'    => { 'key'    => 'WAREHOUSES',
-                                        'bins'   => 'BINS', });
-  # leerer wert für Lager und Lagerplatz korrekt einstellt
-  # ID 0 sollte in Ordnung sein, da der Zähler sowieso höher ist
-  my $no_default_bin_entry = { 'id' => '0', description => '--', 'BINS' => [ { id => '0', description => ''} ] };
-  push @ { $form->{WAREHOUSES} }, $no_default_bin_entry;
-  if (my $max = scalar @{ $form->{WAREHOUSES} }) {
-    my ($default_warehouse_id, $default_bin_id);
-    if ($form->{action} eq 'add') { # default only for new entries
-      $default_warehouse_id = $::instance_conf->get_warehouse_id;
-      $default_bin_id       = $::instance_conf->get_bin_id;
-    }
-    $form->{warehouse_id} ||= $default_warehouse_id || $form->{WAREHOUSES}->[$max -1]->{id};
-    $form->{bin_id}       ||= $default_bin_id       ||  $form->{WAREHOUSES}->[$max -1]->{BINS}->[0]->{id};
-  }
-
-  $form->{LANGUAGES}        = SL::DB::Manager::Language->get_all_sorted;
-  $form->{translations_map} = { map { ($_->{language_id} => $_) } @{ $form->{translations} || [] } };
-
-  IC->retrieve_buchungsgruppen(\%myconfig, $form);
-  @{ $form->{BUCHUNGSGRUPPEN} } = grep { $_->{id} eq $form->{buchungsgruppen_id} || ($form->{id} && $form->{orphaned}) || !$form->{id} } @{ $form->{BUCHUNGSGRUPPEN} };
-
-  if (($form->{partnumber} ne '') && !SL::TransNumber->new(number => $form->{partnumber}, type => $form->{part_type}, id => $form->{id})->is_unique) {
-    flash('info', $::locale->text('This partnumber is not unique. You should change it.'));
-  }
-
-  my $units = AM->retrieve_units(\%myconfig, $form);
-  $form->{ALL_UNITS} = [ map +{ name => $_ }, sort { $units->{$a}{sortkey} <=> $units->{$b}{sortkey} } keys %$units ];
-
-  $form->{defaults} = AM->get_defaults();
-
-  $form->{CUSTOM_VARIABLES} = CVar->get_custom_variables('module' => 'IC', 'trans_id' => $form->{id});
-
-  my ($null, $partsgroup_id) = split /--/, $form->{partsgroup};
-
-  CVar->render_inputs('variables' => $form->{CUSTOM_VARIABLES}, show_disabled_message => 1, partsgroup_id => $partsgroup_id)
-    if (scalar @{ $form->{CUSTOM_VARIABLES} });
-
-  $::request->layout->use_javascript("${_}.js") for qw(ckeditor/ckeditor ckeditor/adapters/jquery kivi.PriceRule);
-  $::request->layout->add_javascripts_inline("\$(function(){kivi.PriceRule.load_price_rules_for_part(@{[ $::form->{id} * 1 ]})});") if $::form->{id};
-  $form->header;
-  #print $form->parse_html_template('ic/form_header', { ALL_PRICE_FACTORS => $form->{ALL_PRICE_FACTORS},
-  #                                                     ALL_UNITS         => $form->{ALL_UNITS},
-  #                                                     BUCHUNGSGRUPPEN   => $form->{BUCHUNGSGRUPPEN},
-  #                                                     payment_terms     => $form->{payment_terms},
-  #                                                     all_partsgroup    => $form->{all_partsgroup}});
-
-  $form->{show_edit_buttons} = $main::auth->check_right($::myconfig{login}, 'part_service_assembly_edit');
-
-  print $form->parse_html_template('ic/form_header');
-  $lxdebug->leave_sub();
-}
-
-sub form_footer {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_details');
-
-  print $form->parse_html_template('ic/form_footer');
-
-  $lxdebug->leave_sub();
-}
-
-sub makemodel_row {
-  $lxdebug->enter_sub();
-  my ($numrows) = @_;
-  #hli
-  my @mm_data = grep { any { $_ ne '' } @$_{qw(make model)} } map +{ make => $form->{"make_$_"}, model => $form->{"model_$_"}, lastcost => $form->{"lastcost_$_"}, lastupdate => $form->{"lastupdate_$_"}, sortorder => $form->{"sortorder_$_"} }, 1 .. $numrows;
-  delete @{$form}{grep { m/^make_\d+/ || m/^model_\d+/ } keys %{ $form }};
-  print $form->parse_html_template('ic/makemodel', { MM_DATA => [ @mm_data, {} ], mm_rows => scalar @mm_data + 1 });
-
-  $lxdebug->leave_sub();
-}
-
-sub assembly_row {
-  $lxdebug->enter_sub();
-  my ($numrows) = @_;
-  my (@column_index);
-  my ($nochange, $callback, $previousform, $linetotal, $line_purchase_price, $href);
-
-  @column_index = qw(runningnumber qty unit bom partnumber description partsgroup lastcost total);
-
-  if ($form->{previousform}) {
-    $nochange     = 1;
-    @column_index = qw(qty unit bom partnumber description partsgroup total);
-  } else {
-
-    # change callback
-    $form->{old_callback} = $form->{callback};
-    $callback             = $form->{callback};
-    $form->{callback}     = "$form->{script}?action=display_form";
-
-    # delete action
-    map { delete $form->{$_} } qw(action header);
-
-    # save form variables in a previousform variable
-    my %form_to_save = map   { ($_ => m/^ (?: listprice | sellprice | lastcost ) $/x ? $form->format_amount(\%myconfig, $form->{$_}) : $form->{$_}) }
-                       keys %{ $form };
-    $previousform    = $::auth->save_form_in_session(form => \%form_to_save);
-
-    $form->{callback} = $callback;
-    $form->{assemblytotal} = 0;
-    $form->{assembly_purchase_price_total} = 0;
-    $form->{weight}        = 0;
-  }
-
-  my %header = (
-   runningnumber => { text =>  $locale->text('No.'),              nowrap => 1, width => '5%',  align => 'left',},
-   qty           => { text =>  $locale->text('Qty'),              nowrap => 1, width => '10%', align => 'left',},
-   unit          => { text =>  $locale->text('Unit'),             nowrap => 1, width => '5%',  align => 'left',},
-   partnumber    => { text =>  $locale->text('Part Number'),      nowrap => 1, width => '20%', align => 'left',},
-   description   => { text =>  $locale->text('Part Description'), nowrap => 1, width => '50%', align => 'left',},
-   lastcost      => { text =>  $locale->text('Purchase Prices'),  nowrap => 1, width => '50%', align => 'right',},
-   total         => { text =>  $locale->text('Sale Prices'),      nowrap => 1,                 align => 'right',},
-   bom           => { text =>  $locale->text('BOM'),                                           align => 'center',},
-   partsgroup    => { text =>  $locale->text('Group'),                                         align => 'left',},
-  );
-
-  my @ROWS;
-
-  for my $i (1 .. $numrows) {
-    my (%row, @row_hiddens);
-
-    $form->{"partnumber_$i"} =~ s/\"/&quot;/g;
-
-    $linetotal           = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"} / ($form->{"price_factor_$i"} || 1), 4);
-    $line_purchase_price = $form->round_amount($form->{"lastcost_$i"} *  $form->{"qty_$i"} / ($form->{"price_factor_$i"} || 1), 4);
-    $form->{assemblytotal}                  += $linetotal;
-    $form->{assembly_purchase_price_total}  += $line_purchase_price;
-    $form->{"qty_$i"}    = $form->format_amount(\%myconfig, $form->{"qty_$i"});
-    $linetotal           = $form->format_amount(\%myconfig, $linetotal, 2);
-    $line_purchase_price = $form->format_amount(\%myconfig, $line_purchase_price, 2);
-    $href                = build_std_url("action=edit", qq|id=$form->{"id_$i"}|, "rowcount=$numrows", "currow=$i", "previousform=$previousform");
-    map { $row{$_}{data} = "" } qw(qty unit partnumber description bom partsgroup runningnumber);
-
-    # last row
-    if (($i >= 1) && ($i == $numrows)) {
-      if (!$form->{previousform}) {
-        $row{partnumber}{data}  = qq|<input name="partnumber_$i" size=15 value="$form->{"partnumber_$i"}">|;
-        $row{qty}{data}         = qq|<input name="qty_$i" size=5 value="$form->{"qty_$i"}">|;
-        $row{description}{data} = qq|<input name="description_$i" size=40 value="$form->{"description_$i"}">|;
-        $row{partsgroup}{data}  = qq|<input name="partsgroup_$i" size=10 value="$form->{"partsgroup_$i"}">|;
-      }
-    # other rows
-    } else {
-      if ($form->{previousform}) {
-        push @row_hiddens,          qw(qty bom);
-        $row{partnumber}{data}    = $form->{"partnumber_$i"};
-        $row{qty}{data}           = $form->{"qty_$i"};
-        $row{bom}{data}           = $form->{"bom_$i"} ? "x" : "&nbsp;";
-        $row{qty}{align}          = 'right';
-      } else {
-        $row{partnumber}{data}    = qq|$form->{"partnumber_$i"}|;
-        $row{partnumber}{link}     = $href;
-        $row{qty}{data}           = qq|<input name="qty_$i" size=5 value="$form->{"qty_$i"}">|;
-        $row{runningnumber}{data} = qq|<input name="runningnumber_$i" size=3 value="$i">|;
-        $row{bom}{data}   = sprintf qq|<input name="bom_$i" type=checkbox class=checkbox value=1 %s>|,
-                                       $form->{"bom_$i"} ? 'checked' : '';
-      }
-      push @row_hiddens,        qw(unit description partnumber partsgroup);
-      $row{unit}{data}        = $form->{"unit_$i"};
-      #Bei der Artikelbeschreibung und Warengruppe können Sonderzeichen verwendet
-      #werden, die den HTML Code stören. Daher sollen diese im Template escaped werden
-      #dies geschieht, wenn die Variable escape gesetzt ist
-      $row{description}{data}   = $form->{"description_$i"};
-      $row{description}{escape} = 1;
-      $row{partsgroup}{data}    = $form->{"partsgroup_$i"};
-      $row{partsgroup}{escape}  = 1;
-      $row{bom}{align}          = 'center';
-    }
-
-    $row{lastcost}{data}      = $line_purchase_price;
-    $row{total}{data}         = $linetotal;
-    $row{lastcost}{align}     = 'right';
-    $row{total}{align}        = 'right';
-    $row{deliverydate}{align} = 'right';
-
-    push @row_hiddens, qw(id sellprice lastcost weight price_factor_id price_factor);
-    $row{hiddens} = [ map +{ name => "${_}_$i", value => $form->{"${_}_$i"} }, @row_hiddens ];
-
-    push @ROWS, \%row;
-  }
-
-  print $form->parse_html_template('ic/assembly_row', { COLUMNS => \@column_index, ROWS => \@ROWS, HEADER => \%header });
-
-  $lxdebug->leave_sub();
-}
-
-sub update {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_edit');
-
-  # update checks whether pricegroups, makemodels or assembly items have been changed/added
-  # new items might have been added (and the original form might have been stored and restored)
-  # so at the end the ic form is run through check_form in io.pl
-  # The various combination of events can lead to problems with the order of parse_amount and format_amount
-  # Currently check_form parses some variables in assembly mode, but not in article or service mode
-  # This will only ever really be sanely resolved with a rewrite...
-
-  # parse pricegroups. and no, don't rely on check_form for this...
-  map { $form->{"price_$_"} = $form->parse_amount(\%myconfig, $form->{"price_$_"}) } 1 .. $form->{price_rows};
-
-  unless ($form->{part_type} eq 'assembly') {
-    # for assemblies check_form will parse sellprice and listprice, but not for parts or services
-    $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) for qw(sellprice listprice ve gv);
-  };
-
-  if ($form->{part_type} eq 'part') {
-    $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) for qw(weight rop);
-  }
-
-  # same for makemodel lastcosts
-  # but parse_amount not necessary for assembly component lastcosts
-  unless ($form->{part_type} eq "assembly") {
-    map { $form->{"lastcost_$_"} = $form->parse_amount(\%myconfig, $form->{"lastcost_$_"}) } 1 .. $form->{"makemodel_rows"};
-    $form->{lastcost} = $form->parse_amount(\%myconfig, $form->{lastcost});
-  }
-
-  if ($form->{part_type} eq "assembly") {
-    my $i = $form->{assembly_rows};
-
-    # if last row is empty check the form otherwise retrieve item
-    if (   ($form->{"partnumber_$i"} eq "")
-        && ($form->{"description_$i"} eq "")
-        && ($form->{"partsgroup_$i"}  eq "")) {
-      # no new assembly item was added
-
-      &check_form;
-
-    } else {
-      # search db for newly added assemblyitems, via partnumber or description
-      IC->assembly_item(\%myconfig, \%$form);
-
-      # form->{item_list} contains the possible matches, next check whether the
-      # match is unique or we need to call the page to select the item
-      my $rows = scalar @{ $form->{item_list} };
-
-      if ($rows) {
-        $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
-
-        if ($rows > 1) {
-          $form->{makemodel_rows}--;
-          select_item(mode => 'IC', pre_entered_qty => $form->parse_amount(\%myconfig, $form->{"qty_$i"}));
-          $::dispatcher->end_request;
-        } else {
-          map { $form->{item_list}[$i]{$_} =~ s/\"/&quot;/g }
-            qw(partnumber description unit partsgroup);
-          map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} }
-            keys %{ $form->{item_list}[0] };
-          $form->{"runningnumber_$i"} = $form->{assembly_rows};
-          $form->{assembly_rows}++;
-
-          &check_form;
-
-        }
-
-      } else {
-
-        $form->{rowcount} = $i;
-        $form->{assembly_rows}++;
-
-        &new_item;
-
-      }
-    }
-
-  } elsif (($form->{part_type} eq 'part') || ($form->{part_type} eq 'service')) {
-    &check_form;
-  }
-
-  $lxdebug->leave_sub();
-}
-
-sub save {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_edit');
-  $::form->mtime_ischanged('parts');
-  my ($parts_id, %newform, $amount, $callback);
-
-  # check if there is a part number - commented out, cause there is an automatic allocation of numbers
-  # $form->isblank("partnumber", $locale->text(ucfirst $form->{part_type}." Part Number missing!"));
-
-  # check if there is a description
-  $form->isblank("description", $locale->text("Part Description missing!"));
-
-  $form->error($locale->text("Inventory quantity must be zero before you can set this $form->{part_type} obsolete!"))
-    if $form->{obsolete} && $form->{onhand} * 1 && $form->{part_type} ne 'service';
-
-  if (!$form->{buchungsgruppen_id}) {
-    $form->error($locale->text("Parts must have an entry type.") . " " .
-     $locale->text("If you see this message, you most likely just setup your LX-Office and haven't added any entry types. If this is the case, the option is accessible for administrators in the System menu.")
-    );
-  }
-
-  $form->error($locale->text('Description must not be empty!')) unless $form->{description};
-  $form->error($locale->text('Partnumber must not be set to empty!')) if $form->{id} && !$form->{partnumber};
-
-  # undef warehouse_id if the empty value is selected
-  if ( ($form->{warehouse_id} == 0) && ($form->{bin_id} == 0) ) {
-    undef $form->{warehouse_id};
-    undef $form->{bin_id};
-  }
-  # save part
-  if (IC->save(\%myconfig, \%$form) == 3) {
-    $form->error($locale->text('Partnumber not unique!'));
-  }
-  # saving the history
-  if(!exists $form->{addition}) {
-    $form->{snumbers}  = qq|partnumber_| . $form->{partnumber};
-    $form->{what_done} = "part";
-    $form->{addition}  = "SAVED";
-    $form->save_history;
-  }
-  # /saving the history
-  $parts_id = $form->{id};
-
-  my $i;
-  # load previous variables
-  if ($form->{previousform}) {
-
-    # save the new form variables before splitting previousform
-    map { $newform{$_} = $form->{$_} } keys %$form;
-
-    # don't trample on previous variables
-    map { delete $form->{$_} } keys %newform;
-
-    my $ic_cvar_configs = CVar->get_configs(module => 'IC');
-    my @ic_cvar_fields  = map { "cvar_$_->{name}" } @{ $ic_cvar_configs };
-
-    # restore original values
-    $::auth->restore_form_from_session($newform{previousform}, form => $form);
-    $form->{taxaccounts} = $newform{taxaccount2};
-
-    if ($form->{part_type} eq 'assembly') {
-
-      # undo number formatting
-      map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) }
-        qw(weight listprice sellprice rop);
-
-      $form->{assembly_rows}--;
-      if ($newform{currow}) {
-        $i = $newform{currow};
-      } else {
-        $i = $form->{assembly_rows};
-      }
-      $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"} > 0);
-
-      $form->{sellprice} -= $form->{"sellprice_$i"} * $form->{"qty_$i"};
-      $form->{weight}    -= $form->{"weight_$i"} * $form->{"qty_$i"};
-
-      # change/add values for assembly item
-      map { $form->{"${_}_$i"} = $newform{$_} } qw(partnumber description bin unit weight listprice sellprice inventory_accno income_accno expense_accno price_factor_id);
-      map { $form->{"ic_${_}_$i"} = $newform{$_} } @ic_cvar_fields;
-
-      # das ist __voll__ bekloppt, dass so auszurechnen jb 22.5.09
-      #$form->{sellprice} += $form->{"sellprice_$i"} * $form->{"qty_$i"};
-      $form->{weight}    += $form->{"weight_$i"} * $form->{"qty_$i"};
-
-    } else {
-
-      # set values for last invoice/order item
-      $i = $form->{rowcount};
-      $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"} > 0);
-
-      map { $form->{"${_}_$i"} = $newform{$_} } qw(partnumber description bin unit listprice inventory_accno income_accno expense_accno sellprice lastcost price_factor_id);
-      map { $form->{"ic_${_}_$i"} = $newform{$_} } @ic_cvar_fields;
-
-      $form->{"longdescription_$i"} = $newform{notes};
-
-      $form->{"sellprice_$i"} = $newform{lastcost} if ($form->{vendor_id});
-
-      if ($form->{exchangerate} != 0) {
-        $form->{"sellprice_$i"} /= $form->{exchangerate};
-      }
-
-      map { $form->{"taxaccounts_$i"} .= "$_ " } split / /, $newform{taxaccount};
-      chop $form->{"taxaccounts_$i"};
-      foreach my $item (qw(description rate taxnumber)) {
-        my $index = $form->{"taxaccounts_$i"} . "_$item";
-        $form->{$index} = $newform{$index};
-      }
-
-      # credit remaining calculation
-      $amount = $form->{"sellprice_$i"} * (1 - $form->{"discount_$i"} / 100) * $form->{"qty_$i"};
-
-      map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"});
-      map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{"taxaccounts_$i"} if !$form->{taxincluded};
-
-      $form->{creditremaining} -= $amount;
-
-      # redo number formatting, because invoice parse them!
-      map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}) } qw(weight listprice sellprice lastcost rop);
-    }
-
-    $form->{"id_$i"} = $parts_id;
-
-    # Get the actual price factor (not just the ID) for the marge calculation.
-    $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS');
-    foreach my $pfac (@{ $form->{ALL_PRICE_FACTORS} }) {
-      next if ($pfac->{id} != $newform{price_factor_id});
-      $form->{"marge_price_factor_$i"} = $pfac->{factor};
-      last;
-    }
-    delete $form->{ALL_PRICE_FACTORS};
-
-    delete $form->{action};
-
-    # restore original callback
-    $callback = $form->unescape($form->{callback});
-    $form->{callback} = $form->unescape($form->{old_callback});
-    delete $form->{old_callback};
-
-    $form->{makemodel_rows}--;
-
-    # put callback together
-    foreach my $key (keys %$form) {
-
-      # do single escape for Apache 2.0
-      my $value = $form->escape($form->{$key}, 1);
-      $callback .= qq|&$key=$value|;
-    }
-    $form->{callback} = $callback;
-  }
-
-  # redirect
-  $form->redirect;
-
-  $lxdebug->leave_sub();
-}
-
-sub save_as_new {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_edit');
-
-  # saving the history
-  if(!exists $form->{addition}) {
-    $form->{snumbers}  = qq|partnumber_| . $form->{partnumber};
-    $form->{addition}  = "SAVED AS NEW";
-    $form->{what_done} = "part";
-    $form->save_history;
-  }
-  # /saving the history
-
-  # deleting addition to get the history saved for the new part, too.
-  delete $form->{addition};
-
-  $form->{id} = 0;
-  if ($form->{"original_partnumber"} &&
-      ($form->{"partnumber"} eq $form->{"original_partnumber"})) {
-    $form->{partnumber} = "";
-  }
-  &save;
-  $lxdebug->leave_sub();
-}
-
-sub delete {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_edit');
-
-  # saving the history
-  if(!exists $form->{addition}) {
-    $form->{snumbers}  = qq|partnumber_| . $form->{partnumber};
-    $form->{addition}  = "DELETED";
-    $form->{what_done} = "part";
-    $form->save_history;
-  }
-  # /saving the history
-  my $rc = IC->delete(\%myconfig, \%$form);
-
-  # redirect
-  $form->redirect($locale->text('Item deleted!')) if ($rc > 0);
-  $form->error($locale->text('Cannot delete item!'));
-
-  $lxdebug->leave_sub();
-}
-
-sub price_row {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_details');
-
-  my ($numrows) = @_;
-
-  my @PRICES = map +{
-    pricegroup    => $form->{"pricegroup_$_"},
-    pricegroup_id => $form->{"pricegroup_id_$_"},
-    price         => $form->{"price_$_"},
-  }, 1 .. $numrows;
-
-  print $form->parse_html_template('ic/price_row', { PRICES => \@PRICES });
-
-  $lxdebug->leave_sub();
-}
-
 sub ajax_autocomplete {
   $main::lxdebug->enter_sub();
 
@@ -1375,27 +734,6 @@ sub ajax_autocomplete {
   $main::lxdebug->leave_sub();
 }
 
-sub display_form {
-  $::lxdebug->enter_sub;
-
-  $auth->assert('part_service_assembly_edit');
-
-  relink_accounts();
-
-  $::form->language_payment(\%::myconfig);
-
-  Common::webdav_folder($::form);
-
-  form_header();
-  price_row($::form->{price_rows});
-  makemodel_row(++$::form->{makemodel_rows}) if $::form->{part_type} =~ /^(part|service)$/;
-  assembly_row(++$::form->{assembly_rows})   if $::form->{part_type} eq 'assembly';
-
-  form_footer();
-
-  $::lxdebug->leave_sub;
-}
-
 sub back_to_record {
   _check_io_auth();