+ $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;
+ } #fi
+
+ if ($form->{"l_linetotal"}) {
+ map { $column_data{$_} = "<td> </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>
+
+</body>
+</html>
+|;
+
+ $lxdebug->leave_sub();
+} # end addtop100
+
+#
+# Report for Wares.
+# Warning, deep magic ahead.
+# This function parses the requested details, sanity checks them, and converts them into a format thats usable for IC->all_parts
+#
+# flags coming from the form:
+# hardcoded:
+# searchitems=part revers=0 lastsort=''
+#
+# filter:
+# partnumber ean description partsgroup serialnumber make model drawing microfiche
+# transdatefrom transdateto
+#
+# radio:
+# itemstatus = active | onhand | short | obsolete | orphaned
+# action = continue | top100
+#
+# checkboxes:
+# bought sold onorder ordered rfq quoted
+# l_partnumber l_description l_serialnumber l_unit l_listprice l_sellprice l_lastcost
+# l_linetotal l_priceupdate l_bin l_rop l_weight l_image l_drawing l_microfiche
+# l_partsgroup l_subtotal l_soldtotal l_deliverydate
+#
+# hiddens:
+# nextsub revers lastsort sort ndxs_counter
+#
+sub generate_report {
+ $lxdebug->enter_sub();
+
+ $auth->assert('part_service_assembly_edit');
+
+ my ($revers, $lastsort, $description);
+
+ $form->{title} = (ucfirst $form->{searchitems}) . "s";
+ $form->{title} = $locale->text($form->{title});
+
+ my $revers = $form->{revers};
+ my $lastsort = $form->{lastsort};
+
+ # sorting and direction of sorting
+ # ToDO: change this to the simpler field+direction method
+ if (($form->{lastsort} eq "") && ($form->{sort} eq undef)) {
+ $form->{revers} = 0;
+ $form->{lastsort} = "partnumber";
+ $form->{sort} = "partnumber";
+ } else {
+ if ($form->{lastsort} eq $form->{sort}) {
+ $form->{revers} = 1 - $form->{revers};
+ } else {
+ $form->{revers} = 0;
+ $form->{lastsort} = $form->{sort};
+ } #fi
+ } #fi
+
+ # special case if we have a serialnumber limit search
+ # serialnumbers are only given in invoices and orders,
+ # so they can only pop up in bought, sold, rfq, and quoted stuff
+ $form->{no_sn_joins} = 'Y' if ( !$form->{bought} && !$form->{sold}
+ && !$form->{rfq} && !$form->{quoted}
+ && ($form->{l_serialnumber} || $form->{serialnumber}));
+
+ # special case for any checkbox of bought | sold | onorder | ordered | rfq | quoted.
+ # if any of these are ticked the behavior changes slightly for lastcost
+ # since all those are aggregation checks for the legder tables this is an internal switch
+ # refered to as ledgerchecks
+ $form->{ledgerchecks} = 'Y' if ( $form->{bought} || $form->{sold} || $form->{onorder}
+ || $form->{ordered} || $form->{rfq} || $form->{quoted});
+
+ # if something should be activated if something else is active, enter it here
+ my %dependencies = (
+ onhand => [ qw(l_onhand) ],
+ short => [ qw(l_onhand) ],
+ onorder => [ qw(l_ordnumber) ],
+ ordered => [ qw(l_ordnumber) ],
+ rfq => [ qw(l_quonumber) ],
+ quoted => [ qw(l_quonumber) ],
+ bought => [ qw(l_invnumber) ],
+ sold => [ qw(l_invnumber) ],
+ ledgerchecks => [ qw(l_name) ],
+ serialnumber => [ qw(l_serialnumber) ],
+ no_sn_joins => [ qw(bought sold) ],
+ );
+
+ # these strings get displayed at the top of the results to indicate the user which switches were used
+ my %optiontexts = (
+ active => $locale->text('Active'),
+ obsolete => $locale->text('Obsolete'),
+ orphaned => $locale->text('Orphaned'),
+ onhand => $locale->text('On Hand'),
+ short => $locale->text('Short'),
+ onorder => $locale->text('On Order'),
+ ordered => $locale->text('Ordered'),
+ rfq => $locale->text('RFQ'),
+ quoted => $locale->text('Quoted'),
+ bought => $locale->text('Bought'),
+ sold => $locale->text('Sold'),
+ transdatefrom => $locale->text('From') . " " . $locale->date(\%myconfig, $form->{transdatefrom}, 1),
+ transdateto => $locale->text('To (time)') . " " . $locale->date(\%myconfig, $form->{transdateto}, 1),
+ partnumber => $locale->text('Part Number') . ": '$form->{partnumber}'",
+ partsgroup => $locale->text('Group') . ": '$form->{partsgroup}'",
+ serialnumber => $locale->text('Serial Number') . ": '$form->{serialnumber}'",
+ description => $locale->text('Part Description') . ": '$form->{description}'",
+ make => $locale->text('Make') . ": '$form->{make}'",
+ model => $locale->text('Model') . ": '$form->{model}'",
+ drawing => $locale->text('Drawing') . ": '$form->{drawing}'",
+ microfiche => $locale->text('Microfiche') . ": '$form->{microfiche}'",
+ l_soldtotal => $locale->text('soldtotal'),
+ );
+
+ my @itemstatus_keys = qw(active obsolete orphaned onhand short);
+ my @callback_keys = qw(onorder ordered rfq quoted bought sold partnumber partsgroup serialnumber description make model
+ drawing microfiche l_soldtotal l_deliverydate transdatefrom transdateto ean);
+
+ # calculate dependencies
+ for (@itemstatus_keys, @callback_keys) {
+ next if ($form->{itemstatus} ne $_ && !$form->{$_});
+ map { $form->{$_} = 'Y' } @{ $dependencies{$_} } if $dependencies{$_};
+ }
+
+ # generate callback and optionstrings
+ my @options;
+ for my $key (@itemstatus_keys, @callback_keys) {
+ next if ($form->{itemstatus} ne $key && !$form->{$key});
+ push @options, $optiontexts{$key};
+ }
+
+ # special case for lastcost
+ $form->{l_lastcost} = "" if $form->{ledgerchecks};
+
+ if ($form->{description}) {
+ $description = $form->{description};
+ $description =~ s/\n/<br>/g;
+ }
+
+ 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} = "";
+ }
+ }
+
+ $form->{l_lastcost} = "" if ($form->{searchitems} eq 'assembly' && !$form->{bom});
+
+ IC->all_parts(\%myconfig, \%$form);
+
+ my @columns =
+ qw(partnumber description partsgroup bin onhand rop unit listprice linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost
+ priceupdate weight image drawing microfiche invnumber ordnumber quonumber name serialnumber soldtotal deliverydate);
+
+ my %column_defs = (
+ 'bin' => { 'text' => $locale->text('Bin'), },
+ 'deliverydate' => { 'text' => $locale->text('deliverydate'), },
+ 'description' => { 'text' => $locale->text('Part Description'), },
+ 'drawing' => { 'text' => $locale->text('Drawing'), },
+ 'image' => { 'text' => $locale->text('Image'), },
+ 'invnumber' => { 'text' => $locale->text('Invoice Number'), },
+ 'lastcost' => { 'text' => $locale->text('Last Cost'), },
+ 'linetotallastcost' => { 'text' => $locale->text('Extended'), },
+ 'linetotallistprice' => { 'text' => $locale->text('Extended'), },
+ 'linetotalsellprice' => { 'text' => $locale->text('Extended'), },
+ 'listprice' => { 'text' => $locale->text('List Price'), },
+ 'microfiche' => { 'text' => $locale->text('Microfiche'), },
+ 'name' => { 'text' => $locale->text('Name'), },
+ 'onhand' => { 'text' => $locale->text('Qty'), },
+ 'ordnumber' => { 'text' => $locale->text('Order Number'), },
+ 'partnumber' => { 'text' => $locale->text('Part Number'), },
+ 'partsgroup' => { 'text' => $locale->text('Group'), },
+ 'priceupdate' => { 'text' => $locale->text('Updated'), },
+ 'quonumber' => { 'text' => $locale->text('Quotation'), },
+ 'rop' => { 'text' => $locale->text('ROP'), },
+ 'sellprice' => { 'text' => $locale->text('Sell Price'), },
+ 'serialnumber' => { 'text' => $locale->text('Serial Number'), },
+ 'soldtotal' => { 'text' => $locale->text('soldtotal'), },
+ 'unit' => { 'text' => $locale->text('Unit'), },
+ 'weight' => { 'text' => $locale->text('Weight'), },
+ );
+
+ 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);
+
+ my @hidden_variables = (qw(l_subtotal l_linetotal searchitems itemstatus bom), @itemstatus_keys, @callback_keys, map { "l_$_" } @columns);
+ my $callback = build_std_url('action=generate_report', grep { $form->{$_} } @hidden_variables);
+
+ my @sort_full = qw(partnumber description onhand soldtotal deliverydate);
+ my @sort_no_revers = qw(partsgroup bin priceupdate invnumber ordnumber quonumber name image drawing serialnumber);
+
+ foreach my $col (@sort_full) {
+ $column_defs{$col}->{link} = join '&', $callback, "sort=$col", map { "$_=" . E($form->{$_}) } qw(revers lastsort);
+ }
+ map { $column_defs{$_}->{link} = "${callback}&sort=$_" } @sort_no_revers;
+
+ # add order to callback
+ $form->{callback} = join '&', ($callback, map { "${_}=" . E($form->{$_}) } qw(sort revers));
+
+ my $report = SL::ReportGenerator->new(\%myconfig, $form);
+
+ my %attachment_basenames = (
+ 'part' => $locale->text('part_list'),
+ 'service' => $locale->text('service_list'),
+ 'assembly' => $locale->text('assembly_list'),
+ );
+
+ $report->set_options('top_info_text' => $locale->text('Options') . ': ' . join(', ', grep $_, @options),
+ 'raw_bottom_info_text' => $form->parse_html_template('ic/generate_report_bottom'),
+ 'output_format' => 'HTML',
+ 'title' => $form->{title},
+ 'attachment_basename' => $attachment_basenames{$form->{searchitems}} . strftime('_%Y%m%d', localtime time),
+ );
+ $report->set_options_from_form();