SL::File: get auch mit dbfile als Parameter aufrufen können
[kivitendo-erp.git] / SL / File.pm
index 231e062..ca065e0 100644 (file)
@@ -4,12 +4,13 @@ use strict;
 
 use parent qw(Rose::Object);
 
 
 use parent qw(Rose::Object);
 
-use Clone qw(clone);
 use SL::File::Backend;
 use SL::File::Object;
 use SL::DB::History;
 use SL::File::Backend;
 use SL::File::Object;
 use SL::DB::History;
+use SL::DB::ShopImage;
 use SL::DB::File;
 use SL::Helper::UserPreferences;
 use SL::DB::File;
 use SL::Helper::UserPreferences;
+use SL::Controller::Helper::ThumbnailCreator qw(file_probe_type);
 use SL::JSON;
 
 use constant RENAME_OK          => 0;
 use SL::JSON;
 
 use constant RENAME_OK          => 0;
@@ -20,11 +21,11 @@ use constant RENAME_NEW_VERSION => 4;
 
 sub get {
   my ($self, %params) = @_;
 
 sub get {
   my ($self, %params) = @_;
-  die 'no id' unless $params{id};
-  my $dbfile = SL::DB::Manager::File->get_first(query => [id => $params{id}]);
-  die 'not found' unless $dbfile;
-  $main::lxdebug->message(LXDebug->DEBUG2(), "object_id=".$dbfile->object_id." object_type=".$dbfile->object_type." dbfile=".$dbfile);
-  SL::File::Object->new(db_file => $dbfile, id => $dbfile->id, loaded => 1);
+  die "no id or dbfile" unless $params{id} || $params{dbfile};
+  $params{dbfile} = SL::DB::Manager::File->get_first(query => [id => $params{id}]) if !$params{dbfile};
+  die 'not found' unless $params{dbfile};
+  $main::lxdebug->message(LXDebug->DEBUG2(), "object_id=".$params{dbfile}->object_id." object_type=".$params{dbfile}->object_type." dbfile=".$params{dbfile});
+  SL::File::Object->new(db_file => $params{dbfile}, id => $params{dbfile}->id, loaded => 1);
 }
 
 sub get_version_count {
 }
 
 sub get_version_count {
@@ -47,10 +48,11 @@ sub get_all {
     object_id   => $params{object_id},
     object_type => $params{object_type}
   );
     object_id   => $params{object_id},
     object_type => $params{object_type}
   );
-  push @query, (file_name => $params{file_name}) if $params{file_name};
-  push @query, (file_type => $params{file_type}) if $params{file_type};
-  push @query, (mime_type => $params{mime_type}) if $params{mime_type};
-  push @query, (source    => $params{source})    if $params{source};
+  push @query, (file_name     => $params{file_name})     if $params{file_name};
+  push @query, (file_type     => $params{file_type})     if $params{file_type};
+  push @query, (mime_type     => $params{mime_type})     if $params{mime_type};
+  push @query, (source        => $params{source})        if $params{source};
+  push @query, (print_variant => $params{print_variant}) if $params{print_variant};
 
   my $sortby = $params{sort_by} || 'itime DESC,file_name ASC';
 
 
   my $sortby = $params{sort_by} || 'itime DESC,file_name ASC';
 
@@ -61,27 +63,28 @@ sub get_all {
 sub get_all_versions {
   my ($self, %params) = @_;
   my @versionobjs;
 sub get_all_versions {
   my ($self, %params) = @_;
   my @versionobjs;
-  my @fileobjs = $self->get_all(%params);
+  my @fileobjs;
   if ( $params{dbfile} ) {
   if ( $params{dbfile} ) {
-    push @fileobjs, SL::File::Object->new(dbfile => $params{db_file}, id => $params{dbfile}->id, loaded => 1);
+    push @fileobjs, SL::File::Object->new(db_file => $params{dbfile}, id => $params{dbfile}->id, loaded => 1);
   } else {
     @fileobjs = $self->get_all(%params);
   }
   foreach my $fileobj (@fileobjs) {
     $main::lxdebug->message(LXDebug->DEBUG2(), "obj=" . $fileobj . " id=" . $fileobj->id." versions=".$fileobj->version_count);
     my $maxversion = $fileobj->version_count;
   } else {
     @fileobjs = $self->get_all(%params);
   }
   foreach my $fileobj (@fileobjs) {
     $main::lxdebug->message(LXDebug->DEBUG2(), "obj=" . $fileobj . " id=" . $fileobj->id." versions=".$fileobj->version_count);
     my $maxversion = $fileobj->version_count;
+    $fileobj->version($maxversion);
     push @versionobjs, $fileobj;
     if ($maxversion > 1) {
       for my $version (2..$maxversion) {
         $main::lxdebug->message(LXDebug->DEBUG2(), "clone for version=".($maxversion-$version+1));
         eval {
     push @versionobjs, $fileobj;
     if ($maxversion > 1) {
       for my $version (2..$maxversion) {
         $main::lxdebug->message(LXDebug->DEBUG2(), "clone for version=".($maxversion-$version+1));
         eval {
-          my $clone = clone($fileobj);
+          my $clone = $fileobj->clone;
           $clone->version($maxversion-$version+1);
           $clone->newest(0);
           $main::lxdebug->message(LXDebug->DEBUG2(), "clone version=".$clone->version." mtime=". $clone->mtime);
           push @versionobjs, $clone;
           1;
           $clone->version($maxversion-$version+1);
           $clone->newest(0);
           $main::lxdebug->message(LXDebug->DEBUG2(), "clone version=".$clone->version." mtime=". $clone->mtime);
           push @versionobjs, $clone;
           1;
-        }
+        } or do {$::lxdebug->message(LXDebug::WARN(), "clone for version=".($maxversion-$version+1) . "failed: " . $@)};
       }
     }
   }
       }
     }
   }
@@ -96,10 +99,11 @@ sub get_all_count {
     object_id   => $params{object_id},
     object_type => $params{object_type}
   );
     object_id   => $params{object_id},
     object_type => $params{object_type}
   );
-  push @query, (file_name => $params{file_name}) if $params{file_name};
-  push @query, (file_type => $params{file_type}) if $params{file_type};
-  push @query, (mime_type => $params{mime_type}) if $params{mime_type};
-  push @query, (source    => $params{source})    if $params{source};
+  push @query, (file_name     => $params{file_name})     if $params{file_name};
+  push @query, (file_type     => $params{file_type})     if $params{file_type};
+  push @query, (mime_type     => $params{mime_type})     if $params{mime_type};
+  push @query, (source        => $params{source})        if $params{source};
+  push @query, (print_variant => $params{print_variant}) if $params{print_variant};
 
   my $cnt = SL::DB::Manager::File->get_all_count(query => [@query]);
   return $cnt;
 
   my $cnt = SL::DB::Manager::File->get_all_count(query => [@query]);
   return $cnt;
@@ -122,12 +126,12 @@ sub delete_all {
 
 sub delete {
   my ($self, %params) = @_;
 
 sub delete {
   my ($self, %params) = @_;
-  die "no id or dbfile" unless $params{id} || $params{dbfile};
-  my $rc = SL::DB->client->with_transaction(\&_delete, $self, %params);
-  if (!$rc) {
-    my $err = SL::DB->client->error;
-    die (ref $err?$$err:$err);
-  }
+  die "no id or dbfile in delete" unless $params{id} || $params{dbfile};
+  my $rc = 0;
+  eval {
+    $rc = SL::DB->client->with_transaction(\&_delete, $self, %params);
+    1;
+  } or do { die $@ };
   return $rc;
 }
 
   return $rc;
 }
 
@@ -149,7 +153,7 @@ sub _delete {
 
     if ($hist) {
       if (!$main::auth->assert('import_ar | import_ap', 1)) {
 
     if ($hist) {
       if (!$main::auth->assert('import_ar | import_ap', 1)) {
-        die \'no permission to unimport';
+        die 'no permission to unimport';
       }
       my $file = $backend->get_filepath(dbfile => $params{dbfile});
       $main::lxdebug->message(LXDebug->DEBUG2(), "del file=" . $file . " to=" . $hist->snumbers);
       }
       my $file = $backend->get_filepath(dbfile => $params{dbfile});
       $main::lxdebug->message(LXDebug->DEBUG2(), "del file=" . $file . " to=" . $hist->snumbers);
@@ -160,8 +164,8 @@ sub _delete {
   }
   if ($backend->delete(%params)) {
     my $do_delete = 0;
   }
   if ($backend->delete(%params)) {
     my $do_delete = 0;
-    if ( $params{last} || $params{all_but_notlast} ) {
-      if ( $backend->get_version_count > 0 ) {
+    if ( $params{last} || $params{version} || $params{all_but_notlast} ) {
+      if ( $backend->get_version_count(%params) > 0 ) {
         $params{dbfile}->mtime(DateTime->now_local);
         $params{dbfile}->save;
       } else {
         $params{dbfile}->mtime(DateTime->now_local);
         $params{dbfile}->save;
       } else {
@@ -179,11 +183,11 @@ sub _delete {
 sub save {
   my ($self, %params) = @_;
 
 sub save {
   my ($self, %params) = @_;
 
-  my $obj = SL::DB->client->with_transaction(\&_save, $self, %params);
-  if (!$obj) {
-    my $err = SL::DB->client->error;
-    die (ref $err?$$err:$err);
-  }
+  my $obj;
+  eval {
+    $obj = SL::DB->client->with_transaction(\&_save, $self, %params);
+    1;
+  } or do { die $@ };
   return $obj;
 }
 
   return $obj;
 }
 
@@ -194,11 +198,11 @@ sub _save {
 
   if ($params{id}) {
     $file = SL::DB::File->new(id => $params{id})->load;
 
   if ($params{id}) {
     $file = SL::DB::File->new(id => $params{id})->load;
-    die \'dbfile not exists'     unless $file;
+    die 'dbfile not exists'     unless $file;
   } elsif (!$file) {
   $main::lxdebug->message(LXDebug->DEBUG2(), "obj_id=" .$params{object_id});
   } elsif (!$file) {
   $main::lxdebug->message(LXDebug->DEBUG2(), "obj_id=" .$params{object_id});
-    die \'no object type set'    unless $params{object_type};
-    die \'no object id set'      unless defined($params{object_id});
+    die 'no object type set'    unless $params{object_type};
+    die 'no object id set'      unless defined($params{object_id});
 
     $exists = $self->get_all_count(%params);
     die 'filename still exist' if $exists && $params{fail_if_exists};
 
     $exists = $self->get_all_count(%params);
     die 'filename still exist' if $exists && $params{fail_if_exists};
@@ -216,7 +220,10 @@ sub _save {
         mime_type      => $params{mime_type},
         title          => $params{title},
         description    => $params{description},
         mime_type      => $params{mime_type},
         title          => $params{title},
         description    => $params{description},
+        print_variant  => $params{print_variant},
       );
       );
+      $file->itime($params{mtime})    if $params{mtime};
+      $params{itime} = $params{mtime} if $params{mtime};
     }
   } else {
     $exists = 1;
     }
   } else {
     $exists = 1;
@@ -233,13 +240,30 @@ sub _save {
     # load itime for new file
     $file->save->load;
   }
     # load itime for new file
     $file->save->load;
   }
-  $main::lxdebug->message(LXDebug->DEBUG2(), "backend3=" .$file->backend);
+
+  $file->mtime(DateTime->now_local) unless $params{mtime};
+  $file->mtime($params{mtime}     ) if     $params{mtime};
+
   my $backend = $self->_get_backend($file->backend);
   $params{dbfile} = $file;
   $backend->save(%params);
 
   my $backend = $self->_get_backend($file->backend);
   $params{dbfile} = $file;
   $backend->save(%params);
 
-  $file->mtime(DateTime->now_local);
   $file->save;
   $file->save;
+  #ShopImage
+  if($file->object_type eq "shop_image"){
+    my $image_content = $params{file_contents};
+    my $thumbnail = file_probe_type($image_content);
+    my $shopimage = SL::DB::ShopImage->new();
+    $shopimage->assign_attributes(
+                                  file_id                => $file->id,
+                                  thumbnail_content      => $thumbnail->{thumbnail_img_content},
+                                  org_file_height        => $thumbnail->{file_image_height},
+                                  org_file_width         => $thumbnail->{file_image_width},
+                                  thumbnail_content_type => $thumbnail->{thumbnail_img_content_type},
+                                  object_id              => $file->object_id,
+                                 );
+    $shopimage->save;
+  }
   if ($params{file_type} eq 'document' && $params{source} ne 'created') {
     SL::DB::History->new(
       addition    => 'IMPORT',
   if ($params{file_type} eq 'document' && $params{source} ne 'created') {
     SL::DB::History->new(
       addition    => 'IMPORT',
@@ -307,7 +331,7 @@ sub sync_from_backend {
   return unless $params{file_type};
   my $file = SL::DB::File->new;
   $file->file_type($params{file_type});
   return unless $params{file_type};
   my $file = SL::DB::File->new;
   $file->file_type($params{file_type});
-  my $backend = $self->_get_backend(dbfile => $file->backend);
+  my $backend = $self->_get_backend($self->_get_backend_by_file_type($file));
   return unless $backend;
   $backend->sync_from_backend(%params);
 }
   return unless $backend;
   $backend->sync_from_backend(%params);
 }
@@ -319,13 +343,18 @@ sub _get_backend {
   my ($self, $backend_name) = @_;
   my $class = 'SL::File::Backend::' . $backend_name;
   my $obj   = undef;
   my ($self, $backend_name) = @_;
   my $class = 'SL::File::Backend::' . $backend_name;
   my $obj   = undef;
+  die $::locale->text('no backend enabled') if $backend_name eq 'None';
   eval {
     eval "require $class";
     $obj = $class->new;
   eval {
     eval "require $class";
     $obj = $class->new;
-    die \'backend not enabled' unless $obj->enabled;
+    die $::locale->text('backend "#1" not enabled',$backend_name) unless $obj->enabled;
     1;
   } or do {
     1;
   } or do {
-    die \'backend class not found';
+    if ( $obj ) {
+      die $@;
+    } else {
+      die $::locale->text('backend "#1" not found',$backend_name);
+    }
   };
   return $obj;
 }
   };
   return $obj;
 }
@@ -356,13 +385,13 @@ SL::File - The intermediate Layer for handling files
 =head1 SYNOPSIS
 
   # In a controller or helper ( see SL::Controller::File or SL::Helper::File )
 =head1 SYNOPSIS
 
   # In a controller or helper ( see SL::Controller::File or SL::Helper::File )
-  # you can create, remove, delete etc. a file in a backend independant way
+  # you can create, remove, delete etc. a file in a backend independent way
 
   my $file  = SL::File->save(
                      object_id     => $self->object_id,
                      object_type   => $self->object_type,
                      mime_type     => 'application/pdf',
 
   my $file  = SL::File->save(
                      object_id     => $self->object_id,
                      object_type   => $self->object_type,
                      mime_type     => 'application/pdf',
-                     file_type     => 'documents',
+                     file_type     => 'document',
                      file_contents => 'this is no pdf');
 
   my $file1  = SL::File->get(id => $id);
                      file_contents => 'this is no pdf');
 
   my $file1  = SL::File->get(id => $id);
@@ -375,7 +404,7 @@ SL::File - The intermediate Layer for handling files
   SL::File->rename(id => $id,to => $newname);
   my $files1 = SL::File->get_all(object_id   => $object_id,
                                  object_type => $object_type,
   SL::File->rename(id => $id,to => $newname);
   my $files1 = SL::File->get_all(object_id   => $object_id,
                                  object_type => $object_type,
-                                 file_type   => 'images',  # may be optional
+                                 file_type   => 'image',   # may be optional
                                  source      => 'uploaded' # may be optional
                                 );
 
                                  source      => 'uploaded' # may be optional
                                 );
 
@@ -384,7 +413,7 @@ SL::File - The intermediate Layer for handling files
 
 =head1 OVERVIEW
 
 
 =head1 OVERVIEW
 
-The Filemanagemt can handle files in a storage independant way. Internal the File
+The Filemanagemt can handle files in a storage independent way. Internal the File
 use the configured storage backend for the type of file.
 These backends must be configured in L<SL::Controller::ClientConfig> or an extra database table.
 
 use the configured storage backend for the type of file.
 These backends must be configured in L<SL::Controller::ClientConfig> or an extra database table.
 
@@ -392,13 +421,13 @@ There are three types of files:
 
 =over 2
 
 
 =over 2
 
-=item - documents,
+=item - document,
 
 which can be generated files (for sales), scanned files or uploaded files (for purchase) for an ERP-object.
 They can exist in different versions. The versioning is handled implicit. All versions of a file may be
 deleted by the user if she/he is allowed to do this.
 
 
 which can be generated files (for sales), scanned files or uploaded files (for purchase) for an ERP-object.
 They can exist in different versions. The versioning is handled implicit. All versions of a file may be
 deleted by the user if she/he is allowed to do this.
 
-=item - attachments,
+=item - attachment,
 
 which have additional information for an ERP-objects. They are uploadable. If a filename still exists
 on a ERP-Object the new uploaded file is a new version of this or it must be renamed by user.
 
 which have additional information for an ERP-objects. They are uploadable. If a filename still exists
 on a ERP-Object the new uploaded file is a new version of this or it must be renamed by user.
@@ -407,7 +436,7 @@ There are generic attachments for a specific document group (like sales_invoices
 combinide/merged with the document-file in the time of printing.
 Today only PDF-Attachmnets can be merged with the generated document-PDF.
 
 combinide/merged with the document-file in the time of printing.
 Today only PDF-Attachmnets can be merged with the generated document-PDF.
 
-=item - images,
+=item - image,
 
 they are like attachments, but they may be have thumbnails for displaying.
 So the must have an image format like png,jpg. The versioning is like attachments
 
 they are like attachments, but they may be have thumbnails for displaying.
 So the must have an image format like png,jpg. The versioning is like attachments
@@ -500,7 +529,7 @@ The Type of the ERP-object like "sales_quotation" for a new file. A clear mappin
 
 =item C<file_type>
 
 
 =item C<file_type>
 
-The type may be "documents", "attachments" or "images" for a new file.
+The type may be "document", "attachment" or "image" for a new file.
 
 =item C<source>
 
 
 =item C<source>
 
@@ -605,7 +634,7 @@ The Type of the ERP-object like "sales_quotation". A clear mapping to the class/
 
 =item C<file_type>
 
 
 =item C<file_type>
 
-The type may be "documents", "attachments" or "images". This parameter is optional.
+The type may be "document", "attachment" or "image". This parameter is optional.
 
 =item C<file_name>
 
 
 =item C<file_name>
 
@@ -704,4 +733,3 @@ The synchronization is done file_type by file_type.
 Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>
 
 =cut
 Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>
 
 =cut
-