Revision 7f8599c0
Von Moritz Bunkus vor fast 12 Jahren hinzugefügt
SL/Controller/Project.pm | ||
---|---|---|
1 |
package SL::Controller::Project; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent qw(SL::Controller::Base); |
|
6 |
|
|
7 |
use Clone qw(clone); |
|
8 |
|
|
9 |
use SL::Controller::Helper::GetModels; |
|
10 |
use SL::Controller::Helper::Paginated; |
|
11 |
use SL::Controller::Helper::Sorted; |
|
12 |
use SL::Controller::Helper::ParseFilter; |
|
13 |
use SL::Controller::Helper::ReportGenerator; |
|
14 |
use SL::CVar; |
|
15 |
use SL::DB::Customer; |
|
16 |
use SL::DB::Project; |
|
17 |
use SL::Helper::Flash; |
|
18 |
use SL::Locale::String; |
|
19 |
|
|
20 |
use Rose::Object::MakeMethods::Generic |
|
21 |
( |
|
22 |
scalar => [ qw(project db_args flat_filter) ], |
|
23 |
); |
|
24 |
|
|
25 |
__PACKAGE__->run_before('check_auth'); |
|
26 |
__PACKAGE__->run_before('load_project', only => [ qw(edit update destroy) ]); |
|
27 |
|
|
28 |
__PACKAGE__->get_models_url_params('flat_filter'); |
|
29 |
__PACKAGE__->make_paginated( |
|
30 |
MODEL => 'Project', |
|
31 |
PAGINATE_ARGS => 'db_args', |
|
32 |
ONLY => [ qw(list) ], |
|
33 |
); |
|
34 |
|
|
35 |
__PACKAGE__->make_sorted( |
|
36 |
MODEL => 'Project', |
|
37 |
ONLY => [ qw(list) ], |
|
38 |
|
|
39 |
DEFAULT_BY => 'projectnumber', |
|
40 |
DEFAULT_DIR => 1, |
|
41 |
|
|
42 |
customer => t8('Customer'), |
|
43 |
description => t8('Description'), |
|
44 |
projectnumber => t8('Project Number'), |
|
45 |
type => t8('Type'), |
|
46 |
); |
|
47 |
|
|
48 |
|
|
49 |
# |
|
50 |
# actions |
|
51 |
# |
|
52 |
|
|
53 |
sub action_search { |
|
54 |
my ($self) = @_; |
|
55 |
|
|
56 |
my %params; |
|
57 |
|
|
58 |
$params{CUSTOM_VARIABLES} = CVar->get_configs(module => 'Projects'); |
|
59 |
($params{CUSTOM_VARIABLES_FILTER_CODE}, $params{CUSTOM_VARIABLES_INCLUSION_CODE}) |
|
60 |
= CVar->render_search_options(variables => $params{CUSTOM_VARIABLES}, |
|
61 |
include_prefix => 'l_', |
|
62 |
include_value => 'Y'); |
|
63 |
|
|
64 |
$self->render('project/search', %params); |
|
65 |
} |
|
66 |
|
|
67 |
sub action_list { |
|
68 |
my ($self) = @_; |
|
69 |
|
|
70 |
$self->setup_db_args_from_filter; |
|
71 |
$self->flat_filter({ map { $_->{key} => $_->{value} } $::form->flatten_variables('filter') }); |
|
72 |
# $self->make_filter_summary; |
|
73 |
|
|
74 |
$self->prepare_report; |
|
75 |
|
|
76 |
$self->{projects} = $self->get_models(%{ $self->db_args }); |
|
77 |
|
|
78 |
$self->list_objects; |
|
79 |
} |
|
80 |
|
|
81 |
sub action_new { |
|
82 |
my ($self) = @_; |
|
83 |
|
|
84 |
$self->project(SL::DB::Project->new); |
|
85 |
$self->display_form(title => $::locale->text('Create a new project'), |
|
86 |
callback => $::form->{callback} || $self->url_for(action => 'new')); |
|
87 |
} |
|
88 |
|
|
89 |
sub action_edit { |
|
90 |
my ($self) = @_; |
|
91 |
$self->display_form(title => $::locale->text('Edit project #1', $self->project->projectnumber), |
|
92 |
callback => $::form->{callback} || $self->url_for(action => 'edit', id => $self->project->id)); |
|
93 |
} |
|
94 |
|
|
95 |
sub action_create { |
|
96 |
my ($self) = @_; |
|
97 |
|
|
98 |
$self->project(SL::DB::Project->new); |
|
99 |
$self->create_or_update; |
|
100 |
} |
|
101 |
|
|
102 |
sub action_update { |
|
103 |
my ($self) = @_; |
|
104 |
$self->create_or_update; |
|
105 |
} |
|
106 |
|
|
107 |
sub action_destroy { |
|
108 |
my ($self) = @_; |
|
109 |
|
|
110 |
if (eval { $self->project->delete; 1; }) { |
|
111 |
flash_later('info', $::locale->text('The project has been deleted.')); |
|
112 |
} else { |
|
113 |
flash_later('error', $::locale->text('The project is in use and cannot be deleted.')); |
|
114 |
} |
|
115 |
|
|
116 |
$self->redirect_to(action => 'search'); |
|
117 |
} |
|
118 |
|
|
119 |
# |
|
120 |
# filters |
|
121 |
# |
|
122 |
|
|
123 |
sub check_auth { |
|
124 |
$::auth->assert('project_edit'); |
|
125 |
} |
|
126 |
|
|
127 |
# |
|
128 |
# helpers |
|
129 |
# |
|
130 |
|
|
131 |
sub display_form { |
|
132 |
my ($self, %params) = @_; |
|
133 |
|
|
134 |
$params{ALL_CUSTOMERS} = SL::DB::Manager::Customer->get_all_sorted(where => [ or => [ obsolete => 0, obsolete => undef, id => $self->project->customer_id ]]); |
|
135 |
$params{CUSTOM_VARIABLES} = CVar->get_custom_variables(module => 'Projects', trans_id => $self->project->id); |
|
136 |
CVar->render_inputs(variables => $params{CUSTOM_VARIABLES}) if @{ $params{CUSTOM_VARIABLES} }; |
|
137 |
|
|
138 |
$::request->{layout}->focus('#projectnumber'); |
|
139 |
|
|
140 |
$self->render('project/form', %params); |
|
141 |
} |
|
142 |
|
|
143 |
sub create_or_update { |
|
144 |
my $self = shift; |
|
145 |
my $is_new = !$self->project->id; |
|
146 |
my $params = delete($::form->{project}) || { }; |
|
147 |
|
|
148 |
delete $params->{id}; |
|
149 |
$self->project->assign_attributes(%{ $params }); |
|
150 |
|
|
151 |
my @errors = $self->project->validate; |
|
152 |
|
|
153 |
if (@errors) { |
|
154 |
flash('error', @errors); |
|
155 |
$self->display_form(title => $is_new ? $::locale->text('Create a new project') : $::locale->text('Edit project'), |
|
156 |
callback => $::form->{callback}); |
|
157 |
return; |
|
158 |
} |
|
159 |
|
|
160 |
$self->project->save; |
|
161 |
|
|
162 |
CVar->save_custom_variables( |
|
163 |
dbh => $self->project->db->dbh, |
|
164 |
module => 'Projects', |
|
165 |
trans_id => $self->project->id, |
|
166 |
variables => $::form, |
|
167 |
always_valid => 1, |
|
168 |
); |
|
169 |
|
|
170 |
flash_later('info', $is_new ? $::locale->text('The project has been created.') : $::locale->text('The project has been saved.')); |
|
171 |
|
|
172 |
$self->redirect_to($::form->{callback} || (action => 'search')); |
|
173 |
} |
|
174 |
|
|
175 |
sub load_project { |
|
176 |
my ($self) = @_; |
|
177 |
$self->project(SL::DB::Project->new(id => $::form->{id})->load); |
|
178 |
} |
|
179 |
|
|
180 |
sub setup_db_args_from_filter { |
|
181 |
my ($self) = @_; |
|
182 |
|
|
183 |
$self->{filter} = {}; |
|
184 |
my %args = parse_filter( |
|
185 |
$self->_pre_parse_filter($::form->{filter}, $self->{filter}), |
|
186 |
with_objects => [ 'customer' ], |
|
187 |
launder_to => $self->{filter}, |
|
188 |
); |
|
189 |
|
|
190 |
$self->db_args(\%args); |
|
191 |
} |
|
192 |
|
|
193 |
# unfortunately ParseFilter can't handle compount filters. |
|
194 |
# so we clone the original filter (still need that for serializing) |
|
195 |
# rip out the options we know an replace them with the compound options. |
|
196 |
# ParseFilter will take care of the prefixing then. |
|
197 |
sub _pre_parse_filter { |
|
198 |
my ($self, $orig_filter, $launder_to) = @_; |
|
199 |
|
|
200 |
return undef unless $orig_filter; |
|
201 |
|
|
202 |
my $filter = clone($orig_filter); |
|
203 |
|
|
204 |
$launder_to->{active} = delete $filter->{active}; |
|
205 |
if ($orig_filter->{active} ne 'both') { |
|
206 |
push @{ $filter->{and} }, $orig_filter->{active} eq 'active' ? (active => 1) : (or => [ active => 0, active => undef ]); |
|
207 |
} |
|
208 |
|
|
209 |
$launder_to->{valid} = delete $filter->{valid}; |
|
210 |
if ($orig_filter->{valid} ne 'both') { |
|
211 |
push @{ $filter->{and} }, $orig_filter->{valid} eq 'valid' ? (valid => 1) : (or => [ valid => 0, valid => undef ]); |
|
212 |
} |
|
213 |
|
|
214 |
$launder_to->{status} = delete $filter->{status}; |
|
215 |
if ($orig_filter->{status} ne 'all') { |
|
216 |
push @{ $filter->{and} }, SL::DB::Manager::Project->is_not_used_filter; |
|
217 |
} |
|
218 |
|
|
219 |
return $filter; |
|
220 |
} |
|
221 |
|
|
222 |
sub prepare_report { |
|
223 |
my ($self) = @_; |
|
224 |
|
|
225 |
my $callback = $self->get_callback; |
|
226 |
|
|
227 |
my $report = SL::ReportGenerator->new(\%::myconfig, $::form); |
|
228 |
$self->{report} = $report; |
|
229 |
|
|
230 |
my @columns = qw(projectnumber description customer active valid type); |
|
231 |
my @sortable = qw(projectnumber description customer type); |
|
232 |
|
|
233 |
my %column_defs = ( |
|
234 |
projectnumber => { obj_link => sub { $self->url_for(action => 'edit', id => $_[0]->id, callback => $callback) } }, |
|
235 |
description => { obj_link => sub { $self->url_for(action => 'edit', id => $_[0]->id, callback => $callback) } }, |
|
236 |
type => { }, |
|
237 |
customer => { sub => sub { $_[0]->customer ? $_[0]->customer->name : '' } }, |
|
238 |
active => { sub => sub { $_[0]->active ? $::locale->text('Active') : $::locale->text('Inactive') }, |
|
239 |
text => $::locale->text('Active') }, |
|
240 |
valid => { sub => sub { $_[0]->valid ? $::locale->text('Valid') : $::locale->text('Invalid') }, |
|
241 |
text => $::locale->text('Valid') }, |
|
242 |
); |
|
243 |
|
|
244 |
map { $column_defs{$_}->{text} ||= $::locale->text( $self->get_sort_spec->{$_}->{title} ) } keys %column_defs; |
|
245 |
|
|
246 |
$report->set_options( |
|
247 |
std_column_visibility => 1, |
|
248 |
controller_class => 'Project', |
|
249 |
output_format => 'HTML', |
|
250 |
top_info_text => $::locale->text('Projects'), |
|
251 |
raw_bottom_info_text => $self->render('project/report_bottom', { no_output => 1, partial => 1 }), |
|
252 |
title => $::locale->text('Projects'), |
|
253 |
allow_pdf_export => 1, |
|
254 |
allow_csv_export => 1, |
|
255 |
); |
|
256 |
$report->set_columns(%column_defs); |
|
257 |
$report->set_column_order(@columns); |
|
258 |
$report->set_export_options(qw(list filter)); |
|
259 |
$report->set_options_from_form; |
|
260 |
$self->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable); |
|
261 |
|
|
262 |
$self->disable_pagination if $report->{options}{output_format} =~ /^(pdf|csv)$/i; |
|
263 |
|
|
264 |
$self->{report_data} = { |
|
265 |
column_defs => \%column_defs, |
|
266 |
columns => \@columns, |
|
267 |
}; |
|
268 |
} |
|
269 |
|
|
270 |
sub list_objects { |
|
271 |
my ($self) = @_; |
|
272 |
my $column_defs = $self->{report_data}->{column_defs}; |
|
273 |
|
|
274 |
for my $obj (@{ $self->{projects} || [] }) { |
|
275 |
my %data = map { |
|
276 |
$_ => { |
|
277 |
data => $column_defs->{$_}{sub} ? $column_defs->{$_}{sub}->($obj) |
|
278 |
: $obj->can($_) ? $obj->$_ |
|
279 |
: $obj->{$_}, |
|
280 |
link => $column_defs->{$_}{obj_link} ? $column_defs->{$_}{obj_link}->($obj) : '', |
|
281 |
}, |
|
282 |
} @{ $self->{report_data}{columns} || {} }; |
|
283 |
|
|
284 |
$self->{report}->add_data(\%data); |
|
285 |
} |
|
286 |
|
|
287 |
return $self->{report}->generate_with_headers; |
|
288 |
} |
|
289 |
|
|
290 |
1; |
SL/DB/Manager/Project.pm | ||
---|---|---|
1 |
package SL::DB::Manager::Project; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
use parent qw(SL::DB::Helper::Manager); |
|
6 |
|
|
7 |
use SL::DB::Helper::Paginated; |
|
8 |
use SL::DB::Helper::Sorted; |
|
9 |
|
|
10 |
sub object_class { 'SL::DB::Project' } |
|
11 |
|
|
12 |
__PACKAGE__->make_manager_methods; |
|
13 |
|
|
14 |
our %project_id_column_prefixes = ( |
|
15 |
ar => 'global', |
|
16 |
ap => 'global', |
|
17 |
oe => 'global', |
|
18 |
delivery_orders => 'global', |
|
19 |
); |
|
20 |
|
|
21 |
our @tables_with_project_id_cols = qw(acc_trans ap ar delivery_order_items delivery_orders invoice oe orderitems rmaitems); |
|
22 |
|
|
23 |
sub _sort_spec { |
|
24 |
return ( |
|
25 |
default => [ 'projectnumber', 1 ], |
|
26 |
columns => { |
|
27 |
SIMPLE => 'ALL', |
|
28 |
customer => 'customer.name', |
|
29 |
}); |
|
30 |
} |
|
31 |
|
|
32 |
sub is_not_used_filter { |
|
33 |
my ($class, $prefix) = @_; |
|
34 |
|
|
35 |
my $query = join ' UNION ', map { |
|
36 |
my $column = $project_id_column_prefixes{$_} . 'project_id'; |
|
37 |
qq|SELECT DISTINCT ${column} FROM ${_} WHERE ${column} IS NOT NULL| |
|
38 |
} @tables_with_project_id_cols; |
|
39 |
|
|
40 |
return ("!${prefix}id" => [ \"(${query})" ]); |
|
41 |
} |
|
42 |
|
|
43 |
1; |
|
44 |
__END__ |
|
45 |
|
|
46 |
=pod |
|
47 |
|
|
48 |
=encoding utf8 |
|
49 |
|
|
50 |
=head1 NAME |
|
51 |
|
|
52 |
SL::DB::Manager::Project - Manager for models for the 'project' table |
|
53 |
|
|
54 |
=head1 SYNOPSIS |
|
55 |
|
|
56 |
This is a standard Rose::DB::Manager based model manager and can be |
|
57 |
used as such. |
|
58 |
|
|
59 |
=head1 FUNCTIONS |
|
60 |
|
|
61 |
=over 4 |
|
62 |
|
|
63 |
=item C<is_not_used_filter> |
|
64 |
|
|
65 |
Returns an array containing a partial filter suitable for the C<query> |
|
66 |
parameter that limits to projects that are not referenced from any |
|
67 |
other database table. |
|
68 |
|
|
69 |
=back |
|
70 |
|
|
71 |
=head1 BUGS |
|
72 |
|
|
73 |
Nothing here yet. |
|
74 |
|
|
75 |
=head1 AUTHOR |
|
76 |
|
|
77 |
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt> |
|
78 |
|
|
79 |
=cut |
SL/DB/Project.pm | ||
---|---|---|
2 | 2 |
|
3 | 3 |
use strict; |
4 | 4 |
|
5 |
use List::MoreUtils qw(any); |
|
6 |
|
|
5 | 7 |
use SL::DB::MetaSetup::Project; |
8 |
use SL::DB::Manager::Project; |
|
6 | 9 |
|
7 | 10 |
use SL::DB::Helper::CustomVariables( |
8 | 11 |
module => 'Project', |
9 | 12 |
cvars_alias => 1, |
10 | 13 |
); |
11 | 14 |
|
12 |
__PACKAGE__->meta->make_manager_class; |
|
13 | 15 |
__PACKAGE__->meta->initialize; |
14 | 16 |
|
17 |
sub validate { |
|
18 |
my ($self) = @_; |
|
19 |
|
|
20 |
my @errors; |
|
21 |
push @errors, $::locale->text('The project number is missing.') if !$self->projectnumber; |
|
22 |
push @errors, $::locale->text('The project number is already in use.') if !$self->is_projectnumber_unique; |
|
23 |
push @errors, $::locale->text('The description is missing.') if !$self->description; |
|
24 |
|
|
25 |
return @errors; |
|
26 |
} |
|
27 |
|
|
28 |
sub is_used { |
|
29 |
my ($self) = @_; |
|
30 |
|
|
31 |
# Unsaved projects are never referenced. |
|
32 |
return 0 unless $self->id; |
|
33 |
|
|
34 |
return any { |
|
35 |
my $column = $SL::DB::Manager::Project::project_id_column_prefixes{$_} . 'project_id'; |
|
36 |
$self->db->dbh->selectrow_arrayref(qq|SELECT EXISTS(SELECT * FROM ${_} WHERE ${column} = ?)|, undef, $self->id)->[0] |
|
37 |
} @SL::DB::Manager::Project::tables_with_project_id_cols; |
|
38 |
} |
|
39 |
|
|
40 |
sub is_projectnumber_unique { |
|
41 |
my ($self) = @_; |
|
42 |
|
|
43 |
return 1 unless $self->projectnumber; |
|
44 |
|
|
45 |
my @filter = (projectnumber => $self->projectnumber); |
|
46 |
@filter = (and => [ @filter, '!id' => $self->id ]) if $self->id; |
|
47 |
|
|
48 |
return !SL::DB::Manager::Project->get_first(where => \@filter); |
|
49 |
} |
|
50 |
|
|
15 | 51 |
1; |
16 | 52 |
|
17 | 53 |
__END__ |
... | ... | |
28 | 64 |
|
29 | 65 |
=head1 FUNCTIONS |
30 | 66 |
|
31 |
None so far. |
|
67 |
=over 4 |
|
68 |
|
|
69 |
=item C<validate> |
|
70 |
|
|
71 |
Checks whether or not all fields are set to valid values so that the |
|
72 |
object can be saved. If valid returns an empty list. Returns an array |
|
73 |
of translated error message otherwise. |
|
74 |
|
|
75 |
=item C<is_used> |
|
76 |
|
|
77 |
Checks whether or not the project is referenced from any other |
|
78 |
database table. Returns a boolean value. |
|
79 |
|
|
80 |
=item C<is_projectnumber_unique> |
|
81 |
|
|
82 |
Returns trueish if the project number is not used for any other |
|
83 |
project in the database. Also returns trueish if no project number has |
|
84 |
been set yet. |
|
85 |
|
|
86 |
=back |
|
32 | 87 |
|
33 | 88 |
=head1 AUTHOR |
34 | 89 |
|
SL/Projects.pm | ||
---|---|---|
1 |
#===================================================================== |
|
2 |
# LX-Office ERP |
|
3 |
# Copyright (C) 2004 |
|
4 |
# Based on SQL-Ledger Version 2.1.9 |
|
5 |
# Web http://www.lx-office.org |
|
6 |
# |
|
7 |
#===================================================================== |
|
8 |
# SQL-Ledger Accounting |
|
9 |
# Copyright (C) 1998-2002 |
|
10 |
# |
|
11 |
# Author: Dieter Simader |
|
12 |
# Email: dsimader@sql-ledger.org |
|
13 |
# Web: http://www.sql-ledger.org |
|
14 |
# |
|
15 |
# Contributors: |
|
16 |
# |
|
17 |
# This program is free software; you can redistribute it and/or modify |
|
18 |
# it under the terms of the GNU General Public License as published by |
|
19 |
# the Free Software Foundation; either version 2 of the License, or |
|
20 |
# (at your option) any later version. |
|
21 |
# |
|
22 |
# This program is distributed in the hope that it will be useful, |
|
23 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
24 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
25 |
# GNU General Public License for more details. |
|
26 |
# You should have received a copy of the GNU General Public License |
|
27 |
# along with this program; if not, write to the Free Software |
|
28 |
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|
29 |
#====================================================================== |
|
30 |
# |
|
31 |
# Project module |
|
32 |
# |
|
33 |
#====================================================================== |
|
34 |
|
|
35 |
package Projects; |
|
36 |
|
|
37 |
use Data::Dumper; |
|
38 |
|
|
39 |
use SL::DBUtils; |
|
40 |
use SL::CVar; |
|
41 |
|
|
42 |
use strict; |
|
43 |
|
|
44 |
my %project_id_column_prefixes = ("ar" => "global", |
|
45 |
"ap" => "global", |
|
46 |
"oe" => "global", |
|
47 |
"delivery_orders" => "global"); |
|
48 |
|
|
49 |
my @tables_with_project_id_cols = qw(acc_trans |
|
50 |
invoice |
|
51 |
orderitems |
|
52 |
rmaitems |
|
53 |
ar |
|
54 |
ap |
|
55 |
oe |
|
56 |
delivery_orders |
|
57 |
delivery_order_items); |
|
58 |
|
|
59 |
sub search_projects { |
|
60 |
$main::lxdebug->enter_sub(); |
|
61 |
|
|
62 |
my $self = shift; |
|
63 |
my %params = @_; |
|
64 |
|
|
65 |
my $myconfig = \%main::myconfig; |
|
66 |
my $form = $main::form; |
|
67 |
|
|
68 |
my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig); |
|
69 |
|
|
70 |
my (@filters, @values); |
|
71 |
|
|
72 |
foreach my $column (qw(projectnumber description)) { |
|
73 |
if ($params{$column}) { |
|
74 |
push @filters, "p.$column ILIKE ?"; |
|
75 |
push @values, '%' . $params{$column} . '%'; |
|
76 |
} |
|
77 |
} |
|
78 |
|
|
79 |
if ($params{status} eq 'orphaned') { |
|
80 |
my @sub_filters; |
|
81 |
|
|
82 |
foreach my $table (@tables_with_project_id_cols) { |
|
83 |
push @sub_filters, qq|SELECT DISTINCT $project_id_column_prefixes{$table}project_id FROM $table |
|
84 |
WHERE NOT $project_id_column_prefixes{$table}project_id ISNULL|; |
|
85 |
} |
|
86 |
|
|
87 |
push @filters, "p.id NOT IN (" . join(" UNION ", @sub_filters) . ")"; |
|
88 |
} |
|
89 |
|
|
90 |
if ($params{active} eq "active") { |
|
91 |
push @filters, 'p.active'; |
|
92 |
|
|
93 |
} elsif ($params{active} eq "inactive") { |
|
94 |
push @filters, 'NOT COALESCE(p.active, FALSE)'; |
|
95 |
} |
|
96 |
|
|
97 |
if ($params{valid} eq "valid") { |
|
98 |
push @filters, 'p.valid'; |
|
99 |
|
|
100 |
} elsif ($params{valid} eq "invalid") { |
|
101 |
push @filters, 'NOT COALESCE(p.valid, FALSE)'; |
|
102 |
} |
|
103 |
|
|
104 |
if ($params{customer}) { |
|
105 |
push @filters, 'c.name ILIKE ?'; |
|
106 |
push @values, '%' . $params{customer} . '%'; |
|
107 |
} |
|
108 |
|
|
109 |
if ($params{type}) { |
|
110 |
push @filters, 'p.type ILIKE ?'; |
|
111 |
push @values, '%' . $params{type} . '%'; |
|
112 |
} |
|
113 |
|
|
114 |
my ($cvar_where, @cvar_values) = CVar->build_filter_query('module' => 'Projects', |
|
115 |
'trans_id_field' => 'p.id', |
|
116 |
'filter' => $form); |
|
117 |
|
|
118 |
if ($cvar_where) { |
|
119 |
push @filters, $cvar_where; |
|
120 |
push @values, @cvar_values; |
|
121 |
} |
|
122 |
|
|
123 |
|
|
124 |
my $where = @filters ? 'WHERE ' . join(' AND ', map { "($_)" } @filters) : ''; |
|
125 |
|
|
126 |
my $sortorder = $params{sort} ? $params{sort} : "projectnumber"; |
|
127 |
$sortorder =~ s/[^a-z_]//g; |
|
128 |
my $query = qq|SELECT p.id, p.projectnumber, p.description, p.active, p.valid, p.type, |
|
129 |
c.name AS customer |
|
130 |
FROM project p |
|
131 |
LEFT JOIN customer c ON (p.customer_id = c.id) |
|
132 |
$where |
|
133 |
ORDER BY $sortorder|; |
|
134 |
|
|
135 |
$form->{project_list} = selectall_hashref_query($form, $dbh, $query, @values); |
|
136 |
|
|
137 |
$main::lxdebug->leave_sub(); |
|
138 |
|
|
139 |
return scalar(@{ $form->{project_list} }); |
|
140 |
} |
|
141 |
|
|
142 |
sub get_project { |
|
143 |
$main::lxdebug->enter_sub(); |
|
144 |
|
|
145 |
my $self = shift; |
|
146 |
my %params = @_; |
|
147 |
|
|
148 |
if (!$params{id}) { |
|
149 |
$main::lxdebug->leave_sub(); |
|
150 |
return { }; |
|
151 |
} |
|
152 |
|
|
153 |
my $myconfig = \%main::myconfig; |
|
154 |
my $form = $main::form; |
|
155 |
|
|
156 |
my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig); |
|
157 |
|
|
158 |
my $project = selectfirst_hashref_query($form, $dbh, qq|SELECT * FROM project WHERE id = ?|, conv_i($params{id})) || { }; |
|
159 |
|
|
160 |
if ($params{orphaned}) { |
|
161 |
# check if it is orphaned |
|
162 |
my (@values, $query); |
|
163 |
|
|
164 |
foreach my $table (@tables_with_project_id_cols) { |
|
165 |
$query .= " + " if ($query); |
|
166 |
$query .= qq|(SELECT COUNT(*) FROM $table |
|
167 |
WHERE $project_id_column_prefixes{$table}project_id = ?) |; |
|
168 |
push @values, conv_i($params{id}); |
|
169 |
} |
|
170 |
|
|
171 |
$query = 'SELECT ' . $query; |
|
172 |
|
|
173 |
($project->{orphaned}) = selectrow_query($form, $dbh, $query, @values); |
|
174 |
$project->{orphaned} = !$project->{orphaned}; |
|
175 |
} |
|
176 |
|
|
177 |
$main::lxdebug->leave_sub(); |
|
178 |
|
|
179 |
return $project; |
|
180 |
} |
|
181 |
|
|
182 |
sub save_project { |
|
183 |
$main::lxdebug->enter_sub(); |
|
184 |
|
|
185 |
my $self = shift; |
|
186 |
my %params = @_; |
|
187 |
|
|
188 |
my $myconfig = \%main::myconfig; |
|
189 |
my $form = $main::form; |
|
190 |
|
|
191 |
my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig); |
|
192 |
|
|
193 |
my @values; |
|
194 |
|
|
195 |
if (!$params{id}) { |
|
196 |
($params{id}) = selectfirst_array_query($form, $dbh, qq|SELECT nextval('id')|); |
|
197 |
do_query($form, $dbh, qq|INSERT INTO project (id) VALUES (?)|, conv_i($params{id})); |
|
198 |
|
|
199 |
$params{active} = 1; |
|
200 |
} |
|
201 |
|
|
202 |
my $query = <<SQL; |
|
203 |
UPDATE project |
|
204 |
SET projectnumber = ?, description = ?, active = ?, customer_id = ?, type = ?, valid = ? |
|
205 |
WHERE id = ? |
|
206 |
SQL |
|
207 |
|
|
208 |
@values = ($params{projectnumber}, $params{description}, $params{active} ? 't' : 'f', conv_i($params{customer_id}), $params{type}, $params{valid} ? 't' : 'f', conv_i($params{id})); |
|
209 |
do_query($form, $dbh, $query, @values); |
|
210 |
|
|
211 |
CVar->save_custom_variables('dbh' => $dbh, |
|
212 |
'module' => 'Projects', |
|
213 |
'trans_id' => $params{id}, |
|
214 |
'variables' => $form, |
|
215 |
'always_valid' => 1); |
|
216 |
|
|
217 |
$dbh->commit(); |
|
218 |
|
|
219 |
$main::lxdebug->leave_sub(); |
|
220 |
|
|
221 |
return $params{id}; |
|
222 |
} |
|
223 |
|
|
224 |
sub delete_project { |
|
225 |
$main::lxdebug->enter_sub(); |
|
226 |
|
|
227 |
my $self = shift; |
|
228 |
my %params = @_; |
|
229 |
|
|
230 |
Common::check_params(\%params, qw(id)); |
|
231 |
|
|
232 |
my $myconfig = \%main::myconfig; |
|
233 |
my $form = $main::form; |
|
234 |
|
|
235 |
my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig); |
|
236 |
|
|
237 |
do_query($form, $dbh, qq|DELETE FROM project WHERE id = ?|, conv_i($params{id})); |
|
238 |
|
|
239 |
$dbh->commit(); |
|
240 |
|
|
241 |
$main::lxdebug->leave_sub(); |
|
242 |
} |
|
243 |
|
|
244 |
1; |
bin/mozilla/arap.pl | ||
---|---|---|
30 | 30 |
# common routines for gl, ar, ap, is, ir, oe |
31 | 31 |
# |
32 | 32 |
|
33 |
use SL::Projects; |
|
34 |
|
|
35 | 33 |
use strict; |
36 | 34 |
|
37 | 35 |
# any custom scripts for this one |
... | ... | |
298 | 296 |
$::form->{salesman_id} = $current_employee->id if $current_employee && exists $::form->{salesman_id}; |
299 | 297 |
} |
300 | 298 |
|
301 |
sub check_project { |
|
302 |
$main::lxdebug->enter_sub(); |
|
303 |
|
|
304 |
my $form = $main::form; |
|
305 |
my $locale = $main::locale; |
|
306 |
|
|
307 |
$main::auth->assert('general_ledger | vendor_invoice_edit | sales_order_edit | invoice_edit |' . |
|
308 |
'request_quotation_edit | sales_quotation_edit | purchase_order_edit | cash | report'); |
|
309 |
|
|
310 |
my $nextsub = shift || 'update'; |
|
311 |
|
|
312 |
for my $i (1 .. $form->{rowcount}) { |
|
313 |
my $suffix = $i ? "_$i" : ""; |
|
314 |
my $prefix = $i ? "" : "global"; |
|
315 |
$form->{"${prefix}project_id${suffix}"} = "" unless $form->{"${prefix}projectnumber$suffix"}; |
|
316 |
if ($form->{"${prefix}projectnumber${suffix}"} ne $form->{"old${prefix}projectnumber${suffix}"}) { |
|
317 |
if ($form->{"${prefix}projectnumber${suffix}"}) { |
|
318 |
|
|
319 |
# get new project |
|
320 |
$form->{projectnumber} = $form->{"${prefix}projectnumber${suffix}"}; |
|
321 |
my %params = map { $_ => $form->{$_} } qw(projectnumber description active); |
|
322 |
my $rows; |
|
323 |
if (($rows = Projects->search_projects(%params)) > 1) { |
|
324 |
|
|
325 |
# check form->{project_list} how many there are |
|
326 |
$form->{rownumber} = $i; |
|
327 |
&select_project($i ? undef : 1, $nextsub); |
|
328 |
::end_of_request(); |
|
329 |
} |
|
330 |
|
|
331 |
if ($rows == 1) { |
|
332 |
$form->{"${prefix}project_id${suffix}"} = $form->{project_list}->[0]->{id}; |
|
333 |
$form->{"${prefix}projectnumber${suffix}"} = $form->{project_list}->[0]->{projectnumber}; |
|
334 |
$form->{"old${prefix}projectnumber${suffix}"} = $form->{project_list}->[0]->{projectnumber}; |
|
335 |
} else { |
|
336 |
|
|
337 |
# not on file |
|
338 |
$form->error($locale->text('Project not on file!')); |
|
339 |
} |
|
340 |
} else { |
|
341 |
$form->{"old${prefix}projectnumber${suffix}"} = ""; |
|
342 |
} |
|
343 |
} |
|
344 |
} |
|
345 |
|
|
346 |
$main::lxdebug->leave_sub(); |
|
347 |
} |
|
348 |
|
|
349 | 299 |
sub select_project { |
350 | 300 |
$::lxdebug->enter_sub; |
351 | 301 |
|
... | ... | |
420 | 370 |
=head1 SYNOPSIS |
421 | 371 |
|
422 | 372 |
check_name('vendor') |
423 |
check_project(); |
|
424 | 373 |
|
425 | 374 |
=head1 DESCRIPTION |
426 | 375 |
|
bin/mozilla/projects.pl | ||
---|---|---|
1 |
#===================================================================== |
|
2 |
# LX-Office ERP |
|
3 |
# Copyright (C) 2004 |
|
4 |
# Based on SQL-Ledger Version 2.1.9 |
|
5 |
# Web http://www.lx-office.org |
|
6 |
# |
|
7 |
#===================================================================== |
|
8 |
# SQL-Ledger Accounting |
|
9 |
# Copyright (c) 1998-2002 |
|
10 |
# |
|
11 |
# Author: Dieter Simader |
|
12 |
# Email: dsimader@sql-ledger.org |
|
13 |
# Web: http://www.sql-ledger.org |
|
14 |
# |
|
15 |
# |
|
16 |
# This program is free software; you can redistribute it and/or modify |
|
17 |
# it under the terms of the GNU General Public License as published by |
|
18 |
# the Free Software Foundation; either version 2 of the License, or |
|
19 |
# (at your option) any later version. |
|
20 |
# |
|
21 |
# This program is distributed in the hope that it will be useful, |
|
22 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
23 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
24 |
# GNU General Public License for more details. |
|
25 |
# You should have received a copy of the GNU General Public License |
|
26 |
# along with this program; if not, write to the Free Software |
|
27 |
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|
28 |
#====================================================================== |
|
29 |
# |
|
30 |
# project administration |
|
31 |
#====================================================================== |
|
32 |
|
|
33 |
use POSIX qw(strftime); |
|
34 |
|
|
35 |
use SL::CVar; |
|
36 |
use SL::Projects; |
|
37 |
use SL::ReportGenerator; |
|
38 |
|
|
39 |
require "bin/mozilla/common.pl"; |
|
40 |
require "bin/mozilla/reportgenerator.pl"; |
|
41 |
|
|
42 |
use strict; |
|
43 |
|
|
44 |
sub add { |
|
45 |
$main::lxdebug->enter_sub(); |
|
46 |
|
|
47 |
$main::auth->assert('project_edit'); |
|
48 |
|
|
49 |
my $form = $main::form; |
|
50 |
my $locale = $main::locale; |
|
51 |
|
|
52 |
# construct callback |
|
53 |
$form->{callback} = build_std_url('action') unless $form->{callback}; |
|
54 |
|
|
55 |
display_project_form(); |
|
56 |
|
|
57 |
$main::lxdebug->leave_sub(); |
|
58 |
} |
|
59 |
|
|
60 |
sub edit { |
|
61 |
$main::lxdebug->enter_sub(); |
|
62 |
|
|
63 |
$main::auth->assert('project_edit'); |
|
64 |
|
|
65 |
my $form = $main::form; |
|
66 |
my $locale = $main::locale; |
|
67 |
|
|
68 |
# show history button |
|
69 |
$form->{javascript} = qq|<script type="text/javascript" src="js/show_history.js"></script>|; |
|
70 |
#/show hhistory button |
|
71 |
$form->{title} = "Edit"; |
|
72 |
|
|
73 |
$form->{project} = Projects->get_project('id' => $form->{id}, 'orphaned' => 1); |
|
74 |
|
|
75 |
display_project_form(); |
|
76 |
|
|
77 |
$main::lxdebug->leave_sub(); |
|
78 |
} |
|
79 |
|
|
80 |
sub search { |
|
81 |
$main::lxdebug->enter_sub(); |
|
82 |
|
|
83 |
$main::auth->assert('project_edit'); |
|
84 |
|
|
85 |
my $form = $main::form; |
|
86 |
my $locale = $main::locale; |
|
87 |
|
|
88 |
$form->{title} = $locale->text('Projects'); |
|
89 |
|
|
90 |
$form->{CUSTOM_VARIABLES} = CVar->get_configs('module' => 'Projects'); |
|
91 |
($form->{CUSTOM_VARIABLES_FILTER_CODE}, |
|
92 |
$form->{CUSTOM_VARIABLES_INCLUSION_CODE}) = CVar->render_search_options('variables' => $form->{CUSTOM_VARIABLES}, |
|
93 |
'include_prefix' => 'l_', |
|
94 |
'include_value' => 'Y'); |
|
95 |
$::request->{layout}->focus('#projectnumber'); |
|
96 |
|
|
97 |
$form->header(); |
|
98 |
print $form->parse_html_template('projects/search'); |
|
99 |
|
|
100 |
$main::lxdebug->leave_sub(); |
|
101 |
} |
|
102 |
|
|
103 |
sub project_report { |
|
104 |
$main::lxdebug->enter_sub(); |
|
105 |
|
|
106 |
$main::auth->assert('project_edit'); |
|
107 |
|
|
108 |
my $form = $main::form; |
|
109 |
my %myconfig = %main::myconfig; |
|
110 |
my $locale = $main::locale; |
|
111 |
|
|
112 |
$form->{sort} ||= 'projectnumber'; |
|
113 |
my $filter = $form->{filter} || { }; |
|
114 |
|
|
115 |
Projects->search_projects(%{ $filter }, 'sort' => $form->{sort}); |
|
116 |
|
|
117 |
my $cvar_configs = CVar->get_configs('module' => 'Projects'); |
|
118 |
|
|
119 |
my $report = SL::ReportGenerator->new(\%myconfig, $form); |
|
120 |
|
|
121 |
my @columns = qw(projectnumber description customer type active valid); |
|
122 |
|
|
123 |
my @includeable_custom_variables = grep { $_->{includeable} } @{ $cvar_configs }; |
|
124 |
my @searchable_custom_variables = grep { $_->{searchable} } @{ $cvar_configs }; |
|
125 |
my %column_defs_cvars = (); |
|
126 |
foreach (@includeable_custom_variables) { |
|
127 |
$column_defs_cvars{"cvar_$_->{name}"} = { |
|
128 |
'text' => $_->{description}, |
|
129 |
'visible' => $form->{"l_cvar_$_->{name}"} eq 'Y', |
|
130 |
}; |
|
131 |
} |
|
132 |
|
|
133 |
push @columns, map { "cvar_$_->{name}" } @includeable_custom_variables; |
|
134 |
|
|
135 |
|
|
136 |
my @hidden_vars = ( |
|
137 |
'filter', |
|
138 |
map({ ('cvar_'. $_->{name} , 'l_cvar_'. $_->{name}) } @includeable_custom_variables), |
|
139 |
map({'cvar_'. $_->{name} .'_qtyop'} grep({$_->{type} eq 'number'} @searchable_custom_variables)), |
|
140 |
); |
|
141 |
my $href = build_std_url('action=project_report', @hidden_vars); |
|
142 |
|
|
143 |
|
|
144 |
my %column_defs = ( |
|
145 |
'projectnumber' => { 'text' => $locale->text('Number'), }, |
|
146 |
'description' => { 'text' => $locale->text('Description'), }, |
|
147 |
'customer' => { 'text' => $locale->text('Customer'), }, |
|
148 |
'type' => { 'text' => $locale->text('Type'), }, |
|
149 |
'active' => { 'text' => $locale->text('Active'), 'visible' => 'both' eq $filter->{active}, }, |
|
150 |
'valid' => { 'text' => $locale->text('Valid'), 'visible' => 'both' eq $filter->{active}, }, |
|
151 |
%column_defs_cvars, |
|
152 |
); |
|
153 |
|
|
154 |
foreach (qw(projectnumber description customer type)) { |
|
155 |
$column_defs{$_}->{link} = $href . "&sort=$_"; |
|
156 |
$column_defs{$_}->{visible} = 1; |
|
157 |
} |
|
158 |
|
|
159 |
$report->set_columns(%column_defs); |
|
160 |
$report->set_column_order(@columns); |
|
161 |
|
|
162 |
$report->set_export_options('project_report', @hidden_vars, 'sort'); |
|
163 |
|
|
164 |
CVar->add_custom_variables_to_report('module' => 'Project', |
|
165 |
'trans_id_field' => 'id', |
|
166 |
'configs' => $cvar_configs, |
|
167 |
'column_defs' => \%column_defs, |
|
168 |
'data' => $form->{project_list}, |
|
169 |
); |
|
170 |
|
|
171 |
$report->set_sort_indicator($form->{sort}, 1); |
|
172 |
|
|
173 |
my @options; |
|
174 |
push @options, $locale->text('All') if ($filter->{all}); |
|
175 |
push @options, $locale->text('Orphaned') if ($filter->{orphaned}); |
|
176 |
push @options, $locale->text('Project Number') . " : $filter->{projectnumber}" if ($filter->{projectnumber}); |
|
177 |
push @options, $locale->text('Description') . " : $filter->{description}" if ($filter->{description}); |
|
178 |
push @options, $locale->text('Customer') . " : $filter->{customer}" if ($filter->{customer}); |
|
179 |
push @options, $locale->text('Type') . " : $filter->{type}" if ($filter->{type}); |
|
180 |
push @options, $locale->text('Active') if ($filter->{active} eq 'active'); |
|
181 |
push @options, $locale->text('Inactive') if ($filter->{active} eq 'inactive'); |
|
182 |
push @options, $locale->text('Orphaned') if ($filter->{status} eq 'orphaned'); |
|
183 |
|
|
184 |
$form->{title} = $locale->text('Projects'); |
|
185 |
|
|
186 |
$report->set_options('top_info_text' => join("\n", @options), |
|
187 |
'output_format' => 'HTML', |
|
188 |
'title' => $form->{title}, |
|
189 |
'attachment_basename' => $locale->text('project_list') . strftime('_%Y%m%d', localtime time), |
|
190 |
); |
|
191 |
$report->set_options_from_form(); |
|
192 |
$locale->set_numberformat_wo_thousands_separator(\%myconfig) if lc($report->{options}->{output_format}) eq 'csv'; |
|
193 |
|
|
194 |
CVar->add_custom_variables_to_report('module' => 'Projects', |
|
195 |
'trans_id_field' => 'id', |
|
196 |
'configs' => $cvar_configs, |
|
197 |
'column_defs' => \%column_defs, |
|
198 |
'data' => $form->{project_list}); |
|
199 |
|
|
200 |
my $edit_url = build_std_url('action=edit&type=project'); |
|
201 |
my $callback = $form->escape($href) . '&sort=' . E($form->{sort}); |
|
202 |
|
|
203 |
foreach my $project (@{ $form->{project_list} }) { |
|
204 |
$project->{active} = $project->{active} ? $locale->text('Yes') : $locale->text('No'); |
|
205 |
$project->{valid} = $project->{valid} ? $locale->text('Yes') : $locale->text('No'); |
|
206 |
|
|
207 |
my $row = { map { $_ => { 'data' => $project->{$_} } } keys %{ $project } }; |
|
208 |
|
|
209 |
$row->{projectnumber}->{link} = $edit_url . "&id=" . E($project->{id}) . "&callback=${callback}"; |
|
210 |
|
|
211 |
$report->add_data($row); |
|
212 |
} |
|
213 |
|
|
214 |
$report->generate_with_headers(); |
|
215 |
|
|
216 |
$main::lxdebug->leave_sub(); |
|
217 |
} |
|
218 |
|
|
219 |
sub display_project_form { |
|
220 |
$main::lxdebug->enter_sub(); |
|
221 |
|
|
222 |
$main::auth->assert('project_edit'); |
|
223 |
|
|
224 |
my $form = $main::form; |
|
225 |
my $locale = $main::locale; |
|
226 |
|
|
227 |
$form->{project} ||= { }; |
|
228 |
|
|
229 |
$form->{title} = $form->{project}->{id} ? $locale->text("Edit Project") : $locale->text("Add Project"); |
|
230 |
|
|
231 |
$form->{ALL_CUSTOMERS} = SL::DB::Manager::Customer->get_all_sorted(where => [ or => [ obsolete => 0, obsolete => undef, id => $form->{project}->{customer_id} ]]); |
|
232 |
$form->{CUSTOM_VARIABLES} = CVar->get_custom_variables('module' => 'Projects', 'trans_id' => $form->{project}->{id}); |
|
233 |
# $main::lxdebug->dump(0, "cv", $form->{CUSTOM_VARIABLES}); |
|
234 |
CVar->render_inputs('variables' => $form->{CUSTOM_VARIABLES}) if (scalar @{ $form->{CUSTOM_VARIABLES} }); |
|
235 |
|
|
236 |
$form->header(); |
|
237 |
print $form->parse_html_template('projects/project_form'); |
|
238 |
|
|
239 |
$main::lxdebug->leave_sub(); |
|
240 |
} |
|
241 |
|
|
242 |
sub save { |
|
243 |
$main::lxdebug->enter_sub(); |
|
244 |
|
|
245 |
$main::auth->assert('project_edit'); |
|
246 |
|
|
247 |
my $form = $main::form; |
|
248 |
my %myconfig = %main::myconfig; |
|
249 |
my $locale = $main::locale; |
|
250 |
|
|
251 |
$form->isblank("project.projectnumber", $locale->text('Project Number missing!')); |
|
252 |
|
|
253 |
my $project = $form->{project} || { }; |
|
254 |
my $is_new = !$project->{id}; |
|
255 |
$project->{id} = Projects->save_project(%{ $project }); |
|
256 |
|
|
257 |
# saving the history |
|
258 |
if(!exists $form->{addition} && $project->{id} ne "") { |
|
259 |
$form->{id} = $project->{id}; |
|
260 |
$form->{snumbers} = qq|projectnumber_| . $project->{projectnumber}; |
|
261 |
$form->{addition} = "SAVED"; |
|
262 |
$form->save_history; |
|
263 |
} |
|
264 |
# /saving the history |
|
265 |
|
|
266 |
if ($form->{callback}) { |
|
267 |
map { $form->{callback} .= "&new_${_}=" . $form->escape($project->{$_}); } qw(projectnumber description id); |
|
268 |
my $message = $is_new ? $locale->text('The project has been added.') : $locale->text('The project has been saved.'); |
|
269 |
$form->{callback} .= "&message=" . E($message); |
|
270 |
} |
|
271 |
|
|
272 |
$form->redirect($locale->text('Project saved!')); |
|
273 |
|
|
274 |
$main::lxdebug->leave_sub(); |
|
275 |
} |
|
276 |
|
|
277 |
sub save_as_new { |
|
278 |
$main::lxdebug->enter_sub(); |
|
279 |
|
|
280 |
my $form = $main::form; |
|
281 |
my $locale = $main::locale; |
|
282 |
|
|
283 |
delete $form->{project}->{id} if ($form->{project}); |
|
284 |
save(); |
|
285 |
|
|
286 |
$main::lxdebug->leave_sub(); |
|
287 |
} |
|
288 |
|
|
289 |
sub delete { |
|
290 |
$main::lxdebug->enter_sub(); |
|
291 |
|
|
292 |
$main::auth->assert('project_edit'); |
|
293 |
|
|
294 |
my $form = $main::form; |
|
295 |
my %myconfig = %main::myconfig; |
|
296 |
my $locale = $main::locale; |
|
297 |
|
|
298 |
my $project = $form->{project} || { }; |
|
299 |
Projects->delete_project('id' => $project->{id}); |
|
300 |
|
|
301 |
# saving the history |
|
302 |
if(!exists $form->{addition}) { |
|
303 |
$form->{snumbers} = qq|projectnumber_| . $project->{projectnumber}; |
|
304 |
$form->{addition} = "DELETED"; |
|
305 |
$form->save_history; |
|
306 |
} |
|
307 |
# /saving the history |
|
308 |
|
|
309 |
$form->redirect($locale->text('Project deleted!')); |
|
310 |
|
|
311 |
$main::lxdebug->leave_sub(); |
|
312 |
} |
|
313 |
|
|
314 |
sub continue { |
|
315 |
call_sub($main::form->{nextsub}); |
|
316 |
} |
bin/mozilla/rp.pl | ||
---|---|---|
37 | 37 |
|
38 | 38 |
use POSIX qw(strftime); |
39 | 39 |
|
40 |
use SL::DB::Project; |
|
40 | 41 |
use SL::PE; |
41 | 42 |
use SL::RP; |
42 | 43 |
use SL::Iconv; |
43 | 44 |
use SL::ReportGenerator; |
44 | 45 |
use Data::Dumper; |
46 |
use List::MoreUtils qw(any); |
|
45 | 47 |
|
46 | 48 |
require "bin/mozilla/arap.pl"; |
47 | 49 |
require "bin/mozilla/common.pl"; |
... | ... | |
213 | 215 |
|
214 | 216 |
sub continue { call_sub($main::form->{"nextsub"}); } |
215 | 217 |
|
216 |
sub get_project { |
|
217 |
$main::lxdebug->enter_sub(); |
|
218 |
|
|
219 |
$main::auth->assert('report'); |
|
220 |
|
|
221 |
my $form = $main::form; |
|
222 |
my %myconfig = %main::myconfig; |
|
223 |
my $locale = $main::locale; |
|
224 |
|
|
225 |
my $nextsub = shift; |
|
226 |
|
|
227 |
$form->{project_id} = $form->{project_id_1}; |
|
228 |
if ($form->{projectnumber} && !$form->{project_id}) { |
|
229 |
$form->{rowcount} = 1; |
|
230 |
|
|
231 |
# call this instead of update |
|
232 |
$form->{update} = $nextsub; |
|
233 |
$form->{projectnumber_1} = $form->{projectnumber}; |
|
234 |
|
|
235 |
delete $form->{sort}; |
|
236 |
check_project('generate_projects'); |
|
237 |
|
|
238 |
# if there is one only, assign id |
|
239 |
$form->{project_id} = $form->{project_id_1}; |
|
240 |
} |
|
241 |
|
|
242 |
$main::lxdebug->leave_sub(); |
|
243 |
} |
|
244 |
|
|
245 | 218 |
sub generate_income_statement { |
246 | 219 |
$main::lxdebug->enter_sub(); |
247 | 220 |
|
... | ... | |
460 | 433 |
my %myconfig = %main::myconfig; |
461 | 434 |
my $locale = $main::locale; |
462 | 435 |
|
463 |
&get_project("generate_projects");
|
|
464 |
$form->{projectnumber} = $form->{projectnumber_1};
|
|
436 |
my $project = $form->{project_id} ? SL::DB::Project->new(id => $form->{project_id})->load : undef;
|
|
437 |
$form->{projectnumber} = $project ? $project->projectnumber : '';
|
|
465 | 438 |
|
466 | 439 |
$form->{nextsub} = "generate_projects"; |
467 | 440 |
$form->{title} = $locale->text('Project Transactions'); |
locale/de/all | ||
---|---|---|
468 | 468 |
'Create a new business' => 'Einen neuen Kunden-/Lieferantentyp erfassen', |
469 | 469 |
'Create a new department' => 'Eine neue Abteilung erfassen', |
470 | 470 |
'Create a new payment term' => 'Neue Zahlungsbedingungen anlegen', |
471 |
'Create a new project' => 'Neues Projekt anlegen', |
|
471 | 472 |
'Create a standard group' => 'Eine Standard-Benutzergruppe anlegen', |
472 | 473 |
'Create and edit RFQs' => 'Lieferantenanfragen erfassen und bearbeiten', |
473 | 474 |
'Create and edit dunnings' => 'Mahnungen erfassen und bearbeiten', |
... | ... | |
741 | 742 |
'Edit Price Factor' => 'Preisfaktor bearbeiten', |
742 | 743 |
'Edit Pricegroup' => 'Preisgruppe bearbeiten', |
743 | 744 |
'Edit Printer' => 'Drucker bearbeiten', |
744 |
'Edit Project' => 'Projekt bearbeiten', |
|
745 | 745 |
'Edit Purchase Delivery Order' => 'Lieferschein (Einkauf) bearbeiten', |
746 | 746 |
'Edit Purchase Order' => 'Lieferantenaufrag bearbeiten', |
747 | 747 |
'Edit Quotation' => 'Angebot bearbeiten', |
... | ... | |
772 | 772 |
'Edit note' => 'Notiz bearbeiten', |
773 | 773 |
'Edit payment term' => 'Zahlungsbedingungen bearbeiten', |
774 | 774 |
'Edit prices and discount (if not used, textfield is ONLY set readonly)' => 'Preise und Rabatt in Formularen frei anpassen (falls deaktiviert, wird allerdings NUR das textfield auf READONLY gesetzt / kann je nach Browserversion und technischen Fähigkeiten des Anwenders noch umgangen werden)', |
775 |
'Edit project' => 'Projekt bearbeiten', |
|
776 |
'Edit project #1' => 'Projekt #1 bearbeiten', |
|
775 | 777 |
'Edit rights' => 'Rechte bearbeiten', |
776 | 778 |
'Edit templates' => 'Vorlagen bearbeiten', |
777 | 779 |
'Edit the Delivery Order' => 'Lieferschein bearbeiten', |
... | ... | |
1490 | 1492 |
'Project' => 'Projekt', |
1491 | 1493 |
'Project Description' => 'Projektbeschreibung', |
1492 | 1494 |
'Project Number' => 'Projektnummer', |
1493 |
'Project Number missing!' => 'Projektnummer fehlt!', |
|
1494 | 1495 |
'Project Numbers' => 'Projektnummern', |
1495 | 1496 |
'Project Transactions' => 'Projektbuchungen', |
1496 |
'Project deleted!' => 'Projekt gelöscht!', |
|
1497 |
'Project not on file!' => 'Dieses Projekt ist nicht in der Datenbank!', |
|
1498 |
'Project saved!' => 'Projekt gespeichert!', |
|
1499 | 1497 |
'Projects' => 'Projekte', |
1500 | 1498 |
'Projecttransactions' => 'Projektbuchungen', |
1501 | 1499 |
'Prozentual/Absolut' => 'Prozentual/Absolut', |
... | ... | |
1655 | 1653 |
'Search AP Aging' => 'Offene Verbindlichkeiten', |
1656 | 1654 |
'Search AR Aging' => 'Offene Forderungen', |
1657 | 1655 |
'Search contacts' => 'Ansprechpersonensuche', |
1656 |
'Search projects' => 'Projektsuche', |
|
1658 | 1657 |
'Search term' => 'Suchbegriff', |
1659 | 1658 |
'Searchable' => 'Durchsuchbar', |
1660 | 1659 |
'Secondary sorting' => 'Untersortierung', |
... | ... | |
1990 | 1989 |
'The profile \'#1\' has been deleted.' => 'Das Profil \'#1\' wurde gelöscht.', |
1991 | 1990 |
'The profile has been saved under the name \'#1\'.' => 'Das Profil wurde unter dem Namen \'#1\' gespeichert.', |
1992 | 1991 |
'The program\'s exit code was #1 ("0" usually means that everything went OK).' => 'Der Exitcode des Programms war #1 ("0" bedeutet normalerweise, dass die Wiederherstellung erfolgreich war).', |
1993 |
'The project has been added.' => 'Das Projekt wurde erfasst.', |
|
1992 |
'The project has been created.' => 'Das Projekt wurde angelegt.', |
|
1993 |
'The project has been deleted.' => 'Das Projekt wurde gelöscht.', |
|
1994 | 1994 |
'The project has been saved.' => 'Das Projekt wurde gespeichert.', |
1995 |
'The project is in use and cannot be deleted.' => 'Das Projekt ist in Verwendung und kann nicht gelöscht werden.', |
|
1996 |
'The project number is already in use.' => 'Die Projektnummer wird bereits verwendet.', |
|
1997 |
'The project number is missing.' => 'Die Projektnummer fehlt.', |
|
1995 | 1998 |
'The restoration process has started. Here\'s the output of the "pg_restore" command:' => 'Der Wiederherstellungsprozess wurde gestartet. Hier ist die Ausgabe des "pg_restore"-Programmes:', |
1996 | 1999 |
'The restoration process is complete. Please review "pg_restore"\'s output to find out if the restoration was successful.' => 'Die Wiederherstellung ist abgeschlossen. Bitte sehen Sie sich die Ausgabe von "pg_restore" an, um festzustellen, ob die Wiederherstellung erfolgreich war.', |
1997 | 2000 |
'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.', |
... | ... | |
2436 | 2439 |
'prev' => 'zurück', |
2437 | 2440 |
'print' => 'drucken', |
2438 | 2441 |
'proforma' => 'Proforma', |
2439 |
'project_list' => 'projektliste', |
|
2440 | 2442 |
'purchase_delivery_order_list' => 'lieferscheinliste_einkauf', |
2441 | 2443 |
'purchase_order' => 'Auftrag', |
2442 | 2444 |
'purchase_order_list' => 'lieferantenauftragsliste', |
menu.ini | ||
---|---|---|
32 | 32 |
|
33 | 33 |
[Master Data--Add Project] |
34 | 34 |
ACCESS=project_edit |
35 |
module=projects.pl
|
|
36 |
action=add
|
|
35 |
module=controller.pl
|
|
36 |
action=Project/new
|
|
37 | 37 |
|
38 | 38 |
[Master Data--Update Prices] |
39 | 39 |
ACCESS=part_service_assembly_edit |
... | ... | |
84 | 84 |
|
85 | 85 |
[Master Data--Reports--Projects] |
86 | 86 |
ACCESS=project_edit |
87 |
module=projects.pl
|
|
88 |
action=search |
|
87 |
module=controller.pl
|
|
88 |
action=Project/search
|
|
89 | 89 |
|
90 | 90 |
[AR] |
91 | 91 |
|
projects.pl | ||
---|---|---|
1 |
am.pl |
templates/webpages/project/form.html | ||
---|---|---|
1 |
[%- USE T8 %] |
|
2 |
[%- USE L %] |
|
3 |
[%- USE HTML %][%- USE LxERP %] |
|
4 |
|
|
5 |
[%- INCLUDE 'common/flash.html' %] |
|
6 |
|
|
7 |
<div class="listtop">[% title %]</div> |
|
8 |
|
|
9 |
<form method="post" action="controller.pl"> |
|
10 |
[% L.hidden_tag("callback", callback) %] |
|
11 |
[% L.hidden_tag("id", SELF.project.id) %] |
|
12 |
|
|
13 |
<ul id="maintab" class="shadetabs"> |
|
14 |
<li class="selected"><a href="#" rel="basic_data">[% 'Basic Data' | $T8 %]</a></li> |
|
15 |
[%- IF CUSTOM_VARIABLES.size %] |
|
16 |
<li><a href="#" rel="custom_variables">[% 'Custom Variables' | $T8 %]</a></li> |
|
17 |
[%- END %] |
|
18 |
</ul> |
|
19 |
|
|
20 |
<div class="tabcontentstyle"> |
|
21 |
|
|
22 |
<div id="basic_data" class="tabcontent"> |
|
23 |
|
|
24 |
<table> |
|
25 |
<tr> |
|
26 |
<th align="right">[% 'Number' | $T8 %]</th> |
|
27 |
<td>[% L.input_tag("project.projectnumber", SELF.project.projectnumber, size=60) %]</td> |
|
28 |
</tr> |
|
29 |
|
|
30 |
<tr> |
|
31 |
<th align="right">[% 'Description' | $T8 %]</th> |
|
32 |
<td> |
|
33 |
[%- SET rows = LxERP.numtextrows(SELF.project.description, 60) %] |
|
34 |
[%- IF rows > 1 %] |
|
35 |
[%- L.textarea_tag("project.description", SELF.project.description, rows=row, size=60, style="width: 100%", wrap="soft") %] |
|
36 |
[%- ELSE %] |
|
37 |
[%- L.input_tag("project.description", SELF.project.description, size=60) %] |
|
38 |
[%- END %] |
|
39 |
</td> |
|
40 |
</tr> |
|
41 |
|
|
42 |
<tr> |
|
43 |
<th align="right">[% 'Type' | $T8 %]</th> |
|
44 |
<td>[% L.input_tag('project.type', SELF.project.type, size=60) %]</td> |
|
45 |
</tr> |
|
46 |
|
|
47 |
<tr> |
|
48 |
<th align="right">[% 'Customer' | $T8 %]</th> |
|
49 |
<td>[% L.select_tag('project.customer_id', ALL_CUSTOMERS, default=SELF.project.customer_id, title_key='name', style='width: 300px') %]</td> |
|
50 |
</tr> |
|
51 |
|
|
52 |
<tr> |
|
53 |
<th align="right">[% 'Valid' | $T8 %]</th> |
|
54 |
<td>[% L.select_tag('project.valid', [ [ 1, LxERP.t8('Valid') ], [ 0, LxERP.t8('Invalid') ] ], default=SELF.project.valid, style='width: 300px') %]</td> |
|
55 |
</tr> |
|
56 |
|
|
57 |
[%- IF SELF.project.id %] |
|
58 |
<tr> |
|
59 |
<th align="right">[% 'Active' | $T8 %]</th> |
|
60 |
<td>[% L.select_tag('project.active', [ [ 1, LxERP.t8('Active') ], [ 0, LxERP.t8('Inactive') ] ], default=SELF.project.active, style='width: 300px') %]</td> |
|
61 |
</tr> |
|
62 |
[%- END %] |
|
63 |
</table> |
|
64 |
|
|
65 |
<br style="clear: left" /> |
|
66 |
</div> |
|
67 |
|
|
68 |
[%- IF CUSTOM_VARIABLES.size %] |
|
69 |
<div id="custom_variables" class="tabcontent"> |
|
70 |
|
|
71 |
<p> |
|
72 |
<table> |
|
73 |
[%- FOREACH var = CUSTOM_VARIABLES %] |
|
74 |
<tr> |
|
75 |
<td align="right" valign="top">[% HTML.escape(var.description) %]</td> |
|
76 |
<td valign="top">[% var.HTML_CODE %]</td> |
|
77 |
</tr> |
|
78 |
[%- END %] |
|
79 |
</table> |
|
80 |
</p> |
|
81 |
|
|
82 |
<br style="clear: left" /> |
|
83 |
</div> |
|
84 |
[%- END %] |
|
85 |
|
|
86 |
</div> |
|
87 |
|
|
88 |
<p> |
|
89 |
[% L.online_help_tag('add_project') %] |
|
90 |
[% L.hidden_tag("action", "Project/dispatch") %] |
|
91 |
[% L.submit_tag("action_" _ (SELF.project.id ? "update" : "create"), LxERP.t8('Save')) %] |
|
92 |
[%- IF SELF.project.id %] |
|
93 |
[% L.submit_tag("action_create", LxERP.t8('Save as new')) %] |
|
94 |
[% L.submit_tag("action_destroy", LxERP.t8('Delete'), confirm=LxERP.t8('Do you really want to delete this object?')) IF !SELF.project.is_used %] |
|
95 |
[%- END %] |
|
96 |
<a href="[% IF callback %][% callback %][% ELSE %][% SELF.url_for(action => 'search') %][% END %]">[%- LxERP.t8('Abort') %]</a> |
|
97 |
</p> |
|
98 |
</form> |
|
99 |
|
|
100 |
<script type="text/javascript"> |
|
101 |
<!-- |
|
102 |
var maintab = new ddtabcontent("maintab"); |
|
103 |
maintab.setpersist(true); |
|
104 |
maintab.setselectedClassTarget("link"); //"link" or "linkparent" |
|
105 |
maintab.init(); |
|
106 |
--> |
|
107 |
</script> |
templates/webpages/project/report_bottom.html | ||
---|---|---|
1 |
[% USE L %] |
|
2 |
[%- L.paginate_controls %] |
templates/webpages/project/search.html | ||
---|---|---|
1 |
[%- USE T8 %] |
|
2 |
[%- USE HTML %] |
|
3 |
[%- USE L %] |
|
4 |
[%- USE LxERP %] |
|
5 |
|
|
6 |
[%- INCLUDE 'common/flash.html' %] |
|
7 |
|
|
8 |
<form method="post" action="controller.pl"> |
|
9 |
|
|
10 |
<div class="listtop">[% 'Search projects' | $T8 %]</div> |
|
11 |
|
|
12 |
<p> |
|
13 |
<table> |
|
14 |
<tr> |
|
15 |
<th align="right">[% 'Number' | $T8 %]</th> |
|
16 |
<td>[% L.input_tag('filter.projectnumber:substr::ilike', filter.projectnumber_substr__ilike, size=60) %]</td> |
|
17 |
</tr> |
|
18 |
|
|
19 |
<tr> |
|
20 |
<th align="right">[% 'Description' | $T8 %]</th> |
|
21 |
<td>[% L.input_tag('filter.description:substr::ilike', filter.description_substr__ilike, size=60) %]</td> |
|
22 |
</tr> |
|
23 |
|
|
24 |
<tr> |
|
25 |
<th align="right">[% 'Customer' | $T8 %]</th> |
|
26 |
<td>[% L.input_tag('filter.customer.name:substr::ilike', filter.customer.name_substr__ilike, size=60) %]</td> |
|
27 |
</tr> |
|
28 |
|
|
29 |
<tr> |
|
30 |
<th align="right">[% 'Type' | $T8 %]</th> |
|
31 |
<td>[% L.input_tag('filter.type:substr::ilike', filter.type_substr__ilike, size=20) %]</td> |
|
32 |
</tr> |
|
33 |
|
|
34 |
[% CUSTOM_VARIABLES_FILTER_CODE %] |
|
35 |
|
|
36 |
<tr> |
|
37 |
<th>[% 'Include in Report' | $T8 %]</th> |
|
38 |
<td> |
|
39 |
<table> |
|
40 |
<tr> |
|
41 |
<td>[% L.select_tag('filter.active', [ [ 'active', LxERP.t8('Active') ], [ 'inactive', LxERP.t8('Inactive') ], [ 'both', LxERP.t8('Both') ] ], default=filter.active, style="width: 200px") %]</td> |
|
42 |
</tr> |
|
43 |
|
|
44 |
<tr> |
|
45 |
<td>[% L.select_tag('filter.valid', [ [ 'valid', LxERP.t8('Valid') ], [ 'invalid', LxERP.t8('Invalid') ], [ 'both', LxERP.t8('Both') ] ], default=filter.valid, style="width: 200px") %]</td> |
|
46 |
</tr> |
|
47 |
|
|
48 |
<tr> |
|
49 |
<td>[% L.select_tag('filter.status', [ [ 'all', LxERP.t8('All') ], [ 'orphaned', LxERP.t8('Orphaned') ] ], default=filter.status, style="width: 200px") %]</td> |
|
50 |
</tr> |
|
51 |
|
|
52 |
[% CUSTOM_VARIABLES_INCLUSION_CODE %] |
|
53 |
|
|
54 |
</table> |
|
55 |
</td> |
|
56 |
</tr> |
|
57 |
</table> |
|
58 |
</p> |
|
59 |
|
|
60 |
<hr size="3" noshade> |
|
61 |
|
|
62 |
[% L.hidden_tag('action', 'Project/list') %] |
|
63 |
|
|
64 |
<p>[% L.submit_tag('dummy', LxERP.t8('Continue')) %]</p> |
|
65 |
</form> |
templates/webpages/projects/project_form.html | ||
---|---|---|
1 |
[%- USE T8 %] |
|
2 |
[%- USE L %] |
|
3 |
[%- USE HTML %][%- USE LxERP %] |
|
4 |
|
|
5 |
[%- IF message %] |
|
6 |
<p>[% message %]</p> |
|
7 |
|
|
8 |
<hr> |
|
9 |
[%- END %] |
|
10 |
|
|
11 |
<p><div class="listtop">[% title %] [% HTML.escape(project.projectnumber) %]</div></p> |
Auch abrufbar als: Unified diff
Projektverwaltung auf Rose- und Controller-Code umgestellt