1 #=====================================================================
4 # Based on SQL-Ledger Version 2.1.9
5 # Web http://www.lx-office.org
7 #=====================================================================
8 # SQL-Ledger Accounting
11 # Author: Dieter Simader
12 # Email: dsimader@sql-ledger.org
13 # Web: http://www.sql-ledger.org
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.
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 #======================================================================
31 # backend code for customers and vendors
34 # DS. 2000-07-04 Created
36 #======================================================================
47 $main::lxdebug->enter_sub();
49 my ( $self, $myconfig, $form ) = @_;
52 my $dbh = $form->dbconnect($myconfig);
54 my $cv = $form->{db} eq "customer" ? "customer" : "vendor";
55 my $join_records = $form->{l_invnumber} || $form->{l_ordnumber} || $form->{l_quonumber};
60 my %allowed_sort_columns = (
62 "customernumber" => "ct.customernumber",
63 "vendornumber" => "ct.vendornumber",
65 "contact" => "ct.contact",
66 "phone" => "ct.phone",
68 "email" => "ct.email",
69 "street" => "ct.street",
70 "taxnumber" => "ct.taxnumber",
71 "business" => "ct.business",
72 "invnumber" => "ct.invnumber",
73 "ordnumber" => "ct.ordnumber",
74 "quonumber" => "ct.quonumber",
75 "zipcode" => "ct.zipcode",
77 "country" => "ct.country",
78 "discount" => "ct.discount",
79 "salesman" => "e.name"
82 $form->{sort} ||= "name";
84 if ( $join_records ) {
85 # in UNION case order by hash key, e.g. salesman
86 # the UNION created an implicit select around the result
87 $sortorder = $allowed_sort_columns{$form->{sort}} ? $form->{sort} : "name";
89 # in not UNION case order by hash value, e.g. e.name
90 $sortorder = $allowed_sort_columns{$form->{sort}} ? $allowed_sort_columns{$form->{sort}} : "ct.name";
92 my $sortdir = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
94 if ($sortorder !~ /(business|id|discount)/ && !$join_records) {
95 $sortorder = "lower($sortorder) ${sortdir}";
97 $sortorder .= " ${sortdir}";
100 if ($form->{"${cv}number"}) {
101 $where .= " AND ct.${cv}number ILIKE ?";
102 push(@values, '%' . $form->{"${cv}number"} . '%');
105 foreach my $key (qw(name contact email)) {
107 $where .= " AND ct.$key ILIKE ?";
108 push(@values, '%' . $form->{$key} . '%');
112 if ($form->{cp_name}) {
113 $where .= " AND ct.id IN (SELECT cp_cv_id FROM contacts WHERE lower(cp_name) LIKE lower(?))";
114 push @values, '%' . $form->{cp_name} . '%';
117 if ($form->{addr_city}) {
118 $where .= " AND ((lower(ct.city) LIKE lower(?))
123 WHERE (sc.module = 'CT')
124 AND (lower(sc.shiptocity) LIKE lower(?))
127 push @values, ('%' . $form->{addr_city} . '%') x 2;
130 if ($form->{addr_country}) {
131 $where .= " AND ((lower(ct.country) LIKE lower(?))
136 WHERE (so.module = 'CT')
137 AND (lower(so.shiptocountry) LIKE lower(?))
140 push @values, ('%' . $form->{addr_country} . '%') x 2;
143 if ( $form->{status} eq 'orphaned' ) {
145 qq| AND ct.id NOT IN | .
146 qq| (SELECT o.${cv}_id FROM oe o, $cv cv WHERE cv.id = o.${cv}_id)|;
147 if ($cv eq 'customer') {
149 qq| AND ct.id NOT IN | .
150 qq| (SELECT a.customer_id FROM ar a, customer cv | .
151 qq| WHERE cv.id = a.customer_id)|;
153 if ($cv eq 'vendor') {
155 qq| AND ct.id NOT IN | .
156 qq| (SELECT a.vendor_id FROM ap a, vendor cv | .
157 qq| WHERE cv.id = a.vendor_id)|;
159 $form->{l_invnumber} = $form->{l_ordnumber} = $form->{l_quonumber} = "";
162 if ($form->{obsolete} eq "Y") {
163 $where .= qq| AND ct.obsolete|;
164 } elsif ($form->{obsolete} eq "N") {
165 $where .= qq| AND NOT ct.obsolete|;
168 if ($form->{business_id}) {
169 $where .= qq| AND (ct.business_id = ?)|;
170 push(@values, conv_i($form->{business_id}));
173 # Nur Kunden finden, bei denen ich selber der Verkäufer bin
174 # Gilt nicht für Lieferanten
175 if ($cv eq 'customer' && !$main::auth->assert('customer_vendor_all_edit', 1)) {
176 $where .= qq| AND ct.salesman_id = (select em.id from employee em where em.login = ?)|;
177 push(@values, $form->{login});
180 my ($cvar_where, @cvar_values) = CVar->build_filter_query('module' => 'CT',
181 'trans_id_field' => 'ct.id',
185 $where .= qq| AND ($cvar_where)|;
186 push @values, @cvar_values;
189 if ($form->{addr_street}) {
190 $where .= qq| AND (ct.street ILIKE ?)|;
191 push @values, '%' . $form->{addr_street} . '%';
194 if ($form->{addr_zipcode}) {
195 $where .= qq| AND (ct.zipcode ILIKE ?)|;
196 push @values, $form->{addr_zipcode} . '%';
200 qq|SELECT ct.*, b.description AS business, e.name as salesman | .
201 (qq|, NULL AS invnumber, NULL AS ordnumber, NULL AS quonumber, NULL AS invid, NULL AS module, NULL AS formtype, NULL AS closed | x!! $join_records) .
203 qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
204 qq|LEFT JOIN employee e ON (ct.salesman_id = e.id) | .
207 my @saved_values = @values;
208 # redo for invoices, orders and quotations
212 if ($form->{l_invnumber}) {
213 my $ar = $cv eq 'customer' ? 'ar' : 'ap';
214 my $module = $ar eq 'ar' ? 'is' : 'ir';
215 push(@values, @saved_values);
218 qq|SELECT ct.*, b.description AS business, e.name as salesman, | .
219 qq| a.invnumber, a.ordnumber, a.quonumber, a.id AS invid, | .
220 qq| '$module' AS module, 'invoice' AS formtype, | .
221 qq| (a.amount = a.paid) AS closed | .
223 qq|JOIN $ar a ON (a.${cv}_id = ct.id) | .
224 qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
225 qq|LEFT JOIN employee e ON (ct.salesman_id = e.id) | .
226 qq|WHERE $where AND (a.invoice = '1')|;
229 if ( $form->{l_ordnumber} ) {
230 push(@values, @saved_values);
233 qq|SELECT ct.*, b.description AS business, e.name as salesman, | .
234 qq| ' ' AS invnumber, o.ordnumber, o.quonumber, o.id AS invid, | .
235 qq| 'oe' AS module, 'order' AS formtype, o.closed | .
237 qq|JOIN oe o ON (o.${cv}_id = ct.id) | .
238 qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
239 qq|LEFT JOIN employee e ON (ct.salesman_id = e.id) | .
240 qq|WHERE $where AND (o.quotation = '0')|;
243 if ( $form->{l_quonumber} ) {
244 push(@values, @saved_values);
247 qq|SELECT ct.*, b.description AS business, e.name as salesman, | .
248 qq| ' ' AS invnumber, o.ordnumber, o.quonumber, o.id AS invid, | .
249 qq| 'oe' AS module, 'quotation' AS formtype, o.closed | .
251 qq|JOIN oe o ON (o.${cv}_id = ct.id) | .
252 qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
253 qq|LEFT JOIN employee e ON (ct.salesman_id = e.id) | .
254 qq|WHERE $where AND (o.quotation = '1')|;
258 $query .= qq| ORDER BY $sortorder|;
260 $form->{CT} = selectall_hashref_query($form, $dbh, $query, @values);
262 $main::lxdebug->leave_sub();
266 $main::lxdebug->enter_sub();
268 my ( $self, $myconfig, $form ) = @_;
270 die 'Missing argument: cp_id' unless $::form->{cp_id};
272 my $dbh = $form->dbconnect($myconfig);
274 qq|SELECT * FROM contacts c | .
275 qq|WHERE cp_id = ? ORDER BY cp_id limit 1|;
276 my $sth = prepare_execute_query($form, $dbh, $query, $form->{cp_id});
277 my $ref = $sth->fetchrow_hashref("NAME_lc");
279 map { $form->{$_} = $ref->{$_} } keys %$ref;
281 $query = qq|SELECT COUNT(cp_id) AS used FROM (
282 SELECT cp_id FROM oe UNION
283 SELECT cp_id FROM ar UNION
284 SELECT cp_id FROM ap UNION
285 SELECT cp_id FROM delivery_orders
286 ) AS cpid WHERE cp_id = ? OR ? = 0|;
287 ($form->{cp_used}) = selectfirst_array_query($form, $dbh, $query, ($form->{cp_id})x2);
292 $main::lxdebug->leave_sub();
296 $main::lxdebug->enter_sub();
301 Common::check_params(\%params, qw(vc id));
303 my $myconfig = \%main::myconfig;
304 my $form = $main::form;
306 my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
308 my $table = $params{vc} eq 'customer' ? 'customer' : 'vendor';
309 my @ids = ref $params{id} eq 'ARRAY' ? @{ $params{id} } : ($params{id});
310 my $placeholders = join ", ", ('?') x scalar @ids;
311 my $c_mandate = $params{vc} eq 'customer' ? ', mandator_id, mandate_date_of_signature' : '';
312 my $query = qq|SELECT id, name, account_number, bank, bank_code, iban, bic ${c_mandate}
314 WHERE id IN (${placeholders})|;
316 my $result = selectall_hashref_query($form, $dbh, $query, map { conv_i($_) } @ids);
318 if (ref $params{id} eq 'ARRAY') {
319 $result = { map { $_->{id} => $_ } @{ $result } };
321 $result = $result->[0] || { 'id' => $params{id} };
324 $main::lxdebug->leave_sub();
329 sub search_contacts {
330 $::lxdebug->enter_sub;
335 my $dbh = $params{dbh} || $::form->get_standard_dbh;
338 'cp_name' => 'cp_name, cp_givenname',
339 'vcname' => 'vcname, cp_name, cp_givenname',
340 'vcnumber' => 'vcnumber, cp_name, cp_givenname',
343 my %sortcols = map { $_ => 1 } qw(cp_name cp_givenname cp_phone1 cp_phone2 cp_mobile1 cp_email cp_street cp_zipcode cp_city cp_position vcname vcnumber);
345 my $order_by = $sortcols{$::form->{sort}} ? $::form->{sort} : 'cp_name';
346 $::form->{sort} = $order_by;
347 $order_by = $sortspecs{$order_by} if ($sortspecs{$order_by});
349 my $sortdir = $::form->{sortdir} ? 'ASC' : 'DESC';
350 $order_by =~ s/,/ ${sortdir},/g;
351 $order_by .= " $sortdir";
353 my @where_tokens = ();
356 if ($params{search_term}) {
359 'cp.cp_name ILIKE ?',
360 'cp.cp_givenname ILIKE ?',
361 'cp.cp_email ILIKE ?';
362 push @values, ('%' . $params{search_term} . '%') x 3;
364 if (($params{search_term} =~ m/\d/) && ($params{search_term} !~ m/[^\d \(\)+\-]/)) {
365 my $number = $params{search_term};
366 $number =~ s/[^\d]//g;
367 $number = join '[ /\(\)+\-]*', split(m//, $number);
369 push @tokens, map { "($_ ~ '$number')" } qw(cp_phone1 cp_phone2 cp_mobile1 cp_mobile2);
372 push @where_tokens, map { "($_)" } join ' OR ', @tokens;
375 my ($cvar_where, @cvar_values) = CVar->build_filter_query('module' => 'Contacts',
376 'trans_id_field' => 'cp.cp_id',
377 'filter' => $params{filter});
380 push @where_tokens, $cvar_where;
381 push @values, @cvar_values;
384 if (my $filter = $params{filter}) {
385 for (qw(name title givenname email project abteilung)) {
386 next unless $filter->{"cp_$_"};
387 add_token(\@where_tokens, \@values, col => "cp.cp_$_", val => $filter->{"cp_$_"}, method => 'ILIKE', esc => 'substr');
390 push @where_tokens, 'cp.cp_cv_id IS NOT NULL' if $filter->{status} eq 'active';
391 push @where_tokens, 'cp.cp_cv_id IS NULL' if $filter->{status} eq 'orphaned';
394 my $where = @where_tokens ? 'WHERE ' . join ' AND ', @where_tokens : '';
396 my $query = qq|SELECT cp.*,
397 COALESCE(c.id, v.id) AS vcid,
398 COALESCE(c.name, v.name) AS vcname,
399 COALESCE(c.customernumber, v.vendornumber) AS vcnumber,
400 CASE WHEN c.name IS NULL THEN 'vendor' ELSE 'customer' END AS db
402 LEFT JOIN customer c ON (cp.cp_cv_id = c.id)
403 LEFT JOIN vendor v ON (cp.cp_cv_id = v.id)
407 my $contacts = selectall_hashref_query($::form, $dbh, $query, @values);
409 $::lxdebug->leave_sub;
411 return @{ $contacts };