use List::MoreUtils qw(all);
use YAML;
+use SL::CVar;
use SL::DBUtils;
sub get_part {
$form->{onhand} *= 1;
- my %oid = ('Pg' => 'a.oid',
- 'Oracle' => 'a.rowid');
-
# part or service item
$form->{item} = ($form->{inventory_accno}) ? 'part' : 'service';
if ($form->{assembly}) {
LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
LEFT JOIN price_factors pfac ON pfac.id = p.price_factor_id
WHERE (a.id = ?)
- ORDER BY $oid{$myconfig->{dbdriver}}|;
+ ORDER BY a.oid|;
$sth = prepare_execute_query($form, $dbh, $query, conv_i($form->{id}));
$form->{assembly_rows} = 0;
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
$form->{assembly_rows}++;
foreach my $key (keys %{$ref}) {
$form->{"${key}_$form->{assembly_rows}"} = $ref->{$key};
$form->{PRICEGROUPS} = selectall_hashref_query($form, $dbh, $query);
#find not used pricegroups
- while ($tmp = pop(@{ $form->{PRICEGROUPS} })) {
+ while (my $tmp = pop(@{ $form->{PRICEGROUPS} })) {
my $in_use = 0;
foreach my $item (@pricegroups) {
if ($item eq $tmp->{id}) {
# if not used pricegroups are avaible
if (@pricegroups_not_used) {
- foreach $name (@pricegroups_not_used) {
+ foreach my $name (@pricegroups_not_used) {
$form->{"klass_$i"} = "$name->{id}";
$form->{"pricegroup_id_$i"} = "$name->{id}";
$form->{"pricegroup_$i"} = "$name->{pricegroup}";
if ($form->{makemodel}) {
$query = qq|SELECT m.make, m.model FROM makemodel m | .
qq|WHERE m.parts_id = ?|;
- @values = ($form->{id});
+ my @values = ($form->{id});
$sth = $dbh->prepare($query);
$sth->execute(@values) || $form->dberror("$query (" . join(', ', @values) . ")");
FROM translation
WHERE parts_id = ?|;
my $trq = prepare_execute_query($form, $dbh, $query, conv_i($form->{id}));
- while (my $tr = $trq->fetchrow_hashref(NAME_lc)) {
+ while (my $tr = $trq->fetchrow_hashref("NAME_lc")) {
$form->{language_values} .= "---+++---" . join('--++--', @{$tr}{qw(language_id translation longdescription)});
}
$trq->finish;
FROM chart c, partstax pt
WHERE (pt.chart_id = c.id) AND (pt.parts_id = ?)|;
$sth = prepare_execute_query($form, $dbh, $query, conv_i($form->{id}));
- while (($key) = $sth->fetchrow_array) {
+ while (my ($key) = $sth->fetchrow_array) {
$form->{amount}{$key} = $key;
}
my $pricegroups = selectall_hashref_query($form, $dbh, $query);
my $i = 1;
- foreach $pg (@{ $pricegroups }) {
+ foreach my $pg (@{ $pricegroups }) {
$form->{"klass_$i"} = "$pg->{id}";
$form->{"price_$i"} = $form->format_amount($myconfig, $form->{"price_$i"}, -2);
$form->{"pricegroup_id_$i"} = "$pg->{id}";
my $partsgroup_id = 0;
if ($form->{partsgroup}) {
- ($partsgroup, $partsgroup_id) = split(/--/, $form->{partsgroup});
+ (my $partsgroup, $partsgroup_id) = split(/--/, $form->{partsgroup});
}
my ($subq_inventory, $subq_expense, $subq_income);
do_query($form, $dbh, qq|DELETE FROM translation WHERE parts_id = ?|, conv_i($form->{id}));
if ($form->{language_values} ne "") {
- foreach $item (split(/---\+\+\+---/, $form->{language_values})) {
+ foreach my $item (split(/---\+\+\+---/, $form->{language_values})) {
my ($language_id, $translation, $longdescription) = split(/--\+\+--/, $item);
if ($translation ne "") {
$query = qq|INSERT into translation (parts_id, language_id, translation, longdescription)
# insert price records only if different to sellprice
for my $i (1 .. $form->{price_rows}) {
- if ($form->{"price_$i"} eq "0") {
+ my $price = $form->parse_amount($myconfig, $form->{"price_$i"});
+ if ($price == 0) {
$form->{"price_$i"} = $form->{sellprice};
}
if (
- ( $form->{"price_$i"}
+ ( $price
|| $form->{"klass_$i"}
|| $form->{"pricegroup_id_$i"})
- and $form->{"price_$i"} != $form->{sellprice}
+ and $price != $form->{sellprice}
) {
#$klass = $form->parse_amount($myconfig, $form->{"klass_$i"});
- $price = $form->parse_amount($myconfig, $form->{"price_$i"});
- $pricegroup_id =
- $form->parse_amount($myconfig, $form->{"pricegroup_id_$i"});
$query = qq|INSERT INTO prices (parts_id, pricegroup_id, price) | .
qq|VALUES(?, ?, ?)|;
- @values = (conv_i($form->{id}), conv_i($pricegroup_id), $price);
+ @values = (conv_i($form->{id}), conv_i($form->{"pricegroup_id_$i"}), $price);
do_query($form, $dbh, $query, @values);
}
}
}
# insert taxes
- foreach $item (split(/ /, $form->{taxaccounts})) {
+ foreach my $item (split(/ /, $form->{taxaccounts})) {
if ($form->{"IC_tax_$item"}) {
$query =
qq|INSERT INTO partstax (parts_id, chart_id)
}
}
- @a = localtime;
+ my @a = localtime;
$a[5] += 1900;
$a[4]++;
my $shippingdate = "$a[5]-$a[4]-$a[3]";
}
#set expense_accno=inventory_accno if they are different => bilanz
- $vendor_accno =
+ my $vendor_accno =
($form->{expense_accno} != $form->{inventory_accno})
? $form->{inventory_accno}
: $form->{expense_accno};
# get tax rates and description
- $accno_id =
+ my $accno_id =
($form->{vc} eq "customer") ? $form->{income_accno} : $vendor_accno;
$query =
qq|SELECT c.accno, c.description, t.rate, t.taxnumber
FROM chart c, tax t
WHERE (c.id = t.chart_id) AND (t.taxkey IN (SELECT taxkey_id FROM chart where accno = ?))
ORDER BY c.accno|;
- $stw = prepare_execute_query($form, $dbh, $query, $accno_id);
+ my $stw = prepare_execute_query($form, $dbh, $query, $accno_id);
$form->{taxaccount} = "";
- while ($ptr = $stw->fetchrow_hashref(NAME_lc)) {
+ while (my $ptr = $stw->fetchrow_hashref("NAME_lc")) {
$form->{taxaccount} .= "$ptr->{accno} ";
if (!($form->{taxaccount2} =~ /\Q$ptr->{accno}\E/)) {
$form->{"$ptr->{accno}_rate"} = $ptr->{rate};
}
}
+ CVar->save_custom_variables('dbh' => $dbh,
+ 'module' => 'IC',
+ 'trans_id' => $form->{id},
+ 'variables' => $form);
+
# commit
my $rc = $dbh->commit;
$dbh->disconnect;
$query =
qq|UPDATE parts SET sellprice = sellprice + ?, weight = weight + ?
WHERE id = ?|;
- @values = ($qty * ($form->{sellprice} - $sellprice),
+ my @values = ($qty * ($form->{sellprice} - $sellprice),
$qty * ($form->{weight} - $weight), conv_i($id));
do_query($form, $dbh, $query, @values);
push(@values, conv_i($form->{id}));
}
- if ($partnumber) {
+ if ($form->{partnumber}) {
$where .= qq| ORDER BY p.partnumber|;
} else {
$where .= qq| ORDER BY p.description|;
# not working:
# onhand - as above, but masking the simple itemstatus results (doh!)
# masking of onhand in bsooqr mode - ToDO: fixme
+# warehouse onhand
#
# disabled sanity checks and changes:
# - searchitems = assembly will no longer disable bought
my @all_columns = (@simple_filters, @makemodel_filters, @apoe_filters, qw(serialnumber));
my @simple_l_switches = (@all_columns, qw(listprice sellprice lastcost priceupdate weight unit bin rop image));
my @oe_flags = qw(bought sold onorder ordered rfq quoted);
- my @qsooqr_flags = qw(invnumber ordnumber quonumber trans_id name module);
+ my @qsooqr_flags = qw(invnumber ordnumber quonumber trans_id name module qty);
my @deliverydate_flags = qw(deliverydate);
# my @other_flags = qw(onhand); # ToDO: implement these
# my @inactive_flags = qw(l_subtotal short l_linetotal);
) AS cv ON cv.id = apoe.customer_id OR cv.id = apoe.vendor_id|,
);
my @join_order = qw(partsgroup makemodel invoice_oi apoe cv pfac);
+
+ my %table_prefix = (
+ deliverydate => 'apoe.', serialnumber => 'ioi.',
+ transdate => 'apoe.', trans_id => 'ioi.',
+ module => 'apoe.', name => 'cv.',
+ ordnumber => 'apoe.', make => 'mm.',
+ quonumber => 'apoe.', model => 'mm.',
+ invnumber => 'apoe.', partsgroup => 'pg.',
+ lastcost => ' ',
+ factor => 'pfac.',
+ 'SUM(ioi.qty)' => ' ',
+ );
+
+ my %renamed_columns = (
+ 'factor' => 'price_factor',
+ 'SUM(ioi.qty)' => 'soldtotal',
+ );
+
my %joins_needed;
if (($form->{searchitems} eq 'assembly') && $form->{l_lastcost}) {
my @select_tokens = qw(id factor);
my @where_tokens = qw(1=1);
my @group_tokens = ();
+ my @bind_vars = ();
# special case transdate
if (grep { $form->{$_} } qw(transdatefrom transdateto)) {
my $sort_order = ($form->{revers} ? ' DESC' : ' ASC');
+ my $order_clause = " ORDER BY $form->{sort} " . ($form->{revers} ? 'DESC' : 'ASC');
+
# special case: sorting by partnumber
# since partnumbers are expected to be prefixed integers, a special sorting is implemented sorting first lexically by prefix and then by suffix.
# and yes, that expression is designed to hold that array of regexes only once, so the map is kinda messy, sorry about that.
# ToDO: implement proper functional sorting
- $form->{sort} = join ', ', map { push @select_tokens, $_; ($table_prefix{$_} = "substring(partnumber,'[") . $_ } qw|^[:digit:]]+') [:digit:]]+')::INTEGER|
- if $form->{sort} eq 'partnumber';
+ # Nette Idee von Sven, gibt aber Probleme wenn die Artikelnummern groesser als 32bit sind. Korrekt waere es, dass Sort-Natural-Modul zu nehmen
+ # Ich lass das mal hier drin, damit die Idee erhalten bleibt jb 28.5.2009 bug 1018
+ #$form->{sort} = join ', ', map { push @select_tokens, $_; ($table_prefix{$_} = "substring(partnumber,'[") . $_ } qw|^[:digit:]]+') [:digit:]]+')::INTEGER|
+ # if $form->{sort} eq 'partnumber';
- my $order_clause = " ORDER BY $form->{sort} $sort_order";
+ #my $order_clause = " ORDER BY $form->{sort} $sort_order";
my $limit_clause = " LIMIT 100" if $form->{top100};
|| $form->{quoted} || $form->{rfq};
my @bsooqr;
+ my @bsooqr_tokens = ();
push @select_tokens, @qsooqr_flags if $bsooqr;
push @select_tokens, @deliverydate_flags if $bsooqr && $form->{l_deliverydate};
push @select_tokens, $q_assembly_lastcost if ($form->{searchitems} eq 'assembly') && $form->{l_lastcost};
push @bsooqr_tokens, q|module = 'oe' AND quotation AND cv = 'vendor'| if $form->{rfq};
push @where_tokens, join ' OR ', map { "($_)" } @bsooqr_tokens if $bsooqr;
+ $renamed_columns{onhand} = 'onhand_before_bsooqr';
+ $renamed_columns{qty} = 'onhand';
+
$joins_needed{partsgroup} = 1;
$joins_needed{pfac} = 1;
$joins_needed{makemodel} = 1 if grep { $form->{$_} || $form->{"l_$_"} } @makemodel_filters;
#============= build query ================#
- %table_prefix = (
- %table_prefix,
- deliverydate => 'apoe.', serialnumber => 'ioi.',
- transdate => 'apoe.', trans_id => 'ioi.',
- module => 'apoe.', name => 'cv.',
- ordnumber => 'apoe.', make => 'mm.',
- quonumber => 'apoe.', model => 'mm.',
- invnumber => 'apoe.', partsgroup => 'pg.',
- lastcost => ' ',
- factor => 'pfac.',
- 'SUM(ioi.qty)' => ' ',
- );
-
$table_prefix{$q_assembly_lastcost} = ' ';
- my %renamed_columns = (
- 'factor' => 'price_factor',
- 'SUM(ioi.qty)' => 'soldtotal',
- );
-
map { $table_prefix{$_} = 'ioi.' } qw(description serialnumber qty unit) if $joins_needed{invoice_oi};
map { $renamed_columns{$_} = ' AS ' . $renamed_columns{$_} } keys %renamed_columns;
my $where_clause = join ' AND ', map { "($_)" } @where_tokens;
my $group_clause = ' GROUP BY ' . join ', ', map { ($table_prefix{$_} || "p.") . $_ } @group_tokens if scalar @group_tokens;
+ my ($cvar_where, @cvar_values) = CVar->build_filter_query('module' => 'IC',
+ 'trans_id_field' => 'p.id',
+ 'filter' => $form);
+
+ if ($cvar_where) {
+ $where_clause .= qq| AND ($cvar_where)|;
+ push @bind_vars, @cvar_values;
+ }
+
my $query = qq|SELECT DISTINCT $select_clause FROM parts p $join_clause WHERE $where_clause $group_clause $order_clause $limit_clause|;
$form->{parts} = selectall_hashref_query($form, $dbh, $query, @bind_vars);
INNER JOIN assembly a ON (p.id = a.parts_id)
$joins{pfac}
WHERE a.id = ?|;
- $sth = prepare_query($form, $dbh, $query);
+ my $sth = prepare_query($form, $dbh, $query);
- foreach $item (@{ $form->{parts} }) {
+ foreach my $item (@{ $form->{parts} }) {
push(@assemblies, $item);
do_statement($form, $sth, $query, conv_i($item->{id}));
- while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
$ref->{assemblyitem} = 1;
map { $ref->{$_} /= $ref->{factor} || 1 } qw(sellprice listprice lastcost);
push(@assemblies, $ref);
$main::lxdebug->leave_sub();
}
-sub update_prices {
+sub _create_filter_for_priceupdate {
$main::lxdebug->enter_sub();
- my ($self, $myconfig, $form) = @_;
+ my $self = shift;
+ my $myconfig = \%main::myconfig;
+ my $form = $main::form;
+
my @where_values;
my $where = '1 = 1';
- my $var;
- my $group;
- my $limit;
+ foreach my $item (qw(partnumber drawing microfiche make model pg.partsgroup)) {
+ my $column = $item;
+ $column =~ s/.*\.//;
+ next unless ($form->{$column});
- if ($item ne 'make') {
- foreach my $item (qw(partnumber drawing microfiche make model pg.partsgroup)) {
- my $column = $item;
- $column =~ s/.*\.//;
- next unless ($form->{$column});
- $where .= qq| AND $item ILIKE ?|;
- push(@where_values, '%' . $form->{$column} . '%');
- }
+ $where .= qq| AND $item ILIKE ?|;
+ push(@where_values, '%' . $form->{$column} . '%');
}
- # special case for description
- if ($form->{description}
- && !( $form->{bought} || $form->{sold} || $form->{onorder}
- || $form->{ordered} || $form->{rfq} || $form->{quoted})) {
- $where .= qq| AND (p.description ILIKE ?)|;
- push(@where_values, '%' . $form->{description} . '%');
- }
+ foreach my $item (qw(description serialnumber)) {
+ next unless ($form->{$item});
- # special case for serialnumber
- if ($form->{l_serialnumber} && $form->{serialnumber}) {
- $where .= qq| AND serialnumber ILIKE ?|;
- push(@where_values, '%' . $form->{serialnumber} . '%');
+ $where .= qq| AND (${item} ILIKE ?)|;
+ push(@where_values, '%' . $form->{$item} . '%');
}
# items which were never bought, sold or on an order
if ($form->{itemstatus} eq 'orphaned') {
- $form->{onhand} = $form->{short} = 0;
- $form->{bought} = $form->{sold} = 0;
- $form->{onorder} = $form->{ordered} = 0;
- $form->{rfq} = $form->{quoted} = 0;
-
- $form->{transdatefrom} = $form->{transdateto} = "";
-
$where .=
qq| AND (p.onhand = 0)
AND p.id NOT IN
UNION
SELECT DISTINCT parts_id FROM orderitems
)|;
- }
- if ($form->{itemstatus} eq 'active') {
+ } elsif ($form->{itemstatus} eq 'active') {
$where .= qq| AND p.obsolete = '0'|;
- }
- if ($form->{itemstatus} eq 'obsolete') {
+ } elsif ($form->{itemstatus} eq 'obsolete') {
$where .= qq| AND p.obsolete = '1'|;
- $form->{onhand} = $form->{short} = 0;
- }
- if ($form->{itemstatus} eq 'onhand') {
+ } elsif ($form->{itemstatus} eq 'onhand') {
$where .= qq| AND p.onhand > 0|;
- }
- if ($form->{itemstatus} eq 'short') {
+ } elsif ($form->{itemstatus} eq 'short') {
$where .= qq| AND p.onhand < p.rop|;
+
}
foreach my $column (qw(make model)) {
- next unless ($form->{$colum});
+ next unless ($form->{$column});
$where .= qq| AND p.id IN (SELECT DISTINCT parts_id FROM makemodel WHERE $column ILIKE ?|;
push(@where_values, '%' . $form->{$column} . '%');
}
+ $main::lxdebug->leave_sub();
+
+ return ($where, @where_values);
+}
+
+sub get_num_matches_for_priceupdate {
+ $main::lxdebug->enter_sub();
+
+ my $self = shift;
+
+ my $myconfig = \%main::myconfig;
+ my $form = $main::form;
+
+ my $dbh = $form->get_standard_dbh($myconfig);
+
+ my ($where, @where_values) = $self->_create_filter_for_priceupdate();
+
+ my $num_updated = 0;
+ my $query;
+
+ for my $column (qw(sellprice listprice)) {
+ next if ($form->{$column} eq "");
+
+ $query =
+ qq|SELECT COUNT(*)
+ FROM parts
+ WHERE id IN
+ (SELECT p.id
+ FROM parts p
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ WHERE $where)|;
+ my ($result) = selectfirst_array_query($form, $dbh, $query, @where_values);
+ $num_updated += $result if (0 <= $result);
+ }
+
+ $query =
+ qq|SELECT COUNT(*)
+ FROM prices
+ WHERE parts_id IN
+ (SELECT p.id
+ FROM parts p
+ LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
+ WHERE $where) AND (pricegroup_id = ?)|;
+ my $sth = prepare_query($form, $dbh, $query);
+
+ for my $i (1 .. $form->{price_rows}) {
+ next if ($form->{"price_$i"} eq "");
+
+ my ($result) = do_statement($form, $sth, $query, @where_values, conv_i($form->{"pricegroup_id_$i"}));
+ $num_updated += $result if (0 <= $result);
+ }
+ $sth->finish();
+
+ $main::lxdebug->leave_sub();
+
+ return $num_updated;
+}
+
+sub update_prices {
+ $main::lxdebug->enter_sub();
+
+ my ($self, $myconfig, $form) = @_;
+
+ my ($where, @where_values) = $self->_create_filter_for_priceupdate();
+ my $num_updated = 0;
+
# connect to database
my $dbh = $form->dbconnect_noauto($myconfig);
$operator = '*';
}
- $query =
+ my $query =
qq|UPDATE parts SET $column = $column $operator ?
WHERE id IN
(SELECT p.id
FROM parts p
LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
WHERE $where)|;
- do_query($from, $dbh, $query, $value, @where_values);
+ my $result = do_query($form, $dbh, $query, $value, @where_values);
+ $num_updated += $result if (0 <= $result);
}
my $q_add =
next if ($form->{"price_$i"} eq "");
my $value = $form->parse_amount($myconfig, $form->{"price_$i"});
+ my $result;
if ($form->{"pricegroup_type_$i"} eq "percent") {
- do_statement($form, $sth_multiply, $q_multiply, ($value / 100) + 1, @where_values, conv_i($form->{"pricegroup_id_$i"}));
+ $result = do_statement($form, $sth_multiply, $q_multiply, ($value / 100) + 1, @where_values, conv_i($form->{"pricegroup_id_$i"}));
} else {
- do_statement($form, $sth_add, $q_add, $value, @where_values, conv_i($form->{"pricegroup_id_$i"}));
+ $result = do_statement($form, $sth_add, $q_add, $value, @where_values, conv_i($form->{"pricegroup_id_$i"}));
}
+
+ $num_updated += $result if (0 <= $result);
}
$sth_add->finish();
$main::lxdebug->leave_sub();
- return $rc;
+ return $num_updated;
}
sub create_links {
my $dbh = $form->dbconnect($myconfig);
my @values = ('%' . $module . '%');
+ my $query;
if ($form->{id}) {
$query =
}
my $sth = prepare_execute_query($form, $dbh, $query, @values);
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
foreach my $key (split(/:/, $ref->{link})) {
if ($key =~ /\Q$module\E/) {
if ( ($ref->{id} eq $ref->{inventory_accno_id})
my $sth = prepare_execute_query($form, $dbh, $query, @values);
my $j = 0;
- while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
+ while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
if (($ref->{partnumber} eq "*") && ($ref->{description} eq "")) {
next;
}
my ($dbh, $id) = @_;
my $query = qq|SELECT sum(qty) FROM invoice WHERE parts_id = ?|;
- my ($sum) = selectrow_query($form, $dbh, $query, conv_i($id));
+ my ($sum) = selectrow_query($main::form, $dbh, $query, conv_i($id));
$sum ||= 0;
$main::lxdebug->leave_sub();
my @values;
my $where;
+ my $query;
if ($form->{language_values} ne "") {
$query =
while (1) {
do_statement($form, $sth, $query, $accno_id);
- $ref = $sth->fetchrow_hashref();
+ my $ref = $sth->fetchrow_hashref();
last unless ($ref && $ref->{"is_valid"} &&
!grep({ $_ == $ref->{"new_chart_id"} } @visited_accno_ids));
$accno_id = $ref->{"new_chart_id"};