X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;ds=sidebyside;f=SL%2FIC.pm;h=2cf7996fb14260f7f709e3f8d10c99f1f3a1aad6;hb=28c19c1c99304a88bf3cd57eb02a4f3d502a6c62;hp=2455d9e0e11260c2d838ed4b400d264848be537e;hpb=8bf3fee4a887e4e8d7723a23f6ad08f69fb20aa6;p=kivitendo-erp.git diff --git a/SL/IC.pm b/SL/IC.pm index 2455d9e0e..2cf7996fb 100644 --- a/SL/IC.pm +++ b/SL/IC.pm @@ -42,6 +42,9 @@ use SL::CVar; use SL::DBUtils; use SL::HTML::Restrict; use SL::TransNumber; +use SL::Util qw(trim); +use SL::DB; +use Carp; use strict; @@ -72,12 +75,12 @@ sub get_part { # copy to $form variables map { $form->{$_} = $ref->{$_} } (keys %{$ref}); + $form->{mtime} = $form->{itime} if !$form->{mtime}; + $form->{lastmtime} = $form->{mtime}; $form->{onhand} *= 1; # part or service item - $form->{item} = ($form->{inventory_accno}) ? 'part' : 'service'; - if ($form->{assembly}) { - $form->{item} = 'assembly'; + if ($form->{part_type} eq 'assembly') { # retrieve assembly items $query = @@ -190,8 +193,7 @@ sub get_pricegroups { my $i = 1; foreach my $pg (@{ $pricegroups }) { - $form->{"klass_$i"} = "$pg->{id}"; - $form->{"price_$i"} = $form->format_amount($myconfig, $form->{"price_$i"}, -2); + $form->{"price_$i"} = $form->format_amount($myconfig, $form->{"price_$i"}, -2); $form->{"pricegroup_id_$i"} = "$pg->{id}"; $form->{"pricegroup_$i"} = "$pg->{pricegroup}"; $i++; @@ -222,12 +224,20 @@ sub retrieve_buchungsgruppen { } sub save { + my ($self, $myconfig, $form) = @_; $main::lxdebug->enter_sub(); + my $rc = SL::DB->client->with_transaction(\&_save, $self, $myconfig, $form); + + $main::lxdebug->leave_sub(); + return $rc; +} + +sub _save { my ($self, $myconfig, $form) = @_; my @values; - # connect to database, turn off AutoCommit - my $dbh = $form->get_standard_dbh; + + my $dbh = SL::DB->client->dbh; my $restricter = SL::HTML::Restrict->create; # save the part @@ -245,35 +255,26 @@ sub save { my $makemodel = ($form->{make_1} || $form->{model_1} || ($form->{makemodel_rows} > 1)) ? 1 : 0; - $form->{assembly} = ($form->{item} eq 'assembly') ? 1 : 0; my ($query, $sth); my $priceupdate = ', priceupdate = current_date'; if ($form->{id}) { - my $trans_number = SL::TransNumber->new(type => $form->{item}, dbh => $dbh, number => $form->{partnumber}, id => $form->{id}); + my $trans_number = SL::TransNumber->new(type => $form->{part_type}, dbh => $dbh, number => $form->{partnumber}, id => $form->{id}); if (!$trans_number->is_unique) { $::lxdebug->leave_sub; return 3; } # get old price - $query = qq|SELECT sellprice, weight FROM parts WHERE id = ?|; - my ($sellprice, $weight) = selectrow_query($form, $dbh, $query, conv_i($form->{id})); - - # if item is part of an assembly adjust all assemblies - $query = qq|SELECT id, qty FROM assembly WHERE parts_id = ?|; - $sth = prepare_execute_query($form, $dbh, $query, conv_i($form->{id})); - while (my ($id, $qty) = $sth->fetchrow_array) { - &update_assembly($dbh, $form, $id, $qty, $sellprice * 1, $weight * 1); - } - $sth->finish; + $query = qq|SELECT sellprice FROM parts WHERE id = ?|; + my ($sellprice) = selectrow_query($form, $dbh, $query, conv_i($form->{id})); # delete makemodel records do_query($form, $dbh, qq|DELETE FROM makemodel WHERE parts_id = ?|, conv_i($form->{id})); - if ($form->{item} eq 'assembly') { + if ($form->{part_type} eq 'assembly') { # delete assembly records do_query($form, $dbh, qq|DELETE FROM assembly WHERE id = ?|, conv_i($form->{id})); } @@ -287,7 +288,7 @@ sub save { $priceupdate = '' if (all { $previous_values->{$_} == $form->{$_} } qw(sellprice lastcost listprice)); } else { - my $trans_number = SL::TransNumber->new(type => $form->{item}, dbh => $dbh, number => $form->{partnumber}, save => 1); + my $trans_number = SL::TransNumber->new(type => $form->{part_type}, dbh => $dbh, number => $form->{partnumber}, save => 1); if ($form->{partnumber} && !$trans_number->is_unique) { $::lxdebug->leave_sub; @@ -297,7 +298,7 @@ sub save { $form->{partnumber} ||= $trans_number->create_unique; ($form->{id}) = selectrow_query($form, $dbh, qq|SELECT nextval('id')|); - do_query($form, $dbh, qq|INSERT INTO parts (id, partnumber, unit) VALUES (?, ?, ?)|, $form->{id}, $form->{partnumber}, $form->{unit}); + do_query($form, $dbh, qq|INSERT INTO parts (id, partnumber, unit, part_type) VALUES (?, ?, ?, ?)|, $form->{id}, $form->{partnumber}, $form->{unit}, $form->{part_type}); $form->{orphaned} = 1; } @@ -308,7 +309,7 @@ sub save { } my ($subq_inventory, $subq_expense, $subq_income); - if ($form->{"item"} eq "part") { + if ($form->{part_type} eq "part") { $subq_inventory = qq|(SELECT bg.inventory_accno_id FROM buchungsgruppen bg @@ -317,7 +318,7 @@ sub save { $subq_inventory = "NULL"; } - if ($form->{"item"} ne "assembly") { + if ($form->{part_type} ne "assembly") { $subq_expense = qq|(SELECT tc.expense_accno_id FROM taxzone_charts tc @@ -333,8 +334,6 @@ sub save { partnumber = ?, description = ?, makemodel = ?, - alternate = 'f', - assembly = ?, listprice = ?, sellprice = ?, lastcost = ?, @@ -360,6 +359,7 @@ sub save { has_sernumber = ?, not_discountable = ?, microfiche = ?, + part_type = ?, partsgroup_id = ?, price_factor_id = ? $priceupdate @@ -367,7 +367,6 @@ sub save { @values = ($form->{partnumber}, $form->{description}, $makemodel ? 't' : 'f', - $form->{assembly} ? 't' : 'f', $form->{listprice}, $form->{sellprice}, $form->{lastcost}, @@ -391,12 +390,15 @@ sub save { $form->{has_sernumber} ? 't' : 'f', $form->{not_discountable} ? 't' : 'f', $form->{microfiche}, + $form->{part_type}, conv_i($partsgroup_id), conv_i($form->{price_factor_id}), conv_i($form->{id}) ); do_query($form, $dbh, $query, @values); + $form->new_lastmtime('parts'); + # delete translation records do_query($form, $dbh, qq|DELETE FROM translation WHERE parts_id = ?|, conv_i($form->{id})); @@ -455,7 +457,7 @@ sub save { } # add assembly records - if ($form->{item} eq 'assembly') { + if ($form->{part_type} eq 'assembly') { # check additional assembly row my $i = $form->{assembly_rows}; # if last row is not empty add them @@ -526,35 +528,21 @@ sub save { variables => $form, save_validity => 1); - # commit - my $rc = $dbh->commit; - - $main::lxdebug->leave_sub(); - - return $rc; -} - -sub update_assembly { - $main::lxdebug->enter_sub(); - - my ($dbh, $form, $id, $qty, $sellprice, $weight) = @_; - - my $query = qq|SELECT id, qty FROM assembly WHERE parts_id = ?|; - my $sth = prepare_execute_query($form, $dbh, $query, conv_i($id)); - - while (my ($pid, $aqty) = $sth->fetchrow_array) { - &update_assembly($dbh, $form, $pid, $aqty * $qty, $sellprice, $weight); - } - $sth->finish; - - $query = - qq|UPDATE parts SET sellprice = sellprice + ?, weight = weight + ? - WHERE id = ?|; - my @values = ($qty * ($form->{sellprice} - $sellprice), - $qty * ($form->{weight} - $weight), conv_i($id)); - do_query($form, $dbh, $query, @values); + # Delete saved custom variable values for configs that have been + # marked invalid for this part. + $query = <{id}) x 2); - $main::lxdebug->leave_sub(); + return 1; } sub retrieve_assemblies { @@ -570,12 +558,12 @@ sub retrieve_assemblies { if ($form->{partnumber}) { $where .= qq| AND (p.partnumber ILIKE ?)|; - push(@values, '%' . $form->{partnumber} . '%'); + push(@values, like($form->{partnumber})); } if ($form->{description}) { $where .= qq| AND (p.description ILIKE ?)|; - push(@values, '%' . $form->{description} . '%'); + push(@values, like($form->{description})); } # retrieve assembly items @@ -586,7 +574,7 @@ sub retrieve_assemblies { FROM parts p2, assembly a WHERE (p2.id = a.parts_id) AND (a.id = p.id)) AS inventory FROM parts p - WHERE NOT p.obsolete AND p.assembly $where|; + WHERE NOT p.obsolete AND p.part_type = 'assembly' $where|; $form->{assembly_items} = selectall_hashref_query($form, $dbh, $query, @values); @@ -594,26 +582,27 @@ sub retrieve_assemblies { } sub delete { + my ($self, $myconfig, $form) = @_; $main::lxdebug->enter_sub(); + my $rc = SL::DB->client->with_transaction(\&_delete, $self, $myconfig, $form); + + $main::lxdebug->leave_sub(); + return $rc; +} + +sub _delete { my ($self, $myconfig, $form) = @_; my @values = (conv_i($form->{id})); - # connect to database, turn off AutoCommit - my $dbh = $form->get_standard_dbh; my %columns = ( "assembly" => "id", "parts" => "id" ); for my $table (qw(prices makemodel inventory assembly translation parts)) { my $column = defined($columns{$table}) ? $columns{$table} : "parts_id"; - do_query($form, $dbh, qq|DELETE FROM $table WHERE $column = ?|, @values); + do_query($form, SL::DB->client->dbh, qq|DELETE FROM $table WHERE $column = ?|, @values); } - # commit - my $rc = $dbh->commit; - - $main::lxdebug->leave_sub(); - - return $rc; + return 1; } sub assembly_item { @@ -631,7 +620,7 @@ sub assembly_item { while (my ($column, $table) = each(%columns)) { next unless ($form->{"${column}_$i"}); $where .= qq| AND ${table}.${column} ILIKE ?|; - push(@values, '%' . $form->{"${column}_$i"} . '%'); + push(@values, like($form->{"${column}_$i"})); } if ($form->{id}) { @@ -651,18 +640,15 @@ sub assembly_item { $where .= qq| ORDER BY p.description|; } - # connect to database - my $dbh = $form->get_standard_dbh; - my $query = qq|SELECT p.id, p.partnumber, p.description, p.sellprice, p.weight, p.onhand, p.unit, pg.partsgroup, p.lastcost, - p.price_factor_id, pfac.factor AS price_factor + p.price_factor_id, pfac.factor AS price_factor, p.notes as longdescription FROM parts p LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) LEFT JOIN price_factors pfac ON pfac.id = p.price_factor_id WHERE $where|; - $form->{item_list} = selectall_hashref_query($form, $dbh, $query, @values); + $form->{item_list} = selectall_hashref_query($form, SL::DB->client->dbh, $query, @values); $main::lxdebug->leave_sub(); } @@ -730,7 +716,7 @@ sub all_parts { my @apoe_filters = qw(transdate); my @like_filters = (@simple_filters, @invoice_oi_filters); my @all_columns = (@simple_filters, @makemodel_filters, @apoe_filters, @project_filters, qw(serialnumber)); - my @simple_l_switches = (@all_columns, qw(notes listprice sellprice lastcost priceupdate weight unit rop image shop)); + my @simple_l_switches = (@all_columns, qw(notes listprice sellprice lastcost priceupdate weight unit rop image shop insertdate)); my @oe_flags = qw(bought sold onorder ordered rfq quoted); my @qsooqr_flags = qw(invnumber ordnumber quonumber trans_id name module qty); my @deliverydate_flags = qw(deliverydate); @@ -806,10 +792,12 @@ sub all_parts { 'ioi.id' => 'ioi_id', 'ioi.ioi' => 'ioi', 'projectdescription' => 'projectdescription', + 'insertdate' => 'insertdate', ); my %real_column = ( projectdescription => 'description', + insertdate => 'itime::DATE', ); if (($form->{searchitems} eq 'assembly') && $form->{l_lastcost}) { @@ -840,13 +828,37 @@ sub all_parts { #===== switches and simple filters ========# # special case transdate - if (grep { $form->{$_} } qw(transdatefrom transdateto)) { + if (grep { trim($form->{$_}) } qw(transdatefrom transdateto)) { $form->{"l_transdate"} = 1; push @select_tokens, 'transdate'; for (qw(transdatefrom transdateto)) { - next unless $form->{$_}; + my $value = trim($form->{$_}); + next unless $value; push @where_tokens, sprintf "transdate %s ?", /from$/ ? '>=' : '<='; - push @bind_vars, $form->{$_}; + push @bind_vars, $value; + } + } + + # special case smart search + if ($form->{all}) { + $form->{"l_$_"} = 1 for qw(partnumber description unit sellprice lastcost cvar_packaging linetotal); + push @where_tokens, "p.partnumber ILIKE ? OR p.description ILIKE ?"; + push @bind_vars, (like($form->{all})) x 2; + } + + # special case insertdate + if (grep { trim($form->{$_}) } qw(insertdatefrom insertdateto)) { + $form->{"l_insertdate"} = 1; + push @select_tokens, 'insertdate'; + + my $token_builder = $make_token_builder->(); + my $token = $token_builder->('insertdate'); + + for (qw(insertdatefrom insertdateto)) { + my $value = trim($form->{$_}); + next unless $value; + push @where_tokens, sprintf "$token %s ?", /from$/ ? '>=' : '<='; + push @bind_vars, $value; } } @@ -870,7 +882,7 @@ sub all_parts { next unless $form->{$_}; $form->{"l_$_"} = '1'; # show the column push @where_tokens, "$table_prefix{$_}$_ ILIKE ?"; - push @bind_vars, "%$form->{$_}%"; + push @bind_vars, like($form->{$_}); } foreach (@simple_l_switches) { @@ -879,10 +891,9 @@ sub all_parts { } for ($form->{searchitems}) { - push @where_tokens, 'p.inventory_accno_id > 0' if /part/; - push @where_tokens, 'p.inventory_accno_id IS NULL' if /service/; - push @where_tokens, 'NOT p.assembly' if /service/; - push @where_tokens, ' p.assembly' if /assembly/; + push @where_tokens, "p.part_type = 'part'" if /part/; + push @where_tokens, "p.part_type = 'service'" if /service/; + push @where_tokens, "p.part_type = 'assembly'" if /assembly/; } for ($form->{itemstatus}) { @@ -911,11 +922,11 @@ sub all_parts { # fortunately makemodel doesn't need to be displayed later, so adding a special clause to where_token is sufficient. if ($form->{make}) { push @where_tokens, 'mv.name ILIKE ?'; - push @bind_vars, "%$form->{make}%"; + push @bind_vars, like($form->{make}); } if ($form->{model}) { push @where_tokens, 'mm.model ILIKE ?'; - push @bind_vars, "%$form->{model}%"; + push @bind_vars, like($form->{model}); } # special case: sorting by partnumber @@ -983,7 +994,7 @@ sub all_parts { my $token_builder = $make_token_builder->(\%joins_needed); - my @sort_cols = (@simple_filters, qw(id priceupdate onhand invnumber ordnumber quonumber name serialnumber soldtotal deliverydate shop)); + my @sort_cols = (@simple_filters, qw(id priceupdate onhand invnumber ordnumber quonumber name serialnumber soldtotal deliverydate insertdate shop)); $form->{sort} = 'id' unless grep { $form->{"l_$_"} } grep { $form->{sort} eq $_ } @sort_cols; # sort by id if unknown or invisible column my $sort_order = ($form->{revers} ? ' DESC' : ' ASC'); my $order_clause = " ORDER BY " . $token_builder->($form->{sort}) . ($form->{revers} ? ' DESC' : ' ASC'); @@ -1041,7 +1052,7 @@ sub all_parts { if ($form->{searchitems} eq 'assembly' && $form->{bom}) { $query = qq|SELECT p.id, p.partnumber, p.description, a.qty AS onhand, - p.unit, p.notes, + p.unit, p.notes, p.itime::DATE as insertdate, p.sellprice, p.listprice, p.lastcost, p.rop, p.weight, p.priceupdate, p.image, p.drawing, p.microfiche, @@ -1109,14 +1120,14 @@ sub _create_filter_for_priceupdate { next unless ($form->{$column}); $where .= qq| AND $item ILIKE ?|; - push(@where_values, '%' . $form->{$column} . '%'); + push(@where_values, like($form->{$column})); } foreach my $item (qw(description serialnumber)) { next unless ($form->{$item}); $where .= qq| AND (${item} ILIKE ?)|; - push(@where_values, '%' . $form->{$item} . '%'); + push(@where_values, like($form->{$item})); } @@ -1150,7 +1161,7 @@ sub _create_filter_for_priceupdate { foreach my $column (qw(make model)) { next unless ($form->{$column}); $where .= qq| AND p.id IN (SELECT DISTINCT parts_id FROM makemodel WHERE $column ILIKE ?|; - push(@where_values, '%' . $form->{$column} . '%'); + push(@where_values, like($form->{$column})); } $main::lxdebug->leave_sub(); @@ -1212,15 +1223,23 @@ sub get_num_matches_for_priceupdate { } sub update_prices { + my ($self, $myconfig, $form) = @_; $main::lxdebug->enter_sub(); + my $num_updated = SL::DB->client->with_transaction(\&_update_prices, $self, $myconfig, $form); + + $main::lxdebug->leave_sub(); + return $num_updated; +} + +sub _update_prices { my ($self, $myconfig, $form) = @_; my ($where, @where_values) = $self->_create_filter_for_priceupdate(); my $num_updated = 0; # connect to database - my $dbh = $form->get_standard_dbh; + my $dbh = SL::DB->client->dbh; for my $column (qw(sellprice listprice)) { next if ($form->{$column} eq ""); @@ -1280,10 +1299,6 @@ sub update_prices { $sth_add->finish(); $sth_multiply->finish(); - my $rc= $dbh->commit; - - $main::lxdebug->leave_sub(); - return $num_updated; } @@ -1295,7 +1310,7 @@ sub create_links { # connect to database my $dbh = $form->get_standard_dbh; - my @values = ('%' . $module . '%'); + my @values = like($module); my $query; if ($form->{id}) { @@ -1364,15 +1379,15 @@ sub get_parts { if ($sortorder eq "all") { $where .= qq| AND (partnumber ILIKE ?) AND (description ILIKE ?)|; - push(@values, '%' . $form->{partnumber} . '%', '%' . $form->{description} . '%'); + push(@values, like($form->{partnumber}), like($form->{description})); } elsif ($sortorder eq "partnumber") { $where .= qq| AND (partnumber ILIKE ?)|; - push(@values, '%' . $form->{partnumber} . '%'); + push(@values, like($form->{partnumber})); } elsif ($sortorder eq "description") { $where .= qq| AND (description ILIKE ?)|; - push(@values, '%' . $form->{description} . '%'); + push(@values, like($form->{description})); $order = "description"; } @@ -1548,7 +1563,7 @@ sub retrieve_accounts { my %accno_by_part = map { $_->{id} => $_ } selectall_hashref_query($form, $dbh, < $part_id) = each %args) { my $ref = $accno_by_part{$part_id} or next; - $ref->{"inventory_accno_id"} = undef unless $ref->{"is_part"}; + $ref->{"inventory_accno_id"} = undef unless $ref->{"part_type"} eq 'part'; my %accounts; for my $type (qw(inventory income expense)) { @@ -1682,7 +1697,7 @@ sub prepare_parts_for_printing { $sth->finish(); - my @columns = qw(ean image microfiche drawing weight); + my @columns = qw(ean image microfiche drawing); $query = qq|SELECT id, | . join(', ', @columns) . qq| FROM parts @@ -1690,7 +1705,8 @@ sub prepare_parts_for_printing { my %data = selectall_as_map($form, $dbh, $query, 'id', \@columns, @part_ids); - map { $form->{TEMPLATE_ARRAYS}{$_} = [] } (qw(make model), @columns); + my %template_arrays; + map { $template_arrays{$_} = [] } (qw(make model), @columns); foreach my $i (1 .. $rowcount) { my $id = $form->{"${prefix}${i}"}; @@ -1698,16 +1714,16 @@ sub prepare_parts_for_printing { next if (!$id); foreach (@columns) { - push @{ $form->{TEMPLATE_ARRAYS}{$_} }, $data{$id}->{$_}; + push @{ $template_arrays{$_} }, $data{$id}->{$_}; } - push @{ $form->{TEMPLATE_ARRAYS}{make} }, []; - push @{ $form->{TEMPLATE_ARRAYS}{model} }, []; + push @{ $template_arrays{make} }, []; + push @{ $template_arrays{model} }, []; next if (!$makemodel{$id}); foreach my $ref (@{ $makemodel{$id} }) { - map { push @{ $form->{TEMPLATE_ARRAYS}{$_}->[-1] }, $ref->{$_} } qw(make model); + map { push @{ $template_arrays{$_}->[-1] }, $ref->{$_} } qw(make model); } } @@ -1718,9 +1734,10 @@ sub prepare_parts_for_printing { my $id = $form->{"${prefix}${i}"}; next unless $id; - push @{ $form->{TEMPLATE_ARRAYS}{part_type} }, $parts_by_id{$id}->type; + push @{ $template_arrays{part_type} }, $parts_by_id{$id}->type; } + return %template_arrays; $main::lxdebug->leave_sub(); }