X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=bin%2Fmozilla%2Fic.pl;h=f83d42a53b948127361e189caa5d076a5aeb6b3e;hb=74959706407d96a119832a3c807ee4d4d2c53639;hp=06fc13f90762d20aed0d560483ec3982d8319066;hpb=5ebbc846ece0cf580417eeaa6e11154b168ada7b;p=kivitendo-erp.git diff --git a/bin/mozilla/ic.pl b/bin/mozilla/ic.pl index 06fc13f90..f83d42a53 100644 --- a/bin/mozilla/ic.pl +++ b/bin/mozilla/ic.pl @@ -30,28 +30,60 @@ # Inventory Control module # #====================================================================== -#$locale->text('ea'); +use POSIX qw(strftime); +use List::Util qw(first max); +use List::MoreUtils qw(any); + +use SL::AM; +use SL::CVar; use SL::IC; +use SL::Helper::Flash; +use SL::HTML::Util; +use SL::ReportGenerator; #use SL::PE; -require "$form->{path}/io.pl"; +use strict; +#use warnings; + +# global imports +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"; 1; +# Parserhappy(R): +# type=submit $locale->text('Add Part') +# type=submit $locale->text('Add Service') +# type=submit $locale->text('Add Assembly') +# type=submit $locale->text('Edit Part') +# type=submit $locale->text('Edit Service') +# type=submit $locale->text('Edit Assembly') +# $locale->text('Parts') +# $locale->text('Services') +# $locale->text('Inventory quantity must be zero before you can set this part obsolete!') +# $locale->text('Inventory quantity must be zero before you can set this assembly obsolete!') +# $locale->text('Part Number missing!') +# $locale->text('Service Number missing!') +# $locale->text('Assembly Number missing!') +# $locale->text('ea'); + # end of main sub add { $lxdebug->enter_sub(); - $form->{title} = $locale->text('Add ' . ucfirst $form->{item}); + $auth->assert('part_service_assembly_edit'); - $form->{callback} = - "$form->{script}?action=add&item=$form->{item}&path=$form->{path}&login=$form->{login}&password=$form->{password}" - unless $form->{callback}; - - $form->{"unit_changeable"} = 1; + my $title = 'Add ' . ucfirst $form->{item}; + $form->{title} = $locale->text($title); + $form->{callback} = "$form->{script}?action=add&item=$form->{item}" unless $form->{callback}; + $form->{unit_changeable} = 1; IC->get_pricegroups(\%myconfig, \%$form); &link_part; @@ -63,548 +95,91 @@ sub add { sub search { $lxdebug->enter_sub(); - $form->{title} = (ucfirst $form->{searchitems}) . "s"; - $form->{title} = $locale->text($form->{title}); - - # switch for backward sorting - $form->{revers} = 0; - - # memory for which table was sort at last time - $form->{lastsort} = ""; - - # counter for added entries to top100 - $form->{ndxs_counter} = 0; - - # $locale->text('Parts') - # $locale->text('Services') - - # use JavaScript Calendar or not - $form->{jsscript} = $jscalendar; - $jsscript = ""; - if ($form->{jsscript}) { - - # with JavaScript Calendar - $button1 = qq| - - text('button') . qq|> - |; - $button2 = qq| - - text('button') . qq|> - |; - - #write Trigger - $jsscript = - Form->write_trigger(\%myconfig, "2", "transdatefrom", "BL", "trigger1", - "transdateto", "BL", "trigger2"); - } else { - - # without JavaScript Calendar - $button1 = qq| - |; - $button2 = qq| - |; - } - - unless ($form->{searchitems} eq 'service') { - - $onhand = qq| -  | - . $locale->text('On Hand') . qq| -  | - . $locale->text('Short') . qq| -|; - - $makemodel = qq| - - | . $locale->text('Make') . qq| - - | . $locale->text('Model') . qq| - - -|; - - $serialnumber = qq| - | . $locale->text('Serial Number') . qq| - -|; + $auth->assert('part_service_assembly_details'); - $l_serialnumber = qq| -  | - . $locale->text('Serial Number') . qq| -|; - - } - - if ($form->{searchitems} eq 'assembly') { + $form->{revers} = 0; # switch for backward sorting + $form->{lastsort} = ""; # memory for which table was sort at last time + $form->{ndxs_counter} = 0; # counter for added entries to top100 - $form->{title} = $locale->text('Assemblies'); - - $toplevel = qq| - - - -  | - . $locale->text('Top Level') . qq| -  | - . $locale->text('Individual Items') . qq| - - -|; - - $bought = qq| - - - - - - - - - $button1 - - $button2 - -
- - - - - - - - - - - - - - - - - - - -
| . $locale->text('Sold') . qq|

| . $locale->text('Ordered') . qq|

| . $locale->text('Quoted') . qq|
-
 | . $locale->text('From') . qq|| . $locale->text('To (time)') . qq|
- - -|; + my %is_xyz = map { +"is_$_" => ($form->{searchitems} eq $_) } qw(part service assembly); - } else { + $form->{title} = (ucfirst $form->{searchitems}) . "s"; + $form->{title} = $locale->text($form->{title}); + $form->{title} = $locale->text('Assemblies') if ($is_xyz{is_assembly}); - $bought = qq| - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
| . $locale->text('Bought') . qq|| . $locale->text('Sold') . qq|

| . $locale->text('On Order') . qq|| . $locale->text('Ordered') . qq|

| . $locale->text('RFQ') . qq|| . $locale->text('Quoted') . qq|
-
  - - - - $button1 - - $button2 - -
| . $locale->text('From') . qq|| . $locale->text('To (time)') . qq|
-
- - -|; - } + $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}, + 'include_prefix' => 'l_', + 'include_value' => 'Y'); $form->header; - print qq| - - -
{script}> - -{searchitems}> - - - - - - - - - - - - -
$form->{title}
- - - - - - - - - - - - - $serialnumber - - $makemodel - - - - - - - $toplevel - - - - - $bought - - - - - - - - -
| . $locale->text('Part Number') . qq|
| - . $locale->text('Part Description') . qq|
| . $locale->text('Group') . qq|
| . $locale->text('Drawing') . qq|| . $locale->text('Microfiche') . qq|
-  | - . $locale->text('Active') . qq| - $onhand -  | - . $locale->text('Obsolete') . qq| -  | - . $locale->text('Orphaned') . qq| -
-
-
| - . $locale->text('Include in Report') . qq| - - - - - $l_serialnumber - - - - - - - - - - - - - - - - - - - - - - - - - -
 | - . $locale->text('Part Number') . qq| | - . $locale->text('Part Description') . qq| | - . $locale->text('Unit of measure') . qq|
 | - . $locale->text('List Price') . qq| | - . $locale->text('Sell Price') . qq| | - . $locale->text('Last Cost') . qq| | - . $locale->text('Line Total') . qq|
 | - . $locale->text('Updated') . qq| | - . $locale->text('Bin') . qq| | - . $locale->text('ROP') . qq| | - . $locale->text('Weight') . qq|
 | - . $locale->text('Image') . qq| | - . $locale->text('Drawing') . qq| | - . $locale->text('Microfiche') . qq| | - . $locale->text('Group') . qq|
 | - . $locale->text('Subtotal') . qq| | - . $locale->text('soldtotal') . qq| | - . $locale->text('deliverydate') . qq|
-
-

- -$jsscript + $form->get_lists('partsgroup' => 'ALL_PARTSGROUPS'); + print $form->parse_html_template('ic/search', { %is_xyz, + dateformat => $myconfig{dateformat}, + limit => $myconfig{vclimit}, }); - - -{path}> -{login}> -{password}> - - - - - - - -
- - -
- - - -|; $lxdebug->leave_sub(); } #end search() - sub search_update_prices { $lxdebug->enter_sub(); - $form->{title} = $locale->text('Update prices'); - IC->get_pricegroups(\%myconfig, \%$form); - - # use JavaScript Calendar or not -# $form->{jsscript} = $jscalendar; -# $jsscript = ""; -# if ($form->{jsscript}) { -# -# # with JavaScript Calendar -# $button1 = qq| -# -# text('button') . qq|> -# |; -# $button2 = qq| -# -# text('button') . qq|> -# |; -# -# #write Trigger -# $jsscript = -# Form->write_trigger(\%myconfig, "2", "transdatefrom", "BL", "trigger1", -# "transdateto", "BL", "trigger2"); -# } else { -# -# # without JavaScript Calendar -# $button1 = qq| -# |; -# $button2 = qq| -# |; -# } - - $onhand = qq| -  | - . $locale->text('On Hand') . qq| -  | - . $locale->text('Short') . qq| -|; - - $makemodel = qq| - - | . $locale->text('Make') . qq| - - | . $locale->text('Model') . qq| - - -|; - - $serialnumber = qq| - | . $locale->text('Serial Number') . qq| - -|; - - $l_serialnumber = qq| -  | - . $locale->text('Serial Number') . qq| -|; + $auth->assert('part_service_assembly_edit'); + my $pricegroups = IC->get_pricegroups(\%myconfig, \%$form); + $form->{title} = $locale->text('Update Prices'); $form->header; - print qq| - - -
{script}> - - - - - - - - " } @column_index; - $subtotalonhand = 0 if ($form->{searchitems} eq 'assembly' && $form->{bom}); + $auth->assert('part_service_assembly_edit'); + + my (%column_data); + my ($column_index, $subtotalonhand, $subtotalsellprice, $subtotallastcost, $subtotallistprice) = @_; + + map { $column_data{$_} = "" } @{ $column_index }; + $$subtotalonhand = 0 if ($form->{searchitems} eq 'assembly' && $form->{bom}); $column_data{onhand} = ""; $column_data{linetotalsellprice} = ""; $column_data{linetotallistprice} = ""; $column_data{linetotallastcost} = ""; - $subtotalonhand = 0; - $subtotalsellprice = 0; - $subtotallistprice = 0; - $subtotallastcost = 0; + $$subtotalonhand = 0; + $$subtotalsellprice = 0; + $$subtotallistprice = 0; + $$subtotallastcost = 0; print ""; - map { print "\n$column_data{$_}" } @column_index; + map { print "\n$column_data{$_}" } @{ $column_index }; print qq| @@ -2069,11 +1482,17 @@ sub parts_subtotal { sub edit { $lxdebug->enter_sub(); + $auth->assert('part_service_assembly_details'); + + # show history button + $form->{javascript} = qq||; + #/show hhistory button IC->get_part(\%myconfig, \%$form); $form->{"original_partnumber"} = $form->{"partnumber"}; - $form->{title} = $locale->text('Edit ' . ucfirst $form->{item}); + my $title = 'Edit ' . ucfirst $form->{item}; + $form->{title} = $locale->text($title); &link_part; &display_form; @@ -2084,26 +1503,27 @@ sub edit { sub link_part { $lxdebug->enter_sub(); + $auth->assert('part_service_assembly_details'); + IC->create_links("IC", \%myconfig, \%$form); # currencies - map { $form->{selectcurrency} .= "|; - foreach $item (@{ $form->{payment_terms} }) { - if ($form->{payment_id} eq $item->{id}) { - $payment .= qq||; - } else { - $payment .= qq||; - } - } - - - if (($rows = $form->numtextrows($form->{notes}, 40)) < 2) { - $rows = 4; - } - - $notes = - qq||; - if (($rows = $form->numtextrows($form->{description}, 40)) > 1) { - $description = - qq||; - } else { - $description = - qq||; - } - - foreach $item (split / /, $form->{taxaccounts}) { - $form->{"IC_tax_$item"} = ($form->{"IC_tax_$item"}) ? "checked" : ""; - } - - IC->retrieve_buchungsgruppen(\%myconfig, $form); - if (@{ $form->{BUCHUNGSGRUPPEN} }) { - foreach $item (@{ $form->{BUCHUNGSGRUPPEN} }) { - if ($item->{id} == $form->{buchungsgruppen_id}) { - $form->{selectbuchungsgruppe} .= - " - - - |; - - - # set option - foreach $item (qw(IC IC_income IC_expense)) { - if ($form->{$item}) { - if ($form->{id} && $form->{orphaned}) { - $form->{"select$item"} =~ s/ selected//; - $form->{"select$item"} =~ - s/option>\Q$form->{$item}\E/option selected>$form->{$item}/; - } else { - $form->{"select$item"} = qq| - - - -|; - if (!$eur) { - $linkaccounts = qq| - - - - - |; - } - - if ($form->{item} eq "part") { - - $linkaccounts .= qq| - - - - - - - - - - -|; - - $weight = qq| - - - - -|; - - } - - if ($form->{item} eq "assembly") { - - $lastcost = ""; - - $linkaccounts = qq| - - - - - -|; - - $weight = qq| - - - - -|; - - } - - if ($form->{item} eq "service") { - - $linkaccounts = qq| - - - - - - - - - - -|; - - } - $linkaccounts = qq||; - - if ($form->{IC_cogs_default}) { - $form->{IC_expense_default} = $form->{IC_cogs_default}; - } - - if (($form->{item} eq "service") || ($form->{item} eq "part")) { - $linkaccounts .= qq||; - } - if ($form->{item} eq "part") { - $linkaccounts .= qq||; - } - - if ($form->{item} ne 'service') { - $n = ($form->{onhand} > 0) ? "1" : "0"; - $rop = qq| - - - - -|; - - if ($form->{item} eq 'assembly') { - $rop .= qq| - - - - -|; - } - - $rop .= qq| - - - - -|; - - $bin = qq| - - - - -|; - $vegv = qq| - - - - - - - - -|; - $notdiscountableok = ($form->{not_discountable}) == 1 ? "checked" : ""; - $notdiscountable .= qq| - - - - -|; - - $formel = - qq||; - $imagelinks = qq| - - - -|; - - } - - if ($form->{id}) { - $obsolete = qq| - - - - -|; - } - $shopok = $form->{shop} == 1 ? "checked" : ""; - $shop .= qq| - - - - -|; - - - # type=submit $locale->text('Add Part') - # type=submit $locale->text('Add Service') - # type=submit $locale->text('Add Assembly') - - # type=submit $locale->text('Edit Part') - # type=submit $locale->text('Edit Service') - # type=submit $locale->text('Edit Assembly') - # use JavaScript Calendar or not - $form->{jsscript} = $jscalendar; - $jsscript = ""; - if ($form->{jsscript}) { + delete $form->{IC_links}; + delete $form->{amount}; - # with JavaScript Calendar - $button1 = qq| - - - |; + $form->get_partsgroup(\%myconfig, { all => 1 }); - #write Trigger - $jsscript = - Form->write_trigger(\%myconfig, "1", "priceupdate", "BL", "trigger1"); - } else { + $form->{partsgroup} = "$form->{partsgroup}--$form->{partsgroup_id}"; - # without JavaScript Calendar - $button1 = qq| - |; + if (@{ $form->{all_partsgroup} }) { + $form->{selectpartsgroup} = qq|
$form->{title}
- - - - - - - - - - - - - $serialnumber - - $makemodel - - - - - - - $toplevel - - - - - $bought - - - - |; - print qq| - - - - - -
| . $locale->text('Part Number') . qq|
| - . $locale->text('Part Description') . qq|
| . $locale->text('Group') . qq|
| . $locale->text('Drawing') . qq|| . $locale->text('Microfiche') . qq|
-  | - . $locale->text('Active') . qq| - $onhand -  | - . $locale->text('Obsolete') . qq| -  | - . $locale->text('Orphaned') . qq| -
-
-
- - - - - - - - - - - - - - - - -|; - for $i (1 .. $form->{price_rows}) { - print qq| - - - - - - -|; - } - - print qq| -
| . $locale->text('Preisklasse') . qq|| . $locale->text('Preis') . qq|| . $locale->text('Prozentual/Absolut') . qq|
| . $locale->text('Sell Price') . qq|/
| . $locale->text('List Price') . qq|/
$form->{"pricegroup_$i"}/
-

- -{price_rows}> - -{path}> -{login}> -{password}> - -
- - + print $form->parse_html_template('ic/search_update_prices', { PRICE_ROWS => $pricegroups }); - - -|; $lxdebug->leave_sub(); } #end search() sub confirm_price_update { $lxdebug->enter_sub(); + $auth->assert('part_service_assembly_edit'); - $form->{nextsub} = "update_prices"; - $form->header; + my @errors = (); + my $value_found = undef; - print qq| - + foreach my $idx (qw(sellprice listprice), (1..$form->{price_rows})) { + my $name = $idx =~ m/\d/ ? $form->{"pricegroup_${idx}"} : $idx eq 'sellprice' ? $locale->text('Sell Price') : $locale->text('List Price'); + my $type = $idx =~ m/\d/ ? $form->{"pricegroup_type_${idx}"} : $form->{"${idx}_type"}; + my $value_idx = $idx =~ m/\d/ ? "price_${idx}" : $idx; + my $value = $form->parse_amount(\%myconfig, $form->{$value_idx}); -
{script}> -|; + if ((0 > $value) && ($type eq 'percent')) { + push @errors, $locale->text('You cannot adjust the price for pricegroup "#1" by a negative percentage.', $name); - # delete action variable - map { delete $form->{$_} } qw(action header); + } elsif (!$value && ($form->{$value_idx} ne '')) { + push @errors, $locale->text('No valid number entered for pricegroup "#1".', $name); - foreach $key (keys %$form) { - $form->{$key} =~ s/\"/"/g; - print qq|\n|; + } elsif (0 < $value) { + $value_found = 1; + } } - print qq| -

| . $locale->text('Confirm!') . qq|

+ push @errors, $locale->text('No prices will be updated because no prices have been entered.') if (!$value_found); -

| - . $locale->text('Are you sure you want to update the prices') -. qq|

+ my $num_matches = IC->get_num_matches_for_priceupdate(); -

- -

-|; + $form->header(); + + if (@errors) { + $form->show_generic_error(join('
', @errors), 'back_button' => 1); + } + + $form->{nextsub} = "update_prices"; + + map { delete $form->{$_} } qw(action header); + + print $form->parse_html_template('ic/confirm_price_update', { HIDDENS => [ map { name => $_, value => $form->{$_} }, keys %$form ], + num_matches => $num_matches }); $lxdebug->leave_sub(); } @@ -612,8 +187,12 @@ sub confirm_price_update { sub update_prices { $lxdebug->enter_sub(); - if (IC->update_prices(\%myconfig, \%$form)) { - $form->redirect($form->{update_count} . $locale->text('prices updated!')); + $auth->assert('part_service_assembly_edit'); + + my $num_updated = IC->update_prices(\%myconfig, \%$form); + + if (-1 != $num_updated) { + $form->redirect($locale->text('#1 prices were updated.', $num_updated)); } else { $form->error($locale->text('Could not update prices!')); } @@ -621,322 +200,253 @@ sub update_prices { $lxdebug->leave_sub(); } -sub choice { - $lxdebug->enter_sub(); - - $form->{title} = $locale->text('Top 100 hinzufuegen'); - - $form->header; - - print qq| - - -
{script}> - - {searchitems}> - - - - |; - - print qq| - - - - - - - - - -
| - . $locale->text('Part Number') . qq|| - . $locale->text('Part Description') . qq|
-
|; - - print qq| - -{path}> -{login}> -{password}> - - - - - - - - - - - - - - - - - - - - - - +#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| +##{"totop100_partnumber_$i"}> +##{"totop100_description_$i"}> +##{"totop100_unit_$i"}> +##{"totop100_sellprice_$i"}> +##{"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| +#

| . $locale->text('choice part') . qq|

+# +# +# +# +# +# +# +# +# +# |; +# +# my $j = 0; +# my $i = $form->{rows}; +# +# for ($j = 1; $j <= $i; $j++) { +# +# print qq| +# |; +# if ($j == 1) { +# print qq| +# |; +# } else { +# print qq| +# |; +# } +# print qq| +# +# +# +# +# +# +# +# |; +# } +# +# print qq| +# +#
 | . $locale->text('Part Number') . qq|| . $locale->text('Part Description') . qq|| . $locale->text('Unit of measure') . qq|| . $locale->text('Sell Price') . qq|| . $locale->text('soldtotal') . qq|
$form->{"partnumber_$j"}$form->{"description_$j"}$form->{"unit_$j"}$form->{"sellprice_$j"}$form->{"soldtotal_$j"}
+# +#
+# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +#{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| +#{"totop100_partnumber_$i"}> +#{"totop100_description_$i"}> +#{"totop100_unit_$i"}> +#{"totop100_sellprice_$i"}> +#{"totop100_soldtotal_$i"}> +# |; +# } #rof +# } #fi +# +# print $totop100; +# +# print qq| +# +# +#
+#|; +# $lxdebug->leave_sub(); +#} #end list() -{ndxs_counter}> +sub top100 { + $lxdebug->enter_sub(); -{extras}>|; + $auth->assert('part_service_assembly_edit'); - # if choice set data if ($form->{ndx}) { - for ($i = 0; $i < $form->{ndxs_counter}; $i++) { - - # prepeare data - $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"}; - - # insert data into top100 - push @{ $form->{parts} }, - { number => "", - partnumber => "$partnumber", - description => "$description", - unit => "$unit", - sellprice => "$sellprice", - soldtotal => "$soldtotal" }; - } #rof - } #fi + $form->{ndxs_counter}++; - $totop100 = ""; + if ($form->{ndxs_counter} > 0) { - # set data for next page - 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"}; + my $index = $form->{ndx}; - $totop100 .= qq| -{"totop100_partnumber_$i"}> -{"totop100_description_$i"}> -{"totop100_unit_$i"}> -{"totop100_sellprice_$i"}> -{"totop100_soldtotal_$i"}> - |; - } #rof + $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 - - print $totop100; - - print qq| - - - - - |; + &addtop100(); $lxdebug->leave_sub(); -} #end choice +} #end top100 -sub list { +sub addtop100 { $lxdebug->enter_sub(); - # get parts for - if (($form->{partnumber} eq "") and ($form->{description} eq "")) { - IC->get_parts(\%myconfig, \%$form, ""); - } else { - if ((!($form->{partnumber} eq "")) and ($form->{description} eq "")) { - IC->get_parts(\%myconfig, \%$form, "partnumber"); - } else { - if (($form->{partnumber} eq "") and (!($form->{description} eq ""))) { - IC->get_parts(\%myconfig, \%$form, "description"); - } else { - IC->get_parts(\%myconfig, \%$form, "all"); - } #fi - } #fi - } #fi - - $form->{title} = $locale->text('Top 100 hinzufuegen'); - - $form->header; - - print qq| - -
- - - - - - - - - - - - - |; - - my $j = 0; - my $i = $form->{rows}; - - for ($j = 1; $j <= $i; $j++) { + $auth->assert('part_service_assembly_edit'); - print qq| - |; - if ($j == 1) { - print qq| - |; - } else { - print qq| - |; - } - print qq| - - - - - - + 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"; - print qq| + $totop100 = ""; -
| . $locale->text('choice part') . qq|
 | . $locale->text('Part Number') . qq|| . $locale->text('Part Description') . qq|| . $locale->text('Unit of measure') . qq|| . $locale->text('Sell Price') . qq|| . $locale->text('soldtotal') . qq|
$form->{"partnumber_$j"}$form->{"description_$j"}$form->{"unit_$j"}$form->{"sellprice_$j"}$form->{"soldtotal_$j"}
+ $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 -{path}> -{login}> -{password}> - - - - - - - - - - - - - - - - - - - - - - - -{ndxs_counter}>|; - - $totop100 = ""; - - if (($form->{ndxs_counter}) > 0) { - for ($i = 1; ($i < $form->{ndxs_counter} + 1); $i++) { - $j1 = $form->{"totop100_partnumber_$i"}; - $j2 = $form->{"totop100_description_$i"}; - $j3 = $form->{"totop100_unit_$i"}; - $j4 = $form->{"totop100_sellprice_$i"}; - $j5 = $form->{"totop100_soldtotal_$i"}; - - $partnumber = $j1; - $description = $j2; - $unit = $j3; - $sellprice = $j4; - $soldtotal = $j5; - - $totop100 .= qq| -{"totop100_partnumber_$i"}> -{"totop100_description_$i"}> -{"totop100_unit_$i"}> -{"totop100_sellprice_$i"}> -{"totop100_soldtotal_$i"}> - |; - } #rof - } #fi - - print $totop100; - - print qq| - - -
- - -|; - $lxdebug->leave_sub(); -} #end list() - -sub top100 { - $lxdebug->enter_sub(); - - if ($form->{ndx}) { - $form->{ndxs_counter}++; - - if ($form->{ndxs_counter} > 0) { - - $index = $form->{ndx}; - - $j1 = $form->{"new_partnumber_$index"}; - $form->{"totop100_partnumber_$form->{ndxs_counter}"} = $j1; - $j2 = $form->{"new_description_$index"}; - $form->{"totop100_description_$form->{ndxs_counter}"} = $j2; - $j3 = $form->{"new_unit_$index"}; - $form->{"totop100_unit_$form->{ndxs_counter}"} = $j3; - $j4 = $form->{"new_sellprice_$index"}; - $form->{"totop100_sellprice_$form->{ndxs_counter}"} = $j4; - $j5 = $form->{"new_soldtotal_$index"}; - $form->{"totop100_soldtotal_$form->{ndxs_counter}"} = $j5; - } #fi - } #fi - &addtop100(); - $lxdebug->leave_sub(); -} #end top100 - -sub addtop100 { - $lxdebug->enter_sub(); - - $form->{top100} = "top100"; - $form->{l_soldtotal} = "Y"; - $form->{soldtotal} = "soldtotal"; - $form->{sort} = "soldtotal"; - $form->{l_qty} = "N"; - $callback .= "&form->{top100}=$form->{top100}"; - $form->{l_linetotal} = ""; - $form->{revers} = 1; - $form->{number} = "position"; - $form->{l_number} = "Y"; - - my $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&path=$form->{path}&login=$form->{login}&password=$form->{password}&searchitems=$form->{searchitems}&itemstatus=$form->{itemstatus}&bom=$form->{bom}&l_linetotal=$form->{l_linetotal}&title=" - . $form->escape($form->{title}, 1); + $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}) { @@ -1028,22 +538,23 @@ sub addtop100 { $callback .= "&partnumber=$form->{partnumber}"; $option .= $locale->text('Part Number') . qq| : $form->{partnumber}
|; } + if ($form->{ean}) { + $callback .= "&partnumber=$form->{ean}"; + $option .= $locale->text('EAN') . qq| : $form->{ean}
|; + } if ($form->{partsgroup}) { $callback .= "&partsgroup=$form->{partsgroup}"; $option .= $locale->text('Group') . qq| : $form->{partsgroup}
|; } if ($form->{serialnumber}) { $callback .= "&serialnumber=$form->{serialnumber}"; - $option .= - $locale->text('Serial Number') . qq| : $form->{serialnumber}
|; + $option .= $locale->text('Serial Number') . qq| : $form->{serialnumber}
|; } if ($form->{description}) { - $callback .= "&description=$form->{description}"; + $callback .= "&description=$form->{description}"; $description = $form->{description}; - $description =~ s/ -/
/g; - $option .= - $locale->text('Part Description') . qq| : $form->{description}
|; + $description =~ s/\n/
/g; + $option .= $locale->text('Part Description') . qq| : $form->{description}
|; } if ($form->{make}) { $callback .= "&make=$form->{make}"; @@ -1066,8 +577,8 @@ sub addtop100 { $option .= $locale->text('soldtotal') . qq| : $form->{soldtotal}
|; } - @columns = $form->sort_columns( - qw(number partnumber description partsgroup bin onhand rop unit listprice linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost priceupdate weight image drawing microfiche invnumber ordnumber quonumber name serialnumber soldtotal) + 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}) { @@ -1103,10 +614,7 @@ sub addtop100 { } } - $form->{l_lastcost} = "" - if ($form->{searchitems} eq 'assembly' && !$form->{bom}); - - foreach $item (@columns) { + foreach my $item (@columns) { if ($form->{"l_$item"} eq "Y") { push @column_index, $item; @@ -1208,16 +716,12 @@ sub addtop100 { . qq||; $form->header; - $colspan = $#column_index + 1; + my $colspan = $#column_index + 1; print qq| - +

$form->{title}

- - - - @@ -1242,14 +746,14 @@ sub addtop100 { # insert numbers for top100 my $j = 0; - foreach $ref (@{ $form->{parts} }) { + foreach my $ref (@{ $form->{parts} }) { $j++; $ref->{number} = $j; } # if avaible -> insert choice here if (($form->{ndxs_counter}) > 0) { - for ($i = 1; ($i < $form->{ndxs_counter} + 1); $i++) { + 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"}; @@ -1275,11 +779,12 @@ sub addtop100 { } #rof } #fi # build data for columns - foreach $ref (@{ $form->{parts} }) { + my $i = 0; + foreach my $ref (@{ $form->{parts} }) { if ($form->{l_subtotal} eq 'Y' && !$ref->{assemblyitem}) { if ($sameitem ne $ref->{ $form->{sort} }) { - &parts_subtotal; + parts_subtotal(\@column_index, \$subtotalonhand, \$subtotalsellprice, \$subtotallastcost, \$subtotallistprice); $sameitem = $ref->{ $form->{sort} }; } } @@ -1298,12 +803,11 @@ sub addtop100 { $onhand = 0 if ($form->{sold}); } - $ref->{description} =~ s/ -/
/g; + $ref->{description} =~ s/\n/
/g; $column_data{number} = ""; $column_data{partnumber} = ""; @@ -1312,32 +816,29 @@ sub addtop100 { $column_data{onhand} = ""; $column_data{sellprice} = ""; $column_data{listprice} = ""; $column_data{lastcost} = ""; $column_data{linetotalsellprice} = ""; $column_data{linetotallastcost} = ""; $column_data{linetotallistprice} = ""; if (!$ref->{assemblyitem}) { @@ -1353,10 +854,10 @@ sub addtop100 { $column_data{rop} = ""; + . $form->format_amount(\%myconfig, $ref->{rop}) . ""; $column_data{weight} = ""; $column_data{unit} = ""; $column_data{bin} = ""; @@ -1364,15 +865,15 @@ sub addtop100 { $column_data{invnumber} = ($ref->{module} ne 'oe') - ? "" + ? "" : ""; $column_data{ordnumber} = ($ref->{module} eq 'oe') - ? "" + ? "" : ""; $column_data{quonumber} = ($ref->{module} eq 'oe' && !$ref->{ordnumber}) - ? "" + ? "" : ""; $column_data{name} = ""; @@ -1406,22 +907,22 @@ sub addtop100 { } if ($form->{l_subtotal} eq 'Y') { - &parts_subtotal; + parts_subtotal(\@column_index, \$subtotalonhand, \$subtotalsellprice, \$subtotallastcost, \$subtotallistprice); } #fi if ($form->{"l_linetotal"}) { map { $column_data{$_} = "" } @column_index; $column_data{linetotalsellprice} = ""; $column_data{linetotallastcost} = ""; $column_data{linetotallistprice} = ""; print ""; @@ -1444,10 +945,6 @@ sub addtop100 { {script}> -{path}> -{login}> -{password}> - @@ -1468,203 +965,210 @@ sub addtop100 { print $totop100; print qq| - + - |; + - if ($form->{menubar}) { - require "$form->{path}/menu.pl"; - &menubar; - } - - print qq| - - - |; $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 l_pricegroups +# +# hiddens: +# nextsub revers lastsort sort ndxs_counter +# sub generate_report { $lxdebug->enter_sub(); - $revers = $form->{revers}; - $lastsort = $form->{lastsort}; + $auth->assert('part_service_assembly_details'); + + 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 %column_defs = ( + 'bin' => { 'text' => $locale->text('Bin'), }, + 'deliverydate' => { 'text' => $locale->text('deliverydate'), }, + 'description' => { 'text' => $locale->text('Part Description'), }, + 'notes' => { 'text' => $locale->text('Notes'), }, + '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'), }, + '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('Stocked 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('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'), }, + 'shop' => { 'text' => $locale->text('Shopartikel'), }, + 'projectnumber' => { 'text' => $locale->text('Project Number'), }, + 'projectdescription' => { 'text' => $locale->text('Project Description'), }, + ); + + $revers = $form->{revers}; + $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 { - - # switch between backward sorting of tables if ($form->{lastsort} eq $form->{sort}) { - if ($form->{revers} == 0) { - $form->{revers} = 1; - } else { - $form->{revers} = 0; - } #fi + $form->{revers} = 1 - $form->{revers}; } else { - $form->{revers} == 0; + $form->{revers} = 0; $form->{lastsort} = $form->{sort}; } #fi } #fi - $callback = - "$form->{script}?action=generate_report&path=$form->{path}&login=$form->{login}&password=$form->{password}&searchitems=$form->{searchitems}&itemstatus=$form->{itemstatus}&bom=$form->{bom}&l_linetotal=$form->{l_linetotal}&title=" - . $form->escape($form->{title}, 1); + # 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) ], + ); - # 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; - } - } + # get name of partsgroup if id is given + my $pg_name; + if ($form->{partsgroup_id}) { + my $pg = SL::DB::PartsGroup->new(id => $form->{partsgroup_id})->load; + $pg_name = $pg->{'partsgroup'}; + } + + # 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}'", + partsgroup_id => $locale->text('Group') . ": '$pg_name'", + 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('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), + ); - IC->all_parts(\%myconfig, \%$form); + 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 insertdatefrom insertdateto ean shop); - if ($form->{itemstatus} eq 'active') { - $option .= $locale->text('Active') . " : "; + # calculate dependencies + for (@itemstatus_keys, @callback_keys) { + next if ($form->{itemstatus} ne $_ && !$form->{$_}); + map { $form->{$_} = 'Y' } @{ $dependencies{$_} } if $dependencies{$_}; } - 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 .= ""ed=$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
" - . $locale->text('From') - . " " - . $locale->date(\%myconfig, $form->{transdatefrom}, 1); - } - if ($form->{transdateto}) { - $callback .= "&transdateto=$form->{transdateto}"; - $option .= "\n
" - . $locale->text('To (time)') - . " " - . $locale->date(\%myconfig, $form->{transdateto}, 1); - } + # 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}; } - $option .= "
"; - - if ($form->{partnumber}) { - $callback .= "&partnumber=$form->{partnumber}"; - $option .= $locale->text('Part Number') . qq| : $form->{partnumber}
|; - } - if ($form->{partsgroup}) { - $callback .= "&partsgroup=$form->{partsgroup}"; - $option .= $locale->text('Group') . qq| : $form->{partsgroup}
|; - } - if ($form->{serialnumber}) { - $callback .= "&serialnumber=$form->{serialnumber}"; - $option .= - $locale->text('Serial Number') . qq| : $form->{serialnumber}
|; + # special case for lastcost + if ($form->{ledgerchecks}){ + # ledgerchecks don't know about sellprice or lastcost. they just return a + # price. so rename sellprice to price, and drop lastcost. + $column_defs{sellprice}{text} = $locale->text('Price'); + $form->{l_lastcost} = "" } + if ($form->{description}) { - $callback .= "&description=$form->{description}"; $description = $form->{description}; - $description =~ s/ -/
/g; - $option .= - $locale->text('Part Description') . qq| : $form->{description}
|; - } - if ($form->{make}) { - $callback .= "&make=$form->{make}"; - $option .= $locale->text('Make') . qq| : $form->{make}
|; - } - if ($form->{model}) { - $callback .= "&model=$form->{model}"; - $option .= $locale->text('Model') . qq| : $form->{model}
|; - } - if ($form->{drawing}) { - $callback .= "&drawing=$form->{drawing}"; - $option .= $locale->text('Drawing') . qq| : $form->{drawing}
|; - } - if ($form->{microfiche}) { - $callback .= "µfiche=$form->{microfiche}"; - $option .= $locale->text('Microfiche') . qq| : $form->{microfiche}
|; + $description =~ s/\n/
/g; } - # table soldtotal aktive - if ($form->{l_soldtotal}) { - $callback .= "&soldtotal=$form->{soldtotal}"; - $option .= $locale->text('soldtotal') . qq| : $form->{soldtotal}
|; - } - - if ($form->{l_deliverydate}) { - $callback .= "&deliverydate=$form->{deliverydate}"; - } - - @columns = $form->sort_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) - ); - if ($form->{l_linetotal}) { - $form->{l_onhand} = "Y"; + $form->{l_qty} = "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_linetotallastcost} = $form->{searchitems} eq 'assembly' && !$form->{bom} ? "" : 'Y' if $form->{l_lastcost}; $form->{l_linetotallistprice} = "Y" if $form->{l_listprice}; } @@ -1682,346 +1186,250 @@ sub generate_report { || $form->{ordered} || $form->{rfq} || $form->{quoted}) { - $form->{l_onhand} = "Y"; +# $form->{l_onhand} = "Y"; } else { $form->{l_linetotalsellprice} = ""; $form->{l_linetotallastcost} = ""; } } - $form->{l_lastcost} = "" - if ($form->{searchitems} eq 'assembly' && !$form->{bom}); - - foreach $item (@columns) { - if ($form->{"l_$item"} eq "Y") { - push @column_index, $item; + # 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_mode = grep { $form->{$_} } @bsooqr; + if ($form->{l_subtotal} && 1 < $bsooqr_mode) { + my $enabled = first { $form->{$_} } @bsooqr; + $form->{$_} = '' for @bsooqr; + $form->{$enabled} = 'Y'; - # add column to callback - $callback .= "&l_$item=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}; - if ($form->{l_subtotal} eq 'Y') { - $callback .= "&l_subtotal=Y"; + flash('warning', $::locale->text('Soldtotal does not make sense without any bsooqr options')); } - $column_header{partnumber} = - qq||; - $column_header{description} = - qq||; - $column_header{partsgroup} = - qq||; - $column_header{bin} = - qq||; - $column_header{priceupdate} = - qq||; - $column_header{onhand} = - qq||; - $column_header{unit} = - qq||; - $column_header{listprice} = - qq||; - $column_header{lastcost} = - qq||; - $column_header{rop} = - qq||; - $column_header{weight} = - qq||; - - $column_header{invnumber} = - qq||; - $column_header{ordnumber} = - qq||; - $column_header{quonumber} = - qq||; - - $column_header{name} = - qq||; - - $column_header{sellprice} = - qq||; - $column_header{linetotalsellprice} = - qq||; - $column_header{linetotallastcost} = - qq||; - $column_header{linetotallistprice} = - qq||; - - $column_header{image} = - qq||; - $column_header{drawing} = - qq||; - $column_header{microfiche} = - qq||; - - $column_header{serialnumber} = - qq||; - $column_header{soldtotal} = - qq||; + if ($form->{l_name} && !$bsooqr_mode) { + delete $form->{l_name}; - $column_header{deliverydate} = - qq||; - - $form->header; - $colspan = $#column_index + 1; - - print qq| - + flash('warning', $::locale->text('Name does not make sense without any bsooqr options')); + } + IC->all_parts(\%myconfig, \%$form); -
$form->{title}
$option
" - . $form->format_amount(\%myconfig, $ref->{number}, '', " ") + . $form->format_amount(\%myconfig, $ref->{number}) . "$ref->{partnumber} " - . $form->format_amount(\%myconfig, $ref->{onhand}, '', " ") + . $form->format_amount(\%myconfig, $ref->{onhand}) . "" - . $form->format_amount(\%myconfig, $ref->{sellprice}, 2, " ") + . $form->format_amount(\%myconfig, $ref->{sellprice}) . "" - . $form->format_amount(\%myconfig, $ref->{listprice}, 2, " ") + . $form->format_amount(\%myconfig, $ref->{listprice}) . "" - . $form->format_amount(\%myconfig, $ref->{lastcost}, 2, " ") + . $form->format_amount(\%myconfig, $ref->{lastcost}) . "" - . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{sellprice}, - 2, " ") + . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{sellprice}, 2) . "" - . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{lastcost}, - 2, " ") + . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{lastcost}, 2) . "" - . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{listprice}, - 2, " ") + . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{listprice}, 2) . "" - . $form->format_amount(\%myconfig, $ref->{rop}, '', " ") . "" - . $form->format_amount(\%myconfig, $ref->{weight}, '', " ") + . $form->format_amount(\%myconfig, $ref->{weight}) . "$ref->{unit} $ref->{bin} {module}.pl?action=edit&type=invoice&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{invnumber}{module}.pl?action=edit&type=invoice&id=$ref->{trans_id}&callback=$callback>$ref->{invnumber}$ref->{invnumber}{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{ordnumber}{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&callback=$callback>$ref->{ordnumber}$ref->{ordnumber}{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{quonumber}{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&callback=$callback>$ref->{quonumber}$ref->{quonumber}$ref->{name} " - . $form->format_amount(\%myconfig, $totalsellprice, 2, " ") + . $form->format_amount(\%myconfig, $totalsellprice, 2) . "" - . $form->format_amount(\%myconfig, $totallastcost, 2, " ") + . $form->format_amount(\%myconfig, $totallastcost, 2) . "" - . $form->format_amount(\%myconfig, $totallistprice, 2, " ") + . $form->format_amount(\%myconfig, $totallistprice, 2) . "
{revers}&lastsort=$form->{lastsort}>| - . $locale->text('Part Number') - . qq|{revers}&lastsort=$form->{lastsort}>| - . $locale->text('Part Description') - . qq|| - . $locale->text('Group') - . qq|| - . $locale->text('Bin') - . qq|| - . $locale->text('Updated') - . qq|{revers}&lastsort=$form->{lastsort}>| - . $locale->text('Qty') - . qq|| . $locale->text('Unit') . qq|| - . $locale->text('List Price') - . qq|| . $locale->text('Last Cost') . qq|| . $locale->text('ROP') . qq|| . $locale->text('Weight') . qq|| - . $locale->text('Invoice Number') - . qq|| - . $locale->text('Order Number') - . qq|| - . $locale->text('Quotation') - . qq|| - . $locale->text('Name') - . qq|| - . $locale->text('Sell Price') - . qq|| . $locale->text('Extended') . qq|| . $locale->text('Extended') . qq|| . $locale->text('Extended') . qq|| . $locale->text('Image') . qq|| - . $locale->text('Drawing') - . qq|| - . $locale->text('Microfiche') - . qq|| - . $locale->text('Serial Number') - . qq|{revers}&lastsort=$form->{lastsort}>| - . $locale->text('soldtotal') - . qq|{revers}&lastsort=$form->{lastsort}>| - . $locale->text('deliverydate') - . qq|
- - - - + my @columns = qw( + partnumber description notes partsgroup bin onhand rop soldtotal unit listprice + 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 @pricegroup_columns; + my %column_defs_pricegroups; + if ($form->{l_pricegroups}) { + @pricegroup_columns = map { "pricegroup_" . $_->id } @{ $pricegroups }; + %column_defs_pricegroups = map { + "pricegroup_" . $_->id => { + text => $::locale->text('Pricegroup') . ' ' . $_->pricegroup, + visible => 1, + }, + } @{ $pricegroups }; + } + push @columns, @pricegroup_columns; + + my @includeable_custom_variables = grep { $_->{includeable} } @{ $cvar_configs }; + my @searchable_custom_variables = grep { $_->{searchable} } @{ $cvar_configs }; + my %column_defs_cvars = map { +"cvar_$_->{name}" => { 'text' => $_->{description} } } @includeable_custom_variables; + + push @columns, map { "cvar_$_->{name}" } @includeable_custom_variables; + + %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 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); - map { print "\n$column_header{$_}" } @column_index; + 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); - print qq| - - |; + 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} = $callback .= "&sort=$form->{sort}"; - - # escape callback for href - $callback = $form->escape($callback); - - if (@{ $form->{parts} }) { - $sameitem = $form->{parts}->[0]->{ $form->{sort} }; - } + $form->{callback} = join '&', ($callback, map { "${_}=" . E($form->{$_}) } qw(sort revers)); - foreach $ref (@{ $form->{parts} }) { + my $report = SL::ReportGenerator->new(\%myconfig, $form); - if ($form->{l_subtotal} eq 'Y' && !$ref->{assemblyitem}) { - if ($sameitem ne $ref->{ $form->{sort} }) { - &parts_subtotal; - $sameitem = $ref->{ $form->{sort} }; - } - } + my %attachment_basenames = ( + 'part' => $locale->text('part_list'), + 'service' => $locale->text('service_list'), + 'assembly' => $locale->text('assembly_list'), + ); - $ref->{exchangerate} = 1 unless $ref->{exchangerate}; - $ref->{sellprice} *= $ref->{exchangerate}; - $ref->{listprice} *= $ref->{exchangerate}; - $ref->{lastcost} *= $ref->{exchangerate}; + $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}, + 'attachment_basename' => $attachment_basenames{$form->{searchitems}} . strftime('_%Y%m%d', localtime time), + ); + $report->set_options_from_form(); + $locale->set_numberformat_wo_thousands_separator(\%myconfig) if lc($report->{options}->{output_format}) eq 'csv'; - # use this for assemblies - $onhand = $ref->{onhand}; + $report->set_columns(%column_defs); + $report->set_column_order(@columns); - $align = "left"; - if ($ref->{assemblyitem}) { - $align = "right"; - $onhand = 0 if ($form->{sold}); - } + $report->set_export_options('generate_report', @hidden_variables, qw(sort revers)); - $ref->{description} =~ s/ -/
/g; + $report->set_sort_indicator($form->{sort}, $form->{revers} ? 0 : 1); - $column_data{partnumber} = - ""; - $column_data{description} = ""; - $column_data{partsgroup} = ""; + CVar->add_custom_variables_to_report('module' => 'IC', + 'trans_id_field' => 'id', + 'configs' => $cvar_configs, + 'column_defs' => \%column_defs, + 'data' => $form->{parts}); - $column_data{onhand} = - ""; - $column_data{sellprice} = - ""; - $column_data{listprice} = - ""; - $column_data{lastcost} = - ""; + CVar->add_custom_variables_to_report('module' => 'IC', + 'sub_module' => sub { $_[0]->{ioi} }, + 'trans_id_field' => 'ioi_id', + 'configs' => $cvar_configs, + 'column_defs' => \%column_defs, + 'data' => $form->{parts}); - $column_data{linetotalsellprice} = ""; - $column_data{linetotallastcost} = ""; - $column_data{linetotallistprice} = ""; + my @subtotal_columns = qw(sellprice listprice lastcost); + my %subtotals = map { $_ => 0 } ('onhand', @subtotal_columns); + my %totals = map { $_ => 0 } @subtotal_columns; + my $idx = 0; + my $same_item = @{ $form->{parts} } ? $form->{parts}[0]{ $form->{sort} } : undef; - if (!$ref->{assemblyitem}) { - $totalsellprice += $onhand * $ref->{sellprice}; - $totallastcost += $onhand * $ref->{lastcost}; - $totallistprice += $onhand * $ref->{listprice}; + my $defaults = AM->get_defaults(); - $subtotalonhand += $onhand; - $subtotalsellprice += $onhand * $ref->{sellprice}; - $subtotallastcost += $onhand * $ref->{lastcost}; - $subtotallistprice += $onhand * $ref->{listprice}; - } + # postprocess parts + foreach my $ref (@{ $form->{parts} }) { - $column_data{rop} = - ""; - $column_data{weight} = - ""; - $column_data{unit} = ""; - $column_data{bin} = ""; - $column_data{priceupdate} = ""; + # fresh row, for inserting later + my $row = { map { $_ => { 'data' => $ref->{$_} } } @columns }; - $column_data{invnumber} = - ($ref->{module} ne 'oe') - ? "" - : ""; - $column_data{ordnumber} = - ($ref->{module} eq 'oe') - ? "" - : ""; - $column_data{quonumber} = - ($ref->{module} eq 'oe' && !$ref->{ordnumber}) - ? "" - : ""; + $ref->{exchangerate} ||= 1; + $ref->{price_factor} ||= 1; + $ref->{sellprice} *= $ref->{exchangerate} / $ref->{price_factor}; + $ref->{listprice} *= $ref->{exchangerate} / $ref->{price_factor}; + $ref->{lastcost} *= $ref->{exchangerate} / $ref->{price_factor}; - $column_data{name} = ""; + # use this for assemblies + my $soldtotal = $bsooqr_mode ? $ref->{soldtotal} : $ref->{onhand}; - $column_data{image} = - ($ref->{image}) - ? "" - : ""; - $column_data{drawing} = - ($ref->{drawing}) - ? "" - : ""; - $column_data{microfiche} = - ($ref->{microfiche}) - ? "" - : ""; + if ($ref->{assemblyitem}) { + $row->{partnumber}{align} = 'right'; + $row->{soldtotal}{data} = 0; + $soldtotal = 0 if ($form->{sold}); + } - $column_data{serialnumber} = ""; + my $edit_link = build_std_url('action=edit', 'id=' . E($ref->{id}), 'callback'); + $row->{partnumber}->{link} = $edit_link; + $row->{description}->{link} = $edit_link; - $column_data{soldtotal} = - ""; + foreach (qw(sellprice listprice lastcost)) { + $row->{$_}{data} = $form->format_amount(\%myconfig, $ref->{$_}, 2); + $row->{"linetotal$_"}{data} = $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{$_}, 2); + } + foreach ( @pricegroup_columns ) { + $row->{$_}{data} = $form->format_amount(\%myconfig, $ref->{"$_"}, 2); + }; - $column_data{deliverydate} = ""; - $i++; - $i %= 2; - print ""; + map { $row->{$_}{data} = $form->format_amount(\%myconfig, $ref->{$_}); } qw(onhand rop weight soldtotal); - map { print "\n$column_data{$_}" } @column_index; + $row->{weight}->{data} .= ' ' . $defaults->{weightunit}; - print qq| - -|; + # '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}; + $subtotals{$col} += $soldtotal * $ref->{$col}; + } - if ($form->{l_subtotal} eq 'Y') { - &parts_subtotal; - } + $subtotals{soldtotal} += $soldtotal; + } - if ($form->{"l_linetotal"}) { - map { $column_data{$_} = "" } @column_index; - $column_data{linetotalsellprice} = - ""; - $column_data{linetotallastcost} = - ""; - $column_data{linetotallistprice} = - ""; + # set module stuff + if ($ref->{module} eq 'oe') { + # für oe gibt es vier fälle, jeweils nach kunde oder lieferant unterschiedlich: + # + # | ist bestellt | Von Kunden bestellt | -> edit_oe_ord_link + # | Anfrage | Angebot | -> edit_oe_quo_link - print ""; + 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'); - map { print "\n$column_data{$_}" } @column_index; + $row->{ordnumber}{link} = $edit_oe_ord_link; + $row->{quonumber}{link} = $edit_oe_quo_link if (!$ref->{ordnumber}); - print qq| - |; - } + } else { + $row->{invnumber}{link} = build_std_url("script=$ref->{module}.pl", 'action=edit', 'type=invoice', 'id=' . E($ref->{trans_id}), 'callback'); + } - print qq| - -
$form->{title}
$option
{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{partnumber} {script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{description} $ref->{partsgroup} " - . $form->format_amount(\%myconfig, $ref->{onhand}, '', " ") - . "" - . $form->format_amount(\%myconfig, $ref->{sellprice}, 2, " ") - . "" - . $form->format_amount(\%myconfig, $ref->{listprice}, 2, " ") - . "" - . $form->format_amount(\%myconfig, $ref->{lastcost}, 2, " ") - . "" - . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{sellprice}, - 2, " ") - . "" - . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{lastcost}, - 2, " ") - . "" - . $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{listprice}, - 2, " ") - . "" - . $form->format_amount(\%myconfig, $ref->{rop}, '', " ") . "" - . $form->format_amount(\%myconfig, $ref->{weight}, '', " ") - . "$ref->{unit} $ref->{bin} $ref->{priceupdate} {module}.pl?action=edit&type=invoice&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{invnumber}$ref->{invnumber}{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{ordnumber}$ref->{ordnumber}{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{quonumber}$ref->{quonumber}$ref->{name}{image}>{image} height=32 border=0> {drawing}>$ref->{drawing} {microfiche}>$ref->{microfiche} $ref->{serialnumber}" - . $form->format_amount(\%myconfig, $ref->{soldtotal}, '', " ") - . "$ref->{deliverydate}
 " - . $form->format_amount(\%myconfig, $totalsellprice, 2, " ") - . "" - . $form->format_amount(\%myconfig, $totallastcost, 2, " ") - . "" - . $form->format_amount(\%myconfig, $totallistprice, 2, " ") - . "

+ # set properties of images + if ($ref->{image} && (lc $report->{options}->{output_format} eq 'html')) { + $row->{image}{data} = ''; + $row->{image}{raw_data} = ''; + } + map { $row->{$_}{link} = $ref->{$_} } qw(drawing microfiche); -|; + $row->{notes}{data} = SL::HTML::Util->strip($ref->{notes}); - print qq| + $report->add_data($row); -
+ my $next_ref = $form->{parts}[$idx + 1]; -
{script}> + # insert subtotal rows + if (($form->{l_subtotal} eq 'Y') && + (!$next_ref || + (!$next_ref->{assemblyitem} && ($same_item ne $next_ref->{ $form->{sort} })))) { + my $row = { map { $_ => { 'class' => 'listsubtotal', } } @columns }; - + if (($form->{searchitems} ne 'assembly') || !$form->{bom}) { + $row->{soldtotal}->{data} = $form->format_amount(\%myconfig, $subtotals{soldtotal}); + } -{searchitems}> + map { $row->{"linetotal$_"}->{data} = $form->format_amount(\%myconfig, $subtotals{$_}, 2) } @subtotal_columns; + map { $subtotals{$_} = 0 } ('soldtotal', @subtotal_columns); -{path}> -{login}> -{password}>|; + $report->add_data($row); - print qq| - |; + $same_item = $next_ref->{ $form->{sort} }; + } - if ($form->{menubar}) { - require "$form->{path}/menu.pl"; - &menubar; + $idx++; } - print qq| -
+ if ($form->{"l_linetotal"} && !$form->{report_generator_csv_options_for_import}) { + my $row = { map { $_ => { 'class' => 'listtotal', } } @columns }; - - -|; + map { $row->{"linetotal$_"}->{data} = $form->format_amount(\%myconfig, $totals{$_}, 2) } @subtotal_columns; + + $report->add_separator(); + $report->add_data($row); + } + + $report->generate_with_headers(); $lxdebug->leave_sub(); } #end generate_report @@ -2029,35 +1437,40 @@ sub generate_report { sub parts_subtotal { $lxdebug->enter_sub(); - map { $column_data{$_} = "
  " - . $form->format_amount(\%myconfig, $subtotalonhand, '', " ") + . $form->format_amount(\%myconfig, $$subtotalonhand) . "" - . $form->format_amount(\%myconfig, $subtotalsellprice, 2, " ") + . $form->format_amount(\%myconfig, $$subtotalsellprice, 2) . "" - . $form->format_amount(\%myconfig, $subtotallistprice, 2, " ") + . $form->format_amount(\%myconfig, $$subtotallistprice, 2) . "" - . $form->format_amount(\%myconfig, $subtotallastcost, 2, " ") + . $form->format_amount(\%myconfig, $$subtotallastcost, 2) . "
| . $locale->text('Buchungsgruppe') . qq|
| - . $locale->text('Last Cost') . qq|{lastcost}>
| . $locale->text('Inventory') . qq|
| . $locale->text('Revenue') . qq|
| . $locale->text('Expense') . qq|
| . $locale->text('Weight') . qq| - - - - -
- {weight}> -
-
| . $locale->text('Revenue') . qq|
| . $locale->text('Weight') . qq| - - - - -
-  $form->{weight} - {weight}> -
-
| . $locale->text('Revenue') . qq|
| . $locale->text('Expense') . qq|
| . $locale->text('On Hand') . qq| | - . $form->format_amount(\%myconfig, $form->{onhand}) . qq|
| . $locale->text('Stock') . qq|{stock}>
| . $locale->text('ROP') . qq|{rop}>
| . $locale->text('Bin') . qq|{bin}>
| - . $locale->text('Verrechnungseinheit') . qq|{ve}>
| - . $locale->text('Geschäftsvolumen') . qq|{gv}>
| - . $locale->text('Not Discountable') . qq|
- - - - - - - - - - - -
| . $locale->text('Image') . qq|| . $locale->text('Microfiche') . qq|
| . $locale->text('Drawing') . qq|
-
| . $locale->text('Obsolete') . qq|{obsolete}>
| - . $locale->text('Shopartikel') . qq|
text('button') . qq|>
- - - - - - - - - - - $imagelinks + if (@{ $form->{all_partsgroup} }) { + $form->{selectassemblypartsgroup} = qq| - - - {assembly_rows}> -|; + $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->{item} eq $_) } qw(part service assembly); + map { $form->{$_} =~ s/"/"/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}; } - print qq| - {path}> - {login}> - {password}> - - - - {vc}> - - - -
$form->{title}
- - - - - - - - - - - - -
| . $locale->text('Part Number') . qq|| . $locale->text('Part Description') . qq|$group
$description$partsgroup
-
- - - - - -
- - - - - - - - - - - - - - - - - - - -
| - . $locale->text('') . qq|
- - $buchungsgruppe - $linkaccounts -
-
| . $locale->text('Notes') . qq|| . $locale->text('Formula') . qq|
- $notes - - $formel -
- -
- - - - - -
| . $locale->text('Payment Terms') . qq|
-
-
- - - - $button1 - - - - - - - - - - $lastcost - - - - - $weight - $rop - $bin - $notdiscountable - $vegv - $shop - $obsolete -
| - . $locale->text('Updated') . qq|
| . $locale->text('List Price') . qq|{listprice}>
| . $locale->text('Sell Price') . qq|{sellprice}>
| . $locale->text('Unit') . qq|$unit_select
-
-
- - - - - -
| - . $locale->text('Total') . qq| | - . $form->format_amount(\%myconfig, $form->{assemblytotal}, 2) . qq|
-

+ $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} }; - unless ($form->{item} eq "service") { - print qq| - {makemodel_rows}> - |; + 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.')); } - print qq| - {price_rows}>|; - - print qq| - |; - - if ($form->{id}) { + my $units = AM->retrieve_units(\%myconfig, $form); + $form->{ALL_UNITS} = [ map +{ name => $_ }, sort { $units->{$a}{sortkey} <=> $units->{$b}{sortkey} } keys %$units ]; - if (!$form->{previousform}) { - print qq| - |; - } + $form->{defaults} = AM->get_defaults(); - if ($form->{orphaned}) { - if (!$form->{previousform}) { - if ($form->{item} eq 'assembly') { - if (!$form->{onhand}) { - print qq| - |; - } - } else { - print qq| - |; - } - } - } - } + $form->{CUSTOM_VARIABLES} = CVar->get_custom_variables('module' => 'IC', 'trans_id' => $form->{id}); - if (!$form->{previousform}) { - if ($form->{menubar}) { - require "$form->{path}/menu.pl"; - &menubar; - } - } + my ($null, $partsgroup_id) = split /--/, $form->{partsgroup}; - print qq| + 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 makemodel_row { +sub form_footer { $lxdebug->enter_sub(); - my ($numrows) = @_; - $form->{"make_$i"} =~ s/\"/"/g; - $form->{"model_$i"} =~ s/\"/"/g; + $auth->assert('part_service_assembly_details'); - print qq| - - - - - - - -|; + print $form->parse_html_template('ic/form_footer'); - for $i (1 .. $numrows) { - print qq| - - - - -|; - } + $lxdebug->leave_sub(); +} - print qq| -
| . $locale->text('Make') . qq|| . $locale->text('Model') . qq|
- - -|; +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(); } @@ -2797,9 +1682,10 @@ sub makemodel_row { 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 total); + @column_index = qw(runningnumber qty unit bom partnumber description partsgroup lastcost total); if ($form->{previousform}) { $nochange = 1; @@ -2814,149 +1700,95 @@ sub assembly_row { # delete action map { delete $form->{$_} } qw(action header); - $previousform = ""; - # save form variables in a previousform variable - foreach $key (sort keys %$form) { + 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); - # escape ampersands - $form->{$key} =~ s/&/%26/g; - $previousform .= qq|$key=$form->{$key}&|; - } - chop $previousform; - $previousform = $form->escape($form->escape($previousform, 1)); $form->{callback} = $callback; - $form->{assemblytotal} = 0; + $form->{assembly_purchase_price_total} = 0; $form->{weight} = 0; - } - $column_header{runningnumber} = - qq|| . $locale->text('No.') . qq||; - $column_header{qty} = - qq|| . $locale->text('Qty') . qq||; - $column_header{unit} = - qq|| . $locale->text('Unit') . qq||; - $column_header{partnumber} = - qq|| - . $locale->text('Part Number') - . qq||; - $column_header{description} = - qq|| . $locale->text('Part Description') . qq||; - $column_header{total} = - qq|| . $locale->text('Extended') . qq||; - $column_header{bom} = qq|| . $locale->text('BOM') . qq||; - $column_header{partsgroup} = qq|| . $locale->text('Group') . qq||; - print qq| - - | . $locale->text('Individual Items') . qq| - - - - - -|; + 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',}, + ); - map { print "\n$column_header{$_}" } @column_index; + my @ROWS; - print qq| - -|; + for my $i (1 .. $numrows) { + my (%row, @row_hiddens); - for $i (1 .. $numrows) { $form->{"partnumber_$i"} =~ s/\"/"/g; - $linetotal = - $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2); - $form->{assemblytotal} += $linetotal; - - $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"}); - - $linetotal = $form->format_amount(\%myconfig, $linetotal, 2); - + $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 ($nochange) { - map { $column_data{$_} = qq|| } - qw(qty unit partnumber description bom partsgroup); - } else { - - map { $column_data{$_} = qq|| } qw(runningnumber unit bom); - - $column_data{qty} = - qq||; - $column_data{partnumber} = - qq||; - $column_data{description} = - qq||; - $column_data{partsgroup} = - qq||; - + if (!$form->{previousform}) { + $row{partnumber}{data} = qq||; + $row{qty}{data} = qq||; + $row{description}{data} = qq||; + $row{partsgroup}{data} = qq||; } - + # other rows } else { - if ($form->{previousform}) { - $column_data{partnumber} = - qq||; - $column_data{qty} = - qq||; - - $column_data{bom} = - qq||; - - $column_data{partsgroup} = - qq||; - + 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" : " "; + $row{qty}{align} = 'right'; } else { - $href = - qq|$form->{script}?action=edit&id=$form->{"id_$i"}&path=$form->{path}&login=$form->{login}&password=$form->{password}&rowcount=$i&previousform=$previousform|; - $column_data{partnumber} = - qq||; - $column_data{runningnumber} = - qq||; - $column_data{qty} = - qq||; - - $form->{"bom_$i"} = ($form->{"bom_$i"}) ? "checked" : ""; - $column_data{bom} = - qq||; - - $column_data{partsgroup} = - qq||; + $row{partnumber}{data} = qq|$form->{"partnumber_$i"}|; + $row{partnumber}{link} = $href; + $row{qty}{data} = qq||; + $row{runningnumber}{data} = qq||; + $row{bom}{data} = sprintf qq||, + $form->{"bom_$i"} ? 'checked' : ''; } - - $column_data{unit} = - qq||; - $column_data{description} = - qq||; + 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'; } - $column_data{total} = qq||; - - $column_data{deliverydate} = qq||; + $row{lastcost}{data} = $line_purchase_price; + $row{total}{data} = $linetotal; + $row{lastcost}{align} = 'right'; + $row{total}{align} = 'right'; + $row{deliverydate}{align} = 'right'; - print qq| - |; - - map { print "\n$column_data{$_}" } @column_index; + push @row_hiddens, qw(id sellprice lastcost weight price_factor_id price_factor); + $row{hiddens} = [ map +{ name => "${_}_$i", value => $form->{"${_}_$i"} }, @row_hiddens ]; - print qq| - - {"id_$i"}> - {"sellprice_$i"}> - {"weight_$i"}> -|; + push @ROWS, \%row; } - print qq| -
$form->{"partnumber_$i"}$form->{"qty_$i"}{"bom_$i"}>|; - $column_data{bom} .= ($form->{"bom_$i"}) ? "x" : " "; - $column_data{bom} .= qq|$form->{"partsgroup_$i"}$form->{"partnumber_$i"}{"bom_$i"}>$form->{"partsgroup_$i"}$form->{"unit_$i"}$form->{"description_$i"}$linetotal$deliverydate
- - -|; + print $form->parse_html_template('ic/assembly_row', { COLUMNS => \@column_index, ROWS => \@ROWS, HEADER => \%header }); $lxdebug->leave_sub(); } @@ -2964,29 +1796,60 @@ sub assembly_row { 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->{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"}; + $form->{lastcost} = $form->parse_amount(\%myconfig, $form->{lastcost}); + } + if ($form->{item} eq "assembly") { - $i = $form->{assembly_rows}; + 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); - $rows = scalar @{ $form->{item_list} }; + # 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; - exit; + select_item(mode => 'IC', pre_entered_qty => $form->parse_amount(\%myconfig, $form->{"qty_$i"})); + ::end_of_request(); } else { map { $form->{item_list}[$i]{$_} =~ s/\"/"/g } qw(partnumber description unit partsgroup); @@ -3008,82 +1871,72 @@ sub update { } } - } - if ($form->{item} eq "part") { + } elsif (($form->{item} eq 'part') || ($form->{item} eq 'service')) { &check_form; } - if ($form->{item} eq 'service') { - map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } - qw(sellprice listprice); - &form_header; - &price_row; - &form_footer; - } - $lxdebug->leave_sub(); } sub save { $lxdebug->enter_sub(); + $auth->assert('part_service_assembly_edit'); + + 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->{item}." Part Number missing!")); # check if there is a description $form->isblank("description", $locale->text("Part Description missing!")); - if ($form->{obsolete}) { - $form->error( - $locale->text( - "Inventory quantity must be zero before you can set this $form->{item} obsolete!" - )) - if ($form->{onhand}); - } + $form->error($locale->text("Inventory quantity must be zero before you can set this $form->{item} obsolete!")) + if $form->{obsolete} && $form->{onhand} * 1 && $form->{item} 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("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}; - # expand dynamic strings - # $locale->text('Inventory quantity must be zero before you can set this part obsolete!') - # $locale->text('Inventory quantity must be zero before you can set this assembly obsolete!') - # $locale->text('Part Number missing!') - # $locale->text('Service Number missing!') - # $locale->text('Assembly Number missing!') - + # 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 - $lxdebug->message(LXDebug::DEBUG1, - "ic.pl: sellprice in save = $form->{sellprice}\n"); - $rc = IC->save(\%myconfig, \%$form); - if ($rc == 3) { + 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->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; - $previousform = $form->unescape($form->{previousform}); - # don't trample on previous variables map { delete $form->{$_} } keys %newform; - # now take it apart and restore original values - foreach $item (split /&/, $previousform) { - ($key, $value) = split /=/, $item, 2; - $value =~ s/%26/&/g; - $form->{$key} = $value; - } + 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->{item} eq 'assembly') { @@ -3093,63 +1946,71 @@ sub save { qw(weight listprice sellprice rop); $form->{assembly_rows}--; - $i = $newform{rowcount}; - $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"}; # change/add values for assembly item - map { $form->{"${_}_$i"} = $newform{$_} } - qw(partnumber description bin unit weight listprice sellprice inventory_accno income_accno expense_accno); + 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; - $form->{sellprice} += $form->{"sellprice_$i"} * $form->{"qty_$i"}; + # 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"}); + $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}; - map { $form->{"${_}_$i"} = $newform{$_} } - qw(partnumber description bin unit listprice inventory_accno income_accno expense_accno sellprice); $form->{"sellprice_$i"} = $newform{lastcost} if ($form->{vendor_id}); + if ($form->{exchangerate} != 0) { $form->{"sellprice_$i"} /= $form->{exchangerate}; } - $lxdebug->message(LXDebug::DEBUG1, - qq|sellprice_$i in previousform 2 = | - . $form->{"sellprice_$i"} . qq|\n|); - map { $form->{"taxaccounts_$i"} .= "$_ " } split / /, - $newform{taxaccount}; + + map { $form->{"taxaccounts_$i"} .= "$_ " } split / /, $newform{taxaccount}; chop $form->{"taxaccounts_$i"}; - foreach $item (qw(description rate taxnumber)) { - $index = $form->{"taxaccounts_$i"} . "_$item"; + 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}; + $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! - $i = $form->{rowcount}; - map { - $form->{"${_}_$i"} = - $form->format_amount(\%myconfig, $form->{"${_}_$i"}) - } qw(weight listprice sellprice rop); + 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 @@ -3160,17 +2021,14 @@ sub save { $form->{makemodel_rows}--; # put callback together - foreach $key (keys %$form) { + foreach my $key (keys %$form) { # do single escape for Apache 2.0 - $value = $form->escape($form->{$key}, 1); + my $value = $form->escape($form->{$key}, 1); $callback .= qq|&$key=$value|; } $form->{callback} = $callback; } - $lxdebug->message(LXDebug::DEBUG1, - qq|ic.pl: sellprice_$i nach sub save = | - . $form->{"sellprice_$i"} . qq|\n|); # redirect $form->redirect; @@ -3181,20 +2039,37 @@ sub save { 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->save_history; + } + # /saving the history $form->{id} = 0; if ($form->{"original_partnumber"} && ($form->{"partnumber"} eq $form->{"original_partnumber"})) { $form->{partnumber} = ""; } &save; - $lxdebug->leave_sub(); } sub delete { $lxdebug->enter_sub(); - $rc = IC->delete(\%myconfig, \%$form); + $auth->assert('part_service_assembly_edit'); + + # saving the history + if(!exists $form->{addition}) { + $form->{snumbers} = qq|partnumber_| . $form->{partnumber}; + $form->{addition} = "DELETED"; + $form->save_history; + } + # /saving the history + my $rc = IC->delete(\%myconfig, \%$form); # redirect $form->redirect($locale->text('Item deleted!')) if ($rc > 0); @@ -3203,245 +2078,62 @@ sub delete { $lxdebug->leave_sub(); } -sub stock_assembly { +sub price_row { $lxdebug->enter_sub(); - $form->{title} = $locale->text('Stock Assembly'); - - $form->header; - - print qq| - - -
{script}> - - - - - - - - - - -
$form->{title}
- - - - - - - - - - -
| - . $locale->text('Part Number') . qq| 
| - . $locale->text('Part Description') . qq|
-

- -{path}> -{login}> -{password}> + $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 list_assemblies { - $lxdebug->enter_sub(); - - IC->retrieve_assemblies(\%myconfig, \%$form); - - $column_header{partnumber} = - qq|| . $locale->text('Part Number') . qq||; - $column_header{description} = - qq|| . $locale->text('Part Description') . qq||; - $column_header{bin} = - qq|| . $locale->text('Bin') . qq||; - $column_header{onhand} = - qq|| . $locale->text('Qty') . qq||; - $column_header{rop} = - qq|| . $locale->text('ROP') . qq||; - $column_header{stock} = - qq|| . $locale->text('Add') . qq||; - - @column_index = (qw(partnumber description bin onhand rop stock)); - - $form->{title} = $locale->text('Stock Assembly'); - - $form->{callback} = - "$form->{script}?action=stock_assembly&path=$form->{path}&login=$form->{login}&password=$form->{password}"; - - $form->header; - - $colspan = $#column_index + 1; - - print qq| - - -
{script}> - - - - - - - |; - - map { print "\n$column_header{$_}" } @column_index; - - print qq| - -|; - - $i = 1; - foreach $ref (@{ $form->{assembly_items} }) { - - map { $ref->{$_} =~ s/\"/"/g } qw(partnumber description); - - $column_data{partnumber} = qq||; - $column_data{description} = - qq||; - $column_data{bin} = qq||; - $column_data{onhand} = - qq||; - $column_data{rop} = - qq||; - $column_data{stock} = qq||; - - $j++; - $j %= 2; - print - qq|{id}>\n|; - - map { print "\n$column_data{$_}" } @column_index; - - print qq| - -|; - - $i++; - - } - - $i--; - print qq| - - -
$form->{title}
$ref->{partnumber}$ref->{description} $ref->{bin} | - . $form->format_amount(\%myconfig, $ref->{onhand}, '', " ") - . qq|| - . $form->format_amount(\%myconfig, $ref->{rop}, '', " ") - . qq|

-
- - -{path}> -{login}> -{password}> - - - - +sub ajax_autocomplete { + $main::lxdebug->enter_sub(); -
- - -
- - - -|; + my $form = $main::form; + my %myconfig = %main::myconfig; - $lxdebug->leave_sub(); -} + $form->{column} = 'description' unless $form->{column} =~ /^partnumber|description$/; + $form->{$form->{column}} = $form->{q} || ''; + $form->{limit} = ($form->{limit} * 1) || 10; + $form->{searchitems} ||= ''; -sub restock_assemblies { - $lxdebug->enter_sub(); + my @results = IC->all_parts(\%myconfig, $form); - $form->redirect($locale->text('Assemblies restocked!')) - if (IC->restock_assemblies(\%myconfig, \%$form)); - $form->error($locale->text('Cannot stock assemblies!')); + print $form->ajax_response_header(), + $form->parse_html_template('ic/ajax_autocomplete'); - $lxdebug->leave_sub(); + $main::lxdebug->leave_sub(); } -sub price_row { - $lxdebug->enter_sub(); - - my ($numrows) = @_; +sub back_to_record { + _check_io_auth(); - print qq| - - - - - - - -|; - for $i (1 .. $numrows) { - print qq| - - - - - -|; - } - print qq| -
| . $locale->text('Preisklasse') . qq|| . $locale->text('Preis') . qq|
$form->{"pricegroup_$i"}
- - -|; + delete @{$::form}{qw(action action_add action_back_to_record back_sub description item notes partnumber sellprice taxaccount2 unit vc)}; - $lxdebug->leave_sub(); + $::auth->restore_form_from_session($::form->{previousform}, clobber => 1); + $::form->{rowcount}--; + $::form->{action} = 'display_form'; + $::form->{callback} = $::form->{script} . '?' . join('&', map { $::form->escape($_) . '=' . $::form->escape($::form->{$_}) } sort keys %{ $::form }); + $::form->redirect; } +sub continue { call_sub($form->{"nextsub"}); } -sub parts_language_selection { - $lxdebug->enter_sub(); - - - my $languages = IC->retrieve_languages(\%myconfig, $form); +sub dispatcher { + my $action = first { $::form->{"action_${_}"} } qw(add back_to_record); + $::form->error($::locale->text('No action defined.')) unless $action; - - my $callback = "$form->{script}?action=parts_language_selection&"; - map({ $callback .= "$_=" . $form->escape($form->{$_}) . "&" } - (qw(login path password name input_name), grep({ /^[fl]_/ } keys %$form))); - - 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" => $_, - "callback" => $callback, - }, - @header_sort); - - $form->{"title"} = $locale->text("Language Values"); - $form->header(); - print($form->parse_html_template("ic/parts_language_selection", { "HEADER" => \@header, - "LANGUAGES" => $languages, - "onload" => $onload })); - - $lxdebug->leave_sub(); + $::form->{dispatched_action} = $action; + call_sub($action); } - -sub continue { &{ $form->{nextsub} } }