Revision 87e8734c
Von Tamino Steinert vor etwa 1 Jahr hinzugefügt
- ID 87e8734cc2fe02d956e562b3af81261d46e027ca
- Vorgänger 470be0b7
| locale/de/all | ||
|---|---|---|
|   'Automatically assigned with bank transaction' => 'Automatisch beim Kontoauszug verbuchen angelegt',
 | ||
|   'Automatically create new bins' => 'Automatisches Zuweisen der Lagerplätze',
 | ||
|   'Automatically created invoice for fee and interest for dunning %s' => 'Automatisch erzeugte Rechnung für Gebühren und Zinsen zu Mahnung %s',
 | ||
|   'Automatically delete entries for missing files. Ensure that these files are no longer required!' => 'Einträge für fehlende Dateien automatisch löschen. Stellen Sie sicher, dass diese Dateien nicht mehr benötigt werden!',
 | ||
|   'Available'                   => 'Verfügbar',
 | ||
|   'Available Prices'            => 'Mögliche Preise',
 | ||
|   'Available Stock'             => 'verfügbarer Bestand',
 | ||
| ... | ... | |
|   'Equity'                      => 'Passiva',
 | ||
|   'Erfolgsrechnung'             => 'Erfolgsrechnung',
 | ||
|   'Error'                       => 'Fehler',
 | ||
|   'Error Message'               => 'Fehlermeldung',
 | ||
|   'Error getting QR-Bill type.' => 'Fehler in QR-Rechnung Varianten Auswahl.',
 | ||
|   'Error handling'              => 'Fehlerbehandlung',
 | ||
|   'Error in database control file \'%s\': %s' => 'Fehler in Datenbankupgradekontrolldatei \'%s\': %s',
 | ||
| ... | ... | |
|   'Miscellaneous'               => 'Verschiedenes',
 | ||
|   'Missing \'description\' field.' => 'Fehlendes Feld \'description\'.',
 | ||
|   'Missing \'tag\' field.'      => 'Fehlendes Feld \'tag\'.',
 | ||
|   'Missing Files'               => 'Fehlende Dateien',
 | ||
|   'Missing Method!'             => 'Fehlender Voranmeldungszeitraum',
 | ||
|   'Missing Tax Authoritys Preferences' => 'Fehlende Angaben zum Finanzamt!',
 | ||
|   'Missing amount'              => 'Fehlbetrag',
 | ||
| ... | ... | |
|   'Please provide corresponding credentials.' => 'Bitte geben Sie entsprechende Logindaten an.',
 | ||
|   'Please re-run the analysis for broken general ledger entries by clicking this button:' => 'Bitte wiederholen Sie die Analyse der Hauptbucheinträge, indem Sie auf diesen Button klicken:',
 | ||
|   'Please read the file'        => 'Bitte lesen Sie die Datei',
 | ||
|   'Please resolve the errors by deleting the invalid database entries or by adding the corresponding files to the expected paths.' => 'Bitte beheben Sie die Fehler, indem Sie die ungültigen Datenbankeinträge löschen oder die entsprechenden Dateien zu den erwarteten Pfaden hinzufügen.',
 | ||
|   'Please select a customer from the list below.' => 'Bitte einen Endkunden aus der Liste auswählen',
 | ||
|   'Please select a customer.'   => 'Bitte wählen Sie einen Kunden aus.',
 | ||
|   'Please select a deadline date.' => 'Bitte wählen Sie ein Datum für die Fristsetzung aus.',
 | ||
| ... | ... | |
|   'Requirement spec template actions' => 'Pflichtenheftvorlagen-Aktionen',
 | ||
|   'Requirement spec text block "#1"; content: "#2"' => 'Pflichtenheft-Textblock "1"; Inhalt: "#2"',
 | ||
|   'Requirement specs'           => 'Pflichtenhefte',
 | ||
|   'Rerun update'                => 'Wiederhole Update',
 | ||
|   'Reset'                       => 'Zurücksetzen',
 | ||
|   'Reset Filter'                => 'Filter zurücksetzen',
 | ||
|   'Result'                      => 'Ergebnis',
 | ||
| locale/en/all | ||
|---|---|---|
|   'Automatically assigned with bank transaction' => '',
 | ||
|   'Automatically create new bins' => '',
 | ||
|   'Automatically created invoice for fee and interest for dunning %s' => '',
 | ||
|   'Automatically delete entries for missing files. Ensure that these files are no longer required!' => '',
 | ||
|   'Available'                   => '',
 | ||
|   'Available Prices'            => '',
 | ||
|   'Available Stock'             => '',
 | ||
| ... | ... | |
|   'Equity'                      => '',
 | ||
|   'Erfolgsrechnung'             => '',
 | ||
|   'Error'                       => '',
 | ||
|   'Error Message'               => '',
 | ||
|   'Error getting QR-Bill type.' => '',
 | ||
|   'Error handling'              => '',
 | ||
|   'Error in database control file \'%s\': %s' => '',
 | ||
| ... | ... | |
|   'Miscellaneous'               => '',
 | ||
|   'Missing \'description\' field.' => '',
 | ||
|   'Missing \'tag\' field.'      => '',
 | ||
|   'Missing Files'               => '',
 | ||
|   'Missing Method!'             => '',
 | ||
|   'Missing Tax Authoritys Preferences' => '',
 | ||
|   'Missing amount'              => '',
 | ||
| ... | ... | |
|   'Please provide corresponding credentials.' => '',
 | ||
|   'Please re-run the analysis for broken general ledger entries by clicking this button:' => '',
 | ||
|   'Please read the file'        => '',
 | ||
|   'Please resolve the errors by deleting the invalid database entries or by adding the corresponding files to the expected paths.' => '',
 | ||
|   'Please select a customer from the list below.' => '',
 | ||
|   'Please select a customer.'   => '',
 | ||
|   'Please select a deadline date.' => '',
 | ||
| ... | ... | |
|   'Requirement spec template actions' => '',
 | ||
|   'Requirement spec text block "#1"; content: "#2"' => '',
 | ||
|   'Requirement specs'           => '',
 | ||
|   'Rerun update'                => '',
 | ||
|   'Reset'                       => '',
 | ||
|   'Reset Filter'                => '',
 | ||
|   'Result'                      => '',
 | ||
| sql/Pg-upgrade2/add_file_version.pl | ||
|---|---|---|
| use SL::DB::File;
 | ||
| use SL::File::Backend::Webdav;
 | ||
|  | ||
| use SL::Locale::String qw(t8);
 | ||
| use SL::System::Process;
 | ||
|  | ||
| use UUID::Tiny ':std';
 | ||
| ... | ... | |
| use parent qw(SL::DBUpgrade2::Base);
 | ||
|  | ||
| sub get_all_versions {
 | ||
|   my ($fileobj) = @_;
 | ||
|   my ($dbfile) = @_;
 | ||
|  | ||
|   my @versionobjs;
 | ||
|   my $fileobj = SL::File::Object->new(
 | ||
|     db_file => $dbfile,
 | ||
|     id => $dbfile->id,
 | ||
|     loaded => 1,
 | ||
|   );
 | ||
|  | ||
|   my $maxversion = $fileobj->version_count;
 | ||
|   my $maxversion = $fileobj->backend eq 'Filesystem' ? $fileobj->db_file->backend_data : 1;
 | ||
|   $fileobj->version($maxversion);
 | ||
|   push @versionobjs, $fileobj;
 | ||
|   if ($maxversion > 1) {
 | ||
| ... | ... | |
|       push @versionobjs, $clone;
 | ||
|     }
 | ||
|   }
 | ||
|  | ||
|   return @versionobjs;
 | ||
| }
 | ||
|  | ||
| sub get_filepath {
 | ||
|   my ($file_obj) = @_;
 | ||
|  | ||
|   my $file_id = $file_obj->id;
 | ||
|   my $backend = $file_obj->backend
 | ||
|     or die "File with ID '$file_id' has no backend specified.";
 | ||
|   my $db_file   = $file_obj->db_file;
 | ||
|   my $file_name = $file_obj->file_name;
 | ||
|   my $version   = $file_obj->version;
 | ||
|  | ||
|   my $path;
 | ||
|   if ($backend eq 'Webdav') {
 | ||
|     ($path) = $file_obj->backend_class->webdav_path($db_file);
 | ||
|   } elsif ($backend eq 'Filesystem') {
 | ||
|     # use filesystem with depth 3
 | ||
|     my $iddir   = sprintf("%04d", $db_file->id % 1000);
 | ||
|     my $base_path    = File::Spec->catdir($::lx_office_conf{paths}->{document_path}, $::auth->client->{id}, $iddir, $db_file->id);
 | ||
|     $path = File::Spec->catdir($base_path, $db_file->id . '_' . $version);
 | ||
|   } else {
 | ||
|     die "Unknown backend '$backend' for file with ID '$file_id'.";
 | ||
|   }
 | ||
|  | ||
|   die "No file found at $path. Expected: $file_name, file.id: $file_id" if !-f $path;
 | ||
|   return $path;
 | ||
| }
 | ||
|  | ||
| sub test_all_files_exists {
 | ||
|   my @errors;
 | ||
|  | ||
|   my $all_dbfiles = SL::DB::Manager::File->get_all;
 | ||
|  | ||
|   foreach my $dbfile (@{$all_dbfiles}) {
 | ||
|     my @versions = get_all_versions($dbfile);
 | ||
|     foreach my $version (@versions) {
 | ||
|       eval {
 | ||
|         get_filepath($version);
 | ||
|       } or do {
 | ||
|         push @errors, $@;
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|  | ||
|   return @errors;
 | ||
| }
 | ||
|  | ||
| sub print_errors {
 | ||
|   my ($self, $errors) = @_;
 | ||
|  | ||
|   print $::form->parse_html_template("dbupgrade/add_file_version_form", {
 | ||
|       ERRORS => $errors
 | ||
|     });
 | ||
| }
 | ||
|  | ||
| sub run {
 | ||
|   my ($self) = @_;
 | ||
|  | ||
|   my $query = <<SQL;
 | ||
| SELECT f.id
 | ||
| FROM files f
 | ||
| FULL OUTER JOIN file_versions fv ON (f.id = fv.file_id)
 | ||
| GROUP BY f.id
 | ||
| HAVING count(fv.file_id) = 0
 | ||
| SQL
 | ||
|   my @file_ids_without_version = map {$_->[0]} @{$self->dbh->selectall_arrayref($query)};
 | ||
|  | ||
|   unless ($::form->{delete_file_entries_of_missing_files}) {
 | ||
|     my @errors = $self->test_all_files_exists();
 | ||
|     if (scalar @errors) {
 | ||
|       $self->print_errors(\@errors);
 | ||
|       return 2;
 | ||
|     }
 | ||
|   }
 | ||
|  | ||
|   SL::DB->client->with_transaction(sub {
 | ||
|     my @errors;
 | ||
|     my $all_dbfiles = SL::DB::Manager::File->get_all;
 | ||
| ... | ... | |
|       foreach my $version (@versions) {
 | ||
|         my $tofile;
 | ||
|         eval {
 | ||
|           $tofile = $version->get_file();
 | ||
|           $tofile = get_filepath($version);
 | ||
|         } or do {
 | ||
|           my @values;
 | ||
|           push @values, $@; # error message
 | ||
|           push @values, $version->file_name;
 | ||
|           push @values, $version->id;
 | ||
|           push @errors, '<td>' . join('</td><td>', @values) . '</td>';;
 | ||
|           next;
 | ||
|         };
 | ||
|         my $rel_file = $tofile;
 | ||
|         $rel_file    =~ s/$doc_path//;
 | ||
|  | ||
|         my $fv = SL::DB::FileVersion->new(
 | ||
|                               file_id       => $dbfile->id,
 | ||
|                               version       => $version->version || 1,
 | ||
|                               file_location => $rel_file,
 | ||
|                               doc_path      => $doc_path,
 | ||
|                               backend       => $dbfile->backend,
 | ||
|                               guid          => create_uuid_as_string(UUID_V4),
 | ||
|                             )->save;
 | ||
|           file_id       => $dbfile->id,
 | ||
|           version       => $version->version || 1,
 | ||
|           file_location => $rel_file,
 | ||
|           doc_path      => $doc_path,
 | ||
|           backend       => $dbfile->backend,
 | ||
|           guid          => create_uuid_as_string(UUID_V4),
 | ||
|         )->save;
 | ||
|       }
 | ||
|     }
 | ||
|     if (scalar @errors) {
 | ||
|       my $error_message = <<MESSAGE;
 | ||
| Please resolve the errors by deleting the invalid database entries or by adding the corresponding files to the expected paths.
 | ||
| To delete the invalid database entries, run the 'RemoveInvalidFileEntries' background job. Before running the background job, ensure that these files are no longer required.
 | ||
| <table class="tbl-list" border="1" style="border-collapse: collapse">
 | ||
|   <thead><tr>
 | ||
|     <th>error message</th>
 | ||
|     <th>file_name</th>
 | ||
|     <th>file_id</th>
 | ||
|   </tr></thead>
 | ||
| MESSAGE
 | ||
|       $error_message .= '<tr>' . join('</tr><tr>', @errors) . '</tr>';
 | ||
|       $error_message .= '</table>';
 | ||
|       die $error_message;
 | ||
|  | ||
|     my $query = <<SQL;
 | ||
| SELECT f.id
 | ||
| FROM files f
 | ||
| FULL OUTER JOIN file_versions fv ON (f.id = fv.file_id)
 | ||
| GROUP BY f.id
 | ||
| HAVING count(fv.file_id) = 0
 | ||
| SQL
 | ||
|     my @file_ids_without_version =
 | ||
|       map {$_->[0]}
 | ||
|       @{SL::DB::->client->dbh->selectall_arrayref($query)};
 | ||
|     if (scalar @file_ids_without_version) {
 | ||
|       if ($::form->{delete_file_entries_of_missing_files}) {
 | ||
|         SL::DB::Manager::File->delete_all(where => [id => \@file_ids_without_version]);
 | ||
|       } else {
 | ||
|         die "Files without versions: " . join(', ', @file_ids_without_version);
 | ||
|       }
 | ||
|     }
 | ||
|  | ||
|     1;
 | ||
|   }) or do { die SL::DB->client->error };
 | ||
|  | ||
| templates/design40_webpages/dbupgrade/add_file_version_form.html | ||
|---|---|---|
| [%- USE T8 %]
 | ||
| [%- USE P %]
 | ||
| [%- USE LxERP %]
 | ||
| [%- USE HTML %]
 | ||
|  | ||
| <div class="wrapper">
 | ||
|   <h1>[% 'Missing Files' | $T8 %]</h1>
 | ||
|   <form name="Form" method="post" action="login.pl">
 | ||
|     <input type="hidden" name="action" value="login">
 | ||
|  | ||
|     [% 'Please resolve the errors by deleting the invalid database entries or by adding the corresponding files to the expected paths.' | $T8 %]
 | ||
|     <table class="tbl-list">
 | ||
|       <thead><tr>
 | ||
|         <th>[% 'Error Message' | $T8 %]</th>
 | ||
|       </tr></thead>
 | ||
|       <tbody>
 | ||
|         [% FOREACH error = ERRORS %]
 | ||
|         <tr><td>
 | ||
|           [% error | html %]
 | ||
|         </td></tr>
 | ||
|         [% END %]
 | ||
|       </tbody>
 | ||
|     </table>
 | ||
|     [% P.checkbox_tag(
 | ||
|       "delete_file_entries_of_missing_files", value=1,
 | ||
|       label=LxERP.t8("Automatically delete entries for missing files. Ensure that these files are no longer required!")
 | ||
|     ) %]
 | ||
|     <br>
 | ||
|     [% P.submit_tag("rerun_add_file_version", LxERP.t8("Rerun update")) %]
 | ||
|   </form>
 | ||
| </div>
 | ||
| templates/webpages/dbupgrade/add_file_version_form.html | ||
|---|---|---|
| [%- USE T8 %]
 | ||
| [%- USE P %]
 | ||
| [%- USE LxERP %]
 | ||
| [%- USE HTML %]
 | ||
|  | ||
| <h1>[% 'Missing Files' | $T8 %]</h1>
 | ||
| <form name="Form" method="post" action="login.pl">
 | ||
|   <input type="hidden" name="action" value="login">
 | ||
|  | ||
|   [% 'Please resolve the errors by deleting the invalid database entries or by adding the corresponding files to the expected paths.' | $T8 %]
 | ||
|   <table border="1" style="border-collapse: collapse">
 | ||
|     <thead><tr>
 | ||
|       <th>[% 'Error Message' | $T8 %]</th>
 | ||
|     </tr></thead>
 | ||
|     <tbody>
 | ||
|       [% FOREACH error = ERRORS %]
 | ||
|       <tr><td>
 | ||
|         [% error | html %]
 | ||
|       </td></tr>
 | ||
|       [% END %]
 | ||
|     </tbody>
 | ||
|   </table>
 | ||
|   [% P.checkbox_tag(
 | ||
|     "delete_file_entries_of_missing_files", value=1,
 | ||
|     label=LxERP.t8("Automatically delete entries for missing files. Ensure that these files are no longer required!")
 | ||
|   ) %]
 | ||
|   <br>
 | ||
|   [% P.submit_tag("rerun_add_file_version", LxERP.t8("Rerun update")) %]
 | ||
| </form>
 | ||
Auch abrufbar als: Unified diff
FileVersion: Migration: Interaktives Update