Verteilen der Rechte für Finanzbuchhaltung auf Dialogbuchung,Kreditoren-/Debitorenrec...
[kivitendo-erp.git] / bin / mozilla / ic.pl
index 20c670c..cf94b7b 100644 (file)
@@ -38,6 +38,8 @@ use List::MoreUtils qw(any);
 use SL::AM;
 use SL::CVar;
 use SL::IC;
 use SL::AM;
 use SL::CVar;
 use SL::IC;
+use SL::Helper::Flash qw(flash);
+use SL::HTML::Util;
 use SL::ReportGenerator;
 
 #use SL::PE;
 use SL::ReportGenerator;
 
 #use SL::PE;
@@ -49,7 +51,6 @@ use strict;
 our ($form, $locale, %myconfig, $lxdebug, $auth);
 
 require "bin/mozilla/io.pl";
 our ($form, $locale, %myconfig, $lxdebug, $auth);
 
 require "bin/mozilla/io.pl";
-require "bin/mozilla/invoice_io.pl";
 require "bin/mozilla/common.pl";
 require "bin/mozilla/reportgenerator.pl";
 
 require "bin/mozilla/common.pl";
 require "bin/mozilla/reportgenerator.pl";
 
@@ -93,7 +94,7 @@ sub add {
 sub search {
   $lxdebug->enter_sub();
 
 sub search {
   $lxdebug->enter_sub();
 
-  $auth->assert('part_service_assembly_edit');
+  $auth->assert('part_service_assembly_details');
 
   $form->{revers}       = 0;  # switch for backward sorting
   $form->{lastsort}     = ""; # memory for which table was sort at last time
 
   $form->{revers}       = 0;  # switch for backward sorting
   $form->{lastsort}     = ""; # memory for which table was sort at last time
@@ -105,8 +106,6 @@ sub search {
   $form->{title} = $locale->text($form->{title});
   $form->{title} = $locale->text('Assemblies') if ($is_xyz{is_assembly});
 
   $form->{title} = $locale->text($form->{title});
   $form->{title} = $locale->text('Assemblies') if ($is_xyz{is_assembly});
 
-  $form->{jsscript} = 1;
-
   $form->{CUSTOM_VARIABLES}                  = CVar->get_configs('module' => 'IC');
   ($form->{CUSTOM_VARIABLES_FILTER_CODE},
    $form->{CUSTOM_VARIABLES_INCLUSION_CODE}) = CVar->render_search_options('variables'      => $form->{CUSTOM_VARIABLES},
   $form->{CUSTOM_VARIABLES}                  = CVar->get_configs('module' => 'IC');
   ($form->{CUSTOM_VARIABLES_FILTER_CODE},
    $form->{CUSTOM_VARIABLES_INCLUSION_CODE}) = CVar->render_search_options('variables'      => $form->{CUSTOM_VARIABLES},
@@ -116,9 +115,7 @@ sub search {
   $form->header;
 
   $form->get_lists('partsgroup'    => 'ALL_PARTSGROUPS');
   $form->header;
 
   $form->get_lists('partsgroup'    => 'ALL_PARTSGROUPS');
-  print $form->parse_html_template('ic/search', { %is_xyz,
-                                                  dateformat => $myconfig{dateformat},
-                                                  limit => $myconfig{vclimit}, });
+  print $form->parse_html_template('ic/search', { %is_xyz, });
 
   $lxdebug->leave_sub();
 }    #end search()
 
   $lxdebug->leave_sub();
 }    #end search()
@@ -200,786 +197,31 @@ sub update_prices {
   $lxdebug->leave_sub();
 }
 
   $lxdebug->leave_sub();
 }
 
-#sub choice {
-#  $lxdebug->enter_sub();
-#
-#  $auth->assert('part_service_assembly_edit');
-#
-#  our ($j, $lastndx);
-#  my ($totop100);
-#
-#  $form->{title} = $locale->text('Top 100 hinzufuegen');
-#
-#  $form->header;
-#
-#  push @custom_hiddens, qw(searchitems title bom titel revers lastsort sort ndxs_counter extras);
-#  push @custom_hiddens, qw(itemstatus l_linetotal l_partnumber l_description l_onhand l_unit l_sellprice l_linetotalsellprice);
-#  my @HIDDENS = (
-#        +{ name => 'row',     value => $j              },
-#        +{ name => 'nextsub', value => 'item_selected' },
-#        +{ name => 'test',    value => 'item_selected' },
-#        +{ name => 'lastndx', value => $lastndx        },
-#    map(+{ name => $_,        value => $form->{$_}     }, @custom_hiddens),
-#  );
-#
-#  my ($partnumber, $description, $unit, $sellprice, $soldtotal);
-#  # if choice set data
-##  if ($form->{ndx}) {
-##    for my $i (0 .. $form->{ndxs_counter}) {
-##
-##      # insert data into top100
-##      push @{ $form->{parts} },
-##        { number      => "",
-##          partnumber  => $form->{"totop100_partnumber_$j"},
-##          description => $form->{"totop100_description_$j"},
-##          unit        => $form->{"totop100_unit_$j"},
-##          sellprice   => $form->{"totop100_sellprice_$j"},
-##          soldtotal   => $form->{"totop100_soldtotal_$j"},
-##        };
-##    }    #rof
-##  }    #fi
-#
-#  $totop100 = "";
-#
-#  # set data for next page
-#  for my $i (1 .. $form->{ndxs_counter}) {
-#    $partnumber  = $form->{"totop100_partnumber_$i"};
-#    $description = $form->{"totop100_description_$i"};
-#    $unit        = $form->{"totop100_unit_$i"};
-#    $sellprice   = $form->{"totop100_sellprice_$i"};
-#    $soldtotal   = $form->{"totop100_soldtotal_$i"};
-#
-#  push @PARTS, {
-#    totop100_partnumber  => $form->{"totop100_partnumber_$i"},
-#    totop100_description => $form->{"totop100_description_$i"},
-#    totop100_unit        => $form->{"totop100_unit_$i"},
-#    totop100_sellprice   => $form->{"totop100_sellprice_$i"},
-#    totop100_soldtotal   => $form->{"totop100_soldtotal_$i"},
-#  }
-#
-##    $totop100 .= qq|
-##<input type=hidden name=totop100_partnumber_$i value=$form->{"totop100_partnumber_$i"}>
-##<input type=hidden name=totop100_description_$i value=$form->{"totop100_description_$i"}>
-##<input type=hidden name=totop100_unit_$i value=$form->{"totop100_unit_$i"}>
-##<input type=hidden name=totop100_sellprice_$i value=$form->{"totop100_sellprice_$i"}>
-##<input type=hidden name=totop100_soldtotal_$i value=$form->{"totop100_soldtotal_$i"}>
-##    |;
-#  }    #rof
-#
-#  print $form->parse_html_template('ic/choice', +{ HIDDENS => \@HIDDENS, PARTS => \@PARTS });
-#
-#  $lxdebug->leave_sub();
-#}    #end choice
-
-#sub list {
-#  $lxdebug->enter_sub();
-#
-#  $auth->assert('part_service_assembly_edit');
-#
-#  our ($lastndx);
-#  our ($partnumber, $description, $unit, $sellprice, $soldtotal);
-#
-#  my @sortorders = ("", "partnumber", "description", "all");
-#  my $sortorder = $sortorders[($form->{description} ? 2 : 0) + ($form->{partnumber} ? 1 : 0)];
-#  IC->get_parts(\%myconfig, \%$form, $sortorder);
-#
-#  $form->{title} = $locale->text('Top 100 hinzufuegen');
-#
-#  $form->header;
-#
-#  print qq|
-#  <form method=post action=ic.pl>
-#    <table width=100%>
-#     <tr>
-#      <th class=listtop colspan=6>| . $locale->text('choice part') . qq|</th>
-#     </tr>
-#        <tr height="5"></tr>
-#        <tr class=listheading>
-#          <th>&nbsp;</th>
-#          <th class=listheading>| . $locale->text('Part Number') . qq|</th>
-#          <th class=listheading>| . $locale->text('Part Description') . qq|</th>
-#          <th class=listheading>| . $locale->text('Unit of measure') . qq|</th>
-#          <th class=listheading>| . $locale->text('Sell Price') . qq|</th>
-#          <th class=listheading>| . $locale->text('soldtotal') . qq|</th>
-#        </tr>|;
-#
-#  my $j = 0;
-#  my $i = $form->{rows};
-#
-#  for ($j = 1; $j <= $i; $j++) {
-#
-#    print qq|
-#        <tr class=listrow| . ($j % 2) . qq|>|;
-#    if ($j == 1) {
-#      print qq|
-#            <td><input name=ndx class=radio type=radio value=$j checked></td>|;
-#    } else {
-#      print qq|
-#          <td><input name=ndx class=radio type=radio value=$j></td>|;
-#    }
-#    print qq|
-#          <td><input name="new_partnumber_$j" type=hidden value="$form->{"partnumber_$j"}">$form->{"partnumber_$j"}</td>
-#          <td><input name="new_description_$j" type=hidden value="$form->{"description_$j"}">$form->{"description_$j"}</td>
-#          <td><input name="new_unit_$j" type=hidden value="$form->{"unit_$j"}">$form->{"unit_$j"}</td>
-#          <td><input name="new_sellprice_$j" type=hidden value="$form->{"sellprice_$j"}">$form->{"sellprice_$j"}</td>
-#          <td><input name="new_soldtotal_$j" type=hidden value="$form->{"soldtotal_$j"}">$form->{"soldtotal_$j"}</td>
-#        </tr>
-#
-#        <input name="new_id_$j" type=hidden value="$form->{"id_$j"}">|;
-#  }
-#
-#  print qq|
-#
-#</table>
-#
-#<br>
-#
-#
-#<input type=hidden name=itemstatus value="$form->{itemstatus}">
-#<input type=hidden name=l_linetotal value="$form->{l_linetotal}">
-#<input type=hidden name=l_partnumber value="$form->{l_partnumber}">
-#<input type=hidden name=l_description value="$form->{l_description}">
-#<input type=hidden name=l_onhand value="$form->{l_onhand}">
-#<input type=hidden name=l_unit value="$form->{l_unit}">
-#<input type=hidden name=l_sellprice value="$form->{l_sellprice}">
-#<input type=hidden name=l_linetotalsellprice value="$form->{l_linetotalsellprice}">
-#<input type=hidden name=sort value="$form->{sort}">
-#<input type=hidden name=revers value="$form->{revers}">
-#<input type=hidden name=lastsort value="$form->{lastsort}">
-#
-#<input type=hidden name=bom value="$form->{bom}">
-#<input type=hidden name=titel value="$form->{titel}">
-#<input type=hidden name=searchitems value="$form->{searchitems}">
-#
-#<input type=hidden name=row value=$j>
-#
-#<input type=hidden name=nextsub value=item_selected>
-#
-#<input name=lastndx type=hidden value=$lastndx>
-#
-#<input name=ndxs_counter type=hidden value=$form->{ndxs_counter}>|;
-#
-#  my $totop100 = "";
-#
-#  if (($form->{ndxs_counter}) > 0) {
-#    for ($i = 1; ($i < $form->{ndxs_counter} + 1); $i++) {
-#
-#      $partnumber  = $form->{"totop100_partnumber_$i"};
-#      $description = $form->{"totop100_description_$i"};
-#      $unit        = $form->{"totop100_unit_$i"};
-#      $sellprice   = $form->{"totop100_sellprice_$i"};
-#      $soldtotal   = $form->{"totop100_soldtotal_$i"};
-#
-#      $totop100 .= qq|
-#<input type=hidden name=totop100_partnumber_$i value=$form->{"totop100_partnumber_$i"}>
-#<input type=hidden name=totop100_description_$i value=$form->{"totop100_description_$i"}>
-#<input type=hidden name=totop100_unit_$i value=$form->{"totop100_unit_$i"}>
-#<input type=hidden name=totop100_sellprice_$i value=$form->{"totop100_sellprice_$i"}>
-#<input type=hidden name=totop100_soldtotal_$i value=$form->{"totop100_soldtotal_$i"}>
-#      |;
-#    }    #rof
-#  }    #fi
-#
-#  print $totop100;
-#
-#  print qq|
-#<input class=submit type=submit name=action value="|
-#    . $locale->text('TOP100') . qq|">
-#
-#</form>
-#|;
-#  $lxdebug->leave_sub();
-#}    #end list()
-
 sub top100 {
 sub top100 {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_edit');
+  $::lxdebug->enter_sub();
 
 
-  if ($form->{ndx}) {
-    $form->{ndxs_counter}++;
+  $::auth->assert('part_service_assembly_edit');
 
 
-    if ($form->{ndxs_counter} > 0) {
+  $::form->{l_soldtotal} = "Y";
+  $::form->{sort}        = "soldtotal";
+  $::form->{lastsort}    = "soldtotal";
 
 
-      my $index = $form->{ndx};
-
-      $form->{"totop100_partnumber_$form->{ndxs_counter}"} = $form->{"new_partnumber_$index"};
-      $form->{"totop100_description_$form->{ndxs_counter}"} = $form->{"new_description_$index"};
-      $form->{"totop100_unit_$form->{ndxs_counter}"} = $form->{"new_unit_$index"};
-      $form->{"totop100_sellprice_$form->{ndxs_counter}"} = $form->{"new_sellprice_$index"};
-      $form->{"totop100_soldtotal_$form->{ndxs_counter}"} = $form->{"new_soldtotal_$index"};
-    }    #fi
-  }    #fi
-  &addtop100();
-  $lxdebug->leave_sub();
-}    #end top100
+  $::form->{l_qty}       = undef;
+  $::form->{l_linetotal} = undef;
+  $::form->{l_number}    = "Y";
+  $::form->{number}      = "position";
 
 
-sub addtop100 {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_edit');
-
-  my ($revers, $lastsort, $callback, $option, $description, $sameitem,
-      $partnumber, $unit, $sellprice, $soldtotal, $totop100, $onhand, $align);
-  my (@column_index, %column_header, %column_data);
-  my ($totalsellprice, $totallastcost, $totallistprice, $subtotalonhand, $subtotalsellprice, $subtotallastcost, $subtotallistprice);
-
-  $form->{top100}      = "top100";
-  $form->{l_soldtotal} = "Y";
-  $form->{soldtotal}   = "soldtotal";
-  $form->{sort}        = "soldtotal";
-  $form->{l_qty}       = "N";
-  $form->{l_linetotal} = "";
-  $form->{revers}      = 1;
-  $form->{number}      = "position";
-  $form->{l_number}    = "Y";
-
-  $totop100 = "";
-
-  $form->{title} = $locale->text('Top 100');
-
-  $revers   = $form->{revers};
-  $lastsort = $form->{lastsort};
-
-  if (($form->{lastsort} eq "") && ($form->{sort} eq undef)) {
-    $form->{revers}   = 0;
-    $form->{lastsort} = "partnumber";
-    $form->{sort}     = "partnumber";
-  }    #fi
-
-  $callback =
-    "$form->{script}?action=top100&searchitems=$form->{searchitems}&itemstatus=$form->{itemstatus}&bom=$form->{bom}&l_linetotal=$form->{l_linetotal}&title="
-    . $form->escape($form->{title}, 1);
-
-  # if we have a serialnumber limit search
-  if ($form->{serialnumber} || $form->{l_serialnumber}) {
-    $form->{l_serialnumber} = "Y";
-    unless (   $form->{bought}
-            || $form->{sold}
-            || $form->{rfq}
-            || $form->{quoted}) {
-      $form->{bought} = $form->{sold} = 1;
-    }
+  unless (   $::form->{bought}
+          || $::form->{sold}
+          || $::form->{rfq}
+          || $::form->{quoted}) {
+    $::form->{bought} = $::form->{sold} = 1;
   }
   }
-  IC->all_parts(\%myconfig, \%$form);
-
-  if ($form->{itemstatus} eq 'active') {
-    $option .= $locale->text('Active') . " : ";
-  }
-  if ($form->{itemstatus} eq 'obsolete') {
-    $option .= $locale->text('Obsolete') . " : ";
-  }
-  if ($form->{itemstatus} eq 'orphaned') {
-    $option .= $locale->text('Orphaned') . " : ";
-  }
-  if ($form->{itemstatus} eq 'onhand') {
-    $option .= $locale->text('On Hand') . " : ";
-    $form->{l_onhand} = "Y";
-  }
-  if ($form->{itemstatus} eq 'short') {
-    $option .= $locale->text('Short') . " : ";
-    $form->{l_onhand} = "Y";
-  }
-  if ($form->{onorder}) {
-    $form->{l_ordnumber} = "Y";
-    $callback .= "&onorder=$form->{onorder}";
-    $option   .= $locale->text('On Order') . " : ";
-  }
-  if ($form->{ordered}) {
-    $form->{l_ordnumber} = "Y";
-    $callback .= "&ordered=$form->{ordered}";
-    $option   .= $locale->text('Ordered') . " : ";
-  }
-  if ($form->{rfq}) {
-    $form->{l_quonumber} = "Y";
-    $callback .= "&rfq=$form->{rfq}";
-    $option   .= $locale->text('RFQ') . " : ";
-  }
-  if ($form->{quoted}) {
-    $form->{l_quonumber} = "Y";
-    $callback .= "&quoted=$form->{quoted}";
-    $option   .= $locale->text('Quoted') . " : ";
-  }
-  if ($form->{bought}) {
-    $form->{l_invnumber} = "Y";
-    $callback .= "&bought=$form->{bought}";
-    $option   .= $locale->text('Bought') . " : ";
-  }
-  if ($form->{sold}) {
-    $form->{l_invnumber} = "Y";
-    $callback .= "&sold=$form->{sold}";
-    $option   .= $locale->text('Sold') . " : ";
-  }
-  if (   $form->{bought}
-      || $form->{sold}
-      || $form->{onorder}
-      || $form->{ordered}
-      || $form->{rfq}
-      || $form->{quoted}) {
-
-    $form->{l_lastcost} = "";
-    $form->{l_name}     = "Y";
-    if ($form->{transdatefrom}) {
-      $callback .= "&transdatefrom=$form->{transdatefrom}";
-      $option   .= "\n<br>"
-        . $locale->text('From')
-        . "&nbsp;"
-        . $locale->date(\%myconfig, $form->{transdatefrom}, 1);
-    }
-    if ($form->{transdateto}) {
-      $callback .= "&transdateto=$form->{transdateto}";
-      $option   .= "\n<br>"
-        . $locale->text('To')
-        . "&nbsp;"
-        . $locale->date(\%myconfig, $form->{transdateto}, 1);
-    }
-  }
-
-  $option .= "<br>";
-
-  if ($form->{partnumber}) {
-    $callback .= "&partnumber=$form->{partnumber}";
-    $option   .= $locale->text('Part Number') . qq| : $form->{partnumber}<br>|;
-  }
-  if ($form->{ean}) {
-    $callback .= "&partnumber=$form->{ean}";
-    $option   .= $locale->text('EAN') . qq| : $form->{ean}<br>|;
-  }
-  if ($form->{partsgroup}) {
-    $callback .= "&partsgroup=$form->{partsgroup}";
-    $option   .= $locale->text('Group') . qq| : $form->{partsgroup}<br>|;
-  }
-  if ($form->{serialnumber}) {
-    $callback .= "&serialnumber=$form->{serialnumber}";
-    $option   .= $locale->text('Serial Number') . qq| : $form->{serialnumber}<br>|;
-  }
-  if ($form->{description}) {
-    $callback   .= "&description=$form->{description}";
-    $description = $form->{description};
-    $description =~ s/\n/<br>/g;
-    $option     .= $locale->text('Part Description') . qq| : $form->{description}<br>|;
-  }
-  if ($form->{make}) {
-    $callback .= "&make=$form->{make}";
-    $option   .= $locale->text('Make') . qq| : $form->{make}<br>|;
-  }
-  if ($form->{model}) {
-    $callback .= "&model=$form->{model}";
-    $option   .= $locale->text('Model') . qq| : $form->{model}<br>|;
-  }
-  if ($form->{drawing}) {
-    $callback .= "&drawing=$form->{drawing}";
-    $option   .= $locale->text('Drawing') . qq| : $form->{drawing}<br>|;
-  }
-  if ($form->{microfiche}) {
-    $callback .= "&microfiche=$form->{microfiche}";
-    $option   .= $locale->text('Microfiche') . qq| : $form->{microfiche}<br>|;
-  }
-  if ($form->{l_soldtotal}) {
-    $callback .= "&soldtotal=$form->{soldtotal}";
-    $option   .= $locale->text('soldtotal') . qq| : $form->{soldtotal}<br>|;
-  }
-
-  my @columns = $form->sort_columns(
-    qw(number partnumber ean description partsgroup bin onhand rop unit listprice linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost priceupdate weight image drawing microfiche invnumber ordnumber quonumber name serialnumber soldtotal)
-  );
 
 
-  if ($form->{l_linetotal}) {
-    $form->{l_onhand} = "Y";
-    $form->{l_linetotalsellprice} = "Y" if $form->{l_sellprice};
-    if ($form->{l_lastcost}) {
-      $form->{l_linetotallastcost} = "Y";
-      if (($form->{searchitems} eq 'assembly') && !$form->{bom}) {
-        $form->{l_linetotallastcost} = "";
-      }
-    }
-    $form->{l_linetotallistprice} = "Y" if $form->{l_listprice};
-  }
-
-  if ($form->{searchitems} eq 'service') {
-
-    # remove bin, weight and rop from list
-    map { $form->{"l_$_"} = "" } qw(bin weight rop);
-
-    $form->{l_onhand} = "";
-
-    # qty is irrelevant unless bought or sold
-    if (   $form->{bought}
-        || $form->{sold}
-        || $form->{onorder}
-        || $form->{ordered}
-        || $form->{rfq}
-        || $form->{quoted}) {
-      $form->{l_onhand} = "Y";
-    } else {
-      $form->{l_linetotalsellprice} = "";
-      $form->{l_linetotallastcost}  = "";
-    }
-  }
-
-  foreach my $item (@columns) {
-    if ($form->{"l_$item"} eq "Y") {
-      push @column_index, $item;
-
-      # add column to callback
-      $callback .= "&l_$item=Y";
-    }
-  }
-
-  if ($form->{l_subtotal} eq 'Y') {
-    $callback .= "&l_subtotal=Y";
-  }
-
-  $column_header{number} =
-    qq|<th class=listheading nowrap>| . $locale->text('number') . qq|</th>|;
-  $column_header{partnumber} =
-    qq|<th nowrap><a class=listheading href=$callback&sort=partnumber&revers=$form->{revers}&lastsort=$form->{lastsort}>|
-    . $locale->text('Part Number')
-    . qq|</a></th>|;
-  $column_header{description} =
-    qq|<th nowrap><a class=listheading href=$callback&sort=description&revers=$form->{revers}&lastsort=$form->{lastsort}>|
-    . $locale->text('Part Description')
-    . qq|</a></th>|;
-  $column_header{partsgroup} =
-      qq|<th nowrap><a class=listheading href=$callback&sort=partsgroup>|
-    . $locale->text('Group')
-    . qq|</a></th>|;
-  $column_header{bin} =
-      qq|<th><a class=listheading href=$callback&sort=bin>|
-    . $locale->text('Bin')
-    . qq|</a></th>|;
-  $column_header{priceupdate} =
-      qq|<th nowrap><a class=listheading href=$callback&sort=priceupdate>|
-    . $locale->text('Updated')
-    . qq|</a></th>|;
-  $column_header{onhand} =
-    qq|<th nowrap><a  class=listheading href=$callback&sort=onhand&revers=$form->{revers}&lastsort=$form->{lastsort}>|
-    . $locale->text('Qty')
-    . qq|</th>|;
-  $column_header{unit} =
-    qq|<th class=listheading nowrap>| . $locale->text('Unit') . qq|</th>|;
-  $column_header{listprice} =
-      qq|<th class=listheading nowrap>|
-    . $locale->text('List Price')
-    . qq|</th>|;
-  $column_header{lastcost} =
-    qq|<th class=listheading nowrap>| . $locale->text('Last Cost') . qq|</th>|;
-  $column_header{rop} =
-    qq|<th class=listheading nowrap>| . $locale->text('ROP') . qq|</th>|;
-  $column_header{weight} =
-    qq|<th class=listheading nowrap>| . $locale->text('Weight') . qq|</th>|;
-
-  $column_header{invnumber} =
-      qq|<th nowrap><a class=listheading href=$callback&sort=invnumber>|
-    . $locale->text('Invoice Number')
-    . qq|</a></th>|;
-  $column_header{ordnumber} =
-      qq|<th nowrap><a class=listheading href=$callback&sort=ordnumber>|
-    . $locale->text('Order Number')
-    . qq|</a></th>|;
-  $column_header{quonumber} =
-      qq|<th nowrap><a class=listheading href=$callback&sort=quonumber>|
-    . $locale->text('Quotation')
-    . qq|</a></th>|;
-
-  $column_header{name} =
-      qq|<th nowrap><a class=listheading href=$callback&sort=name>|
-    . $locale->text('Name')
-    . qq|</a></th>|;
-
-  $column_header{sellprice} =
-      qq|<th class=listheading nowrap>|
-    . $locale->text('Sell Price')
-    . qq|</th>|;
-  $column_header{linetotalsellprice} =
-    qq|<th class=listheading nowrap>| . $locale->text('Extended') . qq|</th>|;
-  $column_header{linetotallastcost} =
-    qq|<th class=listheading nowrap>| . $locale->text('Extended') . qq|</th>|;
-  $column_header{linetotallistprice} =
-    qq|<th class=listheading nowrap>| . $locale->text('Extended') . qq|</th>|;
-
-  $column_header{image} =
-    qq|<th class=listheading nowrap>| . $locale->text('Image') . qq|</a></th>|;
-  $column_header{drawing} =
-      qq|<th nowrap><a class=listheading href=$callback&sort=drawing>|
-    . $locale->text('Drawing')
-    . qq|</a></th>|;
-  $column_header{microfiche} =
-      qq|<th nowrap><a class=listheading href=$callback&sort=microfiche>|
-    . $locale->text('Microfiche')
-    . qq|</a></th>|;
-
-  $column_header{serialnumber} =
-      qq|<th nowrap><a class=listheading href=$callback&sort=serialnumber>|
-    . $locale->text('Serial Number')
-    . qq|</a></th>|;
-  $column_header{soldtotal} =
-    qq|<th nowrap><a class=listheading href=$callback&sort=soldtotal&revers=$form->{revers}&lastsort=$form->{lastsort}>|
-    . $locale->text('soldtotal')
-    . qq|</a></th>|;
-
-  $form->header;
-  my $colspan = $#column_index + 1;
-
-  print qq|
-<table width=100%>
-  <tr>
-    <th class=listtop colspan=$colspan>$form->{title}</th>
-  </tr>
-  <tr height="5"></tr>
-
-  <tr><td colspan=$colspan>$option</td></tr>
-
-  <tr class=listheading>
-|;
-
-  map { print "\n$column_header{$_}" } @column_index;
-
-  print qq|
-  </tr>
-  |;
-
-  # add order to callback
-  $form->{callback} = $callback .= "&sort=$form->{sort}";
-
-  # escape callback for href
-  $callback = $form->escape($callback);
-
-  if (@{ $form->{parts} }) {
-    $sameitem = $form->{parts}->[0]->{ $form->{sort} };
-  }
-
-  # insert numbers for top100
-  my $j = 0;
-  foreach my $ref (@{ $form->{parts} }) {
-    $j++;
-    $ref->{number} = $j;
-  }
-
-  # if avaible -> insert choice here
-  if (($form->{ndxs_counter}) > 0) {
-    for (my $i = 1; ($i < $form->{ndxs_counter} + 1); $i++) {
-      $partnumber  = $form->{"totop100_partnumber_$i"};
-      $description = $form->{"totop100_description_$i"};
-      $unit        = $form->{"totop100_unit_$i"};
-      $sellprice   = $form->{"totop100_sellprice_$i"};
-      $soldtotal   = $form->{"totop100_soldtotal_$i"};
-
-      $totop100 .= qq|
-<input type=hidden name=totop100_partnumber_$i value=$form->{"totop100_partnumber_$i"}>
-<input type=hidden name=totop100_description_$i value=$form->{"totop100_description_$i"}>
-<input type=hidden name=totop100_unit_$i value=$form->{"totop100_unit_$i"}>
-<input type=hidden name=totop100_sellprice_$i value=$form->{"totop100_sellprice_$i"}>
-<input type=hidden name=totop100_soldtotal_$i value=$form->{"totop100_soldtotal_$i"}>
-      |;
-
-      # insert into list
-      push @{ $form->{parts} },
-        { number      => "",
-          partnumber  => "$partnumber",
-          description => "$description",
-          unit        => "$unit",
-          sellprice   => "$sellprice",
-          soldtotal   => "$soldtotal" };
-    }    #rof
-  }    #fi
-       # build data for columns
-  my $i = 0;
-  foreach my $ref (@{ $form->{parts} }) {
-
-    if ($form->{l_subtotal} eq 'Y' && !$ref->{assemblyitem}) {
-      if ($sameitem ne $ref->{ $form->{sort} }) {
-        parts_subtotal(\@column_index, \$subtotalonhand, \$subtotalsellprice, \$subtotallastcost, \$subtotallistprice);
-        $sameitem = $ref->{ $form->{sort} };
-      }
-    }
-
-    $ref->{exchangerate} = 1 unless $ref->{exchangerate};
-    $ref->{sellprice} *= $ref->{exchangerate};
-    $ref->{listprice} *= $ref->{exchangerate};
-    $ref->{lastcost}  *= $ref->{exchangerate};
-
-    # use this for assemblies
-    $onhand = $ref->{onhand};
-
-    $align = "left";
-    if ($ref->{assemblyitem}) {
-      $align = "right";
-      $onhand = 0 if ($form->{sold});
-    }
-
-    $ref->{description} =~ s/\n/<br>/g;
-
-    $column_data{number} =
-        "<td align=right>"
-      . $form->format_amount(\%myconfig, $ref->{number})
-      . "</td>";
-    $column_data{partnumber} =
-      "<td align=$align>$ref->{partnumber}&nbsp;</a></td>";
-    $column_data{description} = "<td>$ref->{description}&nbsp;</td>";
-    $column_data{partsgroup}  = "<td>$ref->{partsgroup}&nbsp;</td>";
-
-    $column_data{onhand} =
-        "<td align=right>"
-      . $form->format_amount(\%myconfig, $ref->{onhand})
-      . "</td>";
-    $column_data{sellprice} =
-        "<td align=right>"
-      . $form->format_amount(\%myconfig, $ref->{sellprice})
-      . "</td>";
-    $column_data{listprice} =
-        "<td align=right>"
-      . $form->format_amount(\%myconfig, $ref->{listprice})
-      . "</td>";
-    $column_data{lastcost} =
-        "<td align=right>"
-      . $form->format_amount(\%myconfig, $ref->{lastcost})
-      . "</td>";
-
-    $column_data{linetotalsellprice} = "<td align=right>"
-      . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{sellprice}, 2)
-      . "</td>";
-    $column_data{linetotallastcost} = "<td align=right>"
-      . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{lastcost}, 2)
-      . "</td>";
-    $column_data{linetotallistprice} = "<td align=right>"
-      . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{listprice}, 2)
-      . "</td>";
-
-    if (!$ref->{assemblyitem}) {
-      $totalsellprice += $onhand * $ref->{sellprice};
-      $totallastcost  += $onhand * $ref->{lastcost};
-      $totallistprice += $onhand * $ref->{listprice};
-
-      $subtotalonhand    += $onhand;
-      $subtotalsellprice += $onhand * $ref->{sellprice};
-      $subtotallastcost  += $onhand * $ref->{lastcost};
-      $subtotallistprice += $onhand * $ref->{listprice};
-    }
-
-    $column_data{rop} =
-      "<td align=right>"
-      . $form->format_amount(\%myconfig, $ref->{rop}) . "</td>";
-    $column_data{weight} =
-        "<td align=right>"
-      . $form->format_amount(\%myconfig, $ref->{weight})
-      . "</td>";
-    $column_data{unit}        = "<td>$ref->{unit}&nbsp;</td>";
-    $column_data{bin}         = "<td>$ref->{bin}&nbsp;</td>";
-    $column_data{priceupdate} = "<td>$ref->{priceupdate}&nbsp;</td>";
-
-    $column_data{invnumber} =
-      ($ref->{module} ne 'oe')
-      ? "<td><a href=$ref->{module}.pl?action=edit&type=invoice&id=$ref->{trans_id}&callback=$callback>$ref->{invnumber}</a></td>"
-      : "<td>$ref->{invnumber}</td>";
-    $column_data{ordnumber} =
-      ($ref->{module} eq 'oe')
-      ? "<td><a href=$ref->{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&callback=$callback>$ref->{ordnumber}</a></td>"
-      : "<td>$ref->{ordnumber}</td>";
-    $column_data{quonumber} =
-      ($ref->{module} eq 'oe' && !$ref->{ordnumber})
-      ? "<td><a href=$ref->{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&callback=$callback>$ref->{quonumber}</a></td>"
-      : "<td>$ref->{quonumber}</td>";
-
-    $column_data{name} = "<td>$ref->{name}</td>";
-
-    $column_data{image} =
-      ($ref->{image})
-      ? "<td><a href=$ref->{image}><img src=$ref->{image} height=32 border=0></a></td>"
-      : "<td>&nbsp;</td>";
-    $column_data{drawing} =
-      ($ref->{drawing})
-      ? "<td><a href=$ref->{drawing}>$ref->{drawing}</a></td>"
-      : "<td>&nbsp;</td>";
-    $column_data{microfiche} =
-      ($ref->{microfiche})
-      ? "<td><a href=$ref->{microfiche}>$ref->{microfiche}</a></td>"
-      : "<td>&nbsp;</td>";
-
-    $column_data{serialnumber} = "<td>$ref->{serialnumber}</td>";
-
-    $column_data{soldtotal} = "<td  align=right>$ref->{soldtotal}</td>";
-
-    $i++;
-    $i %= 2;
-    print "<tr class=listrow$i>";
-
-    map { print "\n$column_data{$_}" } @column_index;
-
-    print qq|
-    </tr>
-|;
-  }
-
-  if ($form->{l_subtotal} eq 'Y') {
-    parts_subtotal(\@column_index, \$subtotalonhand, \$subtotalsellprice, \$subtotallastcost, \$subtotallistprice);
-  }    #fi
-
-  if ($form->{"l_linetotal"}) {
-    map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
-    $column_data{linetotalsellprice} =
-        "<th class=listtotal align=right>"
-      . $form->format_amount(\%myconfig, $totalsellprice, 2)
-      . "</th>";
-    $column_data{linetotallastcost} =
-        "<th class=listtotal align=right>"
-      . $form->format_amount(\%myconfig, $totallastcost, 2)
-      . "</th>";
-    $column_data{linetotallistprice} =
-        "<th class=listtotal align=right>"
-      . $form->format_amount(\%myconfig, $totallistprice, 2)
-      . "</th>";
-
-    print "<tr class=listtotal>";
-
-    map { print "\n$column_data{$_}" } @column_index;
-
-    print qq|</tr>
-    |;
-  }
-
-  print qq|
-  <tr><td colspan=$colspan><hr size=3 noshade></td></tr>
-</table>
-
-|;
-
-  print qq|
-
-<br>
-
-<form method=post action=$form->{script}>
-
-<input type=hidden name=itemstatus value="$form->{itemstatus}">
-<input type=hidden name=l_linetotal value="$form->{l_linetotal}">
-<input type=hidden name=l_partnumber value="$form->{l_partnumber}">
-<input type=hidden name=l_description value="$form->{l_description}">
-<input type=hidden name=l_onhand value="$form->{l_onhand}">
-<input type=hidden name=l_unit value="$form->{l_unit}">
-<input type=hidden name=l_sellprice value="$form->{l_sellprice}">
-<input type=hidden name=l_linetotalsellprice value="$form->{l_linetotalsellprice}">
-<input type=hidden name=sort value="$form->{sort}">
-<input type=hidden name=revers value="$form->{revers}">
-<input type=hidden name=lastsort value="$form->{lastsort}">
-<input type=hidden name=parts value="$form->{parts}">
-
-<input type=hidden name=bom value="$form->{bom}">
-<input type=hidden name=titel value="$form->{titel}">
-<input type=hidden name=searchitems value="$form->{searchitems}">|;
-
-  print $totop100;
-
-  print qq|
-<!--    <input type=hidden name=ndxs_counter value="$form->{ndxs_counter}">-->
-
-    <input class=submit type=submit name=action value="|
-    . $locale->text('choice') . qq|">
-
-  </form>
-|;
+  generate_report();
 
   $lxdebug->leave_sub();
 
   $lxdebug->leave_sub();
-}    # end addtop100
+}
 
 #
 # Report for Wares.
 
 #
 # Report for Wares.
@@ -1010,15 +252,20 @@ sub addtop100 {
 sub generate_report {
   $lxdebug->enter_sub();
 
 sub generate_report {
   $lxdebug->enter_sub();
 
-  $auth->assert('part_service_assembly_edit');
+  $auth->assert('part_service_assembly_details');
 
   my ($revers, $lastsort, $description);
 
   my $cvar_configs = CVar->get_configs('module' => 'IC');
 
 
   my ($revers, $lastsort, $description);
 
   my $cvar_configs = CVar->get_configs('module' => 'IC');
 
-  $form->{title} = (ucfirst $form->{searchitems}) . "s";
-  $form->{title} =~ s/ys$/ies/;
-  $form->{title} = $locale->text($form->{title});
+  my %titles = (
+    ''       => $locale->text('Articles'),
+    part     => $locale->text('Parts'),
+    service  => $locale->text('Services'),
+    assembly => $locale->text('Assemblies'),
+  );
+
+  $form->{title} = $titles{$form->{searchitems}};
 
   my %column_defs = (
     'bin'                => { 'text' => $locale->text('Bin'), },
 
   my %column_defs = (
     'bin'                => { 'text' => $locale->text('Bin'), },
@@ -1028,6 +275,7 @@ sub generate_report {
     'drawing'            => { 'text' => $locale->text('Drawing'), },
     'ean'                => { 'text' => $locale->text('EAN'), },
     'image'              => { 'text' => $locale->text('Image'), },
     'drawing'            => { 'text' => $locale->text('Drawing'), },
     'ean'                => { 'text' => $locale->text('EAN'), },
     'image'              => { 'text' => $locale->text('Image'), },
+    'insertdate'         => { 'text' => $locale->text('Insert Date'), },
     'invnumber'          => { 'text' => $locale->text('Invoice Number'), },
     'lastcost'           => { 'text' => $locale->text('Last Cost'), },
     'linetotallastcost'  => { 'text' => $locale->text('Extended'), },
     'invnumber'          => { 'text' => $locale->text('Invoice Number'), },
     'lastcost'           => { 'text' => $locale->text('Last Cost'), },
     'linetotallastcost'  => { 'text' => $locale->text('Extended'), },
@@ -1046,9 +294,11 @@ sub generate_report {
     'sellprice'          => { 'text' => $locale->text('Sell Price'), },
     'serialnumber'       => { 'text' => $locale->text('Serial Number'), },
     'soldtotal'          => { 'text' => $locale->text('Qty in Selected Records'), },
     'sellprice'          => { 'text' => $locale->text('Sell Price'), },
     'serialnumber'       => { 'text' => $locale->text('Serial Number'), },
     'soldtotal'          => { 'text' => $locale->text('Qty in Selected Records'), },
+    'name'               => { 'text' => $locale->text('Name in Selected Records'), },
     'transdate'          => { 'text' => $locale->text('Transdate'), },
     'unit'               => { 'text' => $locale->text('Unit'), },
     'weight'             => { 'text' => $locale->text('Weight'), },
     'transdate'          => { 'text' => $locale->text('Transdate'), },
     'unit'               => { 'text' => $locale->text('Unit'), },
     'weight'             => { 'text' => $locale->text('Weight'), },
+    'shop'               => { 'text' => $locale->text('Shop article'), },
     'projectnumber'      => { 'text' => $locale->text('Project Number'), },
     'projectdescription' => { 'text' => $locale->text('Project Description'), },
   );
     'projectnumber'      => { 'text' => $locale->text('Project Number'), },
     'projectdescription' => { 'text' => $locale->text('Project Description'), },
   );
@@ -1133,11 +383,13 @@ sub generate_report {
     microfiche    => $locale->text('Microfiche')       . ": '$form->{microfiche}'",
     l_soldtotal   => $locale->text('Qty in Selected Records'),
     ean           => $locale->text('EAN')              . ": '$form->{ean}'",
     microfiche    => $locale->text('Microfiche')       . ": '$form->{microfiche}'",
     l_soldtotal   => $locale->text('Qty in Selected Records'),
     ean           => $locale->text('EAN')              . ": '$form->{ean}'",
+    insertdatefrom => $locale->text('Insert Date') . ": " . $locale->text('From')       . " " . $locale->date(\%myconfig, $form->{insertdatefrom}, 1),
+    insertdateto   => $locale->text('Insert Date') . ": " . $locale->text('To (time)')  . " " . $locale->date(\%myconfig, $form->{insertdateto}, 1),
   );
 
   my @itemstatus_keys = qw(active obsolete orphaned onhand short);
   my @callback_keys   = qw(onorder ordered rfq quoted bought sold partnumber partsgroup partsgroup_id serialnumber description make model
   );
 
   my @itemstatus_keys = qw(active obsolete orphaned onhand short);
   my @callback_keys   = qw(onorder ordered rfq quoted bought sold partnumber partsgroup partsgroup_id serialnumber description make model
-                           drawing microfiche l_soldtotal l_deliverydate transdatefrom transdateto ean);
+                           drawing microfiche l_soldtotal l_deliverydate transdatefrom transdateto insertdatefrom insertdateto ean shop all);
 
   # calculate dependencies
   for (@itemstatus_keys, @callback_keys) {
 
   # calculate dependencies
   for (@itemstatus_keys, @callback_keys) {
@@ -1195,15 +447,27 @@ sub generate_report {
 
   # soldtotal doesn't make sense with more than one bsooqr option.
   # so reset it to sold (the most common option), and issue a warning
 
   # soldtotal doesn't make sense with more than one bsooqr option.
   # so reset it to sold (the most common option), and issue a warning
+  # ...
+  # also it doesn't make sense without bsooqr. disable and issue a warning too
   my @bsooqr = qw(sold bought onorder ordered rfq quoted);
   my @bsooqr = qw(sold bought onorder ordered rfq quoted);
-  if ($form->{l_subtotal} && 1 < grep { $form->{$_} } @bsooqr) {
+  my $bsooqr_mode = grep { $form->{$_} } @bsooqr;
+  if ($form->{l_subtotal} && 1 < $bsooqr_mode) {
     my $enabled       = first { $form->{$_} } @bsooqr;
     $form->{$_}       = ''   for @bsooqr;
     $form->{$enabled} = 'Y';
 
     push @options, $::locale->text('Subtotal cannot distinguish betweens record types. Only one of the selected record types will be displayed: #1', $optiontexts{$enabled});
   }
     my $enabled       = first { $form->{$_} } @bsooqr;
     $form->{$_}       = ''   for @bsooqr;
     $form->{$enabled} = 'Y';
 
     push @options, $::locale->text('Subtotal cannot distinguish betweens record types. Only one of the selected record types will be displayed: #1', $optiontexts{$enabled});
   }
+  if ($form->{l_soldtotal} && !$bsooqr_mode) {
+    delete $form->{l_soldtotal};
+
+    flash('warning', $::locale->text('Soldtotal does not make sense without any bsooqr options'));
+  }
+  if ($form->{l_name} && !$bsooqr_mode) {
+    delete $form->{l_name};
 
 
+    flash('warning', $::locale->text('Name does not make sense without any bsooqr options'));
+  }
   IC->all_parts(\%myconfig, \%$form);
 
   my @columns = qw(
   IC->all_parts(\%myconfig, \%$form);
 
   my @columns = qw(
@@ -1211,6 +475,7 @@ sub generate_report {
     linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost
     priceupdate weight image drawing microfiche invnumber ordnumber quonumber
     transdate name serialnumber deliverydate ean projectnumber projectdescription
     linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost
     priceupdate weight image drawing microfiche invnumber ordnumber quonumber
     transdate name serialnumber deliverydate ean projectnumber projectdescription
+    insertdate shop
   );
 
   my $pricegroups = SL::DB::Manager::Pricegroup->get_all(sort => 'id');
   );
 
   my $pricegroups = SL::DB::Manager::Pricegroup->get_all(sort => 'id');
@@ -1235,14 +500,20 @@ sub generate_report {
 
   %column_defs = (%column_defs, %column_defs_cvars, %column_defs_pricegroups);
   map { $column_defs{$_}->{visible} ||= $form->{"l_$_"} ? 1 : 0 } @columns;
 
   %column_defs = (%column_defs, %column_defs_cvars, %column_defs_pricegroups);
   map { $column_defs{$_}->{visible} ||= $form->{"l_$_"} ? 1 : 0 } @columns;
-  map { $column_defs{$_}->{align}   = 'right' } qw(onhand sellprice listprice lastcost linetotalsellprice linetotallastcost linetotallistprice rop weight soldtotal), @pricegroup_columns;
-
-  my @hidden_variables = (qw(l_subtotal l_linetotal searchitems itemstatus bom l_pricegroups), @itemstatus_keys, @callback_keys,
-                              map({ "cvar_$_->{name}" } @searchable_custom_variables), map { "l_$_" } @columns);
+  map { $column_defs{$_}->{align}   = 'right' } qw(onhand sellprice listprice lastcost linetotalsellprice linetotallastcost linetotallistprice rop weight soldtotal shop), @pricegroup_columns;
+
+  my @hidden_variables = (
+    qw(l_subtotal l_linetotal searchitems itemstatus bom l_pricegroups insertdatefrom insertdateto),
+    @itemstatus_keys,
+    @callback_keys,
+    map({ "cvar_$_->{name}" } @searchable_custom_variables),
+    map({'cvar_'. $_->{name} .'_qtyop'} grep({$_->{type} eq 'number'} @searchable_custom_variables)),
+    map({ "l_$_" } @columns),
+  );
 
   my $callback         = build_std_url('action=generate_report', grep { $form->{$_} } @hidden_variables);
 
 
   my $callback         = build_std_url('action=generate_report', grep { $form->{$_} } @hidden_variables);
 
-  my @sort_full        = qw(partnumber description onhand soldtotal deliverydate);
+  my @sort_full        = qw(partnumber description onhand soldtotal deliverydate insertdate shop);
   my @sort_no_revers   = qw(partsgroup bin priceupdate invnumber ordnumber quonumber name image drawing serialnumber);
 
   foreach my $col (@sort_full) {
   my @sort_no_revers   = qw(partsgroup bin priceupdate invnumber ordnumber quonumber name image drawing serialnumber);
 
   foreach my $col (@sort_full) {
@@ -1261,7 +532,7 @@ sub generate_report {
     'assembly' => $locale->text('assembly_list'),
   );
 
     'assembly' => $locale->text('assembly_list'),
   );
 
-  $report->set_options('top_info_text'         => $locale->text('Options') . ': ' . join(', ', grep $_, @options),
+  $report->set_options('raw_top_info_text'     => $form->parse_html_template('ic/generate_report_top', { options => \@options }),
                        'raw_bottom_info_text'  => $form->parse_html_template('ic/generate_report_bottom'),
                        'output_format'         => 'HTML',
                        'title'                 => $form->{title},
                        'raw_bottom_info_text'  => $form->parse_html_template('ic/generate_report_bottom'),
                        'output_format'         => 'HTML',
                        'title'                 => $form->{title},
@@ -1311,7 +582,7 @@ sub generate_report {
     $ref->{lastcost}      *= $ref->{exchangerate} / $ref->{price_factor};
 
     # use this for assemblies
     $ref->{lastcost}      *= $ref->{exchangerate} / $ref->{price_factor};
 
     # use this for assemblies
-    my $soldtotal = $ref->{soldtotal};
+    my $soldtotal = $bsooqr_mode ? $ref->{soldtotal} : $ref->{onhand};
 
     if ($ref->{assemblyitem}) {
       $row->{partnumber}{align}   = 'right';
 
     if ($ref->{assemblyitem}) {
       $row->{partnumber}{align}   = 'right';
@@ -1336,6 +607,11 @@ sub generate_report {
 
     $row->{weight}->{data} .= ' ' . $defaults->{weightunit};
 
 
     $row->{weight}->{data} .= ' ' . $defaults->{weightunit};
 
+    # 'yes' and 'no' for boolean value shop
+    if ($form->{l_shop}) {
+      $row->{shop}{data} = $row->{shop}{data}? $::locale->text('yes') : $::locale->text('no');
+    }
+
     if (!$ref->{assemblyitem}) {
       foreach my $col (@subtotal_columns) {
         $totals{$col}    += $soldtotal * $ref->{$col};
     if (!$ref->{assemblyitem}) {
       foreach my $col (@subtotal_columns) {
         $totals{$col}    += $soldtotal * $ref->{$col};
@@ -1349,8 +625,8 @@ sub generate_report {
     if ($ref->{module} eq 'oe') {
       # für oe gibt es vier fälle, jeweils nach kunde oder lieferant unterschiedlich:
       #
     if ($ref->{module} eq 'oe') {
       # für oe gibt es vier fälle, jeweils nach kunde oder lieferant unterschiedlich:
       #
-      # | ist bestellt  | Vom Kunde bestellt |  -> edit_oe_ord_link
-      # | Anfrage       | Angebot            |  -> edit_oe_quo_link
+      # | ist bestellt  | Von Kunden bestellt |  -> edit_oe_ord_link
+      # | Anfrage       | Angebot             |  -> edit_oe_quo_link
 
       my $edit_oe_ord_link = build_std_url("script=oe.pl", 'action=edit', 'type=' . E($ref->{cv} eq 'vendor' ? 'purchase_order' : 'sales_order'), 'id=' . E($ref->{trans_id}), 'callback');
       my $edit_oe_quo_link = build_std_url("script=oe.pl", 'action=edit', 'type=' . E($ref->{cv} eq 'vendor' ? 'request_quotation' : 'sales_quotation'), 'id=' . E($ref->{trans_id}), 'callback');
 
       my $edit_oe_ord_link = build_std_url("script=oe.pl", 'action=edit', 'type=' . E($ref->{cv} eq 'vendor' ? 'purchase_order' : 'sales_order'), 'id=' . E($ref->{trans_id}), 'callback');
       my $edit_oe_quo_link = build_std_url("script=oe.pl", 'action=edit', 'type=' . E($ref->{cv} eq 'vendor' ? 'request_quotation' : 'sales_quotation'), 'id=' . E($ref->{trans_id}), 'callback');
@@ -1359,7 +635,7 @@ sub generate_report {
       $row->{quonumber}{link} = $edit_oe_quo_link if (!$ref->{ordnumber});
 
     } else {
       $row->{quonumber}{link} = $edit_oe_quo_link if (!$ref->{ordnumber});
 
     } else {
-      $row->{invnumber}{link} = build_std_url("script=$ref->{module}.pl", 'action=edit', 'type=invoice', 'id=' . E($ref->{trans_id}), 'callback');
+      $row->{invnumber}{link} = build_std_url("script=$ref->{module}.pl", 'action=edit', 'type=invoice', 'id=' . E($ref->{trans_id}), 'callback') if ($ref->{invnumber});
     }
 
     # set properties of images
     }
 
     # set properties of images
@@ -1369,6 +645,8 @@ sub generate_report {
     }
     map { $row->{$_}{link} = $ref->{$_} } qw(drawing microfiche);
 
     }
     map { $row->{$_}{link} = $ref->{$_} } qw(drawing microfiche);
 
+    $row->{notes}{data} = SL::HTML::Util->strip($ref->{notes});
+
     $report->add_data($row);
 
     my $next_ref = $form->{parts}[$idx + 1];
     $report->add_data($row);
 
     my $next_ref = $form->{parts}[$idx + 1];
@@ -1456,7 +734,7 @@ sub parts_subtotal {
 sub edit {
   $lxdebug->enter_sub();
 
 sub edit {
   $lxdebug->enter_sub();
 
-  $auth->assert('part_service_assembly_edit');
+  $auth->assert('part_service_assembly_details');
 
   # show history button
   $form->{javascript} = qq|<script type="text/javascript" src="js/show_history.js"></script>|;
 
   # show history button
   $form->{javascript} = qq|<script type="text/javascript" src="js/show_history.js"></script>|;
@@ -1477,13 +755,12 @@ sub edit {
 sub link_part {
   $lxdebug->enter_sub();
 
 sub link_part {
   $lxdebug->enter_sub();
 
-  $auth->assert('part_service_assembly_edit');
+  $auth->assert('part_service_assembly_details');
 
   IC->create_links("IC", \%myconfig, \%$form);
 
   # currencies
 
   IC->create_links("IC", \%myconfig, \%$form);
 
   # currencies
-  map({ $form->{selectcurrency} .= "<option>$_\n" }
-      split(/:/, $form->{currencies}));
+  map({ $form->{selectcurrency} .= "<option>$_\n" } $::form->get_all_currencies());
 
   # parts and assemblies have the same links
   my $item = $form->{item};
 
   # parts and assemblies have the same links
   my $item = $form->{item};
@@ -1568,7 +845,7 @@ sub link_part {
 sub form_header {
   $lxdebug->enter_sub();
 
 sub form_header {
   $lxdebug->enter_sub();
 
-  $auth->assert('part_service_assembly_edit');
+  $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->{pg_keys}          = sub { "$_[0]->{partsgroup}--$_[0]->{id}" };
   $form->{description_area} = ($form->{rows} = $form->numtextrows($form->{description}, 40)) > 1;
@@ -1579,33 +856,56 @@ sub form_header {
 
   $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS',
                    'partsgroup'    => 'all_partsgroup',
 
   $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS',
                    'partsgroup'    => 'all_partsgroup',
-                   'vendors'       => 'ALL_VENDORS',);
+                   '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} };
 
 
   IC->retrieve_buchungsgruppen(\%myconfig, $form);
   @{ $form->{BUCHUNGSGRUPPEN} } = grep { $_->{id} eq $form->{buchungsgruppen_id} || ($form->{id} && $form->{orphaned}) || !$form->{id} } @{ $form->{BUCHUNGSGRUPPEN} };
 
-  # use JavaScript Calendar or not (yes!)
-  $form->{jsscript} = 1;
+  if (($form->{partnumber} ne '') && !SL::TransNumber->new(number => $form->{partnumber}, type => $form->{item}, 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();
 
 
   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();
 
-  $::request->{layout}->focus("#partnumber");
-
   $form->{CUSTOM_VARIABLES} = CVar->get_custom_variables('module' => 'IC', 'trans_id' => $form->{id});
 
   $form->{CUSTOM_VARIABLES} = CVar->get_custom_variables('module' => 'IC', 'trans_id' => $form->{id});
 
-  CVar->render_inputs('variables' => $form->{CUSTOM_VARIABLES}, show_disabled_message => 1)
+  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} });
 
     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->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();
 }
   print $form->parse_html_template('ic/form_header');
   $lxdebug->leave_sub();
 }
@@ -1613,7 +913,7 @@ sub form_header {
 sub form_footer {
   $lxdebug->enter_sub();
 
 sub form_footer {
   $lxdebug->enter_sub();
 
-  $auth->assert('part_service_assembly_edit');
+  $auth->assert('part_service_assembly_details');
 
   print $form->parse_html_template('ic/form_footer');
 
 
   print $form->parse_html_template('ic/form_footer');
 
@@ -1664,15 +964,15 @@ sub assembly_row {
   }
 
   my %header = (
   }
 
   my %header = (
-   runningnumber => { text =>  $locale->text('No.'),              nowrap => 1, width => '5%'  },
-   qty           => { text =>  $locale->text('Qty'),              nowrap => 1, width => '10%' },
-   unit          => { text =>  $locale->text('Unit'),             nowrap => 1, width => '5%'  },
-   partnumber    => { text =>  $locale->text('Part Number'),      nowrap => 1, width => '20%' },
-   description   => { text =>  $locale->text('Part Description'), nowrap => 1, width => '50%' },
-   lastcost      => { text =>  $locale->text('Purchase Prices'),  nowrap => 1, width => '50%' },
-   total         => { text =>  $locale->text('Sale Prices'),      nowrap => 1,                },
-   bom           => { text =>  $locale->text('BOM'),                                          },
-   partsgroup    => { text =>  $locale->text('Group'),                                        },
+   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;
   );
 
   my @ROWS;
@@ -1689,7 +989,7 @@ sub assembly_row {
     $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);
     $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                = qq|$form->{script}?action=edit&id=$form->{"id_$i"}&rowcount=$i&previousform=$previousform|;
+    $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
     map { $row{$_}{data} = "" } qw(qty unit partnumber description bom partsgroup runningnumber);
 
     # last row
@@ -1709,7 +1009,8 @@ sub assembly_row {
         $row{bom}{data}           = $form->{"bom_$i"} ? "x" : "&nbsp;";
         $row{qty}{align}          = 'right';
       } else {
         $row{bom}{data}           = $form->{"bom_$i"} ? "x" : "&nbsp;";
         $row{qty}{align}          = 'right';
       } else {
-        $row{partnumber}{data}    = qq|<a href=$href>$form->{"partnumber_$i"}</a>|;
+        $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>|,
         $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>|,
@@ -1747,14 +1048,33 @@ sub assembly_row {
 sub update {
   $lxdebug->enter_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};
 
   # 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->{item} 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->{item} 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->{item} eq "assembly") {
     map { $form->{"lastcost_$_"} = $form->parse_amount(\%myconfig, $form->{"lastcost_$_"}) } 1 .. $form->{"makemodel_rows"};
   # same for makemodel lastcosts
   # but parse_amount not necessary for assembly component lastcosts
   unless ($form->{item} 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->{item} eq "assembly") {
     my $i = $form->{assembly_rows};
 
   if ($form->{item} eq "assembly") {
     my $i = $form->{assembly_rows};
@@ -1763,13 +1083,16 @@ sub update {
     if (   ($form->{"partnumber_$i"} eq "")
         && ($form->{"description_$i"} eq "")
         && ($form->{"partsgroup_$i"}  eq "")) {
     if (   ($form->{"partnumber_$i"} eq "")
         && ($form->{"description_$i"} eq "")
         && ($form->{"partsgroup_$i"}  eq "")) {
+      # no new assembly item was added
 
       &check_form;
 
     } else {
 
       &check_form;
 
     } else {
-
+      # search db for newly added assemblyitems, via partnumber or description
       IC->assembly_item(\%myconfig, \%$form);
 
       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) {
       my $rows = scalar @{ $form->{item_list} };
 
       if ($rows) {
@@ -1777,8 +1100,8 @@ sub update {
 
         if ($rows > 1) {
           $form->{makemodel_rows}--;
 
         if ($rows > 1) {
           $form->{makemodel_rows}--;
-          select_item(mode => 'IC');
-          ::end_of_request();
+          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);
         } else {
           map { $form->{item_list}[$i]{$_} =~ s/\"/&quot;/g }
             qw(partnumber description unit partsgroup);
@@ -1812,7 +1135,7 @@ sub save {
   $lxdebug->enter_sub();
 
   $auth->assert('part_service_assembly_edit');
   $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
   my ($parts_id, %newform, $amount, $callback);
 
   # check if there is a part number - commented out, cause there is an automatic allocation of numbers
@@ -1833,14 +1156,20 @@ sub save {
   $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};
 
   $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}) {
   # 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->{addition} = "SAVED";
+    $form->{snumbers}  = qq|partnumber_| . $form->{partnumber};
+    $form->{what_done} = "part";
+    $form->{addition}  = "SAVED";
     $form->save_history;
   }
   # /saving the history
     $form->save_history;
   }
   # /saving the history
@@ -1870,8 +1199,12 @@ sub save {
         qw(weight listprice sellprice rop);
 
       $form->{assembly_rows}--;
         qw(weight listprice sellprice rop);
 
       $form->{assembly_rows}--;
-      $i = $form->{assembly_rows};
-      $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
+      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"};
 
       $form->{sellprice} -= $form->{"sellprice_$i"} * $form->{"qty_$i"};
       $form->{weight}    -= $form->{"weight_$i"} * $form->{"qty_$i"};
@@ -1888,7 +1221,7 @@ sub save {
 
       # set values for last invoice/order item
       $i = $form->{rowcount};
 
       # set values for last invoice/order item
       $i = $form->{rowcount};
-      $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
+      $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;
 
       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;
@@ -1963,8 +1296,9 @@ sub save_as_new {
 
   # saving the history
   if(!exists $form->{addition}) {
 
   # saving the history
   if(!exists $form->{addition}) {
-    $form->{snumbers} = qq|partnumber_| . $form->{partnumber};
-    $form->{addition} = "SAVED AS NEW";
+    $form->{snumbers}  = qq|partnumber_| . $form->{partnumber};
+    $form->{addition}  = "SAVED AS NEW";
+    $form->{what_done} = "part";
     $form->save_history;
   }
   # /saving the history
     $form->save_history;
   }
   # /saving the history
@@ -1984,8 +1318,9 @@ sub delete {
 
   # saving the history
   if(!exists $form->{addition}) {
 
   # saving the history
   if(!exists $form->{addition}) {
-    $form->{snumbers} = qq|partnumber_| . $form->{partnumber};
-    $form->{addition} = "DELETED";
+    $form->{snumbers}  = qq|partnumber_| . $form->{partnumber};
+    $form->{addition}  = "DELETED";
+    $form->{what_done} = "part";
     $form->save_history;
   }
   # /saving the history
     $form->save_history;
   }
   # /saving the history
@@ -2001,7 +1336,7 @@ sub delete {
 sub price_row {
   $lxdebug->enter_sub();
 
 sub price_row {
   $lxdebug->enter_sub();
 
-  $auth->assert('part_service_assembly_edit');
+  $auth->assert('part_service_assembly_details');
 
   my ($numrows) = @_;
 
 
   my ($numrows) = @_;
 
@@ -2016,50 +1351,6 @@ sub price_row {
   $lxdebug->leave_sub();
 }
 
   $lxdebug->leave_sub();
 }
 
-sub parts_language_selection {
-  $lxdebug->enter_sub();
-
-  $auth->assert('part_service_assembly_edit');
-
-  my $languages = IC->retrieve_languages(\%myconfig, $form);
-
-  if ($form->{language_values} ne "") {
-    foreach my $item (split(/---\+\+\+---/, $form->{language_values})) {
-      my ($language_id, $translation, $longdescription) = split(/--\+\+--/, $item);
-
-      foreach my $language (@{ $languages }) {
-        next unless ($language->{id} == $language_id);
-
-        $language->{translation}     = $translation;
-        $language->{longdescription} = $longdescription;
-
-        $language->{translation_area}     = ($language->{translation_rows} = $form->numtextrows($language->{translation}, 40)) > 1;
-        $language->{longdescription_rows} = max 4, $form->numtextrows($language->{longdescription}, 40);
-
-        last;
-      }
-    }
-  }
-
-  my @header_sort = qw(name longdescription);
-  my %header_title = ( "name" => $locale->text("Name"),
-                       "longdescription" => $locale->text("Long Description"),
-                       );
-
-  my @header =
-    map(+{ "column_title" => $header_title{$_},
-           "column" => $_,
-         },
-        @header_sort);
-
-  $form->{"title"} = $locale->text("Language Values");
-  $form->header();
-  print $form->parse_html_template("ic/parts_language_selection", { "HEADER"    => \@header,
-                                                                    "LANGUAGES" => $languages, });
-
-  $lxdebug->leave_sub();
-}
-
 sub ajax_autocomplete {
   $main::lxdebug->enter_sub();
 
 sub ajax_autocomplete {
   $main::lxdebug->enter_sub();
 
@@ -2079,6 +1370,27 @@ sub ajax_autocomplete {
   $main::lxdebug->leave_sub();
 }
 
   $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->{item} =~ /^(part|service)$/;
+  assembly_row(++$::form->{assembly_rows})   if $::form->{item} eq 'assembly';
+
+  form_footer();
+
+  $::lxdebug->leave_sub;
+}
+
 sub back_to_record {
   _check_io_auth();
 
 sub back_to_record {
   _check_io_auth();