1 package SL::Controller::DownloadZip;
 
   5 use parent qw(SL::Controller::Base);
 
   7 use List::Util qw(first max);
 
  10 use Encode qw(decode encode);
 
  13 use SL::SessionFile::Random;
 
  15 sub action_download_orderitems_files {
 
  19   # special case for customer which want to have not all
 
  20   # in kivitendo.conf some regex may be defined:
 
  21   # For no values just let it commented out
 
  22   # PA = Produktionsauftrag, L = Lieferschein, ML = Materialliste
 
  23   # If you want several options, please separate the letter with '|'. Example: '^(PA|L).*'
 
  24   #set_sales_documenttype_for_delivered_quantity = '^(LS).*'
 
  25   #set_purchase_documenttype_for_delivered_quantity = '^(EL).*'
 
  27   # enbale this perl code:
 
  28   #  my $doctype = $::lx_office_conf{system}->{"set_documenttype_for_part_zip_download"};
 
  30   #    # eliminate first and last char (are quotes)
 
  35   #$Archive::Zip::UNICODE = 1;
 
  37   my $object_id    = $::form->{object_id};
 
  38   my $object_type  = $::form->{object_type};
 
  39   my $element_type = $::form->{element_type};
 
  40   my $sfile = SL::SessionFile::Random->new(mode => "w");
 
  41   my $zip = Archive::Zip->new();
 
  42   #TODO Check client encoding !!
 
  43   #my $name_encoding = 'cp850';
 
  44   my $name_encoding = 'UTF-8';
 
  46   # today only sales_order implementation !
 
  47   if ( $object_id && $object_type eq 'sales_order' && $element_type eq 'part' ) {
 
  48     my $orderitems = SL::DB::Manager::OrderItem->get_all(query => ['order.id' => $object_id ],
 
  49                                                          with_objects => [ 'order', 'part' ],
 
  50                                                          sort_by => 'part.partnumber ASC');
 
  52     foreach my $item ( @{$orderitems} ) {
 
  53       next if $part_id == $item->parts_id;
 
  55       my @files = SL::File->get_all(object_id   => $item->parts_id,
 
  56                                     object_type => $element_type,
 
  59       ## also for filtering if needed:
 
  61       #   @wanted_files = grep { $_->{file_name} =~ /$doctype/ } @files;
 
  63       @wanted_files = @files;
 
  65       if ( scalar (@wanted_files) > 0 ) {
 
  66         $zip->addDirectory($item->part->partnumber);
 
  67         $zip->addFile($_->get_file,
 
  68                       Encode::encode($name_encoding,$item->part->partnumber.'/'.$_->{file_name})
 
  73   unless ( $zip->writeToFileNamed($sfile->file_name) == Archive::Zip::AZ_OK ) {
 
  74     die 'zipfile write error';
 
  78   return $self->send_file(
 
  80     type => 'application/zip',
 
  81     name => $::form->{zipname}.'.zip',
 
  95 SL::Controller::DownloadZip - controller for download all files from parts of an order in one zip file
 
  97 =head2  C<action_download_zip FORMPARAMS>
 
  99 Some customer want all attached files for the parts of an sales order or sales delivery order in one zip to download.
 
 100 This is a special method for one customer, so it is moved into an extra controller.
 
 101 The $Archive::Zip::UNICODE = 1; doesnt work ok
 
 102 So today the filenames in cp850/DOS format for legacy windows.
 
 103 To ues it for Linux Clients an additinal effort must be done,
 
 104 for ex. a link to the same file with an utf-8 name.
 
 106 There is also a special javascript method necessary which calles this controller method.
 
 107 THis method must be inserted into the customer branch:
 
 111   ns.downloadOrderitemsAtt = function(type,id) {
 
 112     var rowcount  = $('input[name=rowcount]').val() - 1;
 
 114         action:     'FileManagement/download_zip',
 
 119     if ( rowcount == 0 ) {
 
 120         kivi.display_flash('error', kivi.t8('No articles have been added yet.'));
 
 123     for (var i = 1; i <= rowcount; i++) {
 
 124         data['parts_id_'+i] =  $('#id_' + i).val();
 
 126     $.download("controller.pl", data);
 
 132 See also L<SL::Controller::FileManagement>
 
 136 Is this method needed in the master branch ?
 
 140 Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>