use SL::IC;
use SL::WH;
use SL::OE;
-# use SL::Helper::Inventory qw(produce_assembly);
+use SL::Helper::Inventory qw(produce_assembly);
use SL::Locale::String qw(t8);
use SL::ReportGenerator;
use SL::Presenter::Tag qw(checkbox_tag);
use SL::Presenter::Part;
-use SL::DB::AssemblyInventoryPart;
use SL::DB::Part;
use Data::Dumper;
my $all_units = AM->retrieve_units(\%myconfig, $form);
foreach (@contents) {
- $_->{qty} = $form->format_amount_units('amount' => $_->{qty},
- 'part_unit' => $_->{partunit},
- 'conv_units' => 'convertible');
+ $_->{qty} = $form->format_amount(\%myconfig, $_->{qty}) . ' ' . $_->{partunit};
+
my $this_unit = $_->{partunit};
if ($all_units->{$_->{partunit}} && ($all_units->{g}->{base_unit} eq $all_units->{$_->{partunit}}->{base_unit})) {
$main::lxdebug->leave_sub();
}
-# vorüberlegung jb 22.2.2009
-# wir benötigen für diese funktion, die anzahl die vom erzeugnis hergestellt werden soll. vielleicht direkt per js fehleingaben verhindern?
-# ferner dann nochmal mit check_asssembly_max_create gegenprüfen und dann transaktionssicher wegbuchen.
-# wir brauchen eine hilfsfunktion, die nee. brauchen wir nicht. der algorithmus läuft genau wie bei check max_create, nur dass hier auch eine lagerbewegung (verbraucht) stattfindet
-# Manko ist derzeit noch, dass unterschiedliche Lagerplätze, bzw. das Quelllager an sich nicht ausgewählt werden können.
-# Laut Absprache in KW11 09 übernimmt mb hier den rest im April ... jb 18.3.09
-
sub create_assembly {
$main::lxdebug->enter_sub();
if ($form->{qty} <= 0) {
$form->show_generic_error($locale->text('Invalid quantity.'));
}
- # TODO Es wäre schön, hier schon die maximale Anzahl der zu fertigenden Erzeugnisse zu haben
- #else { if ($form->{qty} > $maxcreate) { #s.o.
- # $form->show_generic_error($locale->text('Can not create that quantity with current stock'));
- # $form->show_generic_error('Maximale Stückzahl' . $maxcreate);
- # }
- # }
-
if (!$form->{warehouse_id} || !$form->{bin_id}) {
$form->error($locale->text('The warehouse or the bin is missing.'));
}
+ # need part and bin object
+ my ($bin, $assembly);
+ $assembly = SL::DB::Manager::Part->find_by(id => $form->{parts_id}, part_type => 'assembly');
+ $form->show_generic_error($locale->text('Invalid assembly')) unless ref $assembly eq 'SL::DB::Part';
+
+ $bin = SL::DB::Manager::Bin->find_by(id => $form->{bin_id});
+ $form->show_generic_error($locale->text('Invalid bin')) unless ref $bin eq 'SL::DB::Bin';
if (!$::instance_conf->get_show_bestbefore) {
- $form->{bestbefore} = '';
+ $form->{bestbefore} = '';
}
- # WIESO war das nicht vorher schon ein %HASH?? ein hash ist ein hash! das hat mich mehr als eine Stunde gekostet herauszufinden. grr. jb 3.3.2009
- # Anm. jb 18.3. vielleicht auch nur meine unwissenheit in perl-datenstrukturen
- my %TRANSFER = (
- 'transfer_type' => 'assembly',
- 'login' => $::myconfig{login},
- 'dst_warehouse_id' => $form->{warehouse_id},
- 'dst_bin_id' => $form->{bin_id},
- 'chargenumber' => $form->{chargenumber},
- 'bestbefore' => $form->{bestbefore},
- 'assembly_id' => $form->{parts_id},
- 'qty' => $form->{qty},
- 'unit' => $form->{unit},
- 'comment' => $form->{comment}
+ produce_assembly(
+ part => $assembly, # target assembly
+ qty => $form->{qty}, # qty
+ auto_allocate => 1,
+ bin => $bin, # needed unless a global standard target is configured
+ chargenumber => $form->{chargenumber}, # optional
+ bestbefore => $form->{bestbefore},
+ comment => $form->{comment}, # optional
);
- my $ret = WH->transfer_assembly (%TRANSFER);
- # Frage: Ich pack in den return-wert auch gleich die Fehlermeldung. Irgendwelche Nummern als Fehlerkonstanten definieren find ich auch nicht besonders schick...
- # Ideen? jb 18.3.09
- if ($ret ne "1"){
- # Die locale-Funktion kann keine Double-Quotes escapen, deswegen hier erstmal so (ein wahrscheinlich immerwährender Hotfix) s.a. Frage davor jb 25.4.09
- $form->show_generic_error($ret);
- }
-
delete @{$form}{qw(parts_id partnumber description qty unit chargenumber bestbefore comment)};
$form->{saved_message} = $locale->text('The assembly has been created.');
croak("No assembly ids") unless scalar @{ $form->{ids}} > 0;
- # fail safe, only allow disassemble in certain intervals
- my $undo_date = DateTime->today->subtract(days => $::instance_conf->get_undo_transfer_interval);
-
- foreach my $assembly_id (@{ $::form->{ids}} ) {
- my $assembly_parts;
- $assembly_parts = SL::DB::Manager::AssemblyInventoryPart->get_all(where => [ inventory_assembly_id => $assembly_id ]);
- $form->show_generic_error(t8('No relations found for #1', $assembly_id)) unless $assembly_parts;
- # check first entry for insertdate
- # everything in one transaction
- my $db = SL::DB::Inventory->new->db;
- $db->with_transaction(sub {
- my ($assembly_entry, $part_entry);
- foreach my $assembly_part (@{ $assembly_parts }) {
- die("No valid entry found") unless (ref($assembly_part) eq 'SL::DB::AssemblyInventoryPart');
- # fail safe undo date
- die("Invalid time interval") unless DateTime->compare($assembly_part->itime, $undo_date);
-
- $assembly_entry //= $assembly_part->assembly;
- $part_entry = $assembly_part->part;
- $assembly_part->delete;
- $part_entry->delete;
- }
- flash_later('info', t8("Disassembly successful for #1", $assembly_entry->part->partnumber));
-
- $assembly_entry->delete;
+ # everything in one transaction
+ my $db = SL::DB::Inventory->new->db;
+ $db->with_transaction(sub {
- 1;
+ foreach my $trans_id (@{ $::form->{ids}} ) {
+ SL::DB::Manager::Inventory->delete_all(where => [ trans_id => $trans_id ]);
+ flash_later('info', t8("Disassembly successful for trans_id #1", $trans_id));
+ }
- }) || die t8('error while disassembling assembly #1 : #2', $assembly_id) . $db->error . "\n";
+ 1;
+ }) || die t8('error while disassembling for trans_ids #1 : #2', $form->{ids}) . $db->error . "\n";
- }
$main::lxdebug->leave_sub();
$form->redirect;
}
show_no_warehouses_error() if (!scalar @{ $form->{WAREHOUSES} });
+ my $cvar_configs = CVar->get_configs('module' => 'IC');
+ ($form->{CUSTOM_VARIABLES_FILTER_CODE},
+ $form->{CUSTOM_VARIABLES_INCLUSION_CODE}) = CVar->render_search_options('variables' => $cvar_configs,
+ 'include_prefix' => 'l_',
+ 'include_value' => 'Y');
+
setup_wh_journal_action_bar();
$form->header();
$last_nr = $pages->{per_page};
}
+ my $old_l_trans_id = $form->{l_trans_id};
my @contents = WH->get_warehouse_journal(%filter);
+ $form->{l_trans_id} = $old_l_trans_id;
+
# get maxcount
if (!$form->{maxrows}) {
$form->{maxrows} = scalar @contents ;
my $report = SL::ReportGenerator->new(\%myconfig, $form);
+ my $cvar_configs = CVar->get_configs('module' => 'IC');
+ my @includeable_custom_variables = grep { $_->{includeable} } @{ $cvar_configs };
+ my @searchable_custom_variables = grep { $_->{searchable} } @{ $cvar_configs };
+ push @columns, map { "cvar_$_->{name}" } @includeable_custom_variables;
+
my @hidden_variables = map { "l_${_}" } @columns;
push @hidden_variables, qw(warehouse_id bin_id partnumber description chargenumber bestbefore qty_op qty qty_unit unit partunit fromdate todate transtype_ids comment projectnumber);
push @hidden_variables, qw(classification_id);
+ push @hidden_variables, map({'cvar_'. $_->{name}} @searchable_custom_variables);
+ push @hidden_variables, map({'cvar_'. $_->{name} .'_from'} grep({$_->{type} eq 'date'} @searchable_custom_variables));
+ push @hidden_variables, map({'cvar_'. $_->{name} .'_to'} grep({$_->{type} eq 'date'} @searchable_custom_variables));
+ push @hidden_variables, map({'cvar_'. $_->{name} .'_qtyop'} grep({$_->{type} eq 'number'} @searchable_custom_variables));
my %column_defs = (
'ids' => { raw_header_data => checkbox_tag("", id => "check_all", checkall => "[data-checkall=1]") },
'oe_id' => { 'text' => $locale->text('Document'), },
);
+ my %column_defs_cvars = map { +"cvar_$_->{name}" => { 'text' => $_->{description} } } @includeable_custom_variables;
+ %column_defs = (%column_defs, %column_defs_cvars);
+
if ($form->{transtype_ids} && 'ARRAY' eq ref $form->{transtype_ids}) {
for (my $i = 0; $i < scalar(@{ $form->{transtype_ids} }); $i++) {
delete $form->{transtype_ids}[$i] if $form->{transtype_ids}[$i] eq '';
my $href = build_std_url('action=generate_journal', grep { $form->{$_} } @hidden_variables);
$href .= "&maxrows=".$form->{maxrows};
- map { $column_defs{$_}->{link} = $href ."&page=".$page. "&sort=${_}&order=" . Q($_ eq $form->{sort} ? 1 - $form->{order} : $form->{order}) } @columns;
+ map { $column_defs{$_}->{link} = $href ."&page=".$page. "&sort=${_}&order=" . Q($_ eq $form->{sort} ? 1 - $form->{order} : $form->{order}) } grep {!/^cvar/} @columns;
my %column_alignment = map { $_ => 'right' } qw(qty);
my $all_units = AM->retrieve_units(\%myconfig, $form);
+ CVar->add_custom_variables_to_report('module' => 'IC',
+ 'trans_id_field' => 'parts_id',
+ 'configs' => $cvar_configs,
+ 'column_defs' => \%column_defs,
+ 'data' => \@contents);
+
+
my %doc_types = ( 'sales_quotation' => { script => 'oe', title => $locale->text('Sales quotation') },
'sales_order' => { script => 'oe', title => $locale->text('Sales Order') },
'request_quotation' => { script => 'oe', title => $locale->text('Request quotation') },
);
my $idx = 0;
-
+ my $undo_date = DateTime->today->subtract(days => $::instance_conf->get_undo_transfer_interval);
foreach my $entry (@contents) {
$entry->{type_and_classific} = SL::Presenter::Part::type_abbreviation($entry->{part_type}) .
SL::Presenter::Part::classification_abbreviation($entry->{classification_id});
};
}
- $row->{ids}->{raw_data} = checkbox_tag("ids[]", value => $entry->{id}, "data-checkall" => 1) if $entry->{assembled};
-
+ if ($entry->{assembled}) {
+ my $insertdate = DateTime->from_kivitendo($entry->{shippingdate});
+ if (ref $undo_date eq 'DateTime' && ref $insertdate eq 'DateTime' && $insertdate > $undo_date) {
+ $row->{ids}->{raw_data} = checkbox_tag("ids[]", value => $entry->{trans_id}, "data-checkall" => 1);
+ }
+ }
$row->{trans_type}->{raw_data} = $entry->{trans_type};
if ($form->{l_oe_id}) {
$row->{oe_id}->{data} = '';
my $locale = $main::locale;
$form->get_lists('warehouses' => { 'key' => 'WAREHOUSES',
- 'bins' => 'BINS', });
+ 'bins' => 'BINS', },
+ 'partsgroup' => 'PARTSGROUPS');
show_no_warehouses_error() if (!scalar @{ $form->{WAREHOUSES} });
- my $CVAR_CONFIGS = SL::DB::Manager::CustomVariableConfig->get_all_sorted(where => [ module => 'IC' ]);
- my $INCLUDABLE_CVAR_CONFIGS = [ grep { $_->includeable } @{ $CVAR_CONFIGS } ];
+ my $cvar_configs = CVar->get_configs('module' => 'IC');
+ ($form->{CUSTOM_VARIABLES_FILTER_CODE},
+ $form->{CUSTOM_VARIABLES_INCLUSION_CODE}) = CVar->render_search_options('variables' => $cvar_configs,
+ 'include_prefix' => 'l_',
+ 'include_value' => 'Y');
$form->{title} = $locale->text("Report about warehouse contents");
$form->header();
print $form->parse_html_template("wh/report_filter",
- { "WAREHOUSES" => $form->{WAREHOUSES},
- "UNITS" => AM->unit_select_data(AM->retrieve_units(\%myconfig, $form)),
- # "CVAR_CONFIGS" => $CVAR_CONFIGS, # nyi searchable cvars
- "INCLUDABLE_CVAR_CONFIGS" => $INCLUDABLE_CVAR_CONFIGS,
+ { "WAREHOUSES" => $form->{WAREHOUSES},
+ "PARTSGROUPS" => $form->{PARTSGROUPS},
+ "UNITS" => AM->unit_select_data(AM->retrieve_units(\%myconfig, $form)),
});
$main::lxdebug->leave_sub();
my %myconfig = %main::myconfig;
my $locale = $main::locale;
- my $cvar_configs = CVar->get_configs('module' => 'IC');
-
$form->{title} = $locale->text("Report about warehouse contents");
$form->{sort} ||= 'partnumber';
my $sort_col = $form->{sort};
my @columns = qw(warehousedescription bindescription partnumber type_and_classific partdescription chargenumber bestbefore comment qty partunit list_price purchase_price stock_value);
# filter stuff
- map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id classification_id partnumber description chargenumber bestbefore date include_invalid_warehouses);
+ map { $filter{$_} = $form->{$_} if ($form->{$_}) } qw(warehouse_id bin_id classification_id partnumber description partsgroup_id chargenumber bestbefore date include_invalid_warehouses);
# show filter stuff also in report
my @options;
classification_id => sub { push @options, $locale->text('Parts Classification'). " : ".
SL::DB::Manager::PartClassification->get_first(where => [ id => $form->{classification_id} ] )->description; },
description => sub { push @options, $locale->text('Description') . " : $form->{description}"},
+ partsgroup_id => sub { push @options, $locale->text('Partsgroup') . " : " .
+ SL::DB::PartsGroup->new(id => $form->{partsgroup_id})->load->partsgroup},
chargenumber => sub { push @options, $locale->text('Charge Number') . " : $form->{chargenumber}"},
bestbefore => sub { push @options, $locale->text('Best Before') . " : $form->{bestbefore}"},
include_invalid_warehouses => sub { push @options, $locale->text('Include invalid warehouses ')},
my $report = SL::ReportGenerator->new(\%myconfig, $form);
+ my $cvar_configs = CVar->get_configs('module' => 'IC');
my @includeable_custom_variables = grep { $_->{includeable} } @{ $cvar_configs };
+ my @searchable_custom_variables = grep { $_->{searchable} } @{ $cvar_configs };
push @columns, map { "cvar_$_->{name}" } @includeable_custom_variables;
my @hidden_variables = map { "l_${_}" } @columns;
- push @hidden_variables, qw(warehouse_id bin_id partnumber partstypes_id description chargenumber bestbefore qty_op qty qty_unit partunit l_warehousedescription l_bindescription);
+ push @hidden_variables, qw(warehouse_id bin_id partnumber partstypes_id description partsgroup_id chargenumber bestbefore qty_op qty qty_unit partunit l_warehousedescription l_bindescription);
push @hidden_variables, qw(include_empty_bins subtotal include_invalid_warehouses date);
push @hidden_variables, qw(classification_id stock_value_basis allrows);
+ push @hidden_variables, map({'cvar_'. $_->{name}} @searchable_custom_variables);
+ push @hidden_variables, map({'cvar_'. $_->{name} .'_from'} grep({$_->{type} eq 'date'} @searchable_custom_variables));
+ push @hidden_variables, map({'cvar_'. $_->{name} .'_to'} grep({$_->{type} eq 'date'} @searchable_custom_variables));
+ push @hidden_variables, map({'cvar_'. $_->{name} .'_qtyop'} grep({$_->{type} eq 'number'} @searchable_custom_variables));
my %column_defs = (
'warehousedescription' => { 'text' => $locale->text('Warehouse'), },
'list_price' => { 'text' => $locale->text('List Price'), },
);
+ my %column_defs_cvars = map { +"cvar_$_->{name}" => { 'text' => $_->{description} } } @includeable_custom_variables;
+ %column_defs = (%column_defs, %column_defs_cvars);
+
my $href = build_std_url('action=generate_report', grep { $form->{$_} } @hidden_variables);
$href .= "&maxrows=".$form->{maxrows};
- my %column_defs_cvars = map { +"cvar_$_->{name}" => { 'text' => $_->{description} } } @includeable_custom_variables;
- %column_defs = (%column_defs, %column_defs_cvars);
- map { $column_defs{$_}->{link} = $href . "&page=".$page."&sort=${_}&order=" . Q($_ eq $sort_col ? 1 - $form->{order} : $form->{order}) } @columns;
+ map { $column_defs{$_}->{link} = $href . "&page=".$page."&sort=${_}&order=" . Q($_ eq $sort_col ? 1 - $form->{order} : $form->{order}) } grep {!/^cvar_/} @columns;
my %column_alignment = map { $_ => 'right' } qw(qty list_price purchase_price stock_value);
map { $subtotals{$_} += $entry->{$_} } @subtotals_columns;
$total_stock_value += $entry->{stock_value} * 1;
$entry->{qty} = $form->format_amount(\%myconfig, $entry->{qty});
-# $entry->{qty} = $form->format_amount_units('amount' => $entry->{qty},
-# 'part_unit' => $entry->{partunit},
-# 'conv_units' => 'convertible');
$entry->{stock_value} = $form->format_amount(\%myconfig, $entry->{stock_value} * 1, 2);
$entry->{purchase_price} = $form->format_amount(\%myconfig, $entry->{purchase_price} * 1, 2);
$entry->{list_price} = $form->format_amount(\%myconfig, $entry->{list_price} * 1, 2);
my $row = { map { $_ => { 'data' => '', 'class' => 'listsubtotal', 'align' => $column_alignment{$_}, } } @columns };
$row->{qty}->{data} = $form->format_amount(\%myconfig, $subtotals{qty});
-# $row->{qty}->{data} = $form->format_amount_units('amount' => $subtotals{qty} * 1,
-# 'part_unit' => $entry->{partunit},
-# 'conv_units' => 'convertible');
$row->{stock_value}->{data} = $form->format_amount(\%myconfig, $subtotals{stock_value} * 1, 2);
$row->{purchase_price}->{data} = $form->format_amount(\%myconfig, $subtotals{purchase_price} * 1, 2);
$row->{list_price}->{data} = $form->format_amount(\%myconfig, $subtotals{list_price} * 1, 2);