Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision b2e1809f

Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt

  • ID b2e1809f6b6d8852ab0086dcc61ae9540c18b83f
  • Vorgänger d157b20f
  • Nachfolger 7a21a080

Pflichtenhefte: Basisdaten verwalten, Such- und Listfunktion

Unterschiede anzeigen:

SL/Controller/RequirementSpec.pm
1
package SL::Controller::RequirementSpec;
2

  
3
use strict;
4

  
5
use parent qw(SL::Controller::Base);
6

  
7
use SL::Controller::Helper::GetModels;
8
use SL::Controller::Helper::Paginated;
9
use SL::Controller::Helper::Sorted;
10
use SL::Controller::Helper::ParseFilter;
11
use SL::Controller::Helper::ReportGenerator;
12
use SL::DB::Customer;
13
use SL::DB::Project;
14
use SL::DB::RequirementSpecStatus;
15
use SL::DB::RequirementSpecType;
16
use SL::DB::RequirementSpec;
17
use SL::Helper::Flash;
18
use SL::Locale::String;
19

  
20
use Rose::Object::MakeMethods::Generic
21
(
22
 scalar => [ qw(requirement_spec customers projects types statuses db_args flat_filter is_template) ],
23
);
24

  
25
__PACKAGE__->run_before('setup');
26
__PACKAGE__->run_before('load_requirement_spec',      only => [ qw(    edit        update destroy) ]);
27
__PACKAGE__->run_before('load_select_options',        only => [ qw(new edit create update list) ]);
28
__PACKAGE__->run_before('load_search_select_options', only => [ qw(                       list) ]);
29

  
30
__PACKAGE__->get_models_url_params('flat_filter');
31
__PACKAGE__->make_paginated(
32
  MODEL         => 'RequirementSpec',
33
  PAGINATE_ARGS => 'db_args',
34
  ONLY          => [ qw(list) ],
35
);
36

  
37
__PACKAGE__->make_sorted(
38
  MODEL         => 'RequirementSpec',
39
  ONLY          => [ qw(list) ],
40

  
41
  DEFAULT_BY    => 'customer',
42
  DEFAULT_DIR   => 1,
43

  
44
  customer      => t8('Customer'),
45
  title         => t8('Title'),
46
  type          => t8('Requirement Spec Type'),
47
  status        => t8('Requirement Spec Status'),
48
  projectnumber => t8('Project Number'),
49
);
50

  
51
#
52
# actions
53
#
54

  
55
sub action_list {
56
  my ($self) = @_;
57

  
58
  $self->setup_db_args_from_filter;
59
  $self->flat_filter({ map { $_->{key} => $_->{value} } $::form->flatten_variables('filter') });
60

  
61
  $self->prepare_report;
62

  
63
  my $requirement_specs = $self->get_models(%{ $self->db_args });
64

  
65
  $self->report_generator_list_objects(report => $self->{report}, objects => $requirement_specs);
66
}
67

  
68
sub action_new {
69
  my ($self) = @_;
70

  
71
  $self->{requirement_spec} = SL::DB::RequirementSpec->new;
72
  $self->render('requirement_spec/form', title => t8('Create a new requirement spec'));
73
}
74

  
75
sub action_edit {
76
  my ($self) = @_;
77
  $self->render('requirement_spec/form', title => t8('Edit requirement spec'));
78
}
79

  
80
sub action_create {
81
  my ($self) = @_;
82

  
83
  $self->{requirement_spec} = SL::DB::RequirementSpec->new;
84
  $self->create_or_update;
85
}
86

  
87
sub action_update {
88
  my ($self) = @_;
89
  $self->create_or_update;
90
}
91

  
92
sub action_destroy {
93
  my ($self) = @_;
94

  
95
  if (eval { $self->{requirement_spec}->delete; 1; }) {
96
    flash_later('info',  t8('The requirement spec has been deleted.'));
97
  } else {
98
    flash_later('error', t8('The requirement spec is in use and cannot be deleted.'));
99
  }
100

  
101
  $self->redirect_to(action => 'list');
102
}
103

  
104
sub action_reorder {
105
  my ($self) = @_;
106

  
107
  SL::DB::RequirementSpec->reorder_list(@{ $::form->{requirement_spec_id} || [] });
108

  
109
  $self->render('1;', { type => 'js', inline => 1 });
110
}
111

  
112
#
113
# filters
114
#
115

  
116
sub setup {
117
  my ($self) = @_;
118

  
119
  $::auth->assert('config');
120
  $::request->{layout}->use_stylesheet("requirement_spec.css");
121
  $self->is_template($::form->{is_template} ? 1 : 0);
122

  
123
  return 1;
124
}
125

  
126
#
127
# helpers
128
#
129

  
130
sub create_or_update {
131
  my $self   = shift;
132
  my $is_new = !$self->{requirement_spec}->id;
133
  my $params = delete($::form->{requirement_spec}) || { };
134
  my $title  = $is_new ? t8('Create a new requirement spec') : t8('Edit requirement spec');
135

  
136
  $self->{requirement_spec}->assign_attributes(%{ $params });
137

  
138
  my @errors = $self->{requirement_spec}->validate;
139

  
140
  if (@errors) {
141
    flash('error', @errors);
142
    $self->render('requirement_spec/form', title => $title);
143
    return;
144
  }
145

  
146
  $self->{requirement_spec}->save;
147

  
148
  flash_later('info', $is_new ? t8('The requirement spec has been created.') : t8('The requirement spec has been saved.'));
149
  $self->redirect_to(action => 'list');
150
}
151

  
152
sub load_requirement_spec {
153
  my ($self) = @_;
154
  $self->{requirement_spec} = SL::DB::RequirementSpec->new(id => $::form->{id})->load;
155
}
156

  
157
sub load_select_options {
158
  my ($self) = @_;
159

  
160
  my @filter = ('!obsolete' => 1);
161
  if ($self->requirement_spec && $self->requirement_spec->customer_id) {
162
    @filter = ( or => [ @filter, id => $self->requirement_spec->customer_id ] );
163
  }
164

  
165
  $self->customers(SL::DB::Manager::Customer->get_all_sorted(where => \@filter));
166
  $self->statuses( SL::DB::Manager::RequirementSpecStatus->get_all_sorted);
167
  $self->types(    SL::DB::Manager::RequirementSpecType->get_all_sorted);
168
}
169

  
170
sub load_search_select_options {
171
  my ($self) = @_;
172

  
173
  $self->projects(SL::DB::Manager::Project->get_all_sorted);
174
}
175

  
176
sub setup_db_args_from_filter {
177
  my ($self) = @_;
178

  
179
  $self->{filter} = {};
180
  my %args = parse_filter(
181
    $::form->{filter},
182
    with_objects => [ 'customer', 'type', 'status', 'project' ],
183
    launder_to   => $self->{filter},
184
  );
185

  
186
  $args{where} = [
187
    and => [
188
      @{ $args{where} || [] },
189
      is_template => $self->is_template
190
    ]];
191

  
192
  $self->db_args(\%args);
193
}
194

  
195
sub prepare_report {
196
  my ($self)      = @_;
197

  
198
  my $callback    = $self->get_callback;
199

  
200
  my $report      = SL::ReportGenerator->new(\%::myconfig, $::form);
201
  $self->{report} = $report;
202

  
203
  my @columns     = qw(title customer status type projectnumber);
204
  my @sortable    = qw(title customer status type projectnumber);
205

  
206
  my %column_defs = (
207
    title         => { obj_link => sub { $self->url_for(action => 'edit', id => $_[0]->id, callback => $callback) } },
208
    customer      => { raw_data => sub { $self->presenter->customer($_[0]->customer, display => 'table-cell', callback => $callback) },
209
                       sub      => sub { $_[0]->customer->name } },
210
    projectnumber => { raw_data => sub { $self->presenter->project($_[0]->project, display => 'table-cell', callback => $callback) },
211
                       sub      => sub { $_[0]->project_id ? $_[0]->project->projectnumber : '' } },
212
    status        => { sub      => sub { $_[0]->status->description } },
213
    type          => { sub      => sub { $_[0]->type->description } },
214
  );
215

  
216
  map { $column_defs{$_}->{text} ||= $::locale->text( $self->get_sort_spec->{$_}->{title} ) } keys %column_defs;
217

  
218
  $report->set_options(
219
    std_column_visibility => 1,
220
    controller_class      => 'RequirementSpec',
221
    output_format         => 'HTML',
222
    raw_top_info_text     => $self->render('requirement_spec/report_top',    { output => 0 }),
223
    raw_bottom_info_text  => $self->render('requirement_spec/report_bottom', { output => 0 }),
224
    title                 => $::locale->text('Requirement Specs'),
225
    allow_pdf_export      => 1,
226
    allow_csv_export      => 1,
227
  );
228
  $report->set_columns(%column_defs);
229
  $report->set_column_order(@columns);
230
  $report->set_export_options(qw(list filter));
231
  $report->set_options_from_form;
232
  $self->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable);
233

  
234
  $self->disable_pagination if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
235
}
236

  
237
1;
SL/DB/Manager/RequirementSpec.pm
1
package SL::DB::Manager::RequirementSpec;
2

  
3
use strict;
4

  
5
use SL::DB::Helper::Manager;
6
use base qw(SL::DB::Helper::Manager);
7

  
8
use SL::DB::Helper::Paginated;
9
use SL::DB::Helper::Sorted;
10

  
11
sub object_class { 'SL::DB::RequirementSpec' }
12

  
13
__PACKAGE__->make_manager_methods;
14

  
15
sub _sort_spec {
16
  return (
17
    default => [ 'title', 1 ],
18
    columns => {
19
      SIMPLE => 'ALL',
20
      customer      => 'lower(customer.name)',
21
      type          => 'type.position',
22
      status        => 'status.position',
23
      projectnumber => 'project.projectnumber',
24
      map { ( $_ => "lower(requirement_specs.${_})" ) } qw(title),
25
    });
26
}
27

  
28
1;
SL/DB/Project.pm
48 48
  return !SL::DB::Manager::Project->get_first(where => \@filter);
49 49
}
50 50

  
51
sub full_description {
52
  my ($self, %params) = @_;
53

  
54
  $params{style} ||= 'both';
55
  my $description;
56

  
57
  if ($params{style} =~ m/number/) {
58
    $description = $self->projectnumber;
59

  
60
  } elsif ($params{style} =~ m/description/) {
61
    $description = $self->description;
62

  
63
  } else {
64
    $description = $self->projectnumber;
65
    if ($self->description && do { my $desc = quotemeta $self->description; $self->projectnumber !~ m/$desc/ }) {
66
      $description .= ' (' . $self->description . ')';
67
    }
68
  }
69

  
70
  return $description;
71
}
72

  
51 73
1;
52 74

  
53 75
__END__
......
83 105
project in the database. Also returns trueish if no project number has
84 106
been set yet.
85 107

  
108
=item C<full_description %params>
109

  
110
Returns a full description for the project which can consist of the
111
project number, its description or both. This is determined by the
112
parameter C<style> which defaults to C<both>:
113

  
114
=over 2
115

  
116
=item C<both>
117

  
118
Returns the project's number followed by its description in
119
parenthesis (e.g. "12345 (Secret Combinations)"). If the project's
120
description is already part of the project's number then it will not
121
be appended.
122

  
123
=item C<projectnumber> (or simply C<number>)
124

  
125
Returns only the project's number.
126

  
127
=item C<projectdescription> (or simply C<description>)
128

  
129
Returns only the project's description.
130

  
131
=back
132

  
86 133
=back
87 134

  
88 135
=head1 AUTHOR
SL/DB/RequirementSpec.pm
3 3
use strict;
4 4

  
5 5
use SL::DB::MetaSetup::RequirementSpec;
6
use SL::DB::Manager::RequirementSpec;
6 7
use SL::Locale::String;
7 8

  
8 9
__PACKAGE__->meta->add_relationship(
......
18 19
  },
19 20
);
20 21

  
21
# Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
22
__PACKAGE__->meta->make_manager_class;
23

  
24 22
__PACKAGE__->meta->initialize;
25 23

  
24
__PACKAGE__->before_save('_before_save_initialize_not_null_columns');
25

  
26 26
sub validate {
27 27
  my ($self) = @_;
28 28

  
......
32 32
  return @errors;
33 33
}
34 34

  
35
sub _before_save_initialize_not_null_columns {
36
  my ($self) = @_;
37

  
38
  $self->previous_section_number(0) if !defined $self->previous_section_number;
39
  $self->previous_fb_number(0)      if !defined $self->previous_fb_number;
40

  
41
  return 1;
42
}
43

  
35 44
1;
SL/Presenter/CustomerVendor.pm
26 26

  
27 27
  croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
28 28

  
29
  my $callback = $params{callback} ? '&callback=' . $::form->escape($params{callback}) : '';
30

  
29 31
  my $text = join '', (
30 32
    $params{no_link} ? '' : '<a href="controller.pl?action=CustomerVendor/edit&amp;db=' . $type . '&amp;id=' . $self->escape($cv->id) . '">',
31 33
    $self->escape($cv->name),
SL/Presenter/Project.pm
18 18

  
19 19
  croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
20 20

  
21
  $params{style} ||= 'both';
22
  my $description;
23

  
24
  if ($params{style} =~ m/number/) {
25
    $description = $project->projectnumber;
26

  
27
  } elsif ($params{style} =~ m/description/) {
28
    $description = $project->description;
29

  
30
  } else {
31
    $description = $project->projectnumber;
32
    if ($project->description && do { my $desc = quotemeta $project->description; $project->projectnumber !~ m/$desc/ }) {
33
      $description .= ' (' . $project->description . ')';
34
    }
35
  }
21
  my $description = $project->full_description(style => $params{style});
22
  my $callback    = $params{callback} ? '&callback=' . $::form->escape($params{callback}) : '';
36 23

  
37 24
  my $text = join '', (
38
    $params{no_link} ? '' : '<a href="controller.pl?action=Project/edit&amp;id=' . $self->escape($project->id) . '">',
25
    $params{no_link} ? '' : '<a href="controller.pl?action=Project/edit&amp;id=' . $self->escape($project->id) . $callback . '">',
39 26
    $self->escape($description),
40 27
    $params{no_link} ? '' : '</a>',
41 28
  );
css/requirement_spec.css
1
input.rs_input_field, select.rs_input_field,
2
table.rs_input_field input, table.rs_input_field select {
3
  width: 300px;
4
}
locale/de/all
151 151
  'Add Quotation'               => 'Angebot erfassen',
152 152
  'Add RFQ'                     => 'Preisanfrage erfassen',
153 153
  'Add Request for Quotation'   => 'Anfrage erfassen',
154
  'Add Requirement Spec'        => 'Neues Pflichtenheft erfassen',
154 155
  'Add Sales Delivery Order'    => 'Lieferschein (Verkauf) erfassen',
155 156
  'Add Sales Invoice'           => 'Rechnung erfassen',
156 157
  'Add Sales Order'             => 'Auftrag erfassen',
......
531 532
  'Create a new predefined text' => 'Einen neuen vordefinierten Textblock anlegen',
532 533
  'Create a new project'        => 'Neues Projekt anlegen',
533 534
  'Create a new project type'   => 'Einen neuen Projekttypen anlegen',
535
  'Create a new requirement spec' => 'Ein neues Pflichtenheft anlegen',
534 536
  'Create a new requirement spec status' => 'Einen neuen Pflichtenheftstatus anlegen',
535 537
  'Create a new requirement spec type' => 'Einen neuen Pflichtenhefttypen anlegen',
536 538
  'Create a new risk level'     => 'Einen neuen Risikograd anlegen',
......
872 874
  'Edit project'                => 'Projekt bearbeiten',
873 875
  'Edit project #1'             => 'Projekt #1 bearbeiten',
874 876
  'Edit project type'           => 'Projekttypen bearbeiten',
877
  'Edit requirement spec'       => 'Pflichtenheft bearbeiten',
875 878
  'Edit requirement spec status' => 'Pflichtenheftstatus bearbeiten',
876 879
  'Edit requirement spec type'  => 'Pflichtenhefttypen bearbeiten',
877 880
  'Edit risk level'             => 'Risikograd bearbeiten',
......
1096 1099
  'History Search Engine'       => 'Historien Suchmaschine',
1097 1100
  'Homepage'                    => 'Homepage',
1098 1101
  'Host'                        => 'Datenbankcomputer',
1102
  'Hourly Rate'                 => 'Stundensatz',
1099 1103
  'Hourly rate'                 => 'Stundensatz',
1100 1104
  'However, you can create a new part which will then be selected.' => 'Sie k&ouml;nnen jedoch einen neuen Artikel anlegen, der dann automatisch ausgew&auml;hlt wird.',
1101 1105
  'I'                           => 'I',
......
1805 1809
  'Requested execution date to' => 'Gewünschtes Ausführungsdatum bis',
1806 1810
  'Requests for Quotation'      => 'Preisanfragen',
1807 1811
  'Required by'                 => 'Lieferdatum',
1812
  'Requirement Spec Status'     => 'Pflichtenheftstatus',
1808 1813
  'Requirement Spec Statuses'   => 'Pflichtenheftstatus',
1814
  'Requirement Spec Type'       => 'Pflichtenhefttyp',
1809 1815
  'Requirement Spec Types'      => 'Pflichtenhefttypen',
1816
  'Requirement Specs'           => 'Pflichtenhefte',
1810 1817
  'Requirement specs'           => 'Pflichtenhefte',
1811 1818
  'Reset'                       => 'Zurücksetzen',
1812 1819
  'Result'                      => 'Ergebnis',
......
2288 2295
  'The project type is in use and cannot be deleted.' => 'Der Projekttyp wird verwendet und kann nicht gelöscht werden.',
2289 2296
  'The required information consists of the IBAN and the BIC.' => 'Die benötigten Informationen bestehen aus der IBAN und der BIC.',
2290 2297
  '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.',
2298
  'The requirement spec has been created.' => 'Das Pflichtenheft wurde angelegt.',
2299
  'The requirement spec has been deleted.' => 'Das Pflichtenheft wurde gelöscht.',
2300
  'The requirement spec has been saved.' => 'Das Pflichtenheft wurde gespeichert.',
2301
  'The requirement spec is in use and cannot be deleted.' => 'Das Pflichtenheft wird verwendet und kann nicht gelöscht werden.',
2291 2302
  'The requirement spec status has been created.' => 'Der Pflichtenheftstatus wurde angelegt.',
2292 2303
  'The requirement spec status has been deleted.' => 'Der Pflichtenheftstatus wurde gelöscht.',
2293 2304
  'The requirement spec status has been saved.' => 'Der Pflichtenheftstatus wurde gespeichert.',
menus/erp.ini
124 124
module=dn.pl
125 125
action=add
126 126

  
127
[AR--Add Requirement Spec]
128
module=controller.pl
129
action=RequirementSpec/new
130

  
127 131
[AR--Reports]
128 132
module=menu.pl
129 133
action=acc_menu
......
164 168
module=dn.pl
165 169
action=search
166 170

  
171
[AR--Reports--Requirement Specs]
172
module=controller.pl
173
action=RequirementSpec/list
174

  
167 175
[AR--Reports--Delivery Plan]
168 176
ACCESS=delivery_plan
169 177
module=controller.pl
templates/webpages/requirement_spec/_filter.html
1
[%- USE HTML %][%- USE L %][%- USE LxERP %]
2

  
3
<div class="filter_toggle">
4
 <a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8("Show Filter") %]</a>
5
</div>
6

  
7
<div class="filter_toggle" style="display:none">
8
 <a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8("Hide Filter") %]</a>
9

  
10
 <form method="post" action="controller.pl">
11

  
12
  <p>
13
   <table class="rs_input_field">
14
    <tr>
15
     <th align="right">[% LxERP.t8("Title") %]</th>
16
     <td>[% L.input_tag('filter.title:substr::ilike', filter.title_substr__ilike) %]</td>
17
    </tr>
18

  
19
    <tr>
20
     <th align="right">[% LxERP.t8("Customer") %]</th>
21
     <td>[% L.input_tag('filter.customer.name:substr::ilike', filter.customer.name_substr__ilike) %]</td>
22
    </tr>
23

  
24
    <tr>
25
     <th align="right">[% LxERP.t8("Customer Number") %]</th>
26
     <td>[% L.input_tag('filter.customer.customernumber:substr::ilike', filter.customer.customernumber_substr__ilike) %]</td>
27
    </tr>
28

  
29
    <tr>
30
     <th align="right">[% LxERP.t8("Requirement Spec Type") %]</th>
31
     <td>[% L.select_tag('filter.type_id', SELF.types, default=filter.type_id, title_key="description", with_empty=1) %]</td>
32
    </tr>
33

  
34
    <tr>
35
     <th align="right">[% LxERP.t8("Requirement Spec Status") %]</th>
36
     <td>[% L.select_tag('filter.status_id', SELF.statuses, default=filter.status_id, title_key="description", with_empty=1) %]</td>
37
    </tr>
38

  
39
    <tr>
40
     <th align="right">[% LxERP.t8("Project") %]</th>
41
     <td>[% L.select_tag('filter.project_id', SELF.projects, default=filter.project_id, title_key="full_description", with_empty=1) %]</td>
42
    </tr>
43
   </table>
44
  </p>
45

  
46
  [% L.hidden_tag("action", "RequirementSpec/list") %]
47

  
48
  <p>[% L.submit_tag("dummy", LxERP.t8("Continue")) %]</p>
49
 </form>
50
</div>
templates/webpages/requirement_spec/form.html
1
[% USE HTML %][% USE L %][% USE LxERP %]
2

  
3
 <form method="post" action="controller.pl">
4
  <div class="listtop">[% FORM.title %]</div>
5

  
6
[%- INCLUDE 'common/flash.html' %]
7

  
8
  <table class="rs_input_field">
9
   <tr>
10
    <td>[% LxERP.t8("Title") %]</td>
11
    <td>[% L.input_tag("requirement_spec.title", SELF.requirement_spec.description) %]</td>
12
   </tr>
13

  
14
   <tr>
15
    <td>[% LxERP.t8("Requirement Spec Type") %]</td>
16
    <td>[% L.select_tag("requirement_spec.type_id",  SELF.types, default=SELF.requirement_spec.type_id, title_key="description") %]</td>
17
   </tr>
18

  
19
   <tr>
20
    <td>[% LxERP.t8("Requirement Spec Status") %]</td>
21
    <td>[% L.select_tag("requirement_spec.status_id",  SELF.statuses, default=SELF.requirement_spec.status_id, title_key="description") %]</td>
22
   </tr>
23

  
24
   <tr>
25
    <td>[% LxERP.t8("Customer") %]</td>
26
    <td>[% L.select_tag("requirement_spec.customer_id",  SELF.customers, default=SELF.requirement_spec.customer_id, title_key="name", id="customer_id") %]</td>
27
   </tr>
28

  
29
   <tr>
30
    <td>[% LxERP.t8("Hourly Rate") %]</td>
31
    <td>[% L.input_tag("requirement_spec.hourly_rate_as_number", SELF.requirement_spec.hourly_rate_as_number, id="hourly_rate") %]</td>
32
   </tr>
33

  
34
  </table>
35

  
36
  <p>
37
   [% L.hidden_tag("id", SELF.requirement_spec.id) %]
38
   [% L.hidden_tag("action", "RequirementSpec/dispatch") %]
39
   [% L.submit_tag("action_" _ (SELF.requirement_spec.id ? "update" : "create"), LxERP.t8('Save')) %]
40
   [%- IF SELF.requirement_spec.id %]
41
    [% L.submit_tag("action_destroy", LxERP.t8('Delete'), confirm=LxERP.t8('Do you really want to delete this object?')) %]
42
   [%- END %]
43
   <a href="[% SELF.url_for(action="list") %]">[% LxERP.t8('Abort') %]</a>
44
  </p>
45
 </form>
46

  
47
 <script type="text/javascript">
48
  <!--
49
    function on_customer_changed() {
50
      $.ajax({
51
        url: 'controller.pl?action=Customer/get_hourly_rate',
52
        dataType: "json",
53
        data: { id: $("#customer_id").attr('value') },
54
        success: function(data) { if (data["hourly_rate"] > 0) $("#hourly_rate").attr("value", data["hourly_rate_formatted"]); }
55
      });
56
    }
57

  
58
    $(document).ready(function() {
59
      $("#customer_id").change(on_customer_changed);
60
    });
61
  -->
62
 </script>
templates/webpages/requirement_spec/report_bottom.html
1
[% USE L %]
2
[%- L.paginate_controls %]
templates/webpages/requirement_spec/report_top.html
1
[%- USE L %]
2
[%- PROCESS "requirement_spec/_filter.html" filter=SELF.filter %]
3
 <hr>

Auch abrufbar als: Unified diff