From: Moritz Bunkus Date: Thu, 25 Apr 2013 11:44:11 +0000 (+0200) Subject: Pflichtenhefte: PDFs zu Arbeitskopie und Versionen erzeugen X-Git-Tag: release-3.2.0beta~467^2~181 X-Git-Url: http://wagnertech.de/git?a=commitdiff_plain;h=84fc52bdc02b7b84f7a644cf2bed484f1213d9ce;p=kivitendo-erp.git Pflichtenhefte: PDFs zu Arbeitskopie und Versionen erzeugen --- diff --git a/SL/Controller/RequirementSpec.pm b/SL/Controller/RequirementSpec.pm index b557c036c..aa259f6f0 100644 --- a/SL/Controller/RequirementSpec.pm +++ b/SL/Controller/RequirementSpec.pm @@ -1,6 +1,7 @@ package SL::Controller::RequirementSpec; use strict; +use utf8; use parent qw(SL::Controller::Base); @@ -20,6 +21,7 @@ use SL::DB::RequirementSpecType; use SL::DB::RequirementSpec; use SL::Helper::Flash; use SL::Locale::String; +use SL::Template::LaTeX; use Rose::Object::MakeMethods::Generic ( @@ -193,6 +195,22 @@ sub action_revert_to { $self->js->redirect_to($self->url_for(action => 'show', id => $self->requirement_spec->id))->render($self); } +sub action_create_pdf { + my ($self, %params) = @_; + + my %result = SL::Template::LaTeX->parse_and_create_pdf('requirement_spec.tex', SELF => $self, rspec => $self->requirement_spec); + + $::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}; +} + # # filters # diff --git a/SL/Controller/RequirementSpecItem.pm b/SL/Controller/RequirementSpecItem.pm index cffc22c16..98e160ab8 100644 --- a/SL/Controller/RequirementSpecItem.pm +++ b/SL/Controller/RequirementSpecItem.pm @@ -542,8 +542,8 @@ sub create_dependencies { return map { [ $_->fb_number . ' ' . $_->title, [ map { ( $self->create_dependency_item($_), - map { $self->create_dependency_item($_, '->') } @{ $_->sorted_children }) - } @{ $_->sorted_children } ] ] + map { $self->create_dependency_item($_, '->') } @{ $_->children_sorted }) + } @{ $_->children_sorted } ] ] } @{ $self->item->requirement_spec->sections }; } diff --git a/SL/DB/RequirementSpec.pm b/SL/DB/RequirementSpec.pm index 6a43a2849..5cfb5dcfe 100644 --- a/SL/DB/RequirementSpec.pm +++ b/SL/DB/RequirementSpec.pm @@ -8,6 +8,7 @@ use Rose::DB::Object::Helpers; use SL::DB::MetaSetup::RequirementSpec; use SL::DB::Manager::RequirementSpec; use SL::Locale::String; +use SL::Util qw(_hashify); __PACKAGE__->meta->add_relationship( items => { @@ -49,26 +50,43 @@ sub _before_save_initialize_not_null_columns { return 1; } -sub text_blocks_for_position { - my ($self, $output_position) = @_; +sub text_blocks_sorted { + my ($self, %params) = _hashify(1, @_); - return [ sort { $a->position <=> $b->position } grep { $_->output_position == $output_position } @{ $self->text_blocks } ]; + my @text_blocks = @{ $self->text_blocks }; + @text_blocks = grep { $_->output_position == $params{output_position} } @text_blocks if exists $params{output_position}; + @text_blocks = sort { $a->position <=> $b->position } @text_blocks; + + return wantarray ? @text_blocks : \@text_blocks; } -sub sections { +sub sections_sorted { my ($self, @rest) = @_; croak "This sub is not a writer" if @rest; - return [ sort { $a->position <=> $b->position } grep { !$_->parent_id } @{ $self->items } ]; + my @sections = sort { $a->position <=> $b->position } grep { !$_->parent_id } @{ $self->items }; + return wantarray ? @sections : \@sections; } +sub sections { §ions_sorted; } + sub displayable_name { my ($self) = @_; return sprintf('%s: "%s"', $self->type->description, $self->title); } +sub versioned_copies_sorted { + my ($self, %params) = _hashify(1, @_); + + my @copies = @{ $self->versioned_copies }; + @copies = grep { $_->version->version_number <= $params{max_version_number} } @copies if $params{max_version_number}; + @copies = sort { $a->version->version_number <=> $b->version->version_number } @copies; + + return wantarray ? @copies : \@copies; +} + sub create_copy { my ($self, %params) = @_; @@ -195,6 +213,8 @@ SQL sub create_version { my ($self, %attributes) = @_; + croak "Cannot work on a versioned copy" if $self->working_copy_id; + my ($copy, $version); my $ok = $self->db->do_transaction(sub { delete $attributes{version_number}; @@ -213,8 +233,7 @@ sub create_version { sub invalidate_version { my ($self, %params) = @_; - $::lxdebug->message(0, "Invalidate version called for id " . $self->id . " version " . $self->version_id); - $::lxdebug->show_backtrace(1); + croak "Cannot work on a versioned copy" if $self->working_copy_id; return if !$self->id || !$self->version_id; $self->update_attributes(version_id => undef); diff --git a/SL/DB/RequirementSpecItem.pm b/SL/DB/RequirementSpecItem.pm index 69265537c..641982cf1 100644 --- a/SL/DB/RequirementSpecItem.pm +++ b/SL/DB/RequirementSpecItem.pm @@ -99,12 +99,13 @@ sub validate { return @errors; } -sub sorted_children { +sub children_sorted { my ($self, @args) = @_; croak "Not a writer" if @args; - return [ sort { $a->position <=> $b->position } @{ $self->children } ]; + my @children = sort { $a->position <=> $b->position } $self->children; + return wantarray ? @children : \@children; } sub section { diff --git a/SL/Presenter/RequirementSpecItem.pm b/SL/Presenter/RequirementSpecItem.pm index f1c30bb50..c9653e7ac 100644 --- a/SL/Presenter/RequirementSpecItem.pm +++ b/SL/Presenter/RequirementSpecItem.pm @@ -18,7 +18,7 @@ sub requirement_spec_item_tree_node_title { sub requirement_spec_item_jstree_data { my ($self, $item, %params) = @_; - my @children = map { $self->requirement_spec_item_jstree_data($_, %params) } @{ $item->sorted_children }; + my @children = map { $self->requirement_spec_item_jstree_data($_, %params) } @{ $item->children_sorted }; my $type = !$item->parent_id ? 'section' : 'function-block'; my $class = $type . '-context-menu'; $class .= ' flagged' if $item->is_flagged; diff --git a/css/requirement_spec.css b/css/requirement_spec.css index 29b458298..cefdf1983 100644 --- a/css/requirement_spec.css +++ b/css/requirement_spec.css @@ -47,6 +47,7 @@ table.rs_input_field input, table.rs_input_field select { .context-menu-item.icon-close { background-image: url("../image/document-close.png"); } .context-menu-item.icon-save { background-image: url("../image/document-save.png"); } .context-menu-item.icon-revert { background-image: url("../image/edit-undo.png"); } +.context-menu-item.icon-pdf { background-image: url("../image/application-pdf.png"); } /* ------------------------------------------------------------ */ /* Sections & function blocks */ diff --git a/image/application-pdf.png b/image/application-pdf.png new file mode 100644 index 000000000..ad6a39f3f Binary files /dev/null and b/image/application-pdf.png differ diff --git a/js/requirement_spec.js b/js/requirement_spec.js index 6373b69fe..f0c472b20 100644 --- a/js/requirement_spec.js +++ b/js/requirement_spec.js @@ -293,9 +293,9 @@ function standard_time_cost_estimate_ajax_call(key, opt) { // ---------------------------- general actions ---------------------------- // ------------------------------------------------------------------------- -function download_reqspec_pdf(key, opt) { +function create_reqspec_pdf(key, opt) { var data = { - action: "RequirementSpec/download_pdf", + action: "RequirementSpec/create_pdf", id: $('#requirement_spec_id').val() }; $.download("controller.pl", data); @@ -342,7 +342,11 @@ function create_requirement_spec_version() { } function create_pdf_for_versioned_copy_ajax_call(key, opt) { - // TODO: create_pdf_for_versioned_copy_ajax_call + var data = { + action: "RequirementSpec/create_pdf", + id: find_versioned_copy_id(opt.$trigger) + }; + $.download("controller.pl", data); return true; } @@ -371,6 +375,7 @@ function create_requirement_spec_context_menus() { sep98: "---------" , general_actions: { name: kivi.t8('Requirement spec actions'), className: 'context-menu-heading' } // , sep99: "---------" + , create_pdf: { name: kivi.t8('Create PDF'), icon: "pdf", callback: create_reqspec_pdf } , create_version: { name: kivi.t8('Create new version'), icon: "new", callback: create_requirement_spec_version, disabled: disable_requirement_spec_commands } , copy_reqspec: { name: kivi.t8('Copy requirement spec'), icon: "copy", callback: copy_reqspec } , delete_reqspec: { name: kivi.t8('Delete requirement spec'), icon: "delete", callback: delete_reqspec } @@ -466,9 +471,9 @@ function create_requirement_spec_context_menus() { $.contextMenu({ selector: '.versioned-copy-context-menu', items: $.extend({ - heading: { name: kivi.t8('Version actions'), className: 'context-menu-heading' } - // create_pdf: { name: kivi.t8('Create PDF'), icon: "pdf", callback: create_pdf_for_versioned_copy_ajax_call } - , revert_to_version: { name: kivi.t8('Revert to version'), icon: "revert", callback: revert_to_versioned_copy_ajax_call, disabled: disable_versioned_copy_item_commands } + heading: { name: kivi.t8('Version actions'), className: 'context-menu-heading' } + , create_version_pdf: { name: kivi.t8('Create PDF'), icon: "pdf", callback: create_pdf_for_versioned_copy_ajax_call } + , revert_to_version: { name: kivi.t8('Revert to version'), icon: "revert", callback: revert_to_versioned_copy_ajax_call, disabled: disable_versioned_copy_item_commands } }, general_actions) }); } diff --git a/locale/de/all b/locale/de/all index b341d9871..77e9eb0f2 100755 --- a/locale/de/all +++ b/locale/de/all @@ -516,6 +516,7 @@ $self->{texts} = { 'Continue' => 'Weiter', 'Contra' => 'gegen', 'Conversion of "birthday" contact person attribute' => 'Umstellung des Kontaktpersonenfeldes "Geburtstag"', + 'Conversion to PDF failed: #1' => 'Konvertierung zu PDF schlug fehl: #1', 'Copies' => 'Kopien', 'Copy file from #1 to #2 failed: #3' => 'Kopieren der Datei von #1 nach #2 schlug fehl: #3', 'Copy' => 'Kopieren', diff --git a/sql/Pg-upgrade2/requirement_specs_print_templates.pl b/sql/Pg-upgrade2/requirement_specs_print_templates.pl new file mode 100644 index 000000000..4dbe1689d --- /dev/null +++ b/sql/Pg-upgrade2/requirement_specs_print_templates.pl @@ -0,0 +1,22 @@ +# @tag: requirement_specs_print_templates +# @description: requirement_specs_print_templates +# @depends: requirement_specs +package SL::DBUpgrade2::requirement_specs_print_templates; + +use strict; +use utf8; + +use parent qw(SL::DBUpgrade2::Base); + +sub run { + my ($self) = @_; + + $self->add_print_templates( + 'templates/print/Standard', + qw(images/draft.png images/hintergrund_seite1.png images/hintergrund_seite2.png images/schachfiguren.jpg kivitendo.sty requirement_spec.tex) + ); + + return 1; +} + +1; diff --git a/templates/print/Standard/images/draft.png b/templates/print/Standard/images/draft.png new file mode 100644 index 000000000..8181bebde Binary files /dev/null and b/templates/print/Standard/images/draft.png differ diff --git a/templates/print/Standard/images/hintergrund_seite1.png b/templates/print/Standard/images/hintergrund_seite1.png new file mode 100644 index 000000000..28610f43e Binary files /dev/null and b/templates/print/Standard/images/hintergrund_seite1.png differ diff --git a/templates/print/Standard/images/hintergrund_seite2.png b/templates/print/Standard/images/hintergrund_seite2.png new file mode 100644 index 000000000..e4b204be3 Binary files /dev/null and b/templates/print/Standard/images/hintergrund_seite2.png differ diff --git a/templates/print/Standard/images/schachfiguren.jpg b/templates/print/Standard/images/schachfiguren.jpg new file mode 100644 index 000000000..d8e9cca82 Binary files /dev/null and b/templates/print/Standard/images/schachfiguren.jpg differ diff --git a/templates/print/Standard/kivitendo.sty b/templates/print/Standard/kivitendo.sty new file mode 100644 index 000000000..32d2e229b --- /dev/null +++ b/templates/print/Standard/kivitendo.sty @@ -0,0 +1,182 @@ +\ProvidesFile{kivitendo.sty} +\usepackage{colortbl} +\usepackage{eurosym} +\usepackage{german} +\usepackage{graphicx} +\usepackage{ifthen} +\usepackage[utf8]{inputenc} +\usepackage{latexsym} +\usepackage{longtable} +\usepackage{textcomp} + +%% Paketoptionen +\newboolean{defaultbg}\setboolean{defaultbg}{true} +\newboolean{draftbg} +\newboolean{reqspeclogo} +\newboolean{secondpagelogo} +\DeclareOption{nologo}{\setboolean{defaultbg}{false}} +\DeclareOption{draftlogo}{\setboolean{defaultbg}{false}\setboolean{draftbg}{true}} +\DeclareOption{reqspeclogo}{\setboolean{reqspeclogo}{true}} +\DeclareOption{secondpagelogo}{\setboolean{defaultbg}{false}\setboolean{secondpagelogo}{true}} +\ProcessOptions + +%% Seitenlayout +\setlength{\voffset}{-1.5cm} +\setlength{\hoffset}{-2.5cm} +\setlength{\topmargin}{0cm} +\setlength{\headheight}{0.5cm} +\setlength{\headsep}{1cm} +\setlength{\topskip}{0pt} +\setlength{\oddsidemargin}{2cm} +\setlength{\textwidth}{16.4cm} +\setlength{\textheight}{25cm} +\setlength{\footskip}{1cm} +\setlength{\parindent}{0pt} +\setlength{\tabcolsep}{0.2cm} + +\setlength{\unitlength}{1cm} + +\newcommand{\kivitendobgsettings}{% + \setlength{\headsep}{2.5cm} + \setlength{\textheight}{22.5cm} + \setlength{\footskip}{0.9cm} +} + +%% Standardschrift +\newcommand{\defaultfont}{\fontfamily{cmss}\fontsize{10pt}{12pt}\fontseries{m}\selectfont} +\renewcommand{\familydefault}{cmss} + +%% Checkboxen +\newsavebox{\checkedbox} +\savebox{\checkedbox}(0.2,0.4){ + \put(-0.15,-0.425){$\times$} + \put(-0.15,-0.45){$\Box$} +} +\newsavebox{\uncheckedbox} +\savebox{\uncheckedbox}(0.2,0.4){ + \put(-0.15,-0.45){$\Box$} +} + +%% Farben +\definecolor{kivitendoorange}{rgb}{1,0.4,0.2} +\definecolor{kivitendodarkred}{rgb}{0.49,0,0} +\definecolor{kivitendoyellow}{rgb}{1,1,0.4} +\definecolor{kivitendobggray}{gray}{0.9} +\definecolor{kivitendowhite}{gray}{1} + +%% Kopf- und Fußzeilen +\newcommand{\kivitendofirsthead}{} +\newcommand{\kivitendofirstfoot}{} +\newcommand{\kivitendosecondhead}{} +\newcommand{\kivitendosecondfoot}{\centerline{\defaultfont\small Seite \thepage}} + +\newcommand{\myhead}{% + \ifthenelse{\boolean{defaultbg}}{% + \begin{picture}(0,0) + \put(-2.025,-28.1){\includegraphics*[width=\paperwidth,keepaspectratio=true]{images/hintergrund_seite1.png}} + \end{picture}% + }{}% + \ifthenelse{\boolean{secondpagelogo}}{% + \begin{picture}(0,0) + \put(-2.025,-28.1){\includegraphics*[width=\paperwidth,keepaspectratio=true]{images/hintergrund_seite2.png}} + \end{picture}% + }{}% + \ifthenelse{\boolean{draftbg}}{% + \begin{picture}(0,0) + \put(-2.025,-26.9){\includegraphics*[width=\paperwidth,keepaspectratio=true]{images/draft.png}} + \end{picture}% + }{}% + \ifthenelse{\boolean{reqspeclogo}}{% + \begin{picture}(0,0) + \put(3,-22){\includegraphics*[width=13cm,keepaspectratio=true]{images/schachfiguren.jpg}} + \put(0.275,-4.1){\colorbox{kivitendoorange}{\begin{minipage}[t][4.5cm]{2.5cm}\hspace*{2.5cm}\end{minipage}}} + \put(0.275,-8.8){\colorbox{kivitendodarkred}{\begin{minipage}[t][4.5cm]{2.5cm}\hspace*{2.5cm}\end{minipage}}} + \put(0.275,-13.5){\colorbox{kivitendoyellow}{\begin{minipage}[t][4.5cm]{2.5cm}\hspace*{2.5cm}\end{minipage}}} + \end{picture}% + }{}% + \kivitendofirsthead +} + +\newcommand{\mysecondhead}{% + \ifthenelse{\boolean{defaultbg} \or \boolean{secondpagelogo}}{% + \begin{picture}(0,0) + \put(-2.025,-28.1){\includegraphics*[width=\paperwidth,keepaspectratio=true]{images/hintergrund_seite2.png}} + \end{picture}% + }{}% + \ifthenelse{\boolean{draftbg}}{% + \begin{picture}(0,0) + \put(-2.025,-26.9){\includegraphics*[width=\paperwidth,keepaspectratio=true]{images/draft.png}} + \end{picture}% + }{}% + \kivitendosecondhead +} + +\newcommand{\myfoot}{\kivitendofirstfoot} +\newcommand{\mysecondfoot}{\kivitendosecondfoot} + +\renewcommand{\ps@headings}{% + \renewcommand{\@oddhead}{\myhead} + \renewcommand{\@evenhead}{\@oddhead}% + \renewcommand{\@oddfoot}{\myfoot} + \renewcommand{\@evenfoot}{\@oddfoot}% +} + +\renewcommand{\ps@plain}{% + \renewcommand{\@oddhead}{\mysecondhead} + \renewcommand{\@evenhead}{\@oddhead}% + \renewcommand{\@oddfoot}{\mysecondfoot} + \renewcommand{\@evenfoot}{\@oddfoot}% +} + +\pagestyle{plain} +\thispagestyle{headings} + +% Abschnitte mit Kasten hinterlegt + +\newcommand{\reqspecsectionstyle}{% +\renewcommand{\thesection}{\alph{section}} +\makeatletter +\def\section{\@ifstar\unnumberedsection\numberedsection} +\makeatother +} + +\makeatletter +\def\numberedsection{\@ifnextchar[%] + \numberedsectionwithtwoarguments\numberedsectionwithoneargument} +\def\unnumberedsection{\@ifnextchar[%] + \unnumberedsectionwithtwoarguments\unnumberedsectionwithoneargument} +\def\numberedsectionwithoneargument#1{\numberedsectionwithtwoarguments[#1]{#1}} +\def\unnumberedsectionwithoneargument#1{\unnumberedsectionwithtwoarguments[#1]{#1}} +\def\numberedsectionwithtwoarguments[#1]#2{% + \ifhmode\par\fi + \removelastskip + \vskip 3ex\goodbreak + \refstepcounter{section}% + \noindent + \begingroup + \leavevmode\Large\bfseries\raggedright + \begin{picture}(0,0) + \put(0,0){\colorbox{kivitendoorange}{\parbox{0.7cm}{\hspace*{0.7cm}\\\vspace*{0.2cm}}}} + \end{picture}% + \hspace*{0.3cm}\textcolor{white}{\thesection{}.}% + \quad% + #2 + \par + \endgroup + \vskip 2ex\nobreak + \addcontentsline{toc}{section}{\protect\numberline{\thesection{}.}#1}% + } +\def\unnumberedsectionwithtwoarguments[#1]#2{% + \ifhmode\par\fi + \removelastskip + \vskip 3ex\goodbreak + \noindent + \begingroup + \leavevmode\Large\bfseries\raggedright + \leavevmode\Large\bfseries\raggedright + #2 + \par + \endgroup + \vskip 2ex\nobreak% +} +\makeatother diff --git a/templates/print/Standard/requirement_spec.tex b/templates/print/Standard/requirement_spec.tex new file mode 100644 index 000000000..6580a8ea0 --- /dev/null +++ b/templates/print/Standard/requirement_spec.tex @@ -0,0 +1,162 @@ +% config: use-template-toolkit=1 +% config: tag-style=$( )$ +$( USE LxLatex )$ +$( USE P )$ +\documentclass{scrartcl} + +\usepackage[reqspeclogo,$( IF !rspec.version_id )$draftlogo$( ELSE )$secondpagelogo$( END )$]{kivitendo} + +\kivitendobgsettings + +\setlength{\LTpre}{0pt} +\setlength{\LTpost}{0pt} + +\renewcommand{\kivitendosecondfoot}{% + \parbox{12cm}{% + \defaultfont\scriptsize% + $( LxLatex.filter(rspec.displayable_name) )$\\ + $( !rspec.version_id ? "Arbeitskopie ohne Version" : "Version " _ rspec.version.version_number _ " vom " _ rspec.version.itime.to_kivitendo(precision='minute') )$ + + \vspace*{0.2cm}% + Seite \thepage% + }% +} + +\reqspecsectionstyle + +\begin{document} + +%% Titelseite + +\setlongtables +\defaultfont + +\begin{picture}(0,0) + \put(3.5,-5){% + \begin{minipage}[t][6cm]{12cm} + \Large + \textcolor{kivitendodarkred}{$( LxLatex.filter(rspec.type.description) )$} + + \huge + $( LxLatex.filter(rspec.customer.name) )$ + + \vspace*{0.5cm} + \Large + $( LxLatex.filter(rspec.title) )$ + \normalsize +%$( IF rspec.version_id )$ + + Version $( LxLatex.filter(rspec.version.version_number) )$ +%$( END )$ + \end{minipage}% + } +\end{picture} + +%% Inhaltsverzeichnis + +%\newpage + +%\tableofcontents + +%% Versionen +\newpage + +\section{Versionen} + +\vspace*{0.7cm} + +%$( SET working_copy = rspec.working_copy_id ? rspec.working_copy : rspec )$ +%$( SET versioned_copies = rspec.version_id ? working_copy.versioned_copies_sorted(max_version_number = rspec.version.version_number) : working_copy.versioned_copies_sorted )$ +%$( IF !versioned_copies.size )$ + Bisher wurden noch keine Versionen angelegt. +%$( ELSE )$ +\begin{longtable}{|p{2cm}|p{2cm}|p{12cm}|} + \hline + \multicolumn{1}{|r}{\small Version} & + \multicolumn{1}{|r|}{\small Datum} & + \small Beschreibung\\ + \hline +%$( FOREACH versioned_copy = versioned_copies )$ + \multicolumn{1}{|r}{\small $( LxLatex.filter(versioned_copy.version.version_number) )$} & + \multicolumn{1}{|r|}{\small $( LxLatex.filter(versioned_copy.version.itime.to_kivitendo(precision='minute')) )$} & + \small $( LxLatex.filter(versioned_copy.version.description) )$\\ +%$( END )$ + \hline +\end{longtable} +%$( END )$ + +%$( BLOCK text_block_outputter )$ +% $( SET text_blocks = rspec.text_blocks_sorted(output_position=output_position) )$ +% $( IF text_blocks.size )$ + + \newpage + + \section{$( heading )$} + +% $( FOREACH text_block = text_blocks )$ + + \subsection{$( LxLatex.filter(text_block.title) )$} + +$( LxLatex.filter(text_block.text) )$ + +% $( END )$ +% $( END )$ +%$( END )$ + +%% Textblöcke davor +$( PROCESS text_block_outputter output_position=0 heading='Allgemeines' )$ + +%% Abschnitte und Funktionsblöcke +\newpage + +\section{Spezifikation} + +\setlength{\LTpre}{-0.3cm} + + +%$( FOREACH top_item = rspec.sections_sorted )$ + + \subsection{Abschnitt $( LxLatex.filter(top_item.fb_number) )$: $( LxLatex.filter(top_item.title) )$} + +% $( IF top_item.description )$ + $( LxLatex.filter(top_item.description.replace('\r', '').replace('\n+\Z', '')) )$ + + \vspace{0.5cm} +% $( END )$ +% $( FOREACH item = top_item.children_sorted )$ +\parbox[t]{1.0cm}{\textcolor{kivitendodarkred}{$>>>$}}% +\parbox[t]{15.0cm}{% +\begin{longtable}{p{2.8cm}p{11.7cm}} + Funktionsblock & $( LxLatex.filter(item.fb_number) )$\\ + Beschreibung & $( LxLatex.filter(item.description) )$\\ + Abhängigkeiten & $( LxLatex.filter(P.requirement_spec_item_dependency_list(item)) )$ +\end{longtable}} + +% $( FOREACH sub_item = item.children_sorted )$ +\hspace*{1.15cm}\rule{15.2cm}{0.2pt}\\ +\hspace*{1.0cm}% +\parbox[t]{15.0cm}{% +\begin{longtable}{p{2.8cm}p{11.7cm}} + Unterfunktionsblock & $( LxLatex.filter(sub_item.fb_number) )$\\ + Beschreibung & $( LxLatex.filter(sub_item.description) )$\\ + Abhängigkeiten & $( LxLatex.filter(P.requirement_spec_item_dependency_list(sub_item)) )$ +\end{longtable}} + +% $( END )$ + +% $( UNLESS loop.last )$ +\vspace{0.2cm} +\hrule +\vspace{0.4cm} + +% $( END )$ + +% $( END )$ +% +%$( END )$ + +%% Textblöcke dahinter +$( PROCESS text_block_outputter output_position=1 heading='Weitere Punkte' )$ + + +\end{document} diff --git a/templates/webpages/requirement_spec/show.html b/templates/webpages/requirement_spec/show.html index 395e394e5..f861cb1d6 100644 --- a/templates/webpages/requirement_spec/show.html +++ b/templates/webpages/requirement_spec/show.html @@ -48,7 +48,7 @@ $(function() { metadata: { type: "text-blocks-front" }, attr: { id: "tb-front", class: "text-block-context-menu" }, children: [ -[% FOREACH tb = SELF.requirement_spec.text_blocks_for_position(0) %] +[% FOREACH tb = SELF.requirement_spec.text_blocks_sorted(output_position=0) %] [% P.requirement_spec_text_block_jstree_data(tb).json %][% IF !loop.last %],[% END %] [% END %] ]}, @@ -66,7 +66,7 @@ $(function() { metadata: { type: "text-blocks-back" }, attr: { id: "tb-back", class: "text-block-context-menu" }, children: [ -[% FOREACH tb = SELF.requirement_spec.text_blocks_for_position(1) %] +[% FOREACH tb = SELF.requirement_spec.text_blocks_sorted(output_position=1) %] [% P.requirement_spec_text_block_jstree_data(tb).json %][% IF !loop.last %],[% END %] [% END %] ]}]; diff --git a/templates/webpages/requirement_spec_item/_function_block.html b/templates/webpages/requirement_spec_item/_function_block.html index 4105838e8..a580acef4 100644 --- a/templates/webpages/requirement_spec_item/_function_block.html +++ b/templates/webpages/requirement_spec_item/_function_block.html @@ -9,7 +9,7 @@
[%- LxERP.t8("Sub function blocks") -%]
- [%- FOREACH sub_function_block = requirement_spec_item.sorted_children -%] + [%- FOREACH sub_function_block = requirement_spec_item.children_sorted -%] [%- INCLUDE 'requirement_spec_item/_sub_function_block.html' requirement_spec_item=sub_function_block -%] [%- END -%] diff --git a/templates/webpages/requirement_spec_item/_section.html b/templates/webpages/requirement_spec_item/_section.html index 8e7699d86..dfa206367 100644 --- a/templates/webpages/requirement_spec_item/_section.html +++ b/templates/webpages/requirement_spec_item/_section.html @@ -10,7 +10,7 @@
- [%- FOREACH function_block = requirement_spec_item.sorted_children -%] + [%- FOREACH function_block = requirement_spec_item.children_sorted -%] [%- INCLUDE 'requirement_spec_item/_function_block.html' requirement_spec_item=function_block -%] [%- END -%]