Revision b2e1809f
Von Moritz Bunkus vor fast 11 Jahren hinzugefügt
SL/Controller/RequirementSpec.pm | ||
---|---|---|
package SL::Controller::RequirementSpec;
|
||
|
||
use strict;
|
||
|
||
use parent qw(SL::Controller::Base);
|
||
|
||
use SL::Controller::Helper::GetModels;
|
||
use SL::Controller::Helper::Paginated;
|
||
use SL::Controller::Helper::Sorted;
|
||
use SL::Controller::Helper::ParseFilter;
|
||
use SL::Controller::Helper::ReportGenerator;
|
||
use SL::DB::Customer;
|
||
use SL::DB::Project;
|
||
use SL::DB::RequirementSpecStatus;
|
||
use SL::DB::RequirementSpecType;
|
||
use SL::DB::RequirementSpec;
|
||
use SL::Helper::Flash;
|
||
use SL::Locale::String;
|
||
|
||
use Rose::Object::MakeMethods::Generic
|
||
(
|
||
scalar => [ qw(requirement_spec customers projects types statuses db_args flat_filter is_template) ],
|
||
);
|
||
|
||
__PACKAGE__->run_before('setup');
|
||
__PACKAGE__->run_before('load_requirement_spec', only => [ qw( edit update destroy) ]);
|
||
__PACKAGE__->run_before('load_select_options', only => [ qw(new edit create update list) ]);
|
||
__PACKAGE__->run_before('load_search_select_options', only => [ qw( list) ]);
|
||
|
||
__PACKAGE__->get_models_url_params('flat_filter');
|
||
__PACKAGE__->make_paginated(
|
||
MODEL => 'RequirementSpec',
|
||
PAGINATE_ARGS => 'db_args',
|
||
ONLY => [ qw(list) ],
|
||
);
|
||
|
||
__PACKAGE__->make_sorted(
|
||
MODEL => 'RequirementSpec',
|
||
ONLY => [ qw(list) ],
|
||
|
||
DEFAULT_BY => 'customer',
|
||
DEFAULT_DIR => 1,
|
||
|
||
customer => t8('Customer'),
|
||
title => t8('Title'),
|
||
type => t8('Requirement Spec Type'),
|
||
status => t8('Requirement Spec Status'),
|
||
projectnumber => t8('Project Number'),
|
||
);
|
||
|
||
#
|
||
# actions
|
||
#
|
||
|
||
sub action_list {
|
||
my ($self) = @_;
|
||
|
||
$self->setup_db_args_from_filter;
|
||
$self->flat_filter({ map { $_->{key} => $_->{value} } $::form->flatten_variables('filter') });
|
||
|
||
$self->prepare_report;
|
||
|
||
my $requirement_specs = $self->get_models(%{ $self->db_args });
|
||
|
||
$self->report_generator_list_objects(report => $self->{report}, objects => $requirement_specs);
|
||
}
|
||
|
||
sub action_new {
|
||
my ($self) = @_;
|
||
|
||
$self->{requirement_spec} = SL::DB::RequirementSpec->new;
|
||
$self->render('requirement_spec/form', title => t8('Create a new requirement spec'));
|
||
}
|
||
|
||
sub action_edit {
|
||
my ($self) = @_;
|
||
$self->render('requirement_spec/form', title => t8('Edit requirement spec'));
|
||
}
|
||
|
||
sub action_create {
|
||
my ($self) = @_;
|
||
|
||
$self->{requirement_spec} = SL::DB::RequirementSpec->new;
|
||
$self->create_or_update;
|
||
}
|
||
|
||
sub action_update {
|
||
my ($self) = @_;
|
||
$self->create_or_update;
|
||
}
|
||
|
||
sub action_destroy {
|
||
my ($self) = @_;
|
||
|
||
if (eval { $self->{requirement_spec}->delete; 1; }) {
|
||
flash_later('info', t8('The requirement spec has been deleted.'));
|
||
} else {
|
||
flash_later('error', t8('The requirement spec is in use and cannot be deleted.'));
|
||
}
|
||
|
||
$self->redirect_to(action => 'list');
|
||
}
|
||
|
||
sub action_reorder {
|
||
my ($self) = @_;
|
||
|
||
SL::DB::RequirementSpec->reorder_list(@{ $::form->{requirement_spec_id} || [] });
|
||
|
||
$self->render('1;', { type => 'js', inline => 1 });
|
||
}
|
||
|
||
#
|
||
# filters
|
||
#
|
||
|
||
sub setup {
|
||
my ($self) = @_;
|
||
|
||
$::auth->assert('config');
|
||
$::request->{layout}->use_stylesheet("requirement_spec.css");
|
||
$self->is_template($::form->{is_template} ? 1 : 0);
|
||
|
||
return 1;
|
||
}
|
||
|
||
#
|
||
# helpers
|
||
#
|
||
|
||
sub create_or_update {
|
||
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 @errors = $self->{requirement_spec}->validate;
|
||
|
||
if (@errors) {
|
||
flash('error', @errors);
|
||
$self->render('requirement_spec/form', title => $title);
|
||
return;
|
||
}
|
||
|
||
$self->{requirement_spec}->save;
|
||
|
||
flash_later('info', $is_new ? t8('The requirement spec has been created.') : t8('The requirement spec has been saved.'));
|
||
$self->redirect_to(action => 'list');
|
||
}
|
||
|
||
sub load_requirement_spec {
|
||
my ($self) = @_;
|
||
$self->{requirement_spec} = SL::DB::RequirementSpec->new(id => $::form->{id})->load;
|
||
}
|
||
|
||
sub load_select_options {
|
||
my ($self) = @_;
|
||
|
||
my @filter = ('!obsolete' => 1);
|
||
if ($self->requirement_spec && $self->requirement_spec->customer_id) {
|
||
@filter = ( or => [ @filter, id => $self->requirement_spec->customer_id ] );
|
||
}
|
||
|
||
$self->customers(SL::DB::Manager::Customer->get_all_sorted(where => \@filter));
|
||
$self->statuses( SL::DB::Manager::RequirementSpecStatus->get_all_sorted);
|
||
$self->types( SL::DB::Manager::RequirementSpecType->get_all_sorted);
|
||
}
|
||
|
||
sub load_search_select_options {
|
||
my ($self) = @_;
|
||
|
||
$self->projects(SL::DB::Manager::Project->get_all_sorted);
|
||
}
|
||
|
||
sub setup_db_args_from_filter {
|
||
my ($self) = @_;
|
||
|
||
$self->{filter} = {};
|
||
my %args = parse_filter(
|
||
$::form->{filter},
|
||
with_objects => [ 'customer', 'type', 'status', 'project' ],
|
||
launder_to => $self->{filter},
|
||
);
|
||
|
||
$args{where} = [
|
||
and => [
|
||
@{ $args{where} || [] },
|
||
is_template => $self->is_template
|
||
]];
|
||
|
||
$self->db_args(\%args);
|
||
}
|
||
|
||
sub prepare_report {
|
||
my ($self) = @_;
|
||
|
||
my $callback = $self->get_callback;
|
||
|
||
my $report = SL::ReportGenerator->new(\%::myconfig, $::form);
|
||
$self->{report} = $report;
|
||
|
||
my @columns = qw(title customer status type projectnumber);
|
||
my @sortable = qw(title customer status type projectnumber);
|
||
|
||
my %column_defs = (
|
||
title => { obj_link => sub { $self->url_for(action => 'edit', 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 } },
|
||
);
|
||
|
||
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_bottom_info_text => $self->render('requirement_spec/report_bottom', { output => 0 }),
|
||
title => $::locale->text('Requirement Specs'),
|
||
allow_pdf_export => 1,
|
||
allow_csv_export => 1,
|
||
);
|
||
$report->set_columns(%column_defs);
|
||
$report->set_column_order(@columns);
|
||
$report->set_export_options(qw(list filter));
|
||
$report->set_options_from_form;
|
||
$self->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable);
|
||
|
||
$self->disable_pagination if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
|
||
}
|
||
|
||
1;
|
SL/DB/Manager/RequirementSpec.pm | ||
---|---|---|
package SL::DB::Manager::RequirementSpec;
|
||
|
||
use strict;
|
||
|
||
use SL::DB::Helper::Manager;
|
||
use base qw(SL::DB::Helper::Manager);
|
||
|
||
use SL::DB::Helper::Paginated;
|
||
use SL::DB::Helper::Sorted;
|
||
|
||
sub object_class { 'SL::DB::RequirementSpec' }
|
||
|
||
__PACKAGE__->make_manager_methods;
|
||
|
||
sub _sort_spec {
|
||
return (
|
||
default => [ 'title', 1 ],
|
||
columns => {
|
||
SIMPLE => 'ALL',
|
||
customer => 'lower(customer.name)',
|
||
type => 'type.position',
|
||
status => 'status.position',
|
||
projectnumber => 'project.projectnumber',
|
||
map { ( $_ => "lower(requirement_specs.${_})" ) } qw(title),
|
||
});
|
||
}
|
||
|
||
1;
|
SL/DB/Project.pm | ||
---|---|---|
return !SL::DB::Manager::Project->get_first(where => \@filter);
|
||
}
|
||
|
||
sub full_description {
|
||
my ($self, %params) = @_;
|
||
|
||
$params{style} ||= 'both';
|
||
my $description;
|
||
|
||
if ($params{style} =~ m/number/) {
|
||
$description = $self->projectnumber;
|
||
|
||
} elsif ($params{style} =~ m/description/) {
|
||
$description = $self->description;
|
||
|
||
} else {
|
||
$description = $self->projectnumber;
|
||
if ($self->description && do { my $desc = quotemeta $self->description; $self->projectnumber !~ m/$desc/ }) {
|
||
$description .= ' (' . $self->description . ')';
|
||
}
|
||
}
|
||
|
||
return $description;
|
||
}
|
||
|
||
1;
|
||
|
||
__END__
|
||
... | ... | |
project in the database. Also returns trueish if no project number has
|
||
been set yet.
|
||
|
||
=item C<full_description %params>
|
||
|
||
Returns a full description for the project which can consist of the
|
||
project number, its description or both. This is determined by the
|
||
parameter C<style> which defaults to C<both>:
|
||
|
||
=over 2
|
||
|
||
=item C<both>
|
||
|
||
Returns the project's number followed by its description in
|
||
parenthesis (e.g. "12345 (Secret Combinations)"). If the project's
|
||
description is already part of the project's number then it will not
|
||
be appended.
|
||
|
||
=item C<projectnumber> (or simply C<number>)
|
||
|
||
Returns only the project's number.
|
||
|
||
=item C<projectdescription> (or simply C<description>)
|
||
|
||
Returns only the project's description.
|
||
|
||
=back
|
||
|
||
=back
|
||
|
||
=head1 AUTHOR
|
SL/DB/RequirementSpec.pm | ||
---|---|---|
use strict;
|
||
|
||
use SL::DB::MetaSetup::RequirementSpec;
|
||
use SL::DB::Manager::RequirementSpec;
|
||
use SL::Locale::String;
|
||
|
||
__PACKAGE__->meta->add_relationship(
|
||
... | ... | |
},
|
||
);
|
||
|
||
# Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
|
||
__PACKAGE__->meta->make_manager_class;
|
||
|
||
__PACKAGE__->meta->initialize;
|
||
|
||
__PACKAGE__->before_save('_before_save_initialize_not_null_columns');
|
||
|
||
sub validate {
|
||
my ($self) = @_;
|
||
|
||
... | ... | |
return @errors;
|
||
}
|
||
|
||
sub _before_save_initialize_not_null_columns {
|
||
my ($self) = @_;
|
||
|
||
$self->previous_section_number(0) if !defined $self->previous_section_number;
|
||
$self->previous_fb_number(0) if !defined $self->previous_fb_number;
|
||
|
||
return 1;
|
||
}
|
||
|
||
1;
|
SL/Presenter/CustomerVendor.pm | ||
---|---|---|
|
||
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
|
||
|
||
my $callback = $params{callback} ? '&callback=' . $::form->escape($params{callback}) : '';
|
||
|
||
my $text = join '', (
|
||
$params{no_link} ? '' : '<a href="controller.pl?action=CustomerVendor/edit&db=' . $type . '&id=' . $self->escape($cv->id) . '">',
|
||
$self->escape($cv->name),
|
SL/Presenter/Project.pm | ||
---|---|---|
|
||
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
|
||
|
||
$params{style} ||= 'both';
|
||
my $description;
|
||
|
||
if ($params{style} =~ m/number/) {
|
||
$description = $project->projectnumber;
|
||
|
||
} elsif ($params{style} =~ m/description/) {
|
||
$description = $project->description;
|
||
|
||
} else {
|
||
$description = $project->projectnumber;
|
||
if ($project->description && do { my $desc = quotemeta $project->description; $project->projectnumber !~ m/$desc/ }) {
|
||
$description .= ' (' . $project->description . ')';
|
||
}
|
||
}
|
||
my $description = $project->full_description(style => $params{style});
|
||
my $callback = $params{callback} ? '&callback=' . $::form->escape($params{callback}) : '';
|
||
|
||
my $text = join '', (
|
||
$params{no_link} ? '' : '<a href="controller.pl?action=Project/edit&id=' . $self->escape($project->id) . '">',
|
||
$params{no_link} ? '' : '<a href="controller.pl?action=Project/edit&id=' . $self->escape($project->id) . $callback . '">',
|
||
$self->escape($description),
|
||
$params{no_link} ? '' : '</a>',
|
||
);
|
css/requirement_spec.css | ||
---|---|---|
input.rs_input_field, select.rs_input_field,
|
||
table.rs_input_field input, table.rs_input_field select {
|
||
width: 300px;
|
||
}
|
locale/de/all | ||
---|---|---|
'Add Quotation' => 'Angebot erfassen',
|
||
'Add RFQ' => 'Preisanfrage erfassen',
|
||
'Add Request for Quotation' => 'Anfrage erfassen',
|
||
'Add Requirement Spec' => 'Neues Pflichtenheft erfassen',
|
||
'Add Sales Delivery Order' => 'Lieferschein (Verkauf) erfassen',
|
||
'Add Sales Invoice' => 'Rechnung erfassen',
|
||
'Add Sales Order' => 'Auftrag erfassen',
|
||
... | ... | |
'Create a new predefined text' => 'Einen neuen vordefinierten Textblock anlegen',
|
||
'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 status' => 'Einen neuen Pflichtenheftstatus anlegen',
|
||
'Create a new requirement spec type' => 'Einen neuen Pflichtenhefttypen anlegen',
|
||
'Create a new risk level' => 'Einen neuen Risikograd anlegen',
|
||
... | ... | |
'Edit project' => 'Projekt bearbeiten',
|
||
'Edit project #1' => 'Projekt #1 bearbeiten',
|
||
'Edit project type' => 'Projekttypen bearbeiten',
|
||
'Edit requirement spec' => 'Pflichtenheft bearbeiten',
|
||
'Edit requirement spec status' => 'Pflichtenheftstatus bearbeiten',
|
||
'Edit requirement spec type' => 'Pflichtenhefttypen bearbeiten',
|
||
'Edit risk level' => 'Risikograd bearbeiten',
|
||
... | ... | |
'History Search Engine' => 'Historien Suchmaschine',
|
||
'Homepage' => 'Homepage',
|
||
'Host' => 'Datenbankcomputer',
|
||
'Hourly Rate' => 'Stundensatz',
|
||
'Hourly rate' => 'Stundensatz',
|
||
'However, you can create a new part which will then be selected.' => 'Sie können jedoch einen neuen Artikel anlegen, der dann automatisch ausgewählt wird.',
|
||
'I' => 'I',
|
||
... | ... | |
'Requested execution date to' => 'Gewünschtes Ausführungsdatum bis',
|
||
'Requests for Quotation' => 'Preisanfragen',
|
||
'Required by' => 'Lieferdatum',
|
||
'Requirement Spec Status' => 'Pflichtenheftstatus',
|
||
'Requirement Spec Statuses' => 'Pflichtenheftstatus',
|
||
'Requirement Spec Type' => 'Pflichtenhefttyp',
|
||
'Requirement Spec Types' => 'Pflichtenhefttypen',
|
||
'Requirement Specs' => 'Pflichtenhefte',
|
||
'Requirement specs' => 'Pflichtenhefte',
|
||
'Reset' => 'Zurücksetzen',
|
||
'Result' => 'Ergebnis',
|
||
... | ... | |
'The project type is in use and cannot be deleted.' => 'Der Projekttyp wird verwendet und kann nicht gelöscht werden.',
|
||
'The required information consists of the IBAN and the BIC.' => 'Die benötigten Informationen bestehen aus der IBAN und der BIC.',
|
||
'The required information consists of the IBAN, the BIC, the mandator ID and the mandate\'s date of signature.' => 'Die benötigten Informationen bestehen aus IBAN, BIC, Mandanten-ID und dem Unterschriftsdatum des Mandates.',
|
||
'The requirement spec has been created.' => 'Das Pflichtenheft wurde angelegt.',
|
||
'The requirement spec has been deleted.' => 'Das Pflichtenheft wurde gelöscht.',
|
||
'The requirement spec has been saved.' => 'Das Pflichtenheft wurde gespeichert.',
|
||
'The requirement spec is in use and cannot be deleted.' => 'Das Pflichtenheft wird verwendet und kann nicht gelöscht werden.',
|
||
'The requirement spec status has been created.' => 'Der Pflichtenheftstatus wurde angelegt.',
|
||
'The requirement spec status has been deleted.' => 'Der Pflichtenheftstatus wurde gelöscht.',
|
||
'The requirement spec status has been saved.' => 'Der Pflichtenheftstatus wurde gespeichert.',
|
menus/erp.ini | ||
---|---|---|
module=dn.pl
|
||
action=add
|
||
|
||
[AR--Add Requirement Spec]
|
||
module=controller.pl
|
||
action=RequirementSpec/new
|
||
|
||
[AR--Reports]
|
||
module=menu.pl
|
||
action=acc_menu
|
||
... | ... | |
module=dn.pl
|
||
action=search
|
||
|
||
[AR--Reports--Requirement Specs]
|
||
module=controller.pl
|
||
action=RequirementSpec/list
|
||
|
||
[AR--Reports--Delivery Plan]
|
||
ACCESS=delivery_plan
|
||
module=controller.pl
|
templates/webpages/requirement_spec/_filter.html | ||
---|---|---|
[%- USE HTML %][%- USE L %][%- USE LxERP %]
|
||
|
||
<div class="filter_toggle">
|
||
<a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8("Show Filter") %]</a>
|
||
</div>
|
||
|
||
<div class="filter_toggle" style="display:none">
|
||
<a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8("Hide Filter") %]</a>
|
||
|
||
<form method="post" action="controller.pl">
|
||
|
||
<p>
|
||
<table class="rs_input_field">
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Title") %]</th>
|
||
<td>[% L.input_tag('filter.title:substr::ilike', filter.title_substr__ilike) %]</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Customer") %]</th>
|
||
<td>[% L.input_tag('filter.customer.name:substr::ilike', filter.customer.name_substr__ilike) %]</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Customer Number") %]</th>
|
||
<td>[% L.input_tag('filter.customer.customernumber:substr::ilike', filter.customer.customernumber_substr__ilike) %]</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Requirement Spec Type") %]</th>
|
||
<td>[% L.select_tag('filter.type_id', SELF.types, default=filter.type_id, title_key="description", with_empty=1) %]</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Requirement Spec Status") %]</th>
|
||
<td>[% L.select_tag('filter.status_id', SELF.statuses, default=filter.status_id, title_key="description", with_empty=1) %]</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<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>
|
||
</table>
|
||
</p>
|
||
|
||
[% L.hidden_tag("action", "RequirementSpec/list") %]
|
||
|
||
<p>[% L.submit_tag("dummy", LxERP.t8("Continue")) %]</p>
|
||
</form>
|
||
</div>
|
templates/webpages/requirement_spec/form.html | ||
---|---|---|
[% USE HTML %][% USE L %][% USE LxERP %]
|
||
|
||
<form method="post" action="controller.pl">
|
||
<div class="listtop">[% FORM.title %]</div>
|
||
|
||
[%- INCLUDE 'common/flash.html' %]
|
||
|
||
<table class="rs_input_field">
|
||
<tr>
|
||
<td>[% LxERP.t8("Title") %]</td>
|
||
<td>[% L.input_tag("requirement_spec.title", SELF.requirement_spec.description) %]</td>
|
||
</tr>
|
||
|
||
<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") %]</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td>[% LxERP.t8("Requirement Spec Status") %]</td>
|
||
<td>[% L.select_tag("requirement_spec.status_id", SELF.statuses, default=SELF.requirement_spec.status_id, title_key="description") %]</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td>[% LxERP.t8("Customer") %]</td>
|
||
<td>[% L.select_tag("requirement_spec.customer_id", SELF.customers, default=SELF.requirement_spec.customer_id, title_key="name", id="customer_id") %]</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td>[% LxERP.t8("Hourly Rate") %]</td>
|
||
<td>[% L.input_tag("requirement_spec.hourly_rate_as_number", SELF.requirement_spec.hourly_rate_as_number, id="hourly_rate") %]</td>
|
||
</tr>
|
||
|
||
</table>
|
||
|
||
<p>
|
||
[% L.hidden_tag("id", SELF.requirement_spec.id) %]
|
||
[% L.hidden_tag("action", "RequirementSpec/dispatch") %]
|
||
[% L.submit_tag("action_" _ (SELF.requirement_spec.id ? "update" : "create"), LxERP.t8('Save')) %]
|
||
[%- IF SELF.requirement_spec.id %]
|
||
[% L.submit_tag("action_destroy", LxERP.t8('Delete'), confirm=LxERP.t8('Do you really want to delete this object?')) %]
|
||
[%- END %]
|
||
<a href="[% SELF.url_for(action="list") %]">[% LxERP.t8('Abort') %]</a>
|
||
</p>
|
||
</form>
|
||
|
||
<script type="text/javascript">
|
||
<!--
|
||
function on_customer_changed() {
|
||
$.ajax({
|
||
url: 'controller.pl?action=Customer/get_hourly_rate',
|
||
dataType: "json",
|
||
data: { id: $("#customer_id").attr('value') },
|
||
success: function(data) { if (data["hourly_rate"] > 0) $("#hourly_rate").attr("value", data["hourly_rate_formatted"]); }
|
||
});
|
||
}
|
||
|
||
$(document).ready(function() {
|
||
$("#customer_id").change(on_customer_changed);
|
||
});
|
||
-->
|
||
</script>
|
templates/webpages/requirement_spec/report_bottom.html | ||
---|---|---|
[% USE L %]
|
||
[%- L.paginate_controls %]
|
templates/webpages/requirement_spec/report_top.html | ||
---|---|---|
[%- USE L %]
|
||
[%- PROCESS "requirement_spec/_filter.html" filter=SELF.filter %]
|
||
<hr>
|
Auch abrufbar als: Unified diff
Pflichtenhefte: Basisdaten verwalten, Such- und Listfunktion