Revision 84fc52bd
Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt
SL/Controller/RequirementSpec.pm | ||
---|---|---|
1 | 1 |
package SL::Controller::RequirementSpec; |
2 | 2 |
|
3 | 3 |
use strict; |
4 |
use utf8; |
|
4 | 5 |
|
5 | 6 |
use parent qw(SL::Controller::Base); |
6 | 7 |
|
... | ... | |
20 | 21 |
use SL::DB::RequirementSpec; |
21 | 22 |
use SL::Helper::Flash; |
22 | 23 |
use SL::Locale::String; |
24 |
use SL::Template::LaTeX; |
|
23 | 25 |
|
24 | 26 |
use Rose::Object::MakeMethods::Generic |
25 | 27 |
( |
... | ... | |
193 | 195 |
$self->js->redirect_to($self->url_for(action => 'show', id => $self->requirement_spec->id))->render($self); |
194 | 196 |
} |
195 | 197 |
|
198 |
sub action_create_pdf { |
|
199 |
my ($self, %params) = @_; |
|
200 |
|
|
201 |
my %result = SL::Template::LaTeX->parse_and_create_pdf('requirement_spec.tex', SELF => $self, rspec => $self->requirement_spec); |
|
202 |
|
|
203 |
$::form->error(t8('Conversion to PDF failed: #1', $result{error})) if $result{error}; |
|
204 |
|
|
205 |
my $attachment_name = $self->requirement_spec->type->description . ' ' . ($self->requirement_spec->working_copy_id || $self->requirement_spec->id); |
|
206 |
$attachment_name .= ' (v' . $self->requirement_spec->version->version_number . ')' if $self->requirement_spec->version; |
|
207 |
$attachment_name .= '.pdf'; |
|
208 |
$attachment_name =~ s/[^\wäöüÄÖÜß \-\+\(\)\[\]\{\}\.,]+/_/g; |
|
209 |
|
|
210 |
$self->send_file($result{file_name}, type => 'application/pdf', name => $attachment_name); |
|
211 |
unlink $result{file_name}; |
|
212 |
} |
|
213 |
|
|
196 | 214 |
# |
197 | 215 |
# filters |
198 | 216 |
# |
SL/Controller/RequirementSpecItem.pm | ||
---|---|---|
542 | 542 |
|
543 | 543 |
return map { [ $_->fb_number . ' ' . $_->title, |
544 | 544 |
[ map { ( $self->create_dependency_item($_), |
545 |
map { $self->create_dependency_item($_, '->') } @{ $_->sorted_children })
|
|
546 |
} @{ $_->sorted_children } ] ]
|
|
545 |
map { $self->create_dependency_item($_, '->') } @{ $_->children_sorted })
|
|
546 |
} @{ $_->children_sorted } ] ]
|
|
547 | 547 |
} @{ $self->item->requirement_spec->sections }; |
548 | 548 |
} |
549 | 549 |
|
SL/DB/RequirementSpec.pm | ||
---|---|---|
8 | 8 |
use SL::DB::MetaSetup::RequirementSpec; |
9 | 9 |
use SL::DB::Manager::RequirementSpec; |
10 | 10 |
use SL::Locale::String; |
11 |
use SL::Util qw(_hashify); |
|
11 | 12 |
|
12 | 13 |
__PACKAGE__->meta->add_relationship( |
13 | 14 |
items => { |
... | ... | |
49 | 50 |
return 1; |
50 | 51 |
} |
51 | 52 |
|
52 |
sub text_blocks_for_position {
|
|
53 |
my ($self, $output_position) = @_;
|
|
53 |
sub text_blocks_sorted {
|
|
54 |
my ($self, %params) = _hashify(1, @_);
|
|
54 | 55 |
|
55 |
return [ sort { $a->position <=> $b->position } grep { $_->output_position == $output_position } @{ $self->text_blocks } ]; |
|
56 |
my @text_blocks = @{ $self->text_blocks }; |
|
57 |
@text_blocks = grep { $_->output_position == $params{output_position} } @text_blocks if exists $params{output_position}; |
|
58 |
@text_blocks = sort { $a->position <=> $b->position } @text_blocks; |
|
59 |
|
|
60 |
return wantarray ? @text_blocks : \@text_blocks; |
|
56 | 61 |
} |
57 | 62 |
|
58 |
sub sections { |
|
63 |
sub sections_sorted {
|
|
59 | 64 |
my ($self, @rest) = @_; |
60 | 65 |
|
61 | 66 |
croak "This sub is not a writer" if @rest; |
62 | 67 |
|
63 |
return [ sort { $a->position <=> $b->position } grep { !$_->parent_id } @{ $self->items } ]; |
|
68 |
my @sections = sort { $a->position <=> $b->position } grep { !$_->parent_id } @{ $self->items }; |
|
69 |
return wantarray ? @sections : \@sections; |
|
64 | 70 |
} |
65 | 71 |
|
72 |
sub sections { §ions_sorted; } |
|
73 |
|
|
66 | 74 |
sub displayable_name { |
67 | 75 |
my ($self) = @_; |
68 | 76 |
|
69 | 77 |
return sprintf('%s: "%s"', $self->type->description, $self->title); |
70 | 78 |
} |
71 | 79 |
|
80 |
sub versioned_copies_sorted { |
|
81 |
my ($self, %params) = _hashify(1, @_); |
|
82 |
|
|
83 |
my @copies = @{ $self->versioned_copies }; |
|
84 |
@copies = grep { $_->version->version_number <= $params{max_version_number} } @copies if $params{max_version_number}; |
|
85 |
@copies = sort { $a->version->version_number <=> $b->version->version_number } @copies; |
|
86 |
|
|
87 |
return wantarray ? @copies : \@copies; |
|
88 |
} |
|
89 |
|
|
72 | 90 |
sub create_copy { |
73 | 91 |
my ($self, %params) = @_; |
74 | 92 |
|
... | ... | |
195 | 213 |
sub create_version { |
196 | 214 |
my ($self, %attributes) = @_; |
197 | 215 |
|
216 |
croak "Cannot work on a versioned copy" if $self->working_copy_id; |
|
217 |
|
|
198 | 218 |
my ($copy, $version); |
199 | 219 |
my $ok = $self->db->do_transaction(sub { |
200 | 220 |
delete $attributes{version_number}; |
... | ... | |
213 | 233 |
sub invalidate_version { |
214 | 234 |
my ($self, %params) = @_; |
215 | 235 |
|
216 |
$::lxdebug->message(0, "Invalidate version called for id " . $self->id . " version " . $self->version_id); |
|
217 |
$::lxdebug->show_backtrace(1); |
|
236 |
croak "Cannot work on a versioned copy" if $self->working_copy_id; |
|
218 | 237 |
|
219 | 238 |
return if !$self->id || !$self->version_id; |
220 | 239 |
$self->update_attributes(version_id => undef); |
SL/DB/RequirementSpecItem.pm | ||
---|---|---|
99 | 99 |
return @errors; |
100 | 100 |
} |
101 | 101 |
|
102 |
sub sorted_children {
|
|
102 |
sub children_sorted {
|
|
103 | 103 |
my ($self, @args) = @_; |
104 | 104 |
|
105 | 105 |
croak "Not a writer" if @args; |
106 | 106 |
|
107 |
return [ sort { $a->position <=> $b->position } @{ $self->children } ]; |
|
107 |
my @children = sort { $a->position <=> $b->position } $self->children; |
|
108 |
return wantarray ? @children : \@children; |
|
108 | 109 |
} |
109 | 110 |
|
110 | 111 |
sub section { |
SL/Presenter/RequirementSpecItem.pm | ||
---|---|---|
18 | 18 |
sub requirement_spec_item_jstree_data { |
19 | 19 |
my ($self, $item, %params) = @_; |
20 | 20 |
|
21 |
my @children = map { $self->requirement_spec_item_jstree_data($_, %params) } @{ $item->sorted_children };
|
|
21 |
my @children = map { $self->requirement_spec_item_jstree_data($_, %params) } @{ $item->children_sorted };
|
|
22 | 22 |
my $type = !$item->parent_id ? 'section' : 'function-block'; |
23 | 23 |
my $class = $type . '-context-menu'; |
24 | 24 |
$class .= ' flagged' if $item->is_flagged; |
css/requirement_spec.css | ||
---|---|---|
47 | 47 |
.context-menu-item.icon-close { background-image: url("../image/document-close.png"); } |
48 | 48 |
.context-menu-item.icon-save { background-image: url("../image/document-save.png"); } |
49 | 49 |
.context-menu-item.icon-revert { background-image: url("../image/edit-undo.png"); } |
50 |
.context-menu-item.icon-pdf { background-image: url("../image/application-pdf.png"); } |
|
50 | 51 |
|
51 | 52 |
/* ------------------------------------------------------------ */ |
52 | 53 |
/* Sections & function blocks */ |
js/requirement_spec.js | ||
---|---|---|
293 | 293 |
// ---------------------------- general actions ---------------------------- |
294 | 294 |
// ------------------------------------------------------------------------- |
295 | 295 |
|
296 |
function download_reqspec_pdf(key, opt) {
|
|
296 |
function create_reqspec_pdf(key, opt) {
|
|
297 | 297 |
var data = { |
298 |
action: "RequirementSpec/download_pdf",
|
|
298 |
action: "RequirementSpec/create_pdf",
|
|
299 | 299 |
id: $('#requirement_spec_id').val() |
300 | 300 |
}; |
301 | 301 |
$.download("controller.pl", data); |
... | ... | |
342 | 342 |
} |
343 | 343 |
|
344 | 344 |
function create_pdf_for_versioned_copy_ajax_call(key, opt) { |
345 |
// TODO: create_pdf_for_versioned_copy_ajax_call |
|
345 |
var data = { |
|
346 |
action: "RequirementSpec/create_pdf", |
|
347 |
id: find_versioned_copy_id(opt.$trigger) |
|
348 |
}; |
|
349 |
$.download("controller.pl", data); |
|
346 | 350 |
|
347 | 351 |
return true; |
348 | 352 |
} |
... | ... | |
371 | 375 |
sep98: "---------" |
372 | 376 |
, general_actions: { name: kivi.t8('Requirement spec actions'), className: 'context-menu-heading' } |
373 | 377 |
// , sep99: "---------" |
378 |
, create_pdf: { name: kivi.t8('Create PDF'), icon: "pdf", callback: create_reqspec_pdf } |
|
374 | 379 |
, create_version: { name: kivi.t8('Create new version'), icon: "new", callback: create_requirement_spec_version, disabled: disable_requirement_spec_commands } |
375 | 380 |
, copy_reqspec: { name: kivi.t8('Copy requirement spec'), icon: "copy", callback: copy_reqspec } |
376 | 381 |
, delete_reqspec: { name: kivi.t8('Delete requirement spec'), icon: "delete", callback: delete_reqspec } |
... | ... | |
466 | 471 |
$.contextMenu({ |
467 | 472 |
selector: '.versioned-copy-context-menu', |
468 | 473 |
items: $.extend({ |
469 |
heading: { name: kivi.t8('Version actions'), className: 'context-menu-heading' } |
|
470 |
// create_pdf: { name: kivi.t8('Create PDF'), icon: "pdf", callback: create_pdf_for_versioned_copy_ajax_call }
|
|
471 |
, revert_to_version: { name: kivi.t8('Revert to version'), icon: "revert", callback: revert_to_versioned_copy_ajax_call, disabled: disable_versioned_copy_item_commands } |
|
474 |
heading: { name: kivi.t8('Version actions'), className: 'context-menu-heading' }
|
|
475 |
, create_version_pdf: { name: kivi.t8('Create PDF'), icon: "pdf", callback: create_pdf_for_versioned_copy_ajax_call }
|
|
476 |
, revert_to_version: { name: kivi.t8('Revert to version'), icon: "revert", callback: revert_to_versioned_copy_ajax_call, disabled: disable_versioned_copy_item_commands }
|
|
472 | 477 |
}, general_actions) |
473 | 478 |
}); |
474 | 479 |
} |
locale/de/all | ||
---|---|---|
516 | 516 |
'Continue' => 'Weiter', |
517 | 517 |
'Contra' => 'gegen', |
518 | 518 |
'Conversion of "birthday" contact person attribute' => 'Umstellung des Kontaktpersonenfeldes "Geburtstag"', |
519 |
'Conversion to PDF failed: #1' => 'Konvertierung zu PDF schlug fehl: #1', |
|
519 | 520 |
'Copies' => 'Kopien', |
520 | 521 |
'Copy file from #1 to #2 failed: #3' => 'Kopieren der Datei von #1 nach #2 schlug fehl: #3', |
521 | 522 |
'Copy' => 'Kopieren', |
sql/Pg-upgrade2/requirement_specs_print_templates.pl | ||
---|---|---|
1 |
# @tag: requirement_specs_print_templates |
|
2 |
# @description: requirement_specs_print_templates |
|
3 |
# @depends: requirement_specs |
|
4 |
package SL::DBUpgrade2::requirement_specs_print_templates; |
|
5 |
|
|
6 |
use strict; |
|
7 |
use utf8; |
|
8 |
|
|
9 |
use parent qw(SL::DBUpgrade2::Base); |
|
10 |
|
|
11 |
sub run { |
|
12 |
my ($self) = @_; |
|
13 |
|
|
14 |
$self->add_print_templates( |
|
15 |
'templates/print/Standard', |
|
16 |
qw(images/draft.png images/hintergrund_seite1.png images/hintergrund_seite2.png images/schachfiguren.jpg kivitendo.sty requirement_spec.tex) |
|
17 |
); |
|
18 |
|
|
19 |
return 1; |
|
20 |
} |
|
21 |
|
|
22 |
1; |
templates/print/Standard/kivitendo.sty | ||
---|---|---|
1 |
\ProvidesFile{kivitendo.sty} |
|
2 |
\usepackage{colortbl} |
|
3 |
\usepackage{eurosym} |
|
4 |
\usepackage{german} |
|
5 |
\usepackage{graphicx} |
|
6 |
\usepackage{ifthen} |
|
7 |
\usepackage[utf8]{inputenc} |
|
8 |
\usepackage{latexsym} |
|
9 |
\usepackage{longtable} |
|
10 |
\usepackage{textcomp} |
|
11 |
|
|
12 |
%% Paketoptionen |
|
13 |
\newboolean{defaultbg}\setboolean{defaultbg}{true} |
|
14 |
\newboolean{draftbg} |
|
15 |
\newboolean{reqspeclogo} |
|
16 |
\newboolean{secondpagelogo} |
|
17 |
\DeclareOption{nologo}{\setboolean{defaultbg}{false}} |
|
18 |
\DeclareOption{draftlogo}{\setboolean{defaultbg}{false}\setboolean{draftbg}{true}} |
|
19 |
\DeclareOption{reqspeclogo}{\setboolean{reqspeclogo}{true}} |
|
20 |
\DeclareOption{secondpagelogo}{\setboolean{defaultbg}{false}\setboolean{secondpagelogo}{true}} |
|
21 |
\ProcessOptions |
|
22 |
|
|
23 |
%% Seitenlayout |
|
24 |
\setlength{\voffset}{-1.5cm} |
|
25 |
\setlength{\hoffset}{-2.5cm} |
|
26 |
\setlength{\topmargin}{0cm} |
|
27 |
\setlength{\headheight}{0.5cm} |
|
28 |
\setlength{\headsep}{1cm} |
|
29 |
\setlength{\topskip}{0pt} |
|
30 |
\setlength{\oddsidemargin}{2cm} |
|
31 |
\setlength{\textwidth}{16.4cm} |
|
32 |
\setlength{\textheight}{25cm} |
|
33 |
\setlength{\footskip}{1cm} |
|
34 |
\setlength{\parindent}{0pt} |
|
35 |
\setlength{\tabcolsep}{0.2cm} |
|
36 |
|
|
37 |
\setlength{\unitlength}{1cm} |
|
38 |
|
|
39 |
\newcommand{\kivitendobgsettings}{% |
|
40 |
\setlength{\headsep}{2.5cm} |
|
41 |
\setlength{\textheight}{22.5cm} |
|
42 |
\setlength{\footskip}{0.9cm} |
|
43 |
} |
|
44 |
|
|
45 |
%% Standardschrift |
|
46 |
\newcommand{\defaultfont}{\fontfamily{cmss}\fontsize{10pt}{12pt}\fontseries{m}\selectfont} |
|
47 |
\renewcommand{\familydefault}{cmss} |
|
48 |
|
|
49 |
%% Checkboxen |
|
50 |
\newsavebox{\checkedbox} |
|
51 |
\savebox{\checkedbox}(0.2,0.4){ |
|
52 |
\put(-0.15,-0.425){$\times$} |
|
53 |
\put(-0.15,-0.45){$\Box$} |
|
54 |
} |
|
55 |
\newsavebox{\uncheckedbox} |
|
56 |
\savebox{\uncheckedbox}(0.2,0.4){ |
|
57 |
\put(-0.15,-0.45){$\Box$} |
|
58 |
} |
|
59 |
|
|
60 |
%% Farben |
|
61 |
\definecolor{kivitendoorange}{rgb}{1,0.4,0.2} |
|
62 |
\definecolor{kivitendodarkred}{rgb}{0.49,0,0} |
|
63 |
\definecolor{kivitendoyellow}{rgb}{1,1,0.4} |
|
64 |
\definecolor{kivitendobggray}{gray}{0.9} |
|
65 |
\definecolor{kivitendowhite}{gray}{1} |
|
66 |
|
|
67 |
%% Kopf- und Fußzeilen |
|
68 |
\newcommand{\kivitendofirsthead}{} |
|
69 |
\newcommand{\kivitendofirstfoot}{} |
|
70 |
\newcommand{\kivitendosecondhead}{} |
|
71 |
\newcommand{\kivitendosecondfoot}{\centerline{\defaultfont\small Seite \thepage}} |
|
72 |
|
|
73 |
\newcommand{\myhead}{% |
|
74 |
\ifthenelse{\boolean{defaultbg}}{% |
|
75 |
\begin{picture}(0,0) |
|
76 |
\put(-2.025,-28.1){\includegraphics*[width=\paperwidth,keepaspectratio=true]{images/hintergrund_seite1.png}} |
|
77 |
\end{picture}% |
|
78 |
}{}% |
|
79 |
\ifthenelse{\boolean{secondpagelogo}}{% |
|
80 |
\begin{picture}(0,0) |
|
81 |
\put(-2.025,-28.1){\includegraphics*[width=\paperwidth,keepaspectratio=true]{images/hintergrund_seite2.png}} |
|
82 |
\end{picture}% |
|
83 |
}{}% |
|
84 |
\ifthenelse{\boolean{draftbg}}{% |
|
85 |
\begin{picture}(0,0) |
|
86 |
\put(-2.025,-26.9){\includegraphics*[width=\paperwidth,keepaspectratio=true]{images/draft.png}} |
|
87 |
\end{picture}% |
|
88 |
}{}% |
|
89 |
\ifthenelse{\boolean{reqspeclogo}}{% |
|
90 |
\begin{picture}(0,0) |
|
91 |
\put(3,-22){\includegraphics*[width=13cm,keepaspectratio=true]{images/schachfiguren.jpg}} |
|
92 |
\put(0.275,-4.1){\colorbox{kivitendoorange}{\begin{minipage}[t][4.5cm]{2.5cm}\hspace*{2.5cm}\end{minipage}}} |
|
93 |
\put(0.275,-8.8){\colorbox{kivitendodarkred}{\begin{minipage}[t][4.5cm]{2.5cm}\hspace*{2.5cm}\end{minipage}}} |
|
94 |
\put(0.275,-13.5){\colorbox{kivitendoyellow}{\begin{minipage}[t][4.5cm]{2.5cm}\hspace*{2.5cm}\end{minipage}}} |
|
95 |
\end{picture}% |
|
96 |
}{}% |
|
97 |
\kivitendofirsthead |
|
98 |
} |
|
99 |
|
|
100 |
\newcommand{\mysecondhead}{% |
|
101 |
\ifthenelse{\boolean{defaultbg} \or \boolean{secondpagelogo}}{% |
|
102 |
\begin{picture}(0,0) |
|
103 |
\put(-2.025,-28.1){\includegraphics*[width=\paperwidth,keepaspectratio=true]{images/hintergrund_seite2.png}} |
|
104 |
\end{picture}% |
|
105 |
}{}% |
|
106 |
\ifthenelse{\boolean{draftbg}}{% |
|
107 |
\begin{picture}(0,0) |
|
108 |
\put(-2.025,-26.9){\includegraphics*[width=\paperwidth,keepaspectratio=true]{images/draft.png}} |
|
109 |
\end{picture}% |
|
110 |
}{}% |
|
111 |
\kivitendosecondhead |
|
112 |
} |
|
113 |
|
|
114 |
\newcommand{\myfoot}{\kivitendofirstfoot} |
|
115 |
\newcommand{\mysecondfoot}{\kivitendosecondfoot} |
|
116 |
|
|
117 |
\renewcommand{\ps@headings}{% |
|
118 |
\renewcommand{\@oddhead}{\myhead} |
|
119 |
\renewcommand{\@evenhead}{\@oddhead}% |
|
120 |
\renewcommand{\@oddfoot}{\myfoot} |
|
121 |
\renewcommand{\@evenfoot}{\@oddfoot}% |
|
122 |
} |
|
123 |
|
|
124 |
\renewcommand{\ps@plain}{% |
|
125 |
\renewcommand{\@oddhead}{\mysecondhead} |
|
126 |
\renewcommand{\@evenhead}{\@oddhead}% |
|
127 |
\renewcommand{\@oddfoot}{\mysecondfoot} |
|
128 |
\renewcommand{\@evenfoot}{\@oddfoot}% |
|
129 |
} |
|
130 |
|
|
131 |
\pagestyle{plain} |
|
132 |
\thispagestyle{headings} |
|
133 |
|
|
134 |
% Abschnitte mit Kasten hinterlegt |
|
135 |
|
|
136 |
\newcommand{\reqspecsectionstyle}{% |
|
137 |
\renewcommand{\thesection}{\alph{section}} |
|
138 |
\makeatletter |
|
139 |
\def\section{\@ifstar\unnumberedsection\numberedsection} |
|
140 |
\makeatother |
|
141 |
} |
|
142 |
|
|
143 |
\makeatletter |
|
144 |
\def\numberedsection{\@ifnextchar[%] |
|
145 |
\numberedsectionwithtwoarguments\numberedsectionwithoneargument} |
|
146 |
\def\unnumberedsection{\@ifnextchar[%] |
|
147 |
\unnumberedsectionwithtwoarguments\unnumberedsectionwithoneargument} |
|
148 |
\def\numberedsectionwithoneargument#1{\numberedsectionwithtwoarguments[#1]{#1}} |
|
149 |
\def\unnumberedsectionwithoneargument#1{\unnumberedsectionwithtwoarguments[#1]{#1}} |
|
150 |
\def\numberedsectionwithtwoarguments[#1]#2{% |
|
151 |
\ifhmode\par\fi |
|
152 |
\removelastskip |
|
153 |
\vskip 3ex\goodbreak |
|
154 |
\refstepcounter{section}% |
|
155 |
\noindent |
|
156 |
\begingroup |
|
157 |
\leavevmode\Large\bfseries\raggedright |
|
158 |
\begin{picture}(0,0) |
|
159 |
\put(0,0){\colorbox{kivitendoorange}{\parbox{0.7cm}{\hspace*{0.7cm}\\\vspace*{0.2cm}}}} |
|
160 |
\end{picture}% |
|
161 |
\hspace*{0.3cm}\textcolor{white}{\thesection{}.}% |
|
162 |
\quad% |
|
163 |
#2 |
|
164 |
\par |
|
165 |
\endgroup |
|
166 |
\vskip 2ex\nobreak |
|
167 |
\addcontentsline{toc}{section}{\protect\numberline{\thesection{}.}#1}% |
|
168 |
} |
|
169 |
\def\unnumberedsectionwithtwoarguments[#1]#2{% |
|
170 |
\ifhmode\par\fi |
|
171 |
\removelastskip |
|
172 |
\vskip 3ex\goodbreak |
|
173 |
\noindent |
|
174 |
\begingroup |
|
175 |
\leavevmode\Large\bfseries\raggedright |
|
176 |
\leavevmode\Large\bfseries\raggedright |
|
177 |
#2 |
|
178 |
\par |
|
179 |
\endgroup |
|
180 |
\vskip 2ex\nobreak% |
|
181 |
} |
|
182 |
\makeatother |
templates/print/Standard/requirement_spec.tex | ||
---|---|---|
1 |
% config: use-template-toolkit=1 |
|
2 |
% config: tag-style=$( )$ |
|
3 |
$( USE LxLatex )$ |
|
4 |
$( USE P )$ |
|
5 |
\documentclass{scrartcl} |
|
6 |
|
|
7 |
\usepackage[reqspeclogo,$( IF !rspec.version_id )$draftlogo$( ELSE )$secondpagelogo$( END )$]{kivitendo} |
|
8 |
|
|
9 |
\kivitendobgsettings |
|
10 |
|
|
11 |
\setlength{\LTpre}{0pt} |
|
12 |
\setlength{\LTpost}{0pt} |
|
13 |
|
|
14 |
\renewcommand{\kivitendosecondfoot}{% |
|
15 |
\parbox{12cm}{% |
|
16 |
\defaultfont\scriptsize% |
|
17 |
$( LxLatex.filter(rspec.displayable_name) )$\\ |
|
18 |
$( !rspec.version_id ? "Arbeitskopie ohne Version" : "Version " _ rspec.version.version_number _ " vom " _ rspec.version.itime.to_kivitendo(precision='minute') )$ |
|
19 |
|
|
20 |
\vspace*{0.2cm}% |
|
21 |
Seite \thepage% |
|
22 |
}% |
|
23 |
} |
|
24 |
|
|
25 |
\reqspecsectionstyle |
|
26 |
|
|
27 |
\begin{document} |
|
28 |
|
|
29 |
%% Titelseite |
|
30 |
|
|
31 |
\setlongtables |
|
32 |
\defaultfont |
|
33 |
|
|
34 |
\begin{picture}(0,0) |
|
35 |
\put(3.5,-5){% |
|
36 |
\begin{minipage}[t][6cm]{12cm} |
|
37 |
\Large |
|
38 |
\textcolor{kivitendodarkred}{$( LxLatex.filter(rspec.type.description) )$} |
|
39 |
|
|
40 |
\huge |
|
41 |
$( LxLatex.filter(rspec.customer.name) )$ |
|
42 |
|
|
43 |
\vspace*{0.5cm} |
|
44 |
\Large |
|
45 |
$( LxLatex.filter(rspec.title) )$ |
|
46 |
\normalsize |
|
47 |
%$( IF rspec.version_id )$ |
|
48 |
|
|
49 |
Version $( LxLatex.filter(rspec.version.version_number) )$ |
|
50 |
%$( END )$ |
|
51 |
\end{minipage}% |
|
52 |
} |
|
53 |
\end{picture} |
|
54 |
|
|
55 |
%% Inhaltsverzeichnis |
|
56 |
|
|
57 |
%\newpage |
|
58 |
|
|
59 |
%\tableofcontents |
|
60 |
|
|
61 |
%% Versionen |
|
62 |
\newpage |
|
63 |
|
|
64 |
\section{Versionen} |
|
65 |
|
|
66 |
\vspace*{0.7cm} |
|
67 |
|
|
68 |
%$( SET working_copy = rspec.working_copy_id ? rspec.working_copy : rspec )$ |
|
69 |
%$( SET versioned_copies = rspec.version_id ? working_copy.versioned_copies_sorted(max_version_number = rspec.version.version_number) : working_copy.versioned_copies_sorted )$ |
|
70 |
%$( IF !versioned_copies.size )$ |
|
71 |
Bisher wurden noch keine Versionen angelegt. |
|
72 |
%$( ELSE )$ |
|
73 |
\begin{longtable}{|p{2cm}|p{2cm}|p{12cm}|} |
|
74 |
\hline |
|
75 |
\multicolumn{1}{|r}{\small Version} & |
|
76 |
\multicolumn{1}{|r|}{\small Datum} & |
|
77 |
\small Beschreibung\\ |
|
78 |
\hline |
|
79 |
%$( FOREACH versioned_copy = versioned_copies )$ |
|
80 |
\multicolumn{1}{|r}{\small $( LxLatex.filter(versioned_copy.version.version_number) )$} & |
|
81 |
\multicolumn{1}{|r|}{\small $( LxLatex.filter(versioned_copy.version.itime.to_kivitendo(precision='minute')) )$} & |
|
82 |
\small $( LxLatex.filter(versioned_copy.version.description) )$\\ |
|
83 |
%$( END )$ |
|
84 |
\hline |
|
85 |
\end{longtable} |
|
86 |
%$( END )$ |
|
87 |
|
|
88 |
%$( BLOCK text_block_outputter )$ |
|
89 |
% $( SET text_blocks = rspec.text_blocks_sorted(output_position=output_position) )$ |
|
90 |
% $( IF text_blocks.size )$ |
|
91 |
|
|
92 |
\newpage |
|
93 |
|
|
94 |
\section{$( heading )$} |
|
95 |
|
|
96 |
% $( FOREACH text_block = text_blocks )$ |
|
97 |
|
|
98 |
\subsection{$( LxLatex.filter(text_block.title) )$} |
|
99 |
|
|
100 |
$( LxLatex.filter(text_block.text) )$ |
|
101 |
|
|
102 |
% $( END )$ |
|
103 |
% $( END )$ |
|
104 |
%$( END )$ |
|
105 |
|
|
106 |
%% Textblöcke davor |
|
107 |
$( PROCESS text_block_outputter output_position=0 heading='Allgemeines' )$ |
|
108 |
|
|
109 |
%% Abschnitte und Funktionsblöcke |
|
110 |
\newpage |
|
111 |
|
|
112 |
\section{Spezifikation} |
|
113 |
|
|
114 |
\setlength{\LTpre}{-0.3cm} |
|
115 |
|
|
116 |
|
|
117 |
%$( FOREACH top_item = rspec.sections_sorted )$ |
|
118 |
|
|
119 |
\subsection{Abschnitt $( LxLatex.filter(top_item.fb_number) )$: $( LxLatex.filter(top_item.title) )$} |
|
120 |
|
|
121 |
% $( IF top_item.description )$ |
|
122 |
$( LxLatex.filter(top_item.description.replace('\r', '').replace('\n+\Z', '')) )$ |
|
123 |
|
|
124 |
\vspace{0.5cm} |
|
125 |
% $( END )$ |
|
126 |
% $( FOREACH item = top_item.children_sorted )$ |
|
127 |
\parbox[t]{1.0cm}{\textcolor{kivitendodarkred}{$>>>$}}% |
|
128 |
\parbox[t]{15.0cm}{% |
|
129 |
\begin{longtable}{p{2.8cm}p{11.7cm}} |
|
130 |
Funktionsblock & $( LxLatex.filter(item.fb_number) )$\\ |
|
131 |
Beschreibung & $( LxLatex.filter(item.description) )$\\ |
|
132 |
Abhängigkeiten & $( LxLatex.filter(P.requirement_spec_item_dependency_list(item)) )$ |
|
133 |
\end{longtable}} |
|
134 |
|
|
135 |
% $( FOREACH sub_item = item.children_sorted )$ |
|
136 |
\hspace*{1.15cm}\rule{15.2cm}{0.2pt}\\ |
|
137 |
\hspace*{1.0cm}% |
|
138 |
\parbox[t]{15.0cm}{% |
|
139 |
\begin{longtable}{p{2.8cm}p{11.7cm}} |
|
140 |
Unterfunktionsblock & $( LxLatex.filter(sub_item.fb_number) )$\\ |
|
141 |
Beschreibung & $( LxLatex.filter(sub_item.description) )$\\ |
|
142 |
Abhängigkeiten & $( LxLatex.filter(P.requirement_spec_item_dependency_list(sub_item)) )$ |
|
143 |
\end{longtable}} |
|
144 |
|
|
145 |
% $( END )$ |
|
146 |
|
|
147 |
% $( UNLESS loop.last )$ |
|
148 |
\vspace{0.2cm} |
|
149 |
\hrule |
|
150 |
\vspace{0.4cm} |
|
151 |
|
|
152 |
% $( END )$ |
|
153 |
|
|
154 |
% $( END )$ |
|
155 |
% |
|
156 |
%$( END )$ |
|
157 |
|
|
158 |
%% Textblöcke dahinter |
|
159 |
$( PROCESS text_block_outputter output_position=1 heading='Weitere Punkte' )$ |
|
160 |
|
|
161 |
|
|
162 |
\end{document} |
templates/webpages/requirement_spec/show.html | ||
---|---|---|
48 | 48 |
metadata: { type: "text-blocks-front" }, |
49 | 49 |
attr: { id: "tb-front", class: "text-block-context-menu" }, |
50 | 50 |
children: [ |
51 |
[% FOREACH tb = SELF.requirement_spec.text_blocks_for_position(0) %]
|
|
51 |
[% FOREACH tb = SELF.requirement_spec.text_blocks_sorted(output_position=0) %]
|
|
52 | 52 |
[% P.requirement_spec_text_block_jstree_data(tb).json %][% IF !loop.last %],[% END %] |
53 | 53 |
[% END %] |
54 | 54 |
]}, |
... | ... | |
66 | 66 |
metadata: { type: "text-blocks-back" }, |
67 | 67 |
attr: { id: "tb-back", class: "text-block-context-menu" }, |
68 | 68 |
children: [ |
69 |
[% FOREACH tb = SELF.requirement_spec.text_blocks_for_position(1) %]
|
|
69 |
[% FOREACH tb = SELF.requirement_spec.text_blocks_sorted(output_position=1) %]
|
|
70 | 70 |
[% P.requirement_spec_text_block_jstree_data(tb).json %][% IF !loop.last %],[% END %] |
71 | 71 |
[% END %] |
72 | 72 |
]}]; |
templates/webpages/requirement_spec_item/_function_block.html | ||
---|---|---|
9 | 9 |
<div class="sub-function-block-header" id="sub-function-block_header_[%- requirement_spec_item.id -%]"> |
10 | 10 |
[%- LxERP.t8("Sub function blocks") -%] |
11 | 11 |
</div> |
12 |
[%- FOREACH sub_function_block = requirement_spec_item.sorted_children -%]
|
|
12 |
[%- FOREACH sub_function_block = requirement_spec_item.children_sorted -%]
|
|
13 | 13 |
[%- INCLUDE 'requirement_spec_item/_sub_function_block.html' requirement_spec_item=sub_function_block -%] |
14 | 14 |
[%- END -%] |
15 | 15 |
</div> |
templates/webpages/requirement_spec_item/_section.html | ||
---|---|---|
10 | 10 |
</div> |
11 | 11 |
|
12 | 12 |
<div id="section-list" class="section"> |
13 |
[%- FOREACH function_block = requirement_spec_item.sorted_children -%]
|
|
13 |
[%- FOREACH function_block = requirement_spec_item.children_sorted -%]
|
|
14 | 14 |
[%- INCLUDE 'requirement_spec_item/_function_block.html' requirement_spec_item=function_block -%] |
15 | 15 |
[%- END -%] |
16 | 16 |
</div> |
Auch abrufbar als: Unified diff
Pflichtenhefte: PDFs zu Arbeitskopie und Versionen erzeugen