X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FWH.pm;h=f05ba4fd5345e14fe94b7b9f164b9a8a673a5811;hb=46f028ef78a55580e7e33c2439cedd0e60bde998;hp=78a1442e56f34febec278459986a8235c138a039;hpb=3c938e03dbb186f9c163e19473e9572f7fa16aea;p=kivitendo-erp.git diff --git a/SL/WH.pm b/SL/WH.pm index 78a1442e5..f05ba4fd5 100644 --- a/SL/WH.pm +++ b/SL/WH.pm @@ -80,7 +80,8 @@ sub transfer { my $db = SL::DB::Inventory->new->db; $db->with_transaction(sub{ while (my $transfer = shift @args) { - my ($trans_id) = selectrow_query($::form, $::form->get_standard_dbh, qq|SELECT nextval('id')|); + my $trans_id; + ($trans_id) = selectrow_query($::form, $::form->get_standard_dbh, qq|SELECT nextval('id')|) if $transfer->{qty}; my $part = $objectify->($transfer, 'parts', 'SL::DB::Part'); my $unit = $objectify->($transfer, 'unit', 'SL::DB::Unit', name => $transfer->{unit}); @@ -98,13 +99,21 @@ sub transfer { $direction |= 1 if $src_bin; $direction |= 2 if $dst_bin; - my $transfer_type = $objectify->($transfer, 'transfer_type', 'SL::DB::TransferType', direction => $directions[$direction], - description => $transfer->{transfer_type}); + my $transfer_type_id; + if ($transfer->{transfer_type_id}) { + $transfer_type_id = $transfer->{transfer_type_id}; + } else { + my $transfer_type = $objectify->($transfer, 'transfer_type', 'SL::DB::TransferType', direction => $directions[$direction], + description => $transfer->{transfer_type}); + $transfer_type_id = $transfer_type->id; + } + + my $stocktaking_qty = $transfer->{stocktaking_qty}; my %params = ( part => $part, employee => $employee, - trans_type => $transfer_type, + trans_type_id => $transfer_type_id, project => $project, trans_id => $trans_id, shippingdate => !$transfer->{shippingdate} || $transfer->{shippingdate} eq 'current_date' @@ -113,13 +122,15 @@ sub transfer { ); if ($unit) { - $qty = $unit->convert_to($qty, $part->unit_obj); + $qty = $unit->convert_to($qty, $part->unit_obj); + $stocktaking_qty = $unit->convert_to($stocktaking_qty, $part->unit_obj); } $params{chargenumber} ||= ''; - if ($direction & 1) { - SL::DB::Inventory->new( + my @inventories; + if ($qty && $direction & 1) { + push @inventories, SL::DB::Inventory->new( %params, warehouse => $src_wh, bin => $src_bin, @@ -127,8 +138,8 @@ sub transfer { )->save; } - if ($direction & 2) { - SL::DB::Inventory->new( + if ($qty && $direction & 2) { + push @inventories, SL::DB::Inventory->new( %params, warehouse => $dst_wh->id, bin => $dst_bin->id, @@ -140,6 +151,30 @@ sub transfer { } } + # Record stocktaking if requested. + # This is only possible if transfer was a stock in or stock out, + # but not both (transfer). + if ($transfer->{record_stocktaking}) { + die 'Stocktaking can only be recorded for stock in or stock out, but not on a transfer.' if scalar @inventories > 1; + + my $inventory_id; + $inventory_id = $inventories[0]->id if $inventories[0]; + + SL::DB::Stocktaking->new( + inventory_id => $inventory_id, + warehouse => $src_wh || $dst_wh, + bin => $src_bin || $dst_bin, + parts_id => $part->id, + employee_id => $employee->id, + qty => $stocktaking_qty, + comment => $transfer->{comment}, + cutoff_date => $transfer->{stocktaking_cutoff_date}, + chargenumber => $transfer->{chargenumber}, + bestbefore => $transfer->{bestbefore}, + )->save; + + } + push @trans_ids, $trans_id; } @@ -312,9 +347,7 @@ sub transfer_assembly { } # gibt die Fehlermeldung zurück. A.) Keine Teile definiert # B.) Artikel und Anzahl der fehlenden Teile/Dienstleistungen - if ($kannNichtFertigen) { - return 0; - } + die "

" . $kannNichtFertigen if ($kannNichtFertigen); # soweit alles gut. Jetzt noch die wirkliche Lagerbewegung für das Erzeugnis ausführen ... my $transferAssemblySQL = qq|INSERT INTO inventory (parts_id, warehouse_id, bin_id, chargenumber, bestbefore, @@ -438,6 +471,7 @@ sub get_warehouse_journal { 'trans_type' => ['trans_type'], 'employee' => ['employee'], 'projectnumber' => ['projectnumber'], + 'chargenumber' => ['chargenumber'], ); $sort_order = $filter{order} unless $sort_order; @@ -552,27 +586,22 @@ sub get_warehouse_journal { GROUP BY $group_clause ORDER BY r_${sort_spec}) AS lines WHERE r_qty>0|; - $query .= " LIMIT $filter{limit}" if $filter{limit} ; - $query .= " OFFSET $filter{offset}" if $filter{offset} ; + my @all_vars = (@filter_vars,@filter_vars,@filter_vars); + + if ($filter{limit}) { + $query .= " LIMIT ?"; + push @all_vars,$filter{limit}; + } + if ($filter{offset}) { + $query .= " OFFSET ?"; + push @all_vars, $filter{offset}; + } - my $sth = prepare_execute_query($form, $dbh, $query, @filter_vars, @filter_vars, @filter_vars); + my $sth = prepare_execute_query($form, $dbh, $query, @all_vars); my ($h_oe_id, $q_oe_id); if ($form->{l_oe_id}) { $q_oe_id = <{oe_id} || $ref->{invoice_id})) { - my $id = $ref->{oe_id} ? $ref->{oe_id} : $ref->{invoice_id}; - do_statement($form, $h_oe_id, $q_oe_id, ($id) x 6); + do_statement($form, $h_oe_id, $q_oe_id, $ref->{oe_id}, ($ref->{invoice_id}) x 2); $ref->{oe_id_info} = $h_oe_id->fetchrow_hashref() || {}; } @@ -791,8 +807,9 @@ sub get_warehouse_report { "chargeid" => "c.id", "warehousedescription" => "w.description", "partunit" => "p.unit", - "stock_value" => "p.lastcost / COALESCE(pfac.factor, 1)", + "stock_value" => ($form->{stock_value_basis} // '') eq 'list_price' ? "p.listprice / COALESCE(pfac.factor, 1)" : "p.lastcost / COALESCE(pfac.factor, 1)", "purchase_price" => "p.lastcost", + "list_price" => "p.listprice", ); $form->{l_classification_id} = 'Y'; $form->{l_part_type} = 'Y'; @@ -824,10 +841,15 @@ sub get_warehouse_report { GROUP BY $group_clause ORDER BY $sort_spec ) AS lines WHERE qty<>0|; - $query .= " LIMIT $filter{limit}" if $filter{limit} ; - $query .= " OFFSET $filter{offset}" if $filter{offset} ; - - my $sth = prepare_execute_query($form, $dbh, $query, @filter_vars); + if ($filter{limit}) { + $query .= " LIMIT ?"; + push @filter_vars,$filter{limit}; + } + if ($filter{offset}) { + $query .= " OFFSET ?"; + push @filter_vars, $filter{offset}; + } + my $sth = prepare_execute_query($form, $dbh, $query, @filter_vars ); my (%non_empty_bins, @all_fields, @contents); @@ -1147,6 +1169,13 @@ transfer accepts more than one transaction parameter, each being a hash ref. If more than one is supplied, it is guaranteed, that all are processed in the same transaction. +It is possible to record stocktakings within this transaction as well. +This is useful if the transfer is the result of stocktaking (see also +C). To do so the parameters C, +C and C hava to be given. +If stocktaking should be saved, then the transfer quantity can be zero. In this +case no entry in inventory will be made, but only the stocktaking entry. + Here is a full list of parameters. All "_id" parameters except oe and orderitems can be called without id with RDB objects as well. @@ -1213,6 +1242,18 @@ An optional comment. An expiration date. Note that this is not by default used by C. +=item record_stocktaking + +A boolean flag to indicate that a stocktaking entry should be saved. + +=item stocktaking_qty + +The quantity for the stocktaking entry. + +=item stocktaking_cutoff_date + +The cutoff date for the stocktaking entry. + =back =head2 create_assembly \%PARAMS, [ \%PARAMS, ... ] @@ -1294,7 +1335,7 @@ as the specific reason. The method is transaction safe, in case of errors not a single entry will be made in inventory. -Two prerequisites can be changed with this global parameters +Two prerequisites can be changed with these global parameters =over 2