use Rose::Object::MakeMethods::Generic
(
- scalar => [ qw(requirement_spec_item customers types statuses db_args flat_filter is_template visible_item visible_section) ],
+ scalar => [ qw(requirement_spec_item customers types statuses db_args flat_filter visible_item visible_section) ],
'scalar --get_set_init' => [ qw(requirement_spec complexities risks projects copy_source js) ],
);
sub action_new {
my ($self) = @_;
- $self->requirement_spec(SL::DB::RequirementSpec->new);
+ $self->requirement_spec(SL::DB::RequirementSpec->new(is_template => $::form->{is_template}));
if ($self->copy_source) {
$self->requirement_spec->$_($self->copy_source->$_) for qw(type_id status_id customer_id title hourly_rate)
}
- $self->render('requirement_spec/new', title => t8('Create a new requirement spec'));
+ $self->render('requirement_spec/new', title => $self->requirement_spec->is_template ? t8('Create a new requirement spec section template') : t8('Create a new requirement spec'));
}
sub action_ajax_edit {
$::auth->assert('sales_quotation_edit');
$::request->{layout}->use_stylesheet("${_}.css") for qw(jquery.contextMenu requirement_spec);
$::request->{layout}->use_javascript("${_}.js") for qw(jquery.jstree jquery/jquery.contextMenu client_js requirement_spec);
- $self->is_template($::form->{is_template} ? 1 : 0);
$self->init_visible_section;
return 1;
my $self = shift;
my $is_new = !$self->requirement_spec->id;
my $params = delete($::form->{requirement_spec}) || { };
- my $title = $is_new ? t8('Create a new requirement spec') : t8('Edit requirement spec');
$self->requirement_spec->assign_attributes(%{ $params });
+ my $title = $is_new && $self->requirement_spec->is_template ? t8('Create a new requirement spec section template')
+ : $is_new ? t8('Create a new requirement spec')
+ : $self->requirement_spec->is_template ? t8('Edit section template')
+ : t8('Edit requirement spec');
+
my @errors = $self->requirement_spec->validate;
if (@errors) {
return $self->render('requirement_spec/new', title => $title);
}
+ my $info = $self->requirement_spec->is_template ? t8('The section template has been saved.') : t8('The requirement spec has been saved.');
+
if ($::request->is_ajax) {
my $html = $self->render('requirement_spec/_header', { output => 0 });
return $self->invalidate_version
->replaceWith('#requirement-spec-header', $html)
- ->flash('info', t8('The requirement spec has been saved.'))
+ ->flash('info', $info)
->render($self);
}
- flash_later('info', $is_new ? t8('The requirement spec has been created.') : t8('The requirement spec has been saved.'));
+ flash_later('info', $info);
$self->redirect_to(action => 'show', id => $self->requirement_spec->id);
}
and => [
@{ $args{where} || [] },
working_copy_id => undef,
- is_template => $self->is_template
+ is_template => $::form->{is_template} ? 1 : 0,
]];
$self->db_args(\%args);
my $callback = $self->get_callback;
+ my $is_template = $::form->{is_template};
my $report = SL::ReportGenerator->new(\%::myconfig, $::form);
$self->{report} = $report;
- my @columns = qw(title customer status type projectnumber mtime version);
- my @sortable = qw(title customer status type projectnumber mtime);
+ my @columns = $is_template ? qw(title mtime) : qw(title customer status type projectnumber mtime version);
+ my @sortable = $is_template ? qw(title mtime) : qw(title customer status type projectnumber mtime);
my %column_defs = (
title => { obj_link => sub { $self->url_for(action => 'show', id => $_[0]->id, callback => $callback) } },
- customer => { raw_data => sub { $self->presenter->customer($_[0]->customer, display => 'table-cell', callback => $callback) },
- sub => sub { $_[0]->customer->name } },
- projectnumber => { raw_data => sub { $self->presenter->project($_[0]->project, display => 'table-cell', callback => $callback) },
- sub => sub { $_[0]->project_id ? $_[0]->project->projectnumber : '' } },
- status => { sub => sub { $_[0]->status->description } },
- type => { sub => sub { $_[0]->type->description } },
- version => { sub => sub { $_[0]->version_id ? $_[0]->version->version_number : t8('Working copy without version') } },
mtime => { sub => sub { ($_[0]->mtime || $_[0]->itime)->to_kivitendo(precision => 'minute') } },
);
+ if (!$is_template) {
+ %column_defs = (
+ %column_defs,
+ customer => { raw_data => sub { $self->presenter->customer($_[0]->customer, display => 'table-cell', callback => $callback) },
+ sub => sub { $_[0]->customer->name } },
+ projectnumber => { raw_data => sub { $self->presenter->project($_[0]->project, display => 'table-cell', callback => $callback) },
+ sub => sub { $_[0]->project_id ? $_[0]->project->projectnumber : '' } },
+ status => { sub => sub { $_[0]->status->description } },
+ type => { sub => sub { $_[0]->type->description } },
+ version => { sub => sub { $_[0]->version_id ? $_[0]->version->version_number : t8('Working copy without version') } },
+ );
+ }
+
map { $column_defs{$_}->{text} ||= $::locale->text( $self->get_sort_spec->{$_}->{title} ) } keys %column_defs;
$report->set_options(
std_column_visibility => 1,
controller_class => 'RequirementSpec',
output_format => 'HTML',
- raw_top_info_text => $self->render('requirement_spec/report_top', { output => 0 }),
+ raw_top_info_text => $self->render('requirement_spec/report_top', { output => 0 }, is_template => $is_template),
raw_bottom_info_text => $self->render('requirement_spec/report_bottom', { output => 0 }),
- title => $::locale->text('Requirement Specs'),
+ title => $is_template ? t8('Requirement Spec Section Templates') : t8('Requirement Specs'),
allow_pdf_export => 1,
allow_csv_export => 1,
);
my ($self) = @_;
my $rspec = SL::DB::RequirementSpec->new(id => $self->requirement_spec->id)->load;
+ return $self->js if $rspec->is_template;
+
$rspec->invalidate_version;
my $html = $self->render('requirement_spec/_version', { output => 0 }, requirement_spec => $rspec);
return $self->js->html('#requirement_spec_version', $html);
}
-
1;
columns => [
id => { type => 'serial', not_null => 1 },
- type_id => { type => 'integer', not_null => 1 },
- status_id => { type => 'integer', not_null => 1 },
+ type_id => { type => 'integer' },
+ status_id => { type => 'integer' },
version_id => { type => 'integer' },
- customer_id => { type => 'integer', not_null => 1 },
+ customer_id => { type => 'integer' },
project_id => { type => 'integer' },
title => { type => 'text', not_null => 1 },
hourly_rate => { type => 'numeric', default => '0', not_null => 1, precision => 2, scale => 8 },
"Are you sure?":"Sind Sie sicher?",
"Copy":"Kopieren",
"Copy requirement spec":"Pflichtenheft kopieren",
+"Copy section template":"Abschnittsvorlage kopieren",
"Create PDF":"PDF erzeugen",
"Create new version":"Neue Version anlegen",
"Database Connection Test":"Test der Datenbankverbindung",
"Delete":"Löschen",
"Delete requirement spec":"Pflichtenheft löschen",
+"Delete section template":"Abschnittsvorlage löschen",
"Delete text block":"Textblock löschen",
"Do you really want to cancel?":"Wollen Sie wirklich abbrechen?",
"Do you really want to revert to this version?":"Wollen Sie wirklich auf diese Version zurücksetzen?",
"Requirement spec actions":"Pflichtenheftaktionen",
"Revert to version":"Auf Version zurücksetzen",
"Save":"Speichern",
+"Section template actions":"Abschnittsvorlagen-Aktionen",
"Section/Function block actions":"Abschnitts-/Funktionsblockaktionen",
"Text block actions":"Textblockaktionen",
"The description is missing.":"Die Beschreibung fehlt.",
// ----------------------------- context menus -----------------------------
// -------------------------------------------------------------------------
-ns.create_context_menus = function() {
- var general_actions = {
- sep98: "---------"
- , general_actions: { name: kivi.t8('Requirement spec actions'), className: 'context-menu-heading' }
- // , sep99: "---------"
- , create_pdf: { name: kivi.t8('Create PDF'), icon: "pdf", callback: kivi.requirement_spec.create_reqspec_pdf }
- , create_version: { name: kivi.t8('Create new version'), icon: "new", callback: kivi.requirement_spec.create_version, disabled: kivi.requirement_spec.disable_commands }
- , copy_reqspec: { name: kivi.t8('Copy requirement spec'), icon: "copy", callback: kivi.requirement_spec.copy_reqspec }
- , delete_reqspec: { name: kivi.t8('Delete requirement spec'), icon: "delete", callback: kivi.requirement_spec.delete_reqspec }
- };
+ns.create_context_menus = function(is_template) {
+ if (is_template) {
+ var general_actions = {
+ sep98: "---------"
+ , general_actions: { name: kivi.t8('Section template actions'), className: 'context-menu-heading' }
+ // , sep99: "---------"
+ , copy_reqspec: { name: kivi.t8('Copy section template'), icon: "copy", callback: kivi.requirement_spec.copy_reqspec }
+ , delete_reqspec: { name: kivi.t8('Delete section template'), icon: "delete", callback: kivi.requirement_spec.delete_reqspec }
+ };
+ var events = {};
+
+ } else { // if (is_template)
+ var general_actions = {
+ sep98: "---------"
+ , general_actions: { name: kivi.t8('Requirement spec actions'), className: 'context-menu-heading' }
+ // , sep99: "---------"
+ , create_pdf: { name: kivi.t8('Create PDF'), icon: "pdf", callback: kivi.requirement_spec.create_reqspec_pdf }
+ , create_version: { name: kivi.t8('Create new version'), icon: "new", callback: kivi.requirement_spec.create_version, disabled: kivi.requirement_spec.disable_commands }
+ , copy_reqspec: { name: kivi.t8('Copy requirement spec'), icon: "copy", callback: kivi.requirement_spec.copy_reqspec }
+ , delete_reqspec: { name: kivi.t8('Delete requirement spec'), icon: "delete", callback: kivi.requirement_spec.delete_reqspec }
+ };
+
+ var events = {
+ show: kivi.requirement_spec.text_block_popup_menu_shown
+ , hide: kivi.requirement_spec.text_block_popup_menu_hidden
+ };
+
+ $.contextMenu({
+ selector: '.text-block-context-menu',
+ events: {
+ show: kivi.requirement_spec.text_block_popup_menu_shown
+ , hide: kivi.requirement_spec.text_block_popup_menu_hidden
+ },
+ items: $.extend({
+ heading: { name: kivi.t8('Text block actions'), className: 'context-menu-heading' }
+ , add: { name: kivi.t8('Add text block'), icon: "add", callback: kivi.requirement_spec.standard_text_block_ajax_call }
+ , edit: { name: kivi.t8('Edit text block'), icon: "edit", callback: kivi.requirement_spec.standard_text_block_ajax_call, disabled: kivi.requirement_spec.disable_edit_text_block_commands }
+ , delete: { name: kivi.t8('Delete text block'), icon: "delete", callback: kivi.requirement_spec.ask_delete_text_block, disabled: kivi.requirement_spec.disable_edit_text_block_commands }
+ , sep1: "---------"
+ , flag: { name: kivi.t8('Toggle marker'), icon: "flag", callback: kivi.requirement_spec.standard_text_block_ajax_call, disabled: kivi.requirement_spec.disable_edit_text_block_commands }
+ , sep2: "---------"
+ , copy: { name: kivi.t8('Copy'), icon: "copy", callback: kivi.requirement_spec.standard_text_block_ajax_call, disabled: kivi.requirement_spec.disable_edit_text_block_commands }
+ , paste: { name: kivi.t8('Paste'), icon: "paste", callback: kivi.requirement_spec.standard_text_block_ajax_call }
+ }, general_actions)
+ });
+
+ $.contextMenu({
+ selector: '.time-cost-estimate-context-menu',
+ items: $.extend({
+ heading: { name: kivi.t8('Time/cost estimate actions'), className: 'context-menu-heading' }
+ , edit: { name: kivi.t8('Edit'), icon: "edit", callback: kivi.requirement_spec.standard_time_cost_estimate_ajax_call }
+ }, general_actions)
+ });
+
+ $.contextMenu({
+ selector: '.edit-time-cost-estimate-context-menu',
+ items: $.extend({
+ heading: { name: kivi.t8('Time/cost estimate actions'), className: 'context-menu-heading' }
+ , save: { name: kivi.t8('Save'), icon: "save", callback: kivi.requirement_spec.standard_time_cost_estimate_ajax_call }
+ , cancel: { name: kivi.t8('Cancel'), icon: "close", callback: kivi.requirement_spec.standard_time_cost_estimate_ajax_call }
+ }, general_actions)
+ });
+
+ $.contextMenu({
+ selector: '.versioned-copy-context-menu',
+ items: $.extend({
+ heading: { name: kivi.t8('Version actions'), className: 'context-menu-heading' }
+ , create_version_pdf: { name: kivi.t8('Create PDF'), icon: "pdf", callback: kivi.requirement_spec.create_pdf_for_versioned_copy_ajax_call }
+ , revert_to_version: { name: kivi.t8('Revert to version'), icon: "revert", callback: kivi.requirement_spec.revert_to_versioned_copy_ajax_call, disabled: kivi.requirement_spec.disable_versioned_copy_item_commands }
+ }, general_actions)
+ });
+ } // if (is_template) ... else ...
$.contextMenu({
selector: '#content',
items: general_actions
});
- var events = {
- show: kivi.requirement_spec.text_block_popup_menu_shown
- , hide: kivi.requirement_spec.text_block_popup_menu_hidden
- };
-
- $.contextMenu({
- selector: '.text-block-context-menu',
- events: {
- show: kivi.requirement_spec.text_block_popup_menu_shown
- , hide: kivi.requirement_spec.text_block_popup_menu_hidden
- },
- items: $.extend({
- heading: { name: kivi.t8('Text block actions'), className: 'context-menu-heading' }
- , add: { name: kivi.t8('Add text block'), icon: "add", callback: kivi.requirement_spec.standard_text_block_ajax_call }
- , edit: { name: kivi.t8('Edit text block'), icon: "edit", callback: kivi.requirement_spec.standard_text_block_ajax_call, disabled: kivi.requirement_spec.disable_edit_text_block_commands }
- , delete: { name: kivi.t8('Delete text block'), icon: "delete", callback: kivi.requirement_spec.ask_delete_text_block, disabled: kivi.requirement_spec.disable_edit_text_block_commands }
- , sep1: "---------"
- , flag: { name: kivi.t8('Toggle marker'), icon: "flag", callback: kivi.requirement_spec.standard_text_block_ajax_call, disabled: kivi.requirement_spec.disable_edit_text_block_commands }
- , sep2: "---------"
- , copy: { name: kivi.t8('Copy'), icon: "copy", callback: kivi.requirement_spec.standard_text_block_ajax_call, disabled: kivi.requirement_spec.disable_edit_text_block_commands }
- , paste: { name: kivi.t8('Paste'), icon: "paste", callback: kivi.requirement_spec.standard_text_block_ajax_call }
- }, general_actions)
- });
-
events = {
show: kivi.requirement_spec.item_popup_menu_shown
, hide: kivi.requirement_spec.item_popup_menu_hidden
, paste: { name: kivi.t8('Paste'), icon: "paste", callback: kivi.requirement_spec.standard_item_ajax_call }
}, general_actions)
});
-
- $.contextMenu({
- selector: '.time-cost-estimate-context-menu',
- items: $.extend({
- heading: { name: kivi.t8('Time/cost estimate actions'), className: 'context-menu-heading' }
- , edit: { name: kivi.t8('Edit'), icon: "edit", callback: kivi.requirement_spec.standard_time_cost_estimate_ajax_call }
- }, general_actions)
- });
-
- $.contextMenu({
- selector: '.edit-time-cost-estimate-context-menu',
- items: $.extend({
- heading: { name: kivi.t8('Time/cost estimate actions'), className: 'context-menu-heading' }
- , save: { name: kivi.t8('Save'), icon: "save", callback: kivi.requirement_spec.standard_time_cost_estimate_ajax_call }
- , cancel: { name: kivi.t8('Cancel'), icon: "close", callback: kivi.requirement_spec.standard_time_cost_estimate_ajax_call }
- }, general_actions)
- });
-
- $.contextMenu({
- selector: '.versioned-copy-context-menu',
- items: $.extend({
- heading: { name: kivi.t8('Version actions'), className: 'context-menu-heading' }
- , create_version_pdf: { name: kivi.t8('Create PDF'), icon: "pdf", callback: kivi.requirement_spec.create_pdf_for_versioned_copy_ajax_call }
- , revert_to_version: { name: kivi.t8('Revert to version'), icon: "revert", callback: kivi.requirement_spec.revert_to_versioned_copy_ajax_call, disabled: kivi.requirement_spec.disable_versioned_copy_item_commands }
- }, general_actions)
- });
};
}); // end of namespace(...., function() {...
'Add RFQ' => 'Preisanfrage erfassen',
'Add Request for Quotation' => 'Anfrage erfassen',
'Add Requirement Spec' => 'Pflichtenheft erfassen',
+ 'Add Requirement Spec Section Template' => 'Pflichtenheft-Abschnittsvorlage erfassen',
'Add Sales Delivery Order' => 'Lieferschein (Verkauf) erfassen',
'Add Sales Invoice' => 'Rechnung erfassen',
'Add Sales Order' => 'Auftrag erfassen',
'Copy file from #1 to #2 failed: #3' => 'Kopieren der Datei von #1 nach #2 schlug fehl: #3',
'Copy' => 'Kopieren',
'Copy requirement spec' => 'Pflichtenheft kopieren',
+ 'Copy section template' => 'Abschnittsvorlage kopieren',
'Correct taxkey' => 'Richtiger Steuerschlüssel',
'Cost' => 'Kosten',
'Costs' => 'Kosten',
'Create a new project' => 'Neues Projekt anlegen',
'Create a new project type' => 'Einen neuen Projekttypen anlegen',
'Create a new requirement spec' => 'Ein neues Pflichtenheft anlegen',
+ 'Create a new requirement spec section template' => 'Eine neue Pflichtenheft-Abschnittsvorlage erfassen',
'Create a new requirement spec status' => 'Einen neuen Pflichtenheftstatus anlegen',
'Create a new requirement spec type' => 'Einen neuen Pflichtenhefttypen anlegen',
'Create a new risk level' => 'Einen neuen Risikograd anlegen',
'Delete links' => 'Verknüpfungen löschen',
'Delete profile' => 'Profil löschen',
'Delete requirement spec' => 'Pflichtenheft löschen',
+ 'Delete section template' => 'Abschnittsvorlage löschen',
'Delete text block' => 'Textblock löschen',
'Delete transaction' => 'Buchung löschen',
'Deleted' => 'Gelöscht',
'Edit requirement spec type' => 'Pflichtenhefttypen bearbeiten',
'Edit risk level' => 'Risikograd bearbeiten',
'Edit section #1' => 'Abschnitt #1 bearbeiten',
+ 'Edit section template' => 'Abschnittsvorlage bearbeiten',
'Edit templates' => 'Vorlagen bearbeiten',
'Edit text block' => 'Textblock bearbeiten',
'Edit text block \'#1\'' => 'Textblock \'#1\' bearbeiten',
'Requested execution date to' => 'Gewünschtes Ausführungsdatum bis',
'Requests for Quotation' => 'Preisanfragen',
'Required by' => 'Lieferdatum',
+ 'Requirement Spec Section Templates' => 'Pflichtenheft-Abschnittsvorlagen',
'Requirement Spec Status' => 'Pflichtenheftstatus',
'Requirement Spec Statuses' => 'Pflichtenheftstatus',
'Requirement Spec Type' => 'Pflichtenhefttyp',
'Requirement spec actions' => 'Pflichtenheftaktionen',
'Requirement spec function block #1 with #2 sub function blocks; description: "#3"' => 'Pflichtenheft-Funktionsblock #1 mit #2 Unterfunktionsblöcken; Beschreibung: "#3"',
'Requirement spec section #1 "#2" with #3 function blocks and a total of #4 sub function blocks; preamble: "#5"' => 'Pflichtenheftabschnitt #1 "#2" mit #3 Funktionsblöcken und insgesamt #4 Unterfunktionsblöcken; Einleitung: "#5"',
+ 'Requirement spec section template \'#1\'' => 'Pflichtenheft_Abschnittsvorlage \'#1\'',
'Requirement spec sub function block #1; description: "#2"' => 'Pflichtenheft-Unterfunktionsblock #1; Beschreibung: "#2"',
'Requirement spec text block "#1"; content: "#2"' => 'Pflichtenheft-Textblock "1"; Inhalt: "#2"',
'Requirement specs' => 'Pflichtenhefte',
'Searchable' => 'Durchsuchbar',
'Secondary sorting' => 'Untersortierung',
'Section "#1"' => 'Abschnitt "#1"',
+ 'Section template actions' => 'Abschnittsvorlagen-Aktionen',
'Section/Function block actions' => 'Abschnitts-/Funktionsblockaktionen',
'Sections' => 'Abschnitte',
'Select' => 'auswählen',
'The risk level is in use and cannot be deleted.' => 'Der Risikograd wird verwendet und kann nicht gelöscht werden.',
'The second reason is that kivitendo allowed the user to enter the tax amount manually regardless of the taxkey used.' => 'Der zweite Grund war, dass kivitendo zuließ, dass die Benutzer beliebige, von den tatsächlichen Steuerschlüsseln unabhängige Steuerbeträge eintrugen.',
'The second way is to use Perl\'s CPAN module and let it download and install the module for you.' => 'Die zweite Variante besteht darin, Perls CPAN-Modul zu benutzen und es das Modul für Sie installieren zu lassen.',
+ 'The section template has been saved.' => 'Die Abschnittsvorlage wurde gespeichert.',
'The selected bank account does not exist anymore.' => 'Das ausgewählte Bankkonto existiert nicht mehr.',
'The selected bin does not exist.' => 'Der ausgewählte Lagerplatz existiert nicht.',
'The selected currency' => 'Die ausgewählte Währung',
module=controller.pl
action=Project/new
+[Master Data--Add Requirement Spec Section Template]
+ACCESS=project_edit
+module=controller.pl
+action=RequirementSpec/new
+is_template=1
+
[Master Data--Update Prices]
ACCESS=part_service_assembly_edit
module=ic.pl
filter.active=active
filter.valid=valid
+[Master Data--Reports--Requirement Spec Section Templates]
+module=controller.pl
+action=RequirementSpec/list
+is_template=1
+
[AR]
[AR--Add Quotation]
--- /dev/null
+-- @tag: requirement_specs_section_templates
+-- @description: requirement_specs_section_templates
+-- @depends: release_3_0_0 requirement_specs
+-- @charset: utf-8
+
+ALTER TABLE requirement_specs ALTER COLUMN type_id DROP NOT NULL;
+ALTER TABLE requirement_specs ALTER COLUMN status_id DROP NOT NULL;
+ALTER TABLE requirement_specs ALTER COLUMN customer_id DROP NOT NULL;
+
+ALTER TABLE requirement_specs
+ADD CONSTRAINT requirement_specs_is_template_or_has_customer_status_type
+CHECK (
+ is_template
+ OR ( (type_id IS NOT NULL)
+ AND (status_id IS NOT NULL)
+ AND (customer_id IS NOT NULL))
+);
<a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8("Hide Filter") %]</a>
<form method="post" action="controller.pl">
+ [%- L.hidden_tag("is_template", is_template) %]
<p>
<table class="rs_input_field">
<td>[% L.input_tag('filter.title:substr::ilike', filter.title_substr__ilike) %]</td>
</tr>
+[%- UNLESS is_template %]
<tr>
<th align="right">[% LxERP.t8("Customer") %]</th>
<td>[% L.input_tag('filter.customer.name:substr::ilike', filter.customer.name_substr__ilike) %]</td>
<th align="right">[% LxERP.t8("Project") %]</th>
<td>[% L.select_tag('filter.project_id', SELF.projects, default=filter.project_id, title_key="full_description", with_empty=1) %]</td>
</tr>
+[%- END %]
</table>
</p>
%]
<form method="post" action="controller.pl" id="[% id_prefix %]">
[% L.hidden_tag("id", SELF.requirement_spec.id, id=id_prefix _ '_id') %]
+ [% L.hidden_tag("requirement_spec.is_template", SELF.requirement_spec.is_template, id=id_prefix _ '_is_template') %]
<table class="rs_input_field">
<tr>
<td>[% L.input_tag("requirement_spec.title", SELF.requirement_spec.title, id=id_prefix _ '_title') %]</td>
</tr>
+[%- UNLESS SELF.requirement_spec.is_template %]
+
<tr>
<td>[% LxERP.t8("Requirement Spec Type") %]</td>
<td>[% L.select_tag("requirement_spec.type_id", SELF.types, default=SELF.requirement_spec.type_id, title_key="description", id=id_prefix _ '_type_id') %]</td>
<td>[% L.input_tag("requirement_spec.hourly_rate_as_number", SELF.requirement_spec.hourly_rate_as_number, id=id_prefix _ '_hourly_rate_as_number') %]</td>
</tr>
+[%- END %]
+
</table>
[%- IF SELF.copy_source %]
[% IF submit_as == 'post' %]
[% L.hidden_tag("action", "RequirementSpec/dispatch", id=id_prefix _ '_action') %]
[% L.submit_tag("action_" _ (SELF.requirement_spec.id ? "update" : "create"), LxERP.t8('Save'), id=id_prefix _ '_action_update') %]
- <a href="[% SELF.url_for(action="list") %]">[% LxERP.t8('Abort') %]</a>
+ <a href="[% SELF.url_for(action="list", is_template=SELF.requirement_spec.is_template) %]">[% LxERP.t8('Abort') %]</a>
[% ELSE %]
[% L.ajax_submit_tag("controller.pl?action=RequirementSpec/update", "#" _ id_prefix, LxERP.t8("Save")) %]
[% END %]
[%- USE HTML -%][%- USE LxERP -%]
<div id="requirement-spec-header">
<h1>
- [%- HTML.escape(SELF.requirement_spec.displayable_name('format', 'with_customer')) %]
- [% LxERP.t8("for") %]
- [% HTML.escape(SELF.requirement_spec.customer.displayable_name) -%]
+ [%- IF SELF.requirement_spec.is_template %]
+ [%- HTML.escape(LxERP.t8("Requirement spec section template '#1'", SELF.requirement_spec.title)) %]
+ [%- ELSE %]
+ [%- HTML.escape(SELF.requirement_spec.displayable_name('format', 'with_customer')) %]
+ [% LxERP.t8("for") %]
+ [% HTML.escape(SELF.requirement_spec.customer.displayable_name) -%]
+ [%- END %]
</h1>
</div>
[%- INCLUDE 'requirement_spec/_header.html' %]
-[%- L.hidden_tag('requirement_spec_id', SELF.requirement_spec.id) -%]
+[%- L.hidden_tag('requirement_spec_id', SELF.requirement_spec.id, 'data-is-template'=(SELF.requirement_spec.is_template ? 1 : 0)) -%]
<div class="tabwidget">
<ul>
<li><a href="#function-blocks-tab">[%- LxERP.t8("Content") %]</a></li>
<li><a href="controller.pl?action=RequirementSpec/ajax_edit&id=[% HTML.url(SELF.requirement_spec.id) %]">[%- LxERP.t8("Basic settings") %]</a></li>
- <li><a href="controller.pl?action=RequirementSpec/ajax_show_time_and_cost_estimate&id=[% HTML.url(SELF.requirement_spec.id) %]">[%- LxERP.t8("Time and cost estimate") %]</a></li>
- <li><a href="controller.pl?action=RequirementSpecVersion/list&requirement_spec_id=[% HTML.url(SELF.requirement_spec.id) %]">[%- LxERP.t8("Versions") %]</a></li>
+ [%- UNLESS SELF.requirement_spec.is_template %]
+ <li><a href="controller.pl?action=RequirementSpec/ajax_show_time_and_cost_estimate&id=[% HTML.url(SELF.requirement_spec.id) %]">[%- LxERP.t8("Time and cost estimate") %]</a></li>
+ <li><a href="controller.pl?action=RequirementSpecVersion/list&requirement_spec_id=[% HTML.url(SELF.requirement_spec.id) %]">[%- LxERP.t8("Versions") %]</a></li>
+ [%- END %]
</ul>
<div id="function-blocks-tab">
- <div id="requirement_spec_version">
+ [%- UNLESS SELF.requirement_spec.is_template %]
+ <div id="requirement_spec_version">
[%- INCLUDE 'requirement_spec/_version.html' requirement_spec=SELF.requirement_spec -%]
- </div>
+ </div>
+ [%- END %]
<div id="column-container" class="clearfix">
<div id="tree-column">
<script type="text/javascript">
<!--
$(function() {
- var tree_data = [
- { data: [% JSON.json(LxERP.t8("Text blocks front")) %],
- metadata: { type: "text-blocks-front" },
- attr: { id: "tb-front", class: "text-block-context-menu" },
- children: [
-[% 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 %]
- ]},
+ var initially_open = ['sections'
+[%- FOREACH section = SELF.requirement_spec.sections -%]
+ , "fb-[% section.id %]"
+ [%- FOREACH function_block = section.children -%]
+ , "fb-[% function_block.id -%]"
+ [%- END -%]
+[%- END -%]
+ ];
- { data: [% JSON.json(LxERP.t8("Sections")) %],
+ var tree_data = [{
+ data: [% JSON.json(LxERP.t8("Sections")) %],
metadata: { type: "sections" },
attr: { id: "sections", class: "section-context-menu" },
children: [
[% FOREACH section = SELF.requirement_spec.sections %]
[% P.requirement_spec_item_jstree_data(section).json %][% IF !loop.last %],[% END %]
[% END %]
- ]},
+ ]}];
+
+[% UNLESS SELF.requirement_spec.is_template %]
+ tree_data.unshift({
+ data: [% JSON.json(LxERP.t8("Text blocks front")) %],
+ metadata: { type: "text-blocks-front" },
+ attr: { id: "tb-front", class: "text-block-context-menu" },
+ children: [
+[% 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 %]
+ ]});
- { data: [% JSON.json(LxERP.t8("Text blocks back")) %],
+ tree_data.push({
+ data: [% JSON.json(LxERP.t8("Text blocks back")) %],
metadata: { type: "text-blocks-back" },
attr: { id: "tb-back", class: "text-block-context-menu" },
children: [
[% 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 %]
- ]}];
+ ]});
+
+ initially_open = initially_open.concat(['tb-front', 'tb-back']);
+[% END %]
$('#tree').jstree({
core: {
animation: 0,
- initially_open: [ "tb-front", "tb-back", "sections"
-[%- FOREACH section = SELF.requirement_spec.sections -%]
- , "fb-[% section.id %]"
- [%- FOREACH function_block = section.children -%]
- , "fb-[% function_block.id -%]"
- [%- END -%]
-[%- END -%]
- ]},
+ initially_open: initially_open,
+ },
json_data: {
data: tree_data
},
$.jstree._reference("#tree").select_node('#fb-[% SELF.requirement_spec_item.id %]', true);
[% END %]
- kivi.requirement_spec.create_context_menus();
+ kivi.requirement_spec.create_context_menus([% SELF.requirement_spec.is_template ? 'true' : 'false' %]);
});
-->