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" => "b.description",
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 "insertdate" => "ct.itime",
80 "salesman" => "e.name",
81 "payment" => "pt.description",
82 "pricegroup" => "pg.pricegroup",
85 $form->{sort} ||= "name";
87 if ( $join_records ) {
88 # in UNION case order by hash key, e.g. salesman
89 # the UNION created an implicit select around the result
90 $sortorder = $allowed_sort_columns{$form->{sort}} ? $form->{sort} : "name";
92 # in not UNION case order by hash value, e.g. e.name
93 $sortorder = $allowed_sort_columns{$form->{sort}} ? $allowed_sort_columns{$form->{sort}} : "ct.name";
95 my $sortdir = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
97 if ($sortorder !~ /(business|id|discount|itime)/ && !$join_records) {
98 $sortorder = "lower($sortorder) ${sortdir}";
100 $sortorder .= " ${sortdir}";
103 if ($form->{"${cv}number"}) {
104 $where .= " AND ct.${cv}number ILIKE ?";
105 push(@values, '%' . $form->{"${cv}number"} . '%');
108 foreach my $key (qw(name contact email)) {
110 $where .= " AND ct.$key ILIKE ?";
111 push(@values, '%' . $form->{$key} . '%');
115 if ($form->{cp_name}) {
116 $where .= " AND ct.id IN (SELECT cp_cv_id FROM contacts WHERE lower(cp_name) LIKE lower(?))";
117 push @values, '%' . $form->{cp_name} . '%';
120 if ($form->{addr_city}) {
121 $where .= " AND ((lower(ct.city) LIKE lower(?))
126 WHERE (sc.module = 'CT')
127 AND (lower(sc.shiptocity) LIKE lower(?))
130 push @values, ('%' . $form->{addr_city} . '%') x 2;
133 if ($form->{addr_country}) {
134 $where .= " AND ((lower(ct.country) LIKE lower(?))
139 WHERE (so.module = 'CT')
140 AND (lower(so.shiptocountry) LIKE lower(?))
143 push @values, ('%' . $form->{addr_country} . '%') x 2;
146 if ( $form->{status} eq 'orphaned' ) {
148 qq| AND ct.id NOT IN | .
149 qq| (SELECT o.${cv}_id FROM oe o, $cv cv WHERE cv.id = o.${cv}_id)|;
150 if ($cv eq 'customer') {
152 qq| AND ct.id NOT IN | .
153 qq| (SELECT a.customer_id FROM ar a, customer cv | .
154 qq| WHERE cv.id = a.customer_id)|;
156 if ($cv eq 'vendor') {
158 qq| AND ct.id NOT IN | .
159 qq| (SELECT a.vendor_id FROM ap a, vendor cv | .
160 qq| WHERE cv.id = a.vendor_id)|;
162 $form->{l_invnumber} = $form->{l_ordnumber} = $form->{l_quonumber} = "";
165 if ($form->{obsolete} eq "Y") {
166 $where .= qq| AND ct.obsolete|;
167 } elsif ($form->{obsolete} eq "N") {
168 $where .= qq| AND NOT ct.obsolete|;
171 if ($form->{business_id}) {
172 $where .= qq| AND (ct.business_id = ?)|;
173 push(@values, conv_i($form->{business_id}));
176 if ($form->{salesman_id}) {
177 $where .= qq| AND (ct.salesman_id = ?)|;
178 push(@values, conv_i($form->{salesman_id}));
181 if($form->{insertdatefrom}) {
182 $where .= qq| AND (ct.itime::DATE >= ?)|;
183 push@values, conv_date($form->{insertdatefrom});
186 if($form->{insertdateto}) {
187 $where .= qq| AND (ct.itime::DATE <= ?)|;
188 push @values, conv_date($form->{insertdateto});
191 # Nur Kunden finden, bei denen ich selber der Verkäufer bin
192 # Gilt nicht für Lieferanten
193 if ($cv eq 'customer' && !$main::auth->assert('customer_vendor_all_edit', 1)) {
194 $where .= qq| AND ct.salesman_id = (select em.id from employee em where em.login = ?)|;
195 push(@values, $::myconfig{login});
198 my ($cvar_where, @cvar_values) = CVar->build_filter_query('module' => 'CT',
199 'trans_id_field' => 'ct.id',
203 $where .= qq| AND ($cvar_where)|;
204 push @values, @cvar_values;
207 if ($form->{addr_street}) {
208 $where .= qq| AND (ct.street ILIKE ?)|;
209 push @values, '%' . $form->{addr_street} . '%';
212 if ($form->{addr_zipcode}) {
213 $where .= qq| AND (ct.zipcode ILIKE ?)|;
214 push @values, $form->{addr_zipcode} . '%';
217 my $pg_select = $form->{l_pricegroup} ? qq|, pg.pricegroup as pricegroup | : '';
218 my $pg_join = $form->{l_pricegroup} ? qq|LEFT JOIN pricegroup pg ON (ct.klass = pg.id) | : '';
220 qq|SELECT ct.*, ct.itime::DATE AS insertdate, b.description AS business, e.name as salesman, | .
221 qq| pt.description as payment | .
223 (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) .
225 qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
226 qq|LEFT JOIN employee e ON (ct.salesman_id = e.id) | .
227 qq|LEFT JOIN payment_terms pt ON (ct.payment_id = pt.id) | .
231 my @saved_values = @values;
232 # redo for invoices, orders and quotations
236 if ($form->{l_invnumber}) {
237 my $ar = $cv eq 'customer' ? 'ar' : 'ap';
238 my $module = $ar eq 'ar' ? 'is' : 'ir';
239 push(@values, @saved_values);
242 qq|SELECT ct.*, ct.itime::DATE AS insertdate, b.description AS business, e.name as salesman, | .
243 qq| pt.description as payment | .
245 qq|, a.invnumber, a.ordnumber, a.quonumber, a.id AS invid, | .
246 qq| '$module' AS module, 'invoice' AS formtype, | .
247 qq| (a.amount = a.paid) AS closed | .
249 qq|JOIN $ar a ON (a.${cv}_id = ct.id) | .
250 qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
251 qq|LEFT JOIN employee e ON (ct.salesman_id = e.id) | .
252 qq|LEFT JOIN payment_terms pt ON (ct.payment_id = pt.id) | .
254 qq|WHERE $where AND (a.invoice = '1')|;
257 if ( $form->{l_ordnumber} ) {
258 push(@values, @saved_values);
261 qq|SELECT ct.*, ct.itime::DATE AS insertdate, b.description AS business, e.name as salesman, | .
262 qq| pt.description as payment | .
264 qq|, ' ' AS invnumber, o.ordnumber, o.quonumber, o.id AS invid, | .
265 qq| 'oe' AS module, 'order' AS formtype, o.closed | .
267 qq|JOIN oe o ON (o.${cv}_id = ct.id) | .
268 qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
269 qq|LEFT JOIN employee e ON (ct.salesman_id = e.id) | .
270 qq|LEFT JOIN payment_terms pt ON (ct.payment_id = pt.id) | .
272 qq|WHERE $where AND (o.quotation = '0')|;
275 if ( $form->{l_quonumber} ) {
276 push(@values, @saved_values);
279 qq|SELECT ct.*, ct.itime::DATE AS insertdate, b.description AS business, e.name as salesman, | .
280 qq| pt.description as payment | .
282 qq|, ' ' AS invnumber, o.ordnumber, o.quonumber, o.id AS invid, | .
283 qq| 'oe' AS module, 'quotation' AS formtype, o.closed | .
285 qq|JOIN oe o ON (o.${cv}_id = ct.id) | .
286 qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
287 qq|LEFT JOIN employee e ON (ct.salesman_id = e.id) | .
288 qq|LEFT JOIN payment_terms pt ON (ct.payment_id = pt.id) | .
290 qq|WHERE $where AND (o.quotation = '1')|;
294 $query .= qq| ORDER BY $sortorder|;
296 $form->{CT} = selectall_hashref_query($form, $dbh, $query, @values);
298 $main::lxdebug->leave_sub();
302 $main::lxdebug->enter_sub();
304 my ( $self, $myconfig, $form ) = @_;
306 die 'Missing argument: cp_id' unless $::form->{cp_id};
308 my $dbh = $form->dbconnect($myconfig);
310 qq|SELECT * FROM contacts c | .
311 qq|WHERE cp_id = ? ORDER BY cp_id limit 1|;
312 my $sth = prepare_execute_query($form, $dbh, $query, $form->{cp_id});
313 my $ref = $sth->fetchrow_hashref("NAME_lc");
315 map { $form->{$_} = $ref->{$_} } keys %$ref;
317 $query = qq|SELECT COUNT(cp_id) AS used FROM (
318 SELECT cp_id FROM oe UNION
319 SELECT cp_id FROM ar UNION
320 SELECT cp_id FROM ap UNION
321 SELECT cp_id FROM delivery_orders
322 ) AS cpid WHERE cp_id = ? OR ? = 0|;
323 ($form->{cp_used}) = selectfirst_array_query($form, $dbh, $query, ($form->{cp_id})x2);
328 $main::lxdebug->leave_sub();
332 $main::lxdebug->enter_sub();
337 Common::check_params(\%params, qw(vc id));
339 my $myconfig = \%main::myconfig;
340 my $form = $main::form;
342 my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
344 my $table = $params{vc} eq 'customer' ? 'customer' : 'vendor';
345 my @ids = ref $params{id} eq 'ARRAY' ? @{ $params{id} } : ($params{id});
346 my $placeholders = join ", ", ('?') x scalar @ids;
347 my $c_mandate = $params{vc} eq 'customer' ? ', mandator_id, mandate_date_of_signature' : '';
348 my $query = qq|SELECT id, name, account_number, bank, bank_code, iban, bic ${c_mandate}
350 WHERE id IN (${placeholders})|;
352 my $result = selectall_hashref_query($form, $dbh, $query, map { conv_i($_) } @ids);
354 if (ref $params{id} eq 'ARRAY') {
355 $result = { map { $_->{id} => $_ } @{ $result } };
357 $result = $result->[0] || { 'id' => $params{id} };
360 $main::lxdebug->leave_sub();
365 sub search_contacts {
366 $::lxdebug->enter_sub;
371 my $dbh = $params{dbh} || $::form->get_standard_dbh;
374 'cp_name' => 'cp_name, cp_givenname',
375 'vcname' => 'vcname, cp_name, cp_givenname',
376 'vcnumber' => 'vcnumber, cp_name, cp_givenname',
379 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);
381 my $order_by = $sortcols{$::form->{sort}} ? $::form->{sort} : 'cp_name';
382 $::form->{sort} = $order_by;
383 $order_by = $sortspecs{$order_by} if ($sortspecs{$order_by});
385 my $sortdir = $::form->{sortdir} ? 'ASC' : 'DESC';
386 $order_by =~ s/,/ ${sortdir},/g;
387 $order_by .= " $sortdir";
389 my @where_tokens = ();
392 if ($params{search_term}) {
395 'cp.cp_name ILIKE ?',
396 'cp.cp_givenname ILIKE ?',
397 'cp.cp_email ILIKE ?';
398 push @values, ('%' . $params{search_term} . '%') x 3;
400 if (($params{search_term} =~ m/\d/) && ($params{search_term} !~ m/[^\d \(\)+\-]/)) {
401 my $number = $params{search_term};
402 $number =~ s/[^\d]//g;
403 $number = join '[ /\(\)+\-]*', split(m//, $number);
405 push @tokens, map { "($_ ~ '$number')" } qw(cp_phone1 cp_phone2 cp_mobile1 cp_mobile2);
408 push @where_tokens, map { "($_)" } join ' OR ', @tokens;
411 my ($cvar_where, @cvar_values) = CVar->build_filter_query('module' => 'Contacts',
412 'trans_id_field' => 'cp.cp_id',
413 'filter' => $params{filter});
416 push @where_tokens, $cvar_where;
417 push @values, @cvar_values;
420 if (my $filter = $params{filter}) {
421 for (qw(name title givenname email project abteilung)) {
422 next unless $filter->{"cp_$_"};
423 add_token(\@where_tokens, \@values, col => "cp.cp_$_", val => $filter->{"cp_$_"}, method => 'ILIKE', esc => 'substr');
426 push @where_tokens, 'cp.cp_cv_id IS NOT NULL' if $filter->{status} eq 'active';
427 push @where_tokens, 'cp.cp_cv_id IS NULL' if $filter->{status} eq 'orphaned';
430 my $where = @where_tokens ? 'WHERE ' . join ' AND ', @where_tokens : '';
432 my $query = qq|SELECT cp.*,
433 COALESCE(c.id, v.id) AS vcid,
434 COALESCE(c.name, v.name) AS vcname,
435 COALESCE(c.customernumber, v.vendornumber) AS vcnumber,
436 CASE WHEN c.name IS NULL THEN 'vendor' ELSE 'customer' END AS db
438 LEFT JOIN customer c ON (cp.cp_cv_id = c.id)
439 LEFT JOIN vendor v ON (cp.cp_cv_id = v.id)
443 my $contacts = selectall_hashref_query($::form, $dbh, $query, @values);
445 $::lxdebug->leave_sub;
447 return @{ $contacts };