+sub action_revert_to {
+ my ($self, %params) = @_;
+
+ return $self->js->error(t8('Cannot revert a versioned copy.'))->render if $self->requirement_spec->working_copy_id;
+
+ my $versioned_copy = SL::DB::RequirementSpec->new(id => $::form->{versioned_copy_id})->load;
+
+ $self->requirement_spec->copy_from($versioned_copy);
+ my $version = $versioned_copy->versions->[0];
+ $version->update_attributes(working_copy_id => $self->requirement_spec->id);
+
+ flash_later('info', t8('The requirement spec has been reverted to version #1.', $versioned_copy->version->version_number));
+ $self->js->redirect_to($self->url_for(action => 'show', id => $self->requirement_spec->id))->render;
+}
+
+sub action_create_pdf {
+ my ($self, %params) = @_;
+
+ my $keep_temp_files = $::lx_office_conf{debug} && $::lx_office_conf{debug}->{keep_temp_files};
+ my $temp_dir = File::Temp->newdir(
+ "kivitendo-print-XXXXXX",
+ DIR => SL::System::Process::exe_dir() . "/" . $::lx_office_conf{paths}->{userspath},
+ CLEANUP => !$keep_temp_files,
+ );
+
+ my $base_name = $self->requirement_spec->type->template_file_name || 'requirement_spec';
+ my @pictures = $self->prepare_pictures_for_printing($temp_dir->dirname);
+ my %result = SL::Template::LaTeX->parse_and_create_pdf("${base_name}.tex", SELF => $self, rspec => $self->requirement_spec, userspath => $temp_dir->dirname);
+
+ unlink @pictures unless ($::lx_office_conf{debug} || {})->{keep_temp_files};
+
+ $::form->error(t8('Conversion to PDF failed: #1', $result{error})) if $result{error};
+
+ my $attachment_name = $self->requirement_spec->type->description . ' ' . ($self->requirement_spec->working_copy_id || $self->requirement_spec->id);
+ $attachment_name .= ' (v' . $self->requirement_spec->version->version_number . ')' if $self->requirement_spec->version;
+ $attachment_name .= '.pdf';
+ $attachment_name =~ s/[^\wäöüÄÖÜß \-\+\(\)\[\]\{\}\.,]+/_/g;
+
+ $self->send_file($result{file_name}, type => 'application/pdf', name => $attachment_name);
+ unlink $result{file_name};
+}
+
+sub action_create_html {
+ my ($self, %params) = @_;
+
+ my $base_name = $self->requirement_spec->type->template_file_name || 'requirement_spec';
+ my @pictures = $self->prepare_pictures_for_printing;
+ my $content = SL::Helper::CreatePDF->create_parsed_file(
+ template => "${base_name}.html",
+ format => 'html',
+ template_type => 'HTML',
+ variables => {
+ SELF => $self,
+ rspec => $self->requirement_spec,
+ });
+
+ # $content is now a scalar of bytes, but $self->render() expects a
+ # scalar of characters.
+ $content = Encode::decode('utf-8', $content);
+
+ $self->render(\$content, { layout => 0, process => 0 });
+}
+
+sub action_select_template_to_paste {
+ my ($self) = @_;
+
+ my @templates = @{ SL::DB::Manager::RequirementSpec->get_all(
+ where => [ is_template => 1, SL::DB::Manager::RequirementSpec->not_empty_filter ],
+ sort_by => 'lower(requirement_specs.title)',
+ ) };
+ $self->render('requirement_spec/select_template_to_paste', { layout => 0 }, TEMPLATES => \@templates);
+}
+
+sub action_paste_template {
+ my ($self, %params) = @_;
+
+ my $template = SL::DB::RequirementSpec->new(id => $::form->{template_id})->load;
+ my %result = $self->requirement_spec->paste_template($template);
+
+ return $self->js->error($self->requirement_spec->error)->render if !%result;
+
+ $self->render_pasted_text_block($_) for sort { $a->position <=> $b->position } @{ $result{text_blocks} };
+ $self->render_pasted_section($_) for sort { $a->position <=> $b->position } @{ $result{sections} };
+
+ if (@{ $result{sections} } && (($::form->{current_content_type} || 'sections') eq 'sections') && !$::form->{current_content_id}) {
+ $self->render_first_pasted_section_as_list($result{sections}->[0]);
+ }
+
+ my $parts_list = $self->render('requirement_spec_part/show', { output => 0 });
+ $self->js
+ ->replaceWith('#additional_parts_list_container', $parts_list)
+ ->show( '#additional_parts_list_container')
+ ->remove( '#additional_parts_form_container');
+
+ $self->invalidate_version->render;
+}
+
+sub action_renumber_sections {
+ my ($self) = @_;
+
+ my %numbers = map { ($_ => 1) } qw(section function_block);
+ my %formats = map { my $method = "${_}_number_format"; ($_ => $self->requirement_spec->type->$method) } qw(section function_block);
+ my @items = @{ $self->requirement_spec->sections_sorted };
+
+ $self->requirement_spec->db->with_transaction(sub {
+ while (@items) {
+ my $item = shift @items;
+ my $type = $item->parent_id ? 'function_block' : 'section';
+
+ $item->update_attributes(fb_number => SL::PrefixedNumber->new(number => $formats{$type} || 0)->set_to($numbers{$type}));
+
+ $numbers{$type}++;
+
+ unshift @items, @{ $item->children_sorted };
+ }
+
+ $self->requirement_spec->invalidate_version unless $self->requirement_spec->is_template;
+
+ 1;
+ });
+
+ $self->redirect_to(action => 'show', id => $self->requirement_spec->id);
+}
+