Bug in CT: SQL Fehler wenn es keine Ansprechpartner gibt aber CVars für Ansprechpartn...
[kivitendo-erp.git] / SL / CT.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) 2001
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 # backend code for customers and vendors
32 #
33 # CHANGE LOG:
34 #   DS. 2000-07-04  Created
35 #
36 #======================================================================
37
38 package CT;
39
40 use Data::Dumper;
41
42 use SL::Common;
43 use SL::CVar;
44 use SL::DBUtils;
45 use SL::FU;
46 use SL::Notes;
47 use SL::TransNumber;
48
49 use strict;
50
51 sub get_tuple {
52   $main::lxdebug->enter_sub();
53
54   my ( $self, $myconfig, $form ) = @_;
55
56   my $cv = $form->{db} eq "customer" ? "customer" : "vendor";
57
58   my $dbh   = $form->dbconnect($myconfig);
59   my $query =
60     qq|SELECT ct.*, b.id AS business, cp.* | .
61     qq|FROM $cv ct | .
62     qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
63     qq|LEFT JOIN contacts cp ON (ct.id = cp.cp_cv_id) | .
64     qq|WHERE (ct.id = ?) | .
65     qq|ORDER BY cp.cp_id LIMIT 1|;
66   my $sth = prepare_execute_query($form, $dbh, $query, $form->{id});
67
68   my $ref = $sth->fetchrow_hashref("NAME_lc");
69
70   map { $form->{$_} = $ref->{$_} } keys %$ref;
71
72   # remove any trailing whitespace
73   $form->{curr} =~ s/\s*$//;
74
75   $sth->finish;
76   if ( $form->{salesman_id} ) {
77     my $query =
78       qq|SELECT ct.name AS salesman | .
79       qq|FROM $cv ct | .
80       qq|WHERE ct.id = ?|;
81     ($form->{salesman}) =
82       selectrow_query($form, $dbh, $query, $form->{salesman_id});
83   }
84
85   my ($employee_id) = selectrow_query($form, $dbh, qq|SELECT id FROM employee WHERE login = ?|, $form->{login});
86   $query =
87     qq|SELECT n.*, n.itime::DATE AS created_on,
88          e.name AS created_by_name, e.login AS created_by_login
89        FROM notes n
90        LEFT JOIN employee e ON (n.created_by = e.id)
91        WHERE (n.trans_id = ?) AND (n.trans_module = 'ct')|;
92   $form->{NOTES} = selectall_hashref_query($form, $dbh, $query, conv_i($form->{id}));
93
94   $query =
95     qq|SELECT fu.follow_up_date, fu.done AS follow_up_done, e.name AS created_for_name, e.name AS created_for_login
96        FROM follow_ups fu
97        LEFT JOIN employee e ON (fu.created_for_user = e.id)
98        WHERE (fu.note_id = ?)
99          AND NOT COALESCE(fu.done, FALSE)
100          AND (   (fu.created_by = ?)
101               OR (fu.created_by IN (SELECT DISTINCT what FROM follow_up_access WHERE who = ?)))|;
102   $sth = prepare_query($form, $dbh, $query);
103
104   foreach my $note (@{ $form->{NOTES} }) {
105     do_statement($form, $sth, $query, conv_i($note->{id}), conv_i($note->{created_by}), conv_i($employee_id));
106     $ref = $sth->fetchrow_hashref();
107
108     map { $note->{$_} = $ref->{$_} } keys %{ $ref } if ($ref);
109   }
110
111   $sth->finish();
112
113   if ($form->{edit_note_id}) {
114     $query =
115       qq|SELECT n.id AS NOTE_id, n.subject AS NOTE_subject, n.body AS NOTE_body,
116            fu.id AS FU_id, fu.follow_up_date AS FU_date, fu.done AS FU_done, fu.created_for_user AS FU_created_for_user
117          FROM notes n
118          LEFT JOIN follow_ups fu ON ((n.id = fu.note_id) AND NOT COALESCE(fu.done, FALSE))
119          WHERE n.id = ?|;
120     $ref = selectfirst_hashref_query($form, $dbh, $query, conv_i($form->{edit_note_id}));
121
122     if ($ref) {
123       foreach my $key (keys %{ $ref }) {
124         my $new_key       =  $key;
125         $new_key          =~ s/^([^_]+)/\U$1\E/;
126         $form->{$new_key} =  $ref->{$key};
127       }
128     }
129   }
130
131   # check if it is orphaned
132   my $arap      = ( $form->{db} eq 'customer' ) ? "ar" : "ap";
133   my $num_args  = 2;
134   my $makemodel = '';
135   if ($form->{db} eq 'vendor') {
136     $makemodel = qq| UNION SELECT 1 FROM makemodel mm WHERE mm.make = ?|;
137     $num_args++;
138   }
139
140   $query =
141     qq|SELECT a.id | .
142     qq|FROM $arap a | .
143     qq|JOIN $cv ct ON (a.${cv}_id = ct.id) | .
144     qq|WHERE ct.id = ? | .
145     qq|UNION | .
146     qq|SELECT a.id | .
147     qq|FROM oe a | .
148     qq|JOIN $cv ct ON (a.${cv}_id = ct.id) | .
149     qq|WHERE ct.id = ?|
150     . $makemodel;
151   my ($dummy) = selectrow_query($form, $dbh, $query, (conv_i($form->{id})) x $num_args);
152
153   $form->{status} = "orphaned" unless ($dummy);
154
155   $dbh->disconnect;
156
157   $main::lxdebug->leave_sub();
158 }
159
160 sub populate_drop_down_boxes {
161   $main::lxdebug->enter_sub();
162
163   my ($self, $myconfig, $form, $provided_dbh) = @_;
164   my $query;
165
166   my $dbh = $provided_dbh ? $provided_dbh : $form->dbconnect($myconfig);
167
168   # get business types
169   $query = qq|SELECT id, description FROM business ORDER BY id|;
170   $form->{all_business} = selectall_hashref_query($form, $dbh, $query);
171
172   # get shipto address
173   $query =
174     qq|SELECT shipto_id, shiptoname, shiptodepartment_1, shiptostreet, shiptocity
175        FROM shipto
176        WHERE (trans_id = ?) AND (module = 'CT')|;
177   $form->{SHIPTO} = selectall_hashref_query($form, $dbh, $query, $form->{id});
178
179   # get contacts
180   $query  = qq|SELECT cp_id, cp_name, cp_givenname FROM contacts WHERE cp_cv_id = ? ORDER BY cp_name|;
181   $form->{CONTACTS} = selectall_hashref_query($form, $dbh, $query, $form->{id});
182
183   # get languages
184   $query = qq|SELECT id, description FROM language ORDER BY id|;
185   $form->{languages} = selectall_hashref_query($form, $dbh, $query);
186
187   # get payment terms
188   $query = qq|SELECT id, description FROM payment_terms ORDER BY sortkey|;
189   $form->{payment_terms} = selectall_hashref_query($form, $dbh, $query);
190
191   $dbh->disconnect() unless ($provided_dbh);
192
193   $main::lxdebug->leave_sub();
194 }
195
196 sub query_titles_and_greetings {
197   $main::lxdebug->enter_sub();
198
199   my ( $self, $myconfig, $form ) = @_;
200   my ( %tmp,  $ref, $query );
201
202   my $dbh = $form->dbconnect($myconfig);
203
204   $query =
205     qq|SELECT DISTINCT(greeting) | .
206     qq|FROM customer | .
207     qq|WHERE greeting ~ '[a-zA-Z]' | .
208     qq|UNION | .
209     qq|SELECT DISTINCT(greeting) | .
210     qq|FROM vendor | .
211     qq|WHERE greeting ~ '[a-zA-Z]' | .
212     qq|ORDER BY greeting|;
213
214   map({ $tmp{$_} = 1; } selectall_array_query($form, $dbh, $query));
215   $form->{COMPANY_GREETINGS} = [ sort(keys(%tmp)) ];
216
217   $query =
218     qq|SELECT DISTINCT(cp_title) | .
219     qq|FROM contacts | .
220     qq|WHERE cp_title ~ '[a-zA-Z]'|;
221   $form->{TITLES} = [ selectall_array_query($form, $dbh, $query) ];
222
223   $query =
224     qq|SELECT DISTINCT(cp_abteilung) | .
225     qq|FROM contacts | .
226     qq|WHERE cp_abteilung ~ '[a-zA-Z]'|;
227   $form->{DEPARTMENT} = [ selectall_array_query($form, $dbh, $query) ];
228
229   $dbh->disconnect();
230   $main::lxdebug->leave_sub();
231 }
232
233 sub save_customer {
234   $main::lxdebug->enter_sub();
235
236   my ( $self, $myconfig, $form ) = @_;
237
238   # set pricegroup to default
239   $form->{klass} = 0 unless ($form->{klass});
240
241   # connect to database
242   my $dbh = $form->get_standard_dbh;
243
244   map( {
245     $form->{"cp_${_}"} = $form->{"selected_cp_${_}"}
246     if ( $form->{"selected_cp_${_}"} );
247        } qw(title greeting abteilung) );
248   $form->{"greeting"} = $form->{"selected_company_greeting"}
249   if ( $form->{"selected_company_greeting"} );
250
251   # assign value discount, terms, creditlimit
252   $form->{discount} = $form->parse_amount( $myconfig, $form->{discount} );
253   $form->{discount} /= 100;
254   $form->{creditlimit} = $form->parse_amount( $myconfig, $form->{creditlimit} );
255
256   my ( $query, $sth, $f_id );
257
258   if ( $form->{id} ) {
259     $query = qq|SELECT id FROM customer WHERE customernumber = ?|;
260     ($f_id) = selectrow_query($form, $dbh, $query, $form->{customernumber});
261
262     if (($f_id ne $form->{id}) && ($f_id ne "")) {
263       $main::lxdebug->leave_sub();
264       return 3;
265     }
266
267   } else {
268     my $customernumber      = SL::TransNumber->new(type        => 'customer',
269                                                    dbh         => $dbh,
270                                                    number      => $form->{customernumber},
271                                                    business_id => $form->{business},
272                                                    save        => 1);
273     $form->{customernumber} = $customernumber->create_unique unless $customernumber->is_unique;
274
275     $query = qq|SELECT nextval('id')|;
276     ($form->{id}) = selectrow_query($form, $dbh, $query);
277
278     $query = qq|INSERT INTO customer (id, name) VALUES (?, '')|;
279     do_query($form, $dbh, $query, $form->{id});
280   }
281
282   $query = qq|UPDATE customer SET | .
283     qq|customernumber = ?, | .
284     qq|name = ?, | .
285     qq|greeting = ?, | .
286     qq|department_1 = ?, | .
287     qq|department_2 = ?, | .
288     qq|street = ?, | .
289     qq|zipcode = ?, | .
290     qq|city = ?, | .
291     qq|country = ?, | .
292     qq|homepage = ?, | .
293     qq|contact = ?, | .
294     qq|phone = ?, | .
295     qq|fax = ?, | .
296     qq|email = ?, | .
297     qq|cc = ?, | .
298     qq|bcc = ?, | .
299     qq|notes = ?, | .
300     qq|discount = ?, | .
301     qq|creditlimit = ?, | .
302     qq|terms = ?, | .
303     qq|business_id = ?, | .
304     qq|taxnumber = ?, | .
305     qq|language = ?, | .
306     qq|account_number = ?, | .
307     qq|bank_code = ?, | .
308     qq|bank = ?, | .
309     qq|iban = ?, | .
310     qq|bic = ?, | .
311     qq|obsolete = ?, | .
312     qq|direct_debit = ?, | .
313     qq|ustid = ?, | .
314     qq|username = ?, | .
315     qq|salesman_id = ?, | .
316     qq|language_id = ?, | .
317     qq|payment_id = ?, | .
318     qq|taxzone_id = ?, | .
319     qq|user_password = ?, | .
320     qq|c_vendor_id = ?, | .
321     qq|klass = ?, | .
322     qq|curr = ? | .
323     qq|WHERE id = ?|;
324   my @values = (
325     $form->{customernumber},
326     $form->{name},
327     $form->{greeting},
328     $form->{department_1},
329     $form->{department_2},
330     $form->{street},
331     $form->{zipcode},
332     $form->{city},
333     $form->{country},
334     $form->{homepage},
335     $form->{contact},
336     $form->{phone},
337     $form->{fax},
338     $form->{email},
339     $form->{cc},
340     $form->{bcc},
341     $form->{notes},
342     $form->{discount},
343     $form->{creditlimit},
344     conv_i($form->{terms}),
345     conv_i($form->{business}),
346     $form->{taxnumber},
347     $form->{language},
348     $form->{account_number},
349     $form->{bank_code},
350     $form->{bank},
351     $form->{iban},
352     $form->{bic},
353     $form->{obsolete} ? 't' : 'f',
354     $form->{direct_debit} ? 't' : 'f',
355     $form->{ustid},
356     $form->{username},
357     conv_i($form->{salesman_id}),
358     conv_i($form->{language_id}),
359     conv_i($form->{payment_id}),
360     conv_i($form->{taxzone_id}, 0),
361     $form->{user_password},
362     $form->{c_vendor_id},
363     conv_i($form->{klass}),
364     substr($form->{currency}, 0, 3),
365     $form->{id}
366     );
367   do_query( $form, $dbh, $query, @values );
368
369   $query = undef;
370   if ( $form->{cp_id} ) {
371     $query = qq|UPDATE contacts SET | .
372       qq|cp_title = ?,  | .
373       qq|cp_givenname = ?, | .
374       qq|cp_name = ?, | .
375       qq|cp_email = ?, | .
376       qq|cp_phone1 = ?, | .
377       qq|cp_phone2 = ?, | .
378       qq|cp_abteilung = ?, | .
379       qq|cp_fax = ?, | .
380       qq|cp_mobile1 = ?, | .
381       qq|cp_mobile2 = ?, | .
382       qq|cp_satphone = ?, | .
383       qq|cp_satfax = ?, | .
384       qq|cp_project = ?, | .
385       qq|cp_privatphone = ?, | .
386       qq|cp_privatemail = ?, | .
387       qq|cp_birthday = ?, | .
388       qq|cp_gender = ? | .
389       qq|WHERE cp_id = ?|;
390     @values = (
391       $form->{cp_title},
392       $form->{cp_givenname},
393       $form->{cp_name},
394       $form->{cp_email},
395       $form->{cp_phone1},
396       $form->{cp_phone2},
397       $form->{cp_abteilung},
398       $form->{cp_fax},
399       $form->{cp_mobile1},
400       $form->{cp_mobile2},
401       $form->{cp_satphone},
402       $form->{cp_satfax},
403       $form->{cp_project},
404       $form->{cp_privatphone},
405       $form->{cp_privatemail},
406       $form->{cp_birthday},
407       $form->{cp_gender} eq 'f' ? 'f' : 'm',
408       $form->{cp_id}
409       );
410   } elsif ( $form->{cp_name} || $form->{cp_givenname} ) {
411     $query =
412       qq|INSERT INTO contacts ( cp_cv_id, cp_title, cp_givenname,  | .
413       qq|  cp_name, cp_email, cp_phone1, cp_phone2, cp_abteilung, cp_fax, cp_mobile1, | .
414       qq|  cp_mobile2, cp_satphone, cp_satfax, cp_project, cp_privatphone, cp_privatemail, | .
415       qq|  cp_birthday, cp_gender) | .
416       qq|VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|;
417     @values = (
418       $form->{id},
419       $form->{cp_title},
420       $form->{cp_givenname},
421       $form->{cp_name},
422       $form->{cp_email},
423       $form->{cp_phone1},
424       $form->{cp_phone2},
425       $form->{cp_abteilung},
426       $form->{cp_fax},
427       $form->{cp_mobile1},
428       $form->{cp_mobile2},
429       $form->{cp_satphone},
430       $form->{cp_satfax},
431       $form->{cp_project},
432       $form->{cp_privatphone},
433       $form->{cp_privatemail},
434       $form->{cp_birthday},
435       $form->{cp_gender} eq 'f' ? 'f' : 'm',
436       );
437   }
438   do_query( $form, $dbh, $query, @values ) if ($query);
439
440   # add shipto
441   $form->add_shipto( $dbh, $form->{id}, "CT" );
442
443   $self->_save_note('dbh' => $dbh);
444   $self->_delete_selected_notes('dbh' => $dbh);
445
446   CVar->save_custom_variables('dbh'       => $dbh,
447                               'module'    => 'CT',
448                               'trans_id'  => $form->{id},
449                               'variables' => $form,
450                               'always_valid' => 1);
451   if ($form->{cp_id}) {
452     CVar->save_custom_variables('dbh'       => $dbh,
453                                 'module'    => 'Contacts',
454                                 'trans_id'  => $form->{cp_id},
455                                 'variables' => $form,
456                                 'name_prefix'  => 'cp',
457                                 'always_valid' => 1);
458   }
459
460   my $rc = $dbh->commit();
461
462   $main::lxdebug->leave_sub();
463   return $rc;
464 }
465
466 sub save_vendor {
467   $main::lxdebug->enter_sub();
468
469   my ( $self, $myconfig, $form ) = @_;
470
471   $form->{taxzone_id} *= 1;
472   # connect to database
473   my $dbh = $form->get_standard_dbh;
474
475   map( {
476     $form->{"cp_${_}"} = $form->{"selected_cp_${_}"}
477     if ( $form->{"selected_cp_${_}"} );
478        } qw(title greeting abteilung) );
479   $form->{"greeting"} = $form->{"selected_company_greeting"}
480   if ( $form->{"selected_company_greeting"} );
481
482   $form->{discount} = $form->parse_amount( $myconfig, $form->{discount} );
483   $form->{discount} /= 100;
484   $form->{creditlimit} = $form->parse_amount( $myconfig, $form->{creditlimit} );
485
486   my $query;
487
488   if (!$form->{id}) {
489     $query = qq|SELECT nextval('id')|;
490     ($form->{id}) = selectrow_query($form, $dbh, $query);
491
492     $query = qq|INSERT INTO vendor (id, name) VALUES (?, '')|;
493     do_query($form, $dbh, $query, $form->{id});
494
495     my $vendornumber      = SL::TransNumber->new(type   => 'vendor',
496                                                  dbh    => $dbh,
497                                                  number => $form->{vendornumber},
498                                                  save   => 1);
499     $form->{vendornumber} = $vendornumber->create_unique unless $vendornumber->is_unique;
500   }
501
502   $query =
503     qq|UPDATE vendor SET | .
504     qq|  vendornumber = ?, | .
505     qq|  name = ?, | .
506     qq|  greeting = ?, | .
507     qq|  department_1 = ?, | .
508     qq|  department_2 = ?, | .
509     qq|  street = ?, | .
510     qq|  zipcode = ?, | .
511     qq|  city = ?, | .
512     qq|  country = ?, | .
513     qq|  homepage = ?, | .
514     qq|  contact = ?, | .
515     qq|  phone = ?, | .
516     qq|  fax = ?, | .
517     qq|  email = ?, | .
518     qq|  cc = ?, | .
519     qq|  bcc = ?, | .
520     qq|  notes = ?, | .
521     qq|  terms = ?, | .
522     qq|  discount = ?, | .
523     qq|  creditlimit = ?, | .
524     qq|  business_id = ?, | .
525     qq|  taxnumber = ?, | .
526     qq|  language = ?, | .
527     qq|  account_number = ?, | .
528     qq|  bank_code = ?, | .
529     qq|  bank = ?, | .
530     qq|  iban = ?, | .
531     qq|  bic = ?, | .
532     qq|  obsolete = ?, | .
533     qq|  direct_debit = ?, | .
534     qq|  ustid = ?, | .
535     qq|  payment_id = ?, | .
536     qq|  taxzone_id = ?, | .
537     qq|  language_id = ?, | .
538     qq|  username = ?, | .
539     qq|  user_password = ?, | .
540     qq|  v_customer_id = ?, | .
541     qq|  curr = ? | .
542     qq|WHERE id = ?|;
543   my @values = (
544     $form->{vendornumber},
545     $form->{name},
546     $form->{greeting},
547     $form->{department_1},
548     $form->{department_2},
549     $form->{street},
550     $form->{zipcode},
551     $form->{city},
552     $form->{country},
553     $form->{homepage},
554     $form->{contact},
555     $form->{phone},
556     $form->{fax},
557     $form->{email},
558     $form->{cc},
559     $form->{bcc},
560     $form->{notes},
561     conv_i($form->{terms}),
562     $form->{discount},
563     $form->{creditlimit},
564     conv_i($form->{business}),
565     $form->{taxnumber},
566     $form->{language},
567     $form->{account_number},
568     $form->{bank_code},
569     $form->{bank},
570     $form->{iban},
571     $form->{bic},
572     $form->{obsolete} ? 't' : 'f',
573     $form->{direct_debit} ? 't' : 'f',
574     $form->{ustid},
575     conv_i($form->{payment_id}),
576     conv_i($form->{taxzone_id}, 0),
577     conv_i( $form->{language_id}),
578     $form->{username},
579     $form->{user_password},
580     $form->{v_customer_id},
581     substr($form->{currency}, 0, 3),
582     $form->{id}
583     );
584   do_query($form, $dbh, $query, @values);
585
586   $query = undef;
587   if ( $form->{cp_id} ) {
588     $query = qq|UPDATE contacts SET | .
589       qq|cp_title = ?,  | .
590       qq|cp_givenname = ?, | .
591       qq|cp_name = ?, | .
592       qq|cp_email = ?, | .
593       qq|cp_phone1 = ?, | .
594       qq|cp_phone2 = ?, | .
595       qq|cp_abteilung = ?, | .
596       qq|cp_fax = ?, | .
597       qq|cp_mobile1 = ?, | .
598       qq|cp_mobile2 = ?, | .
599       qq|cp_satphone = ?, | .
600       qq|cp_satfax = ?, | .
601       qq|cp_project = ?, | .
602       qq|cp_privatphone = ?, | .
603       qq|cp_privatemail = ?, | .
604       qq|cp_birthday = ?, | .
605       qq|cp_gender = ? | .
606       qq|WHERE cp_id = ?|;
607     @values = (
608       $form->{cp_title},
609       $form->{cp_givenname},
610       $form->{cp_name},
611       $form->{cp_email},
612       $form->{cp_phone1},
613       $form->{cp_phone2},
614       $form->{cp_abteilung},
615       $form->{cp_fax},
616       $form->{cp_mobile1},
617       $form->{cp_mobile2},
618       $form->{cp_satphone},
619       $form->{cp_satfax},
620       $form->{cp_project},
621       $form->{cp_privatphone},
622       $form->{cp_privatemail},
623       $form->{cp_birthday},
624       $form->{cp_gender} eq 'f' ? 'f' : 'm',
625       $form->{cp_id}
626       );
627   } elsif ( $form->{cp_name} || $form->{cp_givenname} ) {
628     $query =
629       qq|INSERT INTO contacts ( cp_cv_id, cp_title, cp_givenname,  | .
630       qq|  cp_name, cp_email, cp_phone1, cp_phone2, cp_abteilung, cp_fax, cp_mobile1, | .
631       qq|  cp_mobile2, cp_satphone, cp_satfax, cp_project, cp_privatphone, cp_privatemail, | .
632       qq|  cp_birthday, cp_gender) | .
633       qq|VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|;
634     @values = (
635       $form->{id},
636       $form->{cp_title},
637       $form->{cp_givenname},
638       $form->{cp_name},
639       $form->{cp_email},
640       $form->{cp_phone1},
641       $form->{cp_phone2},
642       $form->{cp_abteilung},
643       $form->{cp_fax},
644       $form->{cp_mobile1},
645       $form->{cp_mobile2},
646       $form->{cp_satphone},
647       $form->{cp_satfax},
648       $form->{cp_project},
649       $form->{cp_privatphone},
650       $form->{cp_privatemail},
651       $form->{cp_birthday},
652       $form->{cp_gender}
653       );
654   }
655   do_query($form, $dbh, $query, @values) if ($query);
656
657   # add shipto
658   $form->add_shipto( $dbh, $form->{id}, "CT" );
659
660   $self->_save_note('dbh' => $dbh);
661   $self->_delete_selected_notes('dbh' => $dbh);
662
663   CVar->save_custom_variables('dbh'       => $dbh,
664                               'module'    => 'CT',
665                               'trans_id'  => $form->{id},
666                               'variables' => $form,
667                               'always_valid' => 1);
668   if ($form->{cp_id}) {
669     CVar->save_custom_variables('dbh'       => $dbh,
670                                 'module'    => 'Contacts',
671                                 'trans_id'  => $form->{cp_id},
672                                 'variables' => $form,
673                                 'name_prefix'  => 'cp',
674                                 'always_valid' => 1);
675   }
676
677   my $rc = $dbh->commit();
678
679   $main::lxdebug->leave_sub();
680   return $rc;
681 }
682
683 sub delete {
684   $main::lxdebug->enter_sub();
685
686   my ( $self, $myconfig, $form ) = @_;
687   # connect to database
688   my $dbh = $form->dbconnect($myconfig);
689
690   # delete vendor
691   my $cv = $form->{db} eq "customer" ? "customer" : "vendor";
692   my $query = qq|DELETE FROM $cv WHERE id = ?|;
693   do_query($form, $dbh, $query, $form->{id});
694
695   $dbh->disconnect;
696
697   $main::lxdebug->leave_sub();
698 }
699
700 sub search {
701   $main::lxdebug->enter_sub();
702
703   my ( $self, $myconfig, $form ) = @_;
704
705   # connect to database
706   my $dbh = $form->dbconnect($myconfig);
707
708   my $cv = $form->{db} eq "customer" ? "customer" : "vendor";
709
710   my $where = "1 = 1";
711   my @values;
712
713   my %allowed_sort_columns =
714     map { $_, 1 } qw(
715       id customernumber vendornumber name contact phone fax email street
716       taxnumber business invnumber ordnumber quonumber zipcode city
717     );
718   my $sortorder    = $form->{sort} && $allowed_sort_columns{$form->{sort}} ? $form->{sort} : "name";
719   $form->{sort} = $sortorder;
720   my $sortdir   = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
721
722   if ($sortorder !~ /(business|id)/ && 1 >= scalar grep { $form->{$_} } qw(l_ordnumber l_quonumber l_invnumber )) {
723     $sortorder  = "lower($sortorder) ${sortdir}";
724   } else {
725     $sortorder .= " ${sortdir}";
726   }
727
728   if ($form->{"${cv}number"}) {
729     $where .= " AND ct.${cv}number ILIKE ?";
730     push(@values, '%' . $form->{"${cv}number"} . '%');
731   }
732
733   foreach my $key (qw(name contact email)) {
734     if ($form->{$key}) {
735       $where .= " AND ct.$key ILIKE ?";
736       push(@values, '%' . $form->{$key} . '%');
737     }
738   }
739
740   if ($form->{cp_name}) {
741     $where .= " AND ct.id IN (SELECT cp_cv_id FROM contacts WHERE lower(cp_name) LIKE lower(?))";
742     push @values, '%' . $form->{cp_name} . '%';
743   }
744
745   if ($form->{addr_city}) {
746     $where .= " AND ((lower(ct.city) LIKE lower(?))
747                      OR
748                      (ct.id IN (
749                         SELECT trans_id
750                         FROM shipto
751                         WHERE (module = 'CT')
752                           AND (lower(shiptocity) LIKE lower(?))
753                       ))
754                      )";
755     push @values, ('%' . $form->{addr_city} . '%') x 2;
756   }
757
758   if ( $form->{status} eq 'orphaned' ) {
759     $where .=
760       qq| AND ct.id NOT IN | .
761       qq|   (SELECT o.${cv}_id FROM oe o, $cv cv WHERE cv.id = o.${cv}_id)|;
762     if ($cv eq 'customer') {
763       $where .=
764         qq| AND ct.id NOT IN | .
765         qq| (SELECT a.customer_id FROM ar a, customer cv | .
766         qq|  WHERE cv.id = a.customer_id)|;
767     }
768     if ($cv eq 'vendor') {
769       $where .=
770         qq| AND ct.id NOT IN | .
771         qq| (SELECT a.vendor_id FROM ap a, vendor cv | .
772         qq|  WHERE cv.id = a.vendor_id)|;
773     }
774     $form->{l_invnumber} = $form->{l_ordnumber} = $form->{l_quonumber} = "";
775   }
776
777   if ($form->{obsolete} eq "Y") {
778     $where .= qq| AND obsolete|;
779   } elsif ($form->{obsolete} eq "N") {
780     $where .= qq| AND NOT obsolete|;
781   }
782
783   if ($form->{business_id}) {
784     $where .= qq| AND (business_id = ?)|;
785     push(@values, conv_i($form->{business_id}));
786   }
787
788   # Nur Kunden finden, bei denen ich selber der Verkäufer bin
789   # Gilt nicht für Lieferanten
790   if ($cv eq 'customer' &&   !$main::auth->assert('customer_vendor_all_edit', 1)) {
791     $where .= qq| AND ct.salesman_id = (select id from employee where login= ?)|;
792     push(@values, $form->{login});
793   }
794
795   my ($cvar_where, @cvar_values) = CVar->build_filter_query('module'         => 'CT',
796                                                             'trans_id_field' => 'ct.id',
797                                                             'filter'         => $form);
798
799   if ($cvar_where) {
800     $where .= qq| AND ($cvar_where)|;
801     push @values, @cvar_values;
802   }
803
804   if ($form->{addr_street}) {
805     $where .= qq| AND (street ILIKE ?)|;
806     push @values, '%' . $form->{addr_street} . '%';
807   }
808
809   if ($form->{addr_zipcode}) {
810     $where .= qq| AND (zipcode ILIKE ?)|;
811     push @values, $form->{addr_zipcode} . '%';
812   }
813
814   my $query =
815     qq|SELECT ct.*, b.description AS business | .
816     qq|FROM $cv ct | .
817     qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
818     qq|WHERE $where|;
819
820   my @saved_values = @values;
821   # redo for invoices, orders and quotations
822   if ($form->{l_invnumber} || $form->{l_ordnumber} || $form->{l_quonumber}) {
823     my ($ar, $union, $module);
824     $query = "";
825
826     if ($form->{l_invnumber}) {
827       my $ar = $cv eq 'customer' ? 'ar' : 'ap';
828       my $module = $ar eq 'ar' ? 'is' : 'ir';
829
830       $query =
831         qq|SELECT ct.*, b.description AS business, | .
832         qq|  a.invnumber, a.ordnumber, a.quonumber, a.id AS invid, | .
833         qq|  '$module' AS module, 'invoice' AS formtype, | .
834         qq|  (a.amount = a.paid) AS closed | .
835         qq|FROM $cv ct | .
836         qq|JOIN $ar a ON (a.${cv}_id = ct.id) | .
837         qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
838         qq|WHERE $where AND (a.invoice = '1')|;
839
840       $union = qq|UNION|;
841     }
842
843     if ( $form->{l_ordnumber} ) {
844       if ($union eq "UNION") {
845         push(@values, @saved_values);
846       }
847       $query .=
848         qq| $union | .
849         qq|SELECT ct.*, b.description AS business,| .
850         qq|  ' ' AS invnumber, o.ordnumber, o.quonumber, o.id AS invid, | .
851         qq|  'oe' AS module, 'order' AS formtype, o.closed | .
852         qq|FROM $cv ct | .
853         qq|JOIN oe o ON (o.${cv}_id = ct.id) | .
854         qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
855         qq|WHERE $where AND (o.quotation = '0')|;
856
857       $union = qq|UNION|;
858     }
859
860     if ( $form->{l_quonumber} ) {
861       if ($union eq "UNION") {
862         push(@values, @saved_values);
863       }
864       $query .=
865         qq| $union | .
866         qq|SELECT ct.*, b.description AS business, | .
867         qq|  ' ' AS invnumber, o.ordnumber, o.quonumber, o.id AS invid, | .
868         qq|  'oe' AS module, 'quotation' AS formtype, o.closed | .
869         qq|FROM $cv ct | .
870         qq|JOIN oe o ON (o.${cv}_id = ct.id) | .
871         qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
872         qq|WHERE $where AND (o.quotation = '1')|;
873     }
874   }
875
876   $query .= qq| ORDER BY $sortorder|;
877
878   $form->{CT} = selectall_hashref_query($form, $dbh, $query, @values);
879
880   $main::lxdebug->leave_sub();
881 }
882
883 sub get_contact {
884   $main::lxdebug->enter_sub();
885
886   my ( $self, $myconfig, $form ) = @_;
887
888   die 'Missing argument: cp_id' unless $::form->{cp_id};
889
890   my $dbh   = $form->dbconnect($myconfig);
891   my $query =
892     qq|SELECT * FROM contacts c | .
893     qq|WHERE cp_id = ? ORDER BY cp_id limit 1|;
894   my $sth = prepare_execute_query($form, $dbh, $query, $form->{cp_id});
895   my $ref = $sth->fetchrow_hashref("NAME_lc");
896
897   map { $form->{$_} = $ref->{$_} } keys %$ref;
898
899   $query = qq|SELECT COUNT(cp_id) AS used FROM (
900     SELECT cp_id FROM oe UNION
901     SELECT cp_id FROM ar UNION
902     SELECT cp_id FROM ap UNION
903     SELECT cp_id FROM delivery_orders
904   ) AS cpid WHERE cp_id = ? OR ? = 0|;
905   ($form->{cp_used}) = selectfirst_array_query($form, $dbh, $query, ($form->{cp_id})x2);
906
907   $sth->finish;
908   $dbh->disconnect;
909
910   $main::lxdebug->leave_sub();
911 }
912
913 sub get_shipto {
914   $main::lxdebug->enter_sub();
915
916   my ( $self, $myconfig, $form ) = @_;
917   my $dbh   = $form->dbconnect($myconfig);
918   my $query = qq|SELECT * FROM shipto WHERE shipto_id = ?|;
919   my $sth = prepare_execute_query($form, $dbh, $query, $form->{shipto_id});
920
921   my $ref = $sth->fetchrow_hashref("NAME_lc");
922
923   map { $form->{$_} = $ref->{$_} } keys %$ref;
924
925   $query = qq|SELECT COUNT(shipto_id) AS used FROM (
926     SELECT shipto_id FROM oe UNION
927     SELECT shipto_id FROM ar UNION
928     SELECT shipto_id FROM delivery_orders
929   ) AS stid WHERE shipto_id = ? OR ? = 0|;
930   ($form->{shiptoused}) = selectfirst_array_query($form, $dbh, $query, ($form->{shipto_id})x2);
931
932   $sth->finish;
933   $dbh->disconnect;
934
935   $main::lxdebug->leave_sub();
936 }
937
938 sub get_delivery {
939   $main::lxdebug->enter_sub();
940
941   my ( $self, $myconfig, $form ) = @_;
942   my $dbh = $form->dbconnect($myconfig);
943
944   my $arap = $form->{db} eq "vendor" ? "ap" : "ar";
945   my $db = $form->{db} eq "customer" ? "customer" : "vendor";
946   my $qty_sign = $form->{db} eq 'vendor' ? ' * -1 AS qty' : '';
947
948   my $where = " WHERE 1=1 ";
949   my @values;
950
951   if ($form->{shipto_id} && ($arap eq "ar")) {
952     $where .= "AND ${arap}.shipto_id = ?";
953     push(@values, $form->{shipto_id});
954   } else {
955     $where .= "AND ${arap}.${db}_id = ?";
956     push(@values, $form->{id});
957   }
958
959   if ($form->{from}) {
960     $where .= "AND ${arap}.transdate >= ?";
961     push(@values, conv_date($form->{from}));
962   }
963   if ($form->{to}) {
964     $where .= "AND ${arap}.transdate <= ?";
965     push(@values, conv_date($form->{to}));
966   }
967   my $query =
968     qq|SELECT s.shiptoname, i.qty $qty_sign, | .
969     qq|  ${arap}.id, ${arap}.transdate, ${arap}.invnumber, ${arap}.ordnumber, | .
970     qq|  i.description, i.unit, i.sellprice, | .
971     qq|  oe.id AS oe_id, invoice | .
972     qq|FROM $arap | .
973     qq|LEFT JOIN shipto s ON | .
974     ($arap eq "ar"
975      ? qq|(ar.shipto_id = s.shipto_id) |
976      : qq|(ap.id = s.trans_id) |) .
977     qq|LEFT JOIN invoice i ON (${arap}.id = i.trans_id) | .
978     qq|LEFT join parts p ON (p.id = i.parts_id) | .
979     qq|LEFT JOIN oe ON (oe.ordnumber = ${arap}.ordnumber AND NOT ${arap}.ordnumber = '') | .
980     $where .
981     qq|ORDER BY ${arap}.transdate DESC LIMIT 15|;
982
983   $form->{DELIVERY} = selectall_hashref_query($form, $dbh, $query, @values);
984
985   $dbh->disconnect;
986
987   $main::lxdebug->leave_sub();
988 }
989
990 sub _save_note {
991   $main::lxdebug->enter_sub();
992
993   my $self   = shift;
994   my %params = @_;
995
996   my $form   = $main::form;
997
998   Common::check_params(\%params, 'dbh');
999
1000   if (!$form->{NOTE_subject}) {
1001     $main::lxdebug->leave_sub();
1002     return;
1003   }
1004
1005   my $dbh = $params{dbh};
1006
1007   my %follow_up;
1008   my %note = (
1009     'id'           => $form->{NOTE_id},
1010     'subject'      => $form->{NOTE_subject},
1011     'body'         => $form->{NOTE_body},
1012     'trans_id'     => $form->{id},
1013     'trans_module' => 'ct',
1014   );
1015
1016   $note{id} = Notes->save(%note);
1017
1018   if ($form->{FU_date}) {
1019     %follow_up = (
1020       'id'               => $form->{FU_id},
1021       'note_id'          => $note{id},
1022       'follow_up_date'   => $form->{FU_date},
1023       'created_for_user' => $form->{FU_created_for_user},
1024       'done'             => $form->{FU_done} ? 1 : 0,
1025       'subject'          => $form->{NOTE_subject},
1026       'body'             => $form->{NOTE_body},
1027       'LINKS'            => [
1028         {
1029           'trans_id'     => $form->{id},
1030           'trans_type'   => $form->{db} eq 'customer' ? 'customer' : 'vendor',
1031           'trans_info'   => $form->{name},
1032         },
1033       ],
1034     );
1035
1036     $follow_up{id} = FU->save(%follow_up);
1037
1038   } elsif ($form->{FU_id}) {
1039     do_query($form, $dbh, qq|DELETE FROM follow_up_links WHERE follow_up_id = ?|, conv_i($form->{FU_id}));
1040     do_query($form, $dbh, qq|DELETE FROM follow_ups      WHERE id = ?|,           conv_i($form->{FU_id}));
1041   }
1042
1043   delete @{$form}{grep { /^NOTE_|^FU_/ } keys %{ $form }};
1044
1045   $main::lxdebug->leave_sub();
1046 }
1047
1048 sub _delete_selected_notes {
1049   $main::lxdebug->enter_sub();
1050
1051   my $self   = shift;
1052   my %params = @_;
1053
1054   Common::check_params(\%params, 'dbh');
1055
1056   my $form = $main::form;
1057   my $dbh  = $params{dbh};
1058
1059   foreach my $i (1 .. $form->{NOTES_rowcount}) {
1060     next unless ($form->{"NOTE_delete_$i"} && $form->{"NOTE_id_$i"});
1061
1062     Notes->delete('dbh' => $params{dbh},
1063                   'id'  => $form->{"NOTE_id_$i"});
1064   }
1065
1066   $main::lxdebug->leave_sub();
1067 }
1068
1069 # TODO: remove in 2.7.0 stable
1070 sub delete_shipto {
1071   $main::lxdebug->enter_sub();
1072
1073   my $self      = shift;
1074   my $shipto_id = shift;
1075
1076   my $form      = $main::form;
1077   my %myconfig  = %main::myconfig;
1078   my $dbh       = $form->get_standard_dbh(\%myconfig);
1079
1080   do_query($form, $dbh, qq|UPDATE shipto SET trans_id = NULL WHERE shipto_id = ?|, $shipto_id);
1081
1082   $dbh->commit();
1083
1084   $main::lxdebug->leave_sub();
1085 }
1086
1087 # TODO: remove in 2.7.0 stable
1088 sub delete_contact {
1089   $main::lxdebug->enter_sub();
1090
1091   my $self      = shift;
1092   my $cp_id     = shift;
1093
1094   my $form      = $main::form;
1095   my %myconfig  = %main::myconfig;
1096   my $dbh       = $form->get_standard_dbh(\%myconfig);
1097
1098   do_query($form, $dbh, qq|UPDATE contacts SET cp_cv_id = NULL WHERE cp_id = ?|, $cp_id);
1099
1100   $dbh->commit();
1101
1102   $main::lxdebug->leave_sub();
1103 }
1104
1105 sub get_bank_info {
1106   $main::lxdebug->enter_sub();
1107
1108   my $self     = shift;
1109   my %params   = @_;
1110
1111   Common::check_params(\%params, qw(vc id));
1112
1113   my $myconfig = \%main::myconfig;
1114   my $form     = $main::form;
1115
1116   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
1117
1118   my $table        = $params{vc} eq 'customer' ? 'customer' : 'vendor';
1119   my @ids          = ref $params{id} eq 'ARRAY' ? @{ $params{id} } : ($params{id});
1120   my $placeholders = join ", ", ('?') x scalar @ids;
1121   my $query        = qq|SELECT id, name, account_number, bank, bank_code, iban, bic
1122                         FROM ${table}
1123                         WHERE id IN (${placeholders})|;
1124
1125   my $result       = selectall_hashref_query($form, $dbh, $query, map { conv_i($_) } @ids);
1126
1127   if (ref $params{id} eq 'ARRAY') {
1128     $result = { map { $_->{id} => $_ } @{ $result } };
1129   } else {
1130     $result = $result->[0] || { 'id' => $params{id} };
1131   }
1132
1133   $main::lxdebug->leave_sub();
1134
1135   return $result;
1136 }
1137
1138 sub parse_excel_file {
1139   $main::lxdebug->enter_sub();
1140
1141   my ($self, $myconfig, $form) = @_;
1142   my $locale = $main::locale;
1143
1144   $form->{formname}   = 'sales_quotation';
1145   $form->{type}   = 'sales_quotation';
1146   $form->{format} = 'excel';
1147   $form->{media}  = 'screen';
1148   $form->{quonumber} = 1;
1149
1150
1151   # $form->{"notes"} will be overridden by the customer's/vendor's "notes" field. So save it here.
1152   $form->{ $form->{"formname"} . "notes" } = $form->{"notes"};
1153
1154   my $inv                  = "quo";
1155   my $due                  = "req";
1156   $form->{"${inv}date"} = $form->{transdate};
1157   $form->{label}        = $locale->text('Quotation');
1158   my $numberfld            = "sqnumber";
1159   my $order                = 1;
1160
1161   # assign number
1162   $form->{what_done} = $form->{formname};
1163
1164   map({ delete($form->{$_}); } grep(/^cp_/, keys(%{ $form })));
1165
1166   my $output_dateformat = $myconfig->{"dateformat"};
1167   my $output_numberformat = $myconfig->{"numberformat"};
1168   my $output_longdates = 1;
1169
1170   # map login user variables
1171   map { $form->{"login_$_"} = $myconfig->{$_} } ("name", "email", "fax", "tel", "company");
1172
1173   # format item dates
1174   for my $field (qw(transdate_oe deliverydate_oe)) {
1175     map {
1176       $form->{$field}[$_] = $locale->date($myconfig, $form->{$field}[$_], 1);
1177     } 0 .. $#{ $form->{$field} };
1178   }
1179
1180   if ($form->{shipto_id}) {
1181     $form->get_shipto($myconfig);
1182   }
1183
1184   $form->{notes} =~ s/^\s+//g;
1185
1186   $form->{templates} = $myconfig->{templates};
1187
1188   delete $form->{printer_command};
1189
1190   $form->get_employee_info($myconfig);
1191
1192   my ($cvar_date_fields, $cvar_number_fields) = CVar->get_field_format_list('module' => 'CT', 'prefix' => 'vc_');
1193
1194   if (scalar @{ $cvar_date_fields }) {
1195     format_dates($output_dateformat, $output_longdates, @{ $cvar_date_fields });
1196   }
1197
1198   while (my ($precision, $field_list) = each %{ $cvar_number_fields }) {
1199     reformat_numbers($output_numberformat, $precision, @{ $field_list });
1200   }
1201
1202   $form->{excel} = 1;
1203   my $extension            = 'xls';
1204
1205   $form->{IN}         = "$form->{formname}.${extension}";
1206
1207   delete $form->{OUT};
1208
1209   $form->parse_template($myconfig);
1210
1211   $main::lxdebug->leave_sub();
1212 }
1213
1214 sub search_contacts {
1215   $::lxdebug->enter_sub;
1216
1217   my $self      = shift;
1218   my %params    = @_;
1219
1220   my $dbh       = $params{dbh} || $::form->get_standard_dbh;
1221   my $vc        = $params{db} eq 'customer' ? 'customer' : 'vendor';
1222
1223   my %sortspecs = (
1224     'cp_name'   => 'cp_name, cp_givenname',
1225     'vcname'    => 'vcname, cp_name, cp_givenname',
1226     'vcnumber'  => 'vcnumber, cp_name, cp_givenname',
1227     );
1228
1229   my %sortcols  = map { $_ => 1 } qw(cp_name cp_givenname cp_phone1 cp_phone2 cp_mobile1 cp_email vcname vcnumber);
1230
1231   my $order_by  = $sortcols{$::form->{sort}} ? $::form->{sort} : 'cp_name';
1232   $::form->{sort} = $order_by;
1233   $order_by     = $sortspecs{$order_by} if ($sortspecs{$order_by});
1234
1235   my $sortdir   = $::form->{sortdir} ? 'ASC' : 'DESC';
1236   $order_by     =~ s/,/ ${sortdir},/g;
1237   $order_by    .= " $sortdir";
1238
1239   my @where_tokens = ();
1240   my @values;
1241
1242   if ($params{search_term}) {
1243     my @tokens;
1244     push @tokens,
1245       'cp.cp_name      ILIKE ?',
1246       'cp.cp_givenname ILIKE ?',
1247       'cp.cp_email     ILIKE ?';
1248     push @values, ('%' . $params{search_term} . '%') x 3;
1249
1250     if (($params{search_term} =~ m/\d/) && ($params{search_term} !~ m/[^\d \(\)+\-]/)) {
1251       my $number =  $params{search_term};
1252       $number    =~ s/[^\d]//g;
1253       $number    =  join '[ /\(\)+\-]*', split(m//, $number);
1254
1255       push @tokens, map { "($_ ~ '$number')" } qw(cp_phone1 cp_phone2 cp_mobile1 cp_mobile2);
1256     }
1257
1258     push @where_tokens, map { "($_)" } join ' OR ', @tokens;
1259   }
1260
1261   my ($cvar_where, @cvar_values) = CVar->build_filter_query('module'         => 'Contacts',
1262                                                             'trans_id_field' => 'cp.cp_id',
1263                                                             'filter'         => $params{filter});
1264
1265   if ($cvar_where) {
1266     push @where_tokens, $cvar_where;
1267     push @values, @cvar_values;
1268   }
1269
1270   if (my $filter = $params{filter}) {
1271     for (qw(name title givenname email project abteilung)) {
1272       next unless $filter->{"cp_$_"};
1273       add_token(\@where_tokens, \@values, col =>  "cp.cp_$_", val => $filter->{"cp_$_"}, method => 'ILIKE', esc => 'substr');
1274     }
1275
1276     push @where_tokens, 'cp.cp_cv_id IS NOT NULL' if $filter->{status} eq 'active';
1277     push @where_tokens, 'cp.cp_cv_id IS NULL'     if $filter->{status} eq 'orphaned';
1278   }
1279
1280   my $where = @where_tokens ? 'WHERE ' . join ' AND ', @where_tokens : '';
1281
1282   my $query     = qq|SELECT cp.*,
1283                        COALESCE(c.id,             v.id)           AS vcid,
1284                        COALESCE(c.name,           v.name)         AS vcname,
1285                        COALESCE(c.customernumber, v.vendornumber) AS vcnumber,
1286                        CASE WHEN c.name IS NULL THEN 'vendor' ELSE 'customer' END AS db
1287                      FROM contacts cp
1288                      LEFT JOIN customer c ON (cp.cp_cv_id = c.id)
1289                      LEFT JOIN vendor v   ON (cp.cp_cv_id = v.id)
1290                      $where
1291                      ORDER BY $order_by|;
1292
1293   my $contacts  = selectall_hashref_query($::form, $dbh, $query, @values);
1294
1295   $::lxdebug->leave_sub;
1296
1297   return @{ $contacts };
1298 }
1299
1300
1301 1;