Projekt

Allgemein

Profil

Herunterladen (27,8 KB) Statistiken
| Zweig: | Markierung: | Revision:
d319704a Moritz Bunkus
#=====================================================================
# LX-Office ERP
# Copyright (C) 2004
# Based on SQL-Ledger Version 2.1.9
# Web http://www.lx-office.org
#
#=====================================================================
# SQL-Ledger, Accounting
# Copyright (c) 2001
#
# Author: Dieter Simader
# Email: dsimader@sql-ledger.org
# Web: http://www.sql-ledger.org
#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
f7b15d43 Christian Wittmer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1335, USA.
d319704a Moritz Bunkus
#======================================================================
#
# Inventory Control module
#
#======================================================================

728729b6 Moritz Bunkus
use POSIX qw(strftime);
aae0a190 Moritz Bunkus
use List::Util qw(first max);
ec2e4394 Sven Schöling
use List::MoreUtils qw(any);
728729b6 Moritz Bunkus
c14aab2d Moritz Bunkus
use SL::AM;
b2f44e3d Moritz Bunkus
use SL::CVar;
d319704a Moritz Bunkus
use SL::IC;
87949627 Sven Schöling
use SL::Helper::Flash qw(flash);
52131da1 Moritz Bunkus
use SL::HTML::Util;
9c29f718 Sven Schöling
use SL::Presenter::Part;
728729b6 Moritz Bunkus
use SL::ReportGenerator;
081a4f97 Moritz Bunkus
07d71c33 Stephan Köhler
#use SL::PE;
d319704a Moritz Bunkus
b018d857 Sven Schöling
use strict;
2efc8cbc Sven Schöling
#use warnings;

9a0aeac2 Sven Schöling
# global imports
f134996a Sven Schöling
our ($form, $locale, %myconfig, $lxdebug, $auth);
9a0aeac2 Sven Schöling
d629acd8 Sven Schöling
require "bin/mozilla/io.pl";
40782548 Moritz Bunkus
require "bin/mozilla/common.pl";
728729b6 Moritz Bunkus
require "bin/mozilla/reportgenerator.pl";
d319704a Moritz Bunkus
1;

e309bf11 Sven Schöling
# 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')
cd16e602 Sven Schöling
# $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');
e309bf11 Sven Schöling
d319704a Moritz Bunkus
# end of main

sub search {
$lxdebug->enter_sub();

db9a3208 Niclas Zimmermann
$auth->assert('part_service_assembly_details');
8c7e4493 Moritz Bunkus
cd16e602 Sven Schöling
$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
d319704a Moritz Bunkus
2a4980a8 Sven Schöling
$form->{title} = (ucfirst $form->{searchitems}) . "s";
65d2537d Martin Helmling
$form->{title} =~ s/ys$/ies/;
2a4980a8 Sven Schöling
$form->{title} = $locale->text($form->{title});
d319704a Moritz Bunkus
b2f44e3d Moritz Bunkus
$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');

1c4d3cd5 Moritz Bunkus
setup_ic_search_action_bar();
d319704a Moritz Bunkus
$form->header;

83560c63 Bernd Bleßmann
$form->get_lists('partsgroup' => 'ALL_PARTSGROUPS');
c25c69bc Moritz Bunkus
print $form->parse_html_template('ic/search');
d319704a Moritz Bunkus
$lxdebug->leave_sub();
} #end search()

sub top100 {
4c6e9282 Sven Schöling
$::lxdebug->enter_sub();
d319704a Moritz Bunkus
4c6e9282 Sven Schöling
$::auth->assert('part_service_assembly_edit');
2efc8cbc Sven Schöling
4c6e9282 Sven Schöling
$::form->{l_soldtotal} = "Y";
$::form->{sort} = "soldtotal";
$::form->{lastsort} = "soldtotal";
d319704a Moritz Bunkus
4c6e9282 Sven Schöling
$::form->{l_qty} = undef;
$::form->{l_linetotal} = undef;
$::form->{l_number} = "Y";
$::form->{number} = "position";
8c7e4493 Moritz Bunkus
4c6e9282 Sven Schöling
unless ( $::form->{bought}
|| $::form->{sold}
|| $::form->{rfq}
|| $::form->{quoted}) {
$::form->{bought} = $::form->{sold} = 1;
d319704a Moritz Bunkus
}

4c6e9282 Sven Schöling
generate_report();
d319704a Moritz Bunkus
$lxdebug->leave_sub();
4c6e9282 Sven Schöling
}
d319704a Moritz Bunkus
2efc8cbc Sven Schöling
#
# 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:
65d2537d Martin Helmling
# partnumber ean description partsgroup classification serialnumber make model drawing microfiche
2efc8cbc Sven Schöling
# 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
8470071b Geoffrey Richardson
# l_partsgroup l_subtotal l_soldtotal l_deliverydate l_pricegroups
2efc8cbc Sven Schöling
#
273d8de6 Sven Schöling
# hiddens:
8c7e4493 Moritz Bunkus
# nextsub revers lastsort sort ndxs_counter
2efc8cbc Sven Schöling
#
d319704a Moritz Bunkus
sub generate_report {
$lxdebug->enter_sub();

db9a3208 Niclas Zimmermann
$auth->assert('part_service_assembly_details');
8c7e4493 Moritz Bunkus
2efc8cbc Sven Schöling
my ($revers, $lastsort, $description);

b2f44e3d Moritz Bunkus
my $cvar_configs = CVar->get_configs('module' => 'IC');

68d169c1 Moritz Bunkus
$form->{title} = $locale->text('Articles');
728729b6 Moritz Bunkus
a5bebed4 Jan Büren
my %column_defs = (
'deliverydate' => { 'text' => $locale->text('deliverydate'), },
'description' => { 'text' => $locale->text('Part Description'), },
35ca31c0 Niclas Zimmermann
'notes' => { 'text' => $locale->text('Notes'), },
a5bebed4 Jan Büren
'drawing' => { 'text' => $locale->text('Drawing'), },
6d504794 Moritz Bunkus
'ean' => { 'text' => $locale->text('EAN'), },
a5bebed4 Jan Büren
'image' => { 'text' => $locale->text('Image'), },
ad033a76 Bernd Bleßmann
'insertdate' => { 'text' => $locale->text('Insert Date'), },
a5bebed4 Jan Büren
'invnumber' => { 'text' => $locale->text('Invoice Number'), },
'lastcost' => { 'text' => $locale->text('Last Cost'), },
d919a7dc Jan Büren
'assembly_lastcost' => { 'text' => $locale->text('Assembly Last Cost'), },
a5bebed4 Jan Büren
'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'), },
fef43fa5 Sven Schöling
'onhand' => { 'text' => $locale->text('Stocked Qty'), },
a5bebed4 Jan Büren
'ordnumber' => { 'text' => $locale->text('Order Number'), },
'partnumber' => { 'text' => $locale->text('Part Number'), },
df41380a Geoffrey Richardson
'partsgroup' => { 'text' => $locale->text('Partsgroup'), },
d1054383 Bernd Bleßmann
'priceupdate' => { 'text' => $locale->text('Price updated'), },
a5bebed4 Jan Büren
'quonumber' => { 'text' => $locale->text('Quotation'), },
'rop' => { 'text' => $locale->text('ROP'), },
'sellprice' => { 'text' => $locale->text('Sell Price'), },
'serialnumber' => { 'text' => $locale->text('Serial Number'), },
fef43fa5 Sven Schöling
'soldtotal' => { 'text' => $locale->text('Qty in Selected Records'), },
61421f4d Jan Büren
'name' => { 'text' => $locale->text('Name in Selected Records'), },
0070a250 Andreas Rudin
'transdate' => { 'text' => $locale->text('Transdate Record'), },
a5bebed4 Jan Büren
'unit' => { 'text' => $locale->text('Unit'), },
'weight' => { 'text' => $locale->text('Weight'), },
88f11e29 Geoffrey Richardson
'shop' => { 'text' => $locale->text('Shop article'), },
65d2537d Martin Helmling
'type_and_classific' => { 'text' => $locale->text('Type'), },
5b0450c3 Sven Schöling
'projectnumber' => { 'text' => $locale->text('Project Number'), },
'projectdescription' => { 'text' => $locale->text('Project Description'), },
a33ef0ec Jan Büren
'warehouse' => { 'text' => $locale->text('Default Warehouse'), },
'bin' => { 'text' => $locale->text('Default Bin'), },
89407ec8 Jan Büren
'make' => { 'text' => $locale->text('Make'), },
'model' => { 'text' => $locale->text('Model'), },
a5bebed4 Jan Büren
);

f134996a Sven Schöling
$revers = $form->{revers};
$lastsort = $form->{lastsort};
d319704a Moritz Bunkus
2efc8cbc Sven Schöling
# sorting and direction of sorting
# ToDO: change this to the simpler field+direction method
d319704a Moritz Bunkus
if (($form->{lastsort} eq "") && ($form->{sort} eq undef)) {
$form->{revers} = 0;
$form->{lastsort} = "partnumber";
$form->{sort} = "partnumber";
} else {
if ($form->{lastsort} eq $form->{sort}) {
2efc8cbc Sven Schöling
$form->{revers} = 1 - $form->{revers};
d319704a Moritz Bunkus
} else {
2efc8cbc Sven Schöling
$form->{revers} = 0;
d319704a Moritz Bunkus
$form->{lastsort} = $form->{sort};
} #fi
} #fi

2efc8cbc Sven Schöling
# special case if we have a serialnumber limit search
273d8de6 Sven Schöling
# serialnumbers are only given in invoices and orders,
2efc8cbc Sven Schöling
# so they can only pop up in bought, sold, rfq, and quoted stuff
273d8de6 Sven Schöling
$form->{no_sn_joins} = 'Y' if ( !$form->{bought} && !$form->{sold}
&& !$form->{rfq} && !$form->{quoted}
2efc8cbc Sven Schöling
&& ($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});

89497ebe Sven Schöling
# if something should be activated if something else is active, enter it here
2efc8cbc Sven Schöling
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) ],
);
d319704a Moritz Bunkus
83560c63 Bernd Bleßmann
# 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'};
}

2efc8cbc Sven Schöling
# 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}'",
df41380a Geoffrey Richardson
partsgroup => $locale->text('Partsgroup') . ": '$form->{partsgroup}'",
partsgroup_id => $locale->text('Partsgroup') . ": '$pg_name'",
2efc8cbc Sven Schöling
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}'",
62f21410 Martin Helmling
customername => $locale->text('Customer') . ": '$form->{customername}'",
customernumber=> $locale->text('Customer Part Number').": '$form->{customernumber}'",
2efc8cbc Sven Schöling
drawing => $locale->text('Drawing') . ": '$form->{drawing}'",
microfiche => $locale->text('Microfiche') . ": '$form->{microfiche}'",
db8722a4 Sven Schöling
l_soldtotal => $locale->text('Qty in Selected Records'),
7df63f15 Geoffrey Richardson
ean => $locale->text('EAN') . ": '$form->{ean}'",
ad033a76 Bernd Bleßmann
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),
31caad01 Jan Büren
l_service => $locale->text('Services'),
l_assembly => $locale->text('Assemblies'),
l_part => $locale->text('Parts'),
2efc8cbc Sven Schöling
);
d319704a Moritz Bunkus
2efc8cbc Sven Schöling
my @itemstatus_keys = qw(active obsolete orphaned onhand short);
83560c63 Bernd Bleßmann
my @callback_keys = qw(onorder ordered rfq quoted bought sold partnumber partsgroup partsgroup_id serialnumber description make model
31caad01 Jan Büren
drawing microfiche l_soldtotal l_deliverydate transdatefrom transdateto insertdatefrom insertdateto ean shop all
l_service l_assembly l_part);
728729b6 Moritz Bunkus
2efc8cbc Sven Schöling
# calculate dependencies
728729b6 Moritz Bunkus
for (@itemstatus_keys, @callback_keys) {
2efc8cbc Sven Schöling
next if ($form->{itemstatus} ne $_ && !$form->{$_});
map { $form->{$_} = 'Y' } @{ $dependencies{$_} } if $dependencies{$_};
d319704a Moritz Bunkus
}

2efc8cbc Sven Schöling
# generate callback and optionstrings
728729b6 Moritz Bunkus
my @options;
273d8de6 Sven Schöling
for my $key (@itemstatus_keys, @callback_keys) {
2efc8cbc Sven Schöling
next if ($form->{itemstatus} ne $key && !$form->{$key});
push @options, $optiontexts{$key};
d319704a Moritz Bunkus
}

2efc8cbc Sven Schöling
# special case for lastcost
a5bebed4 Jan Büren
if ($form->{ledgerchecks}){
a1c4f3ce Sven Schöling
# ledgerchecks don't know about sellprice or lastcost. they just return a
# price. so rename sellprice to price, and drop lastcost.
a5bebed4 Jan Büren
$column_defs{sellprice}{text} = $locale->text('Price');
a1c4f3ce Sven Schöling
$form->{l_lastcost} = ""
a5bebed4 Jan Büren
}
d919a7dc Jan Büren
$form->{l_assembly_lastcost} = "Y" if $form->{l_assembly} && $form->{l_lastcost};
d319704a Moritz Bunkus
2efc8cbc Sven Schöling
if ($form->{description}) {
$description = $form->{description};
$description =~ s/\n/<br>/g;
66881e5e Moritz Bunkus
}

d319704a Moritz Bunkus
if ($form->{l_linetotal}) {
3bdd3642 Sven Schöling
$form->{l_qty} = "Y";
d319704a Moritz Bunkus
$form->{l_linetotalsellprice} = "Y" if $form->{l_sellprice};
4d9fde96 Sven Schöling
$form->{l_linetotallastcost} = $form->{searchitems} eq 'assembly' && !$form->{bom} ? "" : 'Y' if $form->{l_lastcost};
d319704a Moritz Bunkus
$form->{l_linetotallistprice} = "Y" if $form->{l_listprice};
}
65d2537d Martin Helmling
$form->{"l_type_and_classific"} = "Y";
d319704a Moritz Bunkus
6416b3bb Martin Helmling
if ($form->{l_service} && !$form->{l_assembly} && !$form->{l_part}) {
d319704a Moritz Bunkus
a33ef0ec Jan Büren
# remove warehouse, bin, weight and rop from list
map { $form->{"l_$_"} = "" } qw(bin weight rop warehouse);
d319704a Moritz Bunkus
$form->{l_onhand} = "";

# qty is irrelevant unless bought or sold
if ( $form->{bought}
|| $form->{sold}
|| $form->{onorder}
|| $form->{ordered}
|| $form->{rfq}
|| $form->{quoted}) {
3bdd3642 Sven Schöling
# $form->{l_onhand} = "Y";
54e4131e Moritz Bunkus
} else {
d319704a Moritz Bunkus
$form->{l_linetotalsellprice} = "";
$form->{l_linetotallastcost} = "";
}
}

3dc8c45e Sven Schöling
# soldtotal doesn't make sense with more than one bsooqr option.
# so reset it to sold (the most common option), and issue a warning
0cbac4f7 Sven Schöling
# ...
# also it doesn't make sense without bsooqr. disable and issue a warning too
3dc8c45e Sven Schöling
my @bsooqr = qw(sold bought onorder ordered rfq quoted);
eabcf7e4 Sven Schöling
my $bsooqr_mode = grep { $form->{$_} } @bsooqr;
if ($form->{l_subtotal} && 1 < $bsooqr_mode) {
3dc8c45e Sven Schöling
my $enabled = first { $form->{$_} } @bsooqr;
$form->{$_} = '' for @bsooqr;
$form->{$enabled} = 'Y';

push @options, $::locale->text('Subtotal cannot distinguish betweens record types. Only one of the selected record types will be displayed: #1', $optiontexts{$enabled});
}
eabcf7e4 Sven Schöling
if ($form->{l_soldtotal} && !$bsooqr_mode) {
0cbac4f7 Sven Schöling
delete $form->{l_soldtotal};

flash('warning', $::locale->text('Soldtotal does not make sense without any bsooqr options'));
}
a33ef0ec Jan Büren
if ($form->{l_soldtotal} && ($form->{l_warehouse} || $form->{l_bin})) {
delete $form->{"l_$_"} for qw(bin warehouse);
flash('warning', $::locale->text('Sorry, I am too stupid to figure out the default warehouse/bin and the sold qty. I drop the default warehouse/bin option.'));
}
61421f4d Jan Büren
if ($form->{l_name} && !$bsooqr_mode) {
delete $form->{l_name};
3dc8c45e Sven Schöling
61421f4d Jan Büren
flash('warning', $::locale->text('Name does not make sense without any bsooqr options'));
}
8b797f8b Sven Schöling
IC->all_parts(\%myconfig, \%$form);

4d9fde96 Sven Schöling
my @columns = qw(
a33ef0ec Jan Büren
partnumber type_and_classific description notes partsgroup warehouse bin
89407ec8 Jan Büren
make model onhand rop soldtotal unit listprice
d919a7dc Jan Büren
linetotallistprice sellprice linetotalsellprice lastcost assembly_lastcost linetotallastcost
4d9fde96 Sven Schöling
priceupdate weight image drawing microfiche invnumber ordnumber quonumber
5b0450c3 Sven Schöling
transdate name serialnumber deliverydate ean projectnumber projectdescription
ad033a76 Bernd Bleßmann
insertdate shop
4d9fde96 Sven Schöling
);
728729b6 Moritz Bunkus
e48eb4dc Geoffrey Richardson
my $pricegroups = SL::DB::Manager::Pricegroup->get_all_sorted;
8470071b Geoffrey Richardson
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;

b2f44e3d Moritz Bunkus
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;

8470071b Geoffrey Richardson
%column_defs = (%column_defs, %column_defs_cvars, %column_defs_pricegroups);
map { $column_defs{$_}->{visible} ||= $form->{"l_$_"} ? 1 : 0 } @columns;
d919a7dc Jan Büren
map { $column_defs{$_}->{align} = 'right' } qw(onhand sellprice listprice lastcost assembly_lastcost linetotalsellprice linetotallastcost linetotallistprice rop weight soldtotal shop), @pricegroup_columns;
d319704a Moritz Bunkus
b184cc2b Thomas Heck
my @hidden_variables = (
ad033a76 Bernd Bleßmann
qw(l_subtotal l_linetotal searchitems itemstatus bom l_pricegroups insertdatefrom insertdateto),
018cbc88 Moritz Bunkus
qw(l_type_and_classific classification_id l_part l_service l_assembly l_assortment),
b184cc2b Thomas Heck
@itemstatus_keys,
@callback_keys,
map({ "cvar_$_->{name}" } @searchable_custom_variables),
c9076c9e Bernd Bleßmann
map({'cvar_'. $_->{name} .'_from'} grep({$_->{type} eq 'date'} @searchable_custom_variables)),
map({'cvar_'. $_->{name} .'_to'} grep({$_->{type} eq 'date'} @searchable_custom_variables)),
b184cc2b Thomas Heck
map({'cvar_'. $_->{name} .'_qtyop'} grep({$_->{type} eq 'number'} @searchable_custom_variables)),
map({ "l_$_" } @columns),
);
8470071b Geoffrey Richardson
728729b6 Moritz Bunkus
my $callback = build_std_url('action=generate_report', grep { $form->{$_} } @hidden_variables);
d319704a Moritz Bunkus
ad033a76 Bernd Bleßmann
my @sort_full = qw(partnumber description onhand soldtotal deliverydate insertdate shop);
d1054383 Bernd Bleßmann
my @sort_no_revers = qw(partsgroup invnumber ordnumber quonumber name image drawing serialnumber);
66881e5e Moritz Bunkus
728729b6 Moritz Bunkus
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;
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
# add order to callback
$form->{callback} = join '&', ($callback, map { "${_}=" . E($form->{$_}) } qw(sort revers));
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
my $report = SL::ReportGenerator->new(\%myconfig, $form);
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
my %attachment_basenames = (
'part' => $locale->text('part_list'),
'service' => $locale->text('service_list'),
'assembly' => $locale->text('assembly_list'),
65d2537d Martin Helmling
'article' => $locale->text('article_list'),
728729b6 Moritz Bunkus
);
d319704a Moritz Bunkus
0cbac4f7 Sven Schöling
$report->set_options('raw_top_info_text' => $form->parse_html_template('ic/generate_report_top', { options => \@options }),
65d2537d Martin Helmling
'raw_bottom_info_text' => $form->parse_html_template('ic/generate_report_bottom' ,
{ PART_CLASSIFICATIONS => SL::DB::Manager::PartClassification->get_all_sorted }),
728729b6 Moritz Bunkus
'output_format' => 'HTML',
'title' => $form->{title},
6416b3bb Martin Helmling
'attachment_basename' => 'article_list' . strftime('_%Y%m%d', localtime time),
89497ebe Sven Schöling
);
728729b6 Moritz Bunkus
$report->set_options_from_form();
a873249c Moritz Bunkus
$locale->set_numberformat_wo_thousands_separator(\%myconfig) if lc($report->{options}->{output_format}) eq 'csv';
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
$report->set_columns(%column_defs);
$report->set_column_order(@columns);
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
$report->set_export_options('generate_report', @hidden_variables, qw(sort revers));
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
$report->set_sort_indicator($form->{sort}, $form->{revers} ? 0 : 1);
d319704a Moritz Bunkus
b2f44e3d Moritz Bunkus
CVar->add_custom_variables_to_report('module' => 'IC',
'trans_id_field' => 'id',
'configs' => $cvar_configs,
'column_defs' => \%column_defs,
'data' => $form->{parts});

1163cee7 Sven Schöling
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});

728729b6 Moritz Bunkus
my @subtotal_columns = qw(sellprice listprice lastcost);
my %subtotals = map { $_ => 0 } ('onhand', @subtotal_columns);
my %totals = map { $_ => 0 } @subtotal_columns;
my $idx = 0;
74fca575 Sven Schöling
my $same_item = @{ $form->{parts} } ? $form->{parts}[0]{ $form->{sort} } : undef;
d319704a Moritz Bunkus
c14aab2d Moritz Bunkus
my $defaults = AM->get_defaults();

89497ebe Sven Schöling
# postprocess parts
2efc8cbc Sven Schöling
foreach my $ref (@{ $form->{parts} }) {
89497ebe Sven Schöling
# fresh row, for inserting later
fa8921ca Moritz Bunkus
my $row = { map { $_ => { 'data' => $ref->{$_} } } @columns };
d319704a Moritz Bunkus
1e251313 Moritz Bunkus
$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};
d919a7dc Jan Büren
$ref->{assembly_lastcost} *= $ref->{exchangerate} / $ref->{price_factor};
d319704a Moritz Bunkus
# use this for assemblies
eabcf7e4 Sven Schöling
my $soldtotal = $bsooqr_mode ? $ref->{soldtotal} : $ref->{onhand};
d319704a Moritz Bunkus
if ($ref->{assemblyitem}) {
89497ebe Sven Schöling
$row->{partnumber}{align} = 'right';
3bdd3642 Sven Schöling
$row->{soldtotal}{data} = 0;
$soldtotal = 0 if ($form->{sold});
d319704a Moritz Bunkus
}

c2efdba2 Moritz Bunkus
my $edit_link = build_std_url('script=controller.pl', 'action=Part/edit', 'part.id=' . E($ref->{id}));
728729b6 Moritz Bunkus
$row->{partnumber}->{link} = $edit_link;
$row->{description}->{link} = $edit_link;
d319704a Moritz Bunkus
d919a7dc Jan Büren
foreach (qw(sellprice listprice lastcost assembly_lastcost)) {
09a8d687 Niclas Zimmermann
$row->{$_}{data} = $form->format_amount(\%myconfig, $ref->{$_}, 2);
89497ebe Sven Schöling
$row->{"linetotal$_"}{data} = $form->format_amount(\%myconfig, $ref->{onhand} * $ref->{$_}, 2);
728729b6 Moritz Bunkus
}
8470071b Geoffrey Richardson
foreach ( @pricegroup_columns ) {
09a8d687 Niclas Zimmermann
$row->{$_}{data} = $form->format_amount(\%myconfig, $ref->{"$_"}, 2);
8470071b Geoffrey Richardson
};

d319704a Moritz Bunkus
89497ebe Sven Schöling
map { $row->{$_}{data} = $form->format_amount(\%myconfig, $ref->{$_}); } qw(onhand rop weight soldtotal);
d319704a Moritz Bunkus
c14aab2d Moritz Bunkus
$row->{weight}->{data} .= ' ' . $defaults->{weightunit};

22a52f84 Bernd Bleßmann
# 'yes' and 'no' for boolean value shop
if ($form->{l_shop}) {
$row->{shop}{data} = $row->{shop}{data}? $::locale->text('yes') : $::locale->text('no');
}

d319704a Moritz Bunkus
if (!$ref->{assemblyitem}) {
728729b6 Moritz Bunkus
foreach my $col (@subtotal_columns) {
3bdd3642 Sven Schöling
$totals{$col} += $soldtotal * $ref->{$col};
$subtotals{$col} += $soldtotal * $ref->{$col};
728729b6 Moritz Bunkus
}
d319704a Moritz Bunkus
3bdd3642 Sven Schöling
$subtotals{soldtotal} += $soldtotal;
d319704a Moritz Bunkus
}

89497ebe Sven Schöling
# set module stuff
728729b6 Moritz Bunkus
if ($ref->{module} eq 'oe') {
7846799c Jan Büren
# für oe gibt es vier fälle, jeweils nach kunde oder lieferant unterschiedlich:
#
09e32b3c Bernd Bleßmann
# | ist bestellt | Von Kunden bestellt | -> edit_oe_ord_link
# | Anfrage | Angebot | -> edit_oe_quo_link
7846799c Jan Büren
984f6322 Bernd Bleßmann
my $edit_oe_ord_link = ($::instance_conf->get_feature_experimental_order)
c3db1b36 Bernd Bleßmann
? build_std_url("script=controller.pl", 'action=Order/edit',
'type=' . E($ref->{cv} eq 'vendor' ? 'purchase_order' : 'sales_order'), 'id=' . E($ref->{trans_id}), 'callback')
: build_std_url("script=oe.pl", 'action=edit',
'type=' . E($ref->{cv} eq 'vendor' ? 'purchase_order' : 'sales_order'), 'id=' . E($ref->{trans_id}), 'callback');

984f6322 Bernd Bleßmann
my $edit_oe_quo_link = ($::instance_conf->get_feature_experimental_order)
c3db1b36 Bernd Bleßmann
? build_std_url("script=controller.pl", 'action=Order/edit',
'type=' . E($ref->{cv} eq 'vendor' ? 'request_quotation' : 'sales_quotation'), 'id=' . E($ref->{trans_id}), 'callback')
: build_std_url("script=oe.pl", 'action=edit',
'type=' . E($ref->{cv} eq 'vendor' ? 'request_quotation' : 'sales_quotation'), 'id=' . E($ref->{trans_id}), 'callback');
7846799c Jan Büren
$row->{ordnumber}{link} = $edit_oe_ord_link;
$row->{quonumber}{link} = $edit_oe_quo_link if (!$ref->{ordnumber});
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
} else {
fc2f81b9 Waldemar Toews
$row->{invnumber}{link} = build_std_url("script=$ref->{module}.pl", 'action=edit', 'type=invoice', 'id=' . E($ref->{trans_id}), 'callback') if ($ref->{invnumber});
728729b6 Moritz Bunkus
}
d319704a Moritz Bunkus
89497ebe Sven Schöling
# set properties of images
728729b6 Moritz Bunkus
if ($ref->{image} && (lc $report->{options}->{output_format} eq 'html')) {
89497ebe Sven Schöling
$row->{image}{data} = '';
$row->{image}{raw_data} = '<a href="' . H($ref->{image}) . '"><img src="' . H($ref->{image}) . '" height="32" border="0"></a>';
728729b6 Moritz Bunkus
}
89497ebe Sven Schöling
map { $row->{$_}{link} = $ref->{$_} } qw(drawing microfiche);
d319704a Moritz Bunkus
52131da1 Moritz Bunkus
$row->{notes}{data} = SL::HTML::Util->strip($ref->{notes});
9c29f718 Sven Schöling
$row->{type_and_classific}{data} = SL::Presenter::Part::type_abbreviation($ref->{part_type}).
SL::Presenter::Part::classification_abbreviation($ref->{classification_id});
52131da1 Moritz Bunkus
d1054383 Bernd Bleßmann
# last price update
$row->{priceupdate}{data} = SL::DB::Part->new(id => $ref->{id})->load->last_price_update->valid_from->to_kivitendo;

728729b6 Moritz Bunkus
$report->add_data($row);
d319704a Moritz Bunkus
89497ebe Sven Schöling
my $next_ref = $form->{parts}[$idx + 1];
66881e5e Moritz Bunkus
89497ebe Sven Schöling
# insert subtotal rows
728729b6 Moritz Bunkus
if (($form->{l_subtotal} eq 'Y') &&
(!$next_ref ||
fa8921ca Moritz Bunkus
(!$next_ref->{assemblyitem} && ($same_item ne $next_ref->{ $form->{sort} })))) {
my $row = { map { $_ => { 'class' => 'listsubtotal', } } @columns };
d319704a Moritz Bunkus
6416b3bb Martin Helmling
if ( !$form->{l_assembly} || !$form->{bom}) {
3bdd3642 Sven Schöling
$row->{soldtotal}->{data} = $form->format_amount(\%myconfig, $subtotals{soldtotal});
728729b6 Moritz Bunkus
}
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
map { $row->{"linetotal$_"}->{data} = $form->format_amount(\%myconfig, $subtotals{$_}, 2) } @subtotal_columns;
3bdd3642 Sven Schöling
map { $subtotals{$_} = 0 } ('soldtotal', @subtotal_columns);
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
$report->add_data($row);
fa8921ca Moritz Bunkus
$same_item = $next_ref->{ $form->{sort} };
728729b6 Moritz Bunkus
}
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
$idx++;
d319704a Moritz Bunkus
}

0185267e Thomas Heck
if ($form->{"l_linetotal"} && !$form->{report_generator_csv_options_for_import}) {
fa8921ca Moritz Bunkus
my $row = { map { $_ => { 'class' => 'listtotal', } } @columns };
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
map { $row->{"linetotal$_"}->{data} = $form->format_amount(\%myconfig, $totals{$_}, 2) } @subtotal_columns;
d319704a Moritz Bunkus
728729b6 Moritz Bunkus
$report->add_separator();
$report->add_data($row);
d319704a Moritz Bunkus
}

1c4d3cd5 Moritz Bunkus
setup_ic_generate_report_action_bar();
e7913c4c Moritz Bunkus
$report->generate_with_headers();
d319704a Moritz Bunkus
$lxdebug->leave_sub();
} #end generate_report

1c4d3cd5 Moritz Bunkus
sub setup_ic_search_action_bar {
my %params = @_;

for my $bar ($::request->layout->get('actionbar')) {
$bar->add(
action => [
df33848f Moritz Bunkus
t8('Search'),
1c4d3cd5 Moritz Bunkus
submit => [ '#form', { action => 'generate_report' } ],
accesskey => 'enter',
],

action => [
t8('TOP100'),
submit => [ '#form', { action => 'top100' } ],
],
);
}
}

sub setup_ic_generate_report_action_bar {
my %params = @_;

for my $bar ($::request->layout->get('actionbar')) {
$bar->add(
combobox => [
action => [
t8('Add'),
],
action => [
t8('Add Part'),
submit => [ '#new_form', { action => 'Part/add_part' } ],
accesskey => 'enter',
],
action => [
t8('Add Service'),
submit => [ '#new_form', { action => 'Part/add_service' } ],
],
action => [
t8('Add Assembly'),
submit => [ '#new_form', { action => 'Part/add_assembly' } ],
],
action => [
t8('Add Assortment'),
submit => [ '#new_form', { action => 'Part/add_assortment' } ],
],
], # end of combobox "Add part"
);
}
}