11 |
11 |
use SL::Controller::Helper::GetModels;
|
12 |
12 |
use SL::Locale::String qw(t8);
|
13 |
13 |
use SL::JSON;
|
|
14 |
use File::Temp;
|
14 |
15 |
use List::Util qw(sum);
|
15 |
16 |
use List::UtilsBy qw(extract_by);
|
16 |
17 |
use SL::Helper::Flash;
|
17 |
18 |
use Data::Dumper;
|
18 |
19 |
use DateTime;
|
|
20 |
use POSIX qw(strftime);
|
19 |
21 |
use SL::DB::History;
|
20 |
22 |
use SL::DB::Helper::ValidateAssembly qw(validate_assembly);
|
21 |
23 |
use SL::CVar;
|
22 |
24 |
use SL::MoreCommon qw(save_form);
|
23 |
25 |
use Carp;
|
24 |
26 |
use SL::Presenter::EscapedText qw(escape is_escaped);
|
|
27 |
use SL::Presenter::Part;
|
25 |
28 |
use SL::Presenter::Tag qw(select_tag);
|
|
29 |
use Text::CSV_XS;
|
26 |
30 |
|
27 |
31 |
use Rose::Object::MakeMethods::Generic (
|
28 |
32 |
'scalar --get_set_init' => [ qw(parts models part p warehouses multi_items_models
|
... | ... | |
688 |
692 |
}
|
689 |
693 |
}
|
690 |
694 |
|
|
695 |
sub action_export_assembly_components {
|
|
696 |
my ($self) = @_;
|
|
697 |
|
|
698 |
my @rows = ([
|
|
699 |
$::locale->text('Partnumber'),
|
|
700 |
$::locale->text('Description'),
|
|
701 |
$::locale->text('Type'),
|
|
702 |
$::locale->text('Classification'),
|
|
703 |
$::locale->text('Qty'),
|
|
704 |
$::locale->text('Unit'),
|
|
705 |
$::locale->text('BOM'),
|
|
706 |
$::locale->text('Line Total'),
|
|
707 |
$::locale->text('Sellprice'),
|
|
708 |
$::locale->text('Lastcost'),
|
|
709 |
$::locale->text('Partsgroup'),
|
|
710 |
]);
|
|
711 |
|
|
712 |
foreach my $item (@{ $self->part->items }) {
|
|
713 |
my $part = $item->part;
|
|
714 |
|
|
715 |
my @row = (
|
|
716 |
$part->partnumber,
|
|
717 |
$part->description,
|
|
718 |
SL::Presenter::Part::type_abbreviation($part->part_type),
|
|
719 |
SL::Presenter::Part::classification_abbreviation($part->classification_id),
|
|
720 |
$item->qty_as_number,
|
|
721 |
$part->unit,
|
|
722 |
$item->bom ? $::locale->text('yes') : $::locale->text('no'),
|
|
723 |
$::form->format_amount(\%::myconfig, $item->linetotal_sellprice, 3, 0),
|
|
724 |
$part->sellprice_as_number,
|
|
725 |
$part->lastcost_as_number,
|
|
726 |
$part->partsgroup ? $part->partsgroup->partsgroup : '',
|
|
727 |
);
|
|
728 |
|
|
729 |
push @rows, \@row;
|
|
730 |
}
|
|
731 |
|
|
732 |
my $csv = Text::CSV_XS->new({
|
|
733 |
sep_char => ';',
|
|
734 |
eol => "\n",
|
|
735 |
binary => 1,
|
|
736 |
});
|
|
737 |
|
|
738 |
my ($file_handle, $file_name) = File::Temp::tempfile;
|
|
739 |
|
|
740 |
binmode $file_handle, ":encoding(utf8)";
|
|
741 |
|
|
742 |
$csv->print($file_handle, $_) for @rows;
|
|
743 |
|
|
744 |
$file_handle->close;
|
|
745 |
|
|
746 |
my $timestamp = strftime('_%Y-%m-%d_%H-%M-%S', localtime());
|
|
747 |
my $part_number = $self->part->partnumber;
|
|
748 |
$part_number =~ s{[^[:word:]]+}{_}g;
|
|
749 |
my $attachment_name = sprintf('assembly_components_%s_%s.csv', $part_number, $timestamp);
|
|
750 |
|
|
751 |
$self->send_file(
|
|
752 |
$file_name,
|
|
753 |
content_type => 'text/csv',
|
|
754 |
name => $attachment_name,
|
|
755 |
);
|
|
756 |
|
|
757 |
}
|
|
758 |
|
691 |
759 |
# helper functions
|
692 |
760 |
sub validate_add_items {
|
693 |
761 |
scalar @{$::form->{add_items}};
|
... | ... | |
1394 |
1462 |
],
|
1395 |
1463 |
],
|
1396 |
1464 |
|
|
1465 |
combobox => [
|
|
1466 |
action => [
|
|
1467 |
t8('Export'),
|
|
1468 |
only_if => $self->part->is_assembly,
|
|
1469 |
],
|
|
1470 |
action => [
|
|
1471 |
t8('Assembly items'),
|
|
1472 |
submit => [ '#ic', { action => "Part/export_assembly_components" } ],
|
|
1473 |
checks => ['kivi.validate_form'],
|
|
1474 |
disabled => !$self->part->id ? t8('The object has not been saved yet.')
|
|
1475 |
: !$may_edit ? t8('You do not have the permissions to access this function.')
|
|
1476 |
: !$::auth->assert('purchase_order_edit', 'may fail') ? t8('You do not have the permissions to access this function.')
|
|
1477 |
: undef,
|
|
1478 |
only_if => $self->part->is_assembly,
|
|
1479 |
],
|
|
1480 |
],
|
|
1481 |
|
1397 |
1482 |
action => [
|
1398 |
1483 |
t8('Abort'),
|
1399 |
1484 |
submit => [ '#ic', { action => "Part/abort" } ],
|
Erzeugnisstammdaten: Exportmöglichkeit für Bestandteilliste als CSV