Merge branch 'master' of vc.linet-services.de:public/lx-office-erp
[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   CVar->save_custom_variables('dbh'       => $dbh,
452                               'module'    => 'Contacts',
453                               'trans_id'  => $form->{cp_id},
454                               'variables' => $form,
455                               'name_prefix'  => 'cp',
456                               'always_valid' => 1);
457
458   my $rc = $dbh->commit();
459
460   $main::lxdebug->leave_sub();
461   return $rc;
462 }
463
464 sub save_vendor {
465   $main::lxdebug->enter_sub();
466
467   my ( $self, $myconfig, $form ) = @_;
468
469   $form->{taxzone_id} *= 1;
470   # connect to database
471   my $dbh = $form->get_standard_dbh;
472
473   map( {
474     $form->{"cp_${_}"} = $form->{"selected_cp_${_}"}
475     if ( $form->{"selected_cp_${_}"} );
476        } qw(title greeting abteilung) );
477   $form->{"greeting"} = $form->{"selected_company_greeting"}
478   if ( $form->{"selected_company_greeting"} );
479
480   $form->{discount} = $form->parse_amount( $myconfig, $form->{discount} );
481   $form->{discount} /= 100;
482   $form->{creditlimit} = $form->parse_amount( $myconfig, $form->{creditlimit} );
483
484   my $query;
485
486   if (!$form->{id}) {
487     $query = qq|SELECT nextval('id')|;
488     ($form->{id}) = selectrow_query($form, $dbh, $query);
489
490     $query = qq|INSERT INTO vendor (id, name) VALUES (?, '')|;
491     do_query($form, $dbh, $query, $form->{id});
492
493     my $vendornumber      = SL::TransNumber->new(type   => 'vendor',
494                                                  dbh    => $dbh,
495                                                  number => $form->{vendornumber},
496                                                  save   => 1);
497     $form->{vendornumber} = $vendornumber->create_unique unless $vendornumber->is_unique;
498   }
499
500   $query =
501     qq|UPDATE vendor SET | .
502     qq|  vendornumber = ?, | .
503     qq|  name = ?, | .
504     qq|  greeting = ?, | .
505     qq|  department_1 = ?, | .
506     qq|  department_2 = ?, | .
507     qq|  street = ?, | .
508     qq|  zipcode = ?, | .
509     qq|  city = ?, | .
510     qq|  country = ?, | .
511     qq|  homepage = ?, | .
512     qq|  contact = ?, | .
513     qq|  phone = ?, | .
514     qq|  fax = ?, | .
515     qq|  email = ?, | .
516     qq|  cc = ?, | .
517     qq|  bcc = ?, | .
518     qq|  notes = ?, | .
519     qq|  terms = ?, | .
520     qq|  discount = ?, | .
521     qq|  creditlimit = ?, | .
522     qq|  business_id = ?, | .
523     qq|  taxnumber = ?, | .
524     qq|  language = ?, | .
525     qq|  account_number = ?, | .
526     qq|  bank_code = ?, | .
527     qq|  bank = ?, | .
528     qq|  iban = ?, | .
529     qq|  bic = ?, | .
530     qq|  obsolete = ?, | .
531     qq|  direct_debit = ?, | .
532     qq|  ustid = ?, | .
533     qq|  payment_id = ?, | .
534     qq|  taxzone_id = ?, | .
535     qq|  language_id = ?, | .
536     qq|  username = ?, | .
537     qq|  user_password = ?, | .
538     qq|  v_customer_id = ?, | .
539     qq|  curr = ? | .
540     qq|WHERE id = ?|;
541   my @values = (
542     $form->{vendornumber},
543     $form->{name},
544     $form->{greeting},
545     $form->{department_1},
546     $form->{department_2},
547     $form->{street},
548     $form->{zipcode},
549     $form->{city},
550     $form->{country},
551     $form->{homepage},
552     $form->{contact},
553     $form->{phone},
554     $form->{fax},
555     $form->{email},
556     $form->{cc},
557     $form->{bcc},
558     $form->{notes},
559     conv_i($form->{terms}),
560     $form->{discount},
561     $form->{creditlimit},
562     conv_i($form->{business}),
563     $form->{taxnumber},
564     $form->{language},
565     $form->{account_number},
566     $form->{bank_code},
567     $form->{bank},
568     $form->{iban},
569     $form->{bic},
570     $form->{obsolete} ? 't' : 'f',
571     $form->{direct_debit} ? 't' : 'f',
572     $form->{ustid},
573     conv_i($form->{payment_id}),
574     conv_i($form->{taxzone_id}, 0),
575     conv_i( $form->{language_id}),
576     $form->{username},
577     $form->{user_password},
578     $form->{v_customer_id},
579     substr($form->{currency}, 0, 3),
580     $form->{id}
581     );
582   do_query($form, $dbh, $query, @values);
583
584   $query = undef;
585   if ( $form->{cp_id} ) {
586     $query = qq|UPDATE contacts SET | .
587       qq|cp_title = ?,  | .
588       qq|cp_givenname = ?, | .
589       qq|cp_name = ?, | .
590       qq|cp_email = ?, | .
591       qq|cp_phone1 = ?, | .
592       qq|cp_phone2 = ?, | .
593       qq|cp_abteilung = ?, | .
594       qq|cp_fax = ?, | .
595       qq|cp_mobile1 = ?, | .
596       qq|cp_mobile2 = ?, | .
597       qq|cp_satphone = ?, | .
598       qq|cp_satfax = ?, | .
599       qq|cp_project = ?, | .
600       qq|cp_privatphone = ?, | .
601       qq|cp_privatemail = ?, | .
602       qq|cp_birthday = ?, | .
603       qq|cp_gender = ? | .
604       qq|WHERE cp_id = ?|;
605     @values = (
606       $form->{cp_title},
607       $form->{cp_givenname},
608       $form->{cp_name},
609       $form->{cp_email},
610       $form->{cp_phone1},
611       $form->{cp_phone2},
612       $form->{cp_abteilung},
613       $form->{cp_fax},
614       $form->{cp_mobile1},
615       $form->{cp_mobile2},
616       $form->{cp_satphone},
617       $form->{cp_satfax},
618       $form->{cp_project},
619       $form->{cp_privatphone},
620       $form->{cp_privatemail},
621       $form->{cp_birthday},
622       $form->{cp_gender} eq 'f' ? 'f' : 'm',
623       $form->{cp_id}
624       );
625   } elsif ( $form->{cp_name} || $form->{cp_givenname} ) {
626     $query =
627       qq|INSERT INTO contacts ( cp_cv_id, cp_title, cp_givenname,  | .
628       qq|  cp_name, cp_email, cp_phone1, cp_phone2, cp_abteilung, cp_fax, cp_mobile1, | .
629       qq|  cp_mobile2, cp_satphone, cp_satfax, cp_project, cp_privatphone, cp_privatemail, | .
630       qq|  cp_birthday, cp_gender) | .
631       qq|VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|;
632     @values = (
633       $form->{id},
634       $form->{cp_title},
635       $form->{cp_givenname},
636       $form->{cp_name},
637       $form->{cp_email},
638       $form->{cp_phone1},
639       $form->{cp_phone2},
640       $form->{cp_abteilung},
641       $form->{cp_fax},
642       $form->{cp_mobile1},
643       $form->{cp_mobile2},
644       $form->{cp_satphone},
645       $form->{cp_satfax},
646       $form->{cp_project},
647       $form->{cp_privatphone},
648       $form->{cp_privatemail},
649       $form->{cp_birthday},
650       $form->{cp_gender}
651       );
652   }
653   do_query($form, $dbh, $query, @values) if ($query);
654
655   # add shipto
656   $form->add_shipto( $dbh, $form->{id}, "CT" );
657
658   $self->_save_note('dbh' => $dbh);
659   $self->_delete_selected_notes('dbh' => $dbh);
660
661   CVar->save_custom_variables('dbh'       => $dbh,
662                               'module'    => 'CT',
663                               'trans_id'  => $form->{id},
664                               'variables' => $form,
665                               'always_valid' => 1);
666   CVar->save_custom_variables('dbh'       => $dbh,
667                               'module'    => 'Contacts',
668                               'trans_id'  => $form->{cp_id},
669                               'variables' => $form,
670                               'name_prefix'  => 'cp',
671                               'always_valid' => 1);
672
673   my $rc = $dbh->commit();
674
675   $main::lxdebug->leave_sub();
676   return $rc;
677 }
678
679 sub delete {
680   $main::lxdebug->enter_sub();
681
682   my ( $self, $myconfig, $form ) = @_;
683   # connect to database
684   my $dbh = $form->dbconnect($myconfig);
685
686   # delete vendor
687   my $cv = $form->{db} eq "customer" ? "customer" : "vendor";
688   my $query = qq|DELETE FROM $cv WHERE id = ?|;
689   do_query($form, $dbh, $query, $form->{id});
690
691   $dbh->disconnect;
692
693   $main::lxdebug->leave_sub();
694 }
695
696 sub search {
697   $main::lxdebug->enter_sub();
698
699   my ( $self, $myconfig, $form ) = @_;
700
701   # connect to database
702   my $dbh = $form->dbconnect($myconfig);
703
704   my $cv = $form->{db} eq "customer" ? "customer" : "vendor";
705
706   my $where = "1 = 1";
707   my @values;
708
709   my %allowed_sort_columns =
710     map { $_, 1 } qw(
711       id customernumber vendornumber name contact phone fax email street
712       taxnumber business invnumber ordnumber quonumber zipcode city
713     );
714   my $sortorder    = $form->{sort} && $allowed_sort_columns{$form->{sort}} ? $form->{sort} : "name";
715   $form->{sort} = $sortorder;
716   my $sortdir   = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
717
718   if ($sortorder !~ /(business|id)/ && 1 >= scalar grep { $form->{$_} } qw(l_ordnumber l_quonumber l_invnumber )) {
719     $sortorder  = "lower($sortorder) ${sortdir}";
720   } else {
721     $sortorder .= " ${sortdir}";
722   }
723
724   if ($form->{"${cv}number"}) {
725     $where .= " AND ct.${cv}number ILIKE ?";
726     push(@values, '%' . $form->{"${cv}number"} . '%');
727   }
728
729   foreach my $key (qw(name contact email)) {
730     if ($form->{$key}) {
731       $where .= " AND ct.$key ILIKE ?";
732       push(@values, '%' . $form->{$key} . '%');
733     }
734   }
735
736   if ($form->{cp_name}) {
737     $where .= " AND ct.id IN (SELECT cp_cv_id FROM contacts WHERE lower(cp_name) LIKE lower(?))";
738     push @values, '%' . $form->{cp_name} . '%';
739   }
740
741   if ($form->{addr_city}) {
742     $where .= " AND ((lower(ct.city) LIKE lower(?))
743                      OR
744                      (ct.id IN (
745                         SELECT trans_id
746                         FROM shipto
747                         WHERE (module = 'CT')
748                           AND (lower(shiptocity) LIKE lower(?))
749                       ))
750                      )";
751     push @values, ('%' . $form->{addr_city} . '%') x 2;
752   }
753
754   if ( $form->{status} eq 'orphaned' ) {
755     $where .=
756       qq| AND ct.id NOT IN | .
757       qq|   (SELECT o.${cv}_id FROM oe o, $cv cv WHERE cv.id = o.${cv}_id)|;
758     if ($cv eq 'customer') {
759       $where .=
760         qq| AND ct.id NOT IN | .
761         qq| (SELECT a.customer_id FROM ar a, customer cv | .
762         qq|  WHERE cv.id = a.customer_id)|;
763     }
764     if ($cv eq 'vendor') {
765       $where .=
766         qq| AND ct.id NOT IN | .
767         qq| (SELECT a.vendor_id FROM ap a, vendor cv | .
768         qq|  WHERE cv.id = a.vendor_id)|;
769     }
770     $form->{l_invnumber} = $form->{l_ordnumber} = $form->{l_quonumber} = "";
771   }
772
773   if ($form->{obsolete} eq "Y") {
774     $where .= qq| AND obsolete|;
775   } elsif ($form->{obsolete} eq "N") {
776     $where .= qq| AND NOT obsolete|;
777   }
778
779   if ($form->{business_id}) {
780     $where .= qq| AND (business_id = ?)|;
781     push(@values, conv_i($form->{business_id}));
782   }
783
784   # Nur Kunden finden, bei denen ich selber der Verkäufer bin
785   # Gilt nicht für Lieferanten
786   if ($cv eq 'customer' &&   !$main::auth->assert('customer_vendor_all_edit', 1)) {
787     $where .= qq| AND ct.salesman_id = (select id from employee where login= ?)|;
788     push(@values, $form->{login});
789   }
790
791   my ($cvar_where, @cvar_values) = CVar->build_filter_query('module'         => 'CT',
792                                                             'trans_id_field' => 'ct.id',
793                                                             'filter'         => $form);
794
795   if ($cvar_where) {
796     $where .= qq| AND ($cvar_where)|;
797     push @values, @cvar_values;
798   }
799
800   if ($form->{addr_street}) {
801     $where .= qq| AND (street ILIKE ?)|;
802     push @values, '%' . $form->{addr_street} . '%';
803   }
804
805   if ($form->{addr_zipcode}) {
806     $where .= qq| AND (zipcode ILIKE ?)|;
807     push @values, $form->{addr_zipcode} . '%';
808   }
809
810   my $query =
811     qq|SELECT ct.*, b.description AS business | .
812     qq|FROM $cv ct | .
813     qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
814     qq|WHERE $where|;
815
816   my @saved_values = @values;
817   # redo for invoices, orders and quotations
818   if ($form->{l_invnumber} || $form->{l_ordnumber} || $form->{l_quonumber}) {
819     my ($ar, $union, $module);
820     $query = "";
821
822     if ($form->{l_invnumber}) {
823       my $ar = $cv eq 'customer' ? 'ar' : 'ap';
824       my $module = $ar eq 'ar' ? 'is' : 'ir';
825
826       $query =
827         qq|SELECT ct.*, b.description AS business, | .
828         qq|  a.invnumber, a.ordnumber, a.quonumber, a.id AS invid, | .
829         qq|  '$module' AS module, 'invoice' AS formtype, | .
830         qq|  (a.amount = a.paid) AS closed | .
831         qq|FROM $cv ct | .
832         qq|JOIN $ar a ON (a.${cv}_id = ct.id) | .
833         qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
834         qq|WHERE $where AND (a.invoice = '1')|;
835
836       $union = qq|UNION|;
837     }
838
839     if ( $form->{l_ordnumber} ) {
840       if ($union eq "UNION") {
841         push(@values, @saved_values);
842       }
843       $query .=
844         qq| $union | .
845         qq|SELECT ct.*, b.description AS business,| .
846         qq|  ' ' AS invnumber, o.ordnumber, o.quonumber, o.id AS invid, | .
847         qq|  'oe' AS module, 'order' AS formtype, o.closed | .
848         qq|FROM $cv ct | .
849         qq|JOIN oe o ON (o.${cv}_id = ct.id) | .
850         qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
851         qq|WHERE $where AND (o.quotation = '0')|;
852
853       $union = qq|UNION|;
854     }
855
856     if ( $form->{l_quonumber} ) {
857       if ($union eq "UNION") {
858         push(@values, @saved_values);
859       }
860       $query .=
861         qq| $union | .
862         qq|SELECT ct.*, b.description AS business, | .
863         qq|  ' ' AS invnumber, o.ordnumber, o.quonumber, o.id AS invid, | .
864         qq|  'oe' AS module, 'quotation' AS formtype, o.closed | .
865         qq|FROM $cv ct | .
866         qq|JOIN oe o ON (o.${cv}_id = ct.id) | .
867         qq|LEFT JOIN business b ON (ct.business_id = b.id) | .
868         qq|WHERE $where AND (o.quotation = '1')|;
869     }
870   }
871
872   $query .= qq| ORDER BY $sortorder|;
873
874   $form->{CT} = selectall_hashref_query($form, $dbh, $query, @values);
875
876   $main::lxdebug->leave_sub();
877 }
878
879 sub get_contact {
880   $main::lxdebug->enter_sub();
881
882   my ( $self, $myconfig, $form ) = @_;
883
884   die 'Missing argument: cp_id' unless $::form->{cp_id};
885
886   my $dbh   = $form->dbconnect($myconfig);
887   my $query =
888     qq|SELECT * FROM contacts c | .
889     qq|WHERE cp_id = ? ORDER BY cp_id limit 1|;
890   my $sth = prepare_execute_query($form, $dbh, $query, $form->{cp_id});
891   my $ref = $sth->fetchrow_hashref("NAME_lc");
892
893   map { $form->{$_} = $ref->{$_} } keys %$ref;
894
895   $query = qq|SELECT COUNT(cp_id) AS used FROM (
896     SELECT cp_id FROM oe UNION
897     SELECT cp_id FROM ar UNION
898     SELECT cp_id FROM ap UNION
899     SELECT cp_id FROM delivery_orders
900   ) AS cpid WHERE cp_id = ? OR ? = 0|;
901   ($form->{cp_used}) = selectfirst_array_query($form, $dbh, $query, ($form->{cp_id})x2);
902
903   $sth->finish;
904   $dbh->disconnect;
905
906   $main::lxdebug->leave_sub();
907 }
908
909 sub get_shipto {
910   $main::lxdebug->enter_sub();
911
912   my ( $self, $myconfig, $form ) = @_;
913   my $dbh   = $form->dbconnect($myconfig);
914   my $query = qq|SELECT * FROM shipto WHERE shipto_id = ?|;
915   my $sth = prepare_execute_query($form, $dbh, $query, $form->{shipto_id});
916
917   my $ref = $sth->fetchrow_hashref("NAME_lc");
918
919   map { $form->{$_} = $ref->{$_} } keys %$ref;
920
921   $query = qq|SELECT COUNT(shipto_id) AS used FROM (
922     SELECT shipto_id FROM oe UNION
923     SELECT shipto_id FROM ar UNION
924     SELECT shipto_id FROM delivery_orders
925   ) AS stid WHERE shipto_id = ? OR ? = 0|;
926   ($form->{shiptoused}) = selectfirst_array_query($form, $dbh, $query, ($form->{shipto_id})x2);
927
928   $sth->finish;
929   $dbh->disconnect;
930
931   $main::lxdebug->leave_sub();
932 }
933
934 sub get_delivery {
935   $main::lxdebug->enter_sub();
936
937   my ( $self, $myconfig, $form ) = @_;
938   my $dbh = $form->dbconnect($myconfig);
939
940   my $arap = $form->{db} eq "vendor" ? "ap" : "ar";
941   my $db = $form->{db} eq "customer" ? "customer" : "vendor";
942   my $qty_sign = $form->{db} eq 'vendor' ? ' * -1 AS qty' : '';
943
944   my $where = " WHERE 1=1 ";
945   my @values;
946
947   if ($form->{shipto_id} && ($arap eq "ar")) {
948     $where .= "AND ${arap}.shipto_id = ?";
949     push(@values, $form->{shipto_id});
950   } else {
951     $where .= "AND ${arap}.${db}_id = ?";
952     push(@values, $form->{id});
953   }
954
955   if ($form->{from}) {
956     $where .= "AND ${arap}.transdate >= ?";
957     push(@values, conv_date($form->{from}));
958   }
959   if ($form->{to}) {
960     $where .= "AND ${arap}.transdate <= ?";
961     push(@values, conv_date($form->{to}));
962   }
963   my $query =
964     qq|SELECT s.shiptoname, i.qty $qty_sign, | .
965     qq|  ${arap}.id, ${arap}.transdate, ${arap}.invnumber, ${arap}.ordnumber, | .
966     qq|  i.description, i.unit, i.sellprice, | .
967     qq|  oe.id AS oe_id, invoice | .
968     qq|FROM $arap | .
969     qq|LEFT JOIN shipto s ON | .
970     ($arap eq "ar"
971      ? qq|(ar.shipto_id = s.shipto_id) |
972      : qq|(ap.id = s.trans_id) |) .
973     qq|LEFT JOIN invoice i ON (${arap}.id = i.trans_id) | .
974     qq|LEFT join parts p ON (p.id = i.parts_id) | .
975     qq|LEFT JOIN oe ON (oe.ordnumber = ${arap}.ordnumber AND NOT ${arap}.ordnumber = '') | .
976     $where .
977     qq|ORDER BY ${arap}.transdate DESC LIMIT 15|;
978
979   $form->{DELIVERY} = selectall_hashref_query($form, $dbh, $query, @values);
980
981   $dbh->disconnect;
982
983   $main::lxdebug->leave_sub();
984 }
985
986 sub _save_note {
987   $main::lxdebug->enter_sub();
988
989   my $self   = shift;
990   my %params = @_;
991
992   my $form   = $main::form;
993
994   Common::check_params(\%params, 'dbh');
995
996   if (!$form->{NOTE_subject}) {
997     $main::lxdebug->leave_sub();
998     return;
999   }
1000
1001   my $dbh = $params{dbh};
1002
1003   my %follow_up;
1004   my %note = (
1005     'id'           => $form->{NOTE_id},
1006     'subject'      => $form->{NOTE_subject},
1007     'body'         => $form->{NOTE_body},
1008     'trans_id'     => $form->{id},
1009     'trans_module' => 'ct',
1010   );
1011
1012   $note{id} = Notes->save(%note);
1013
1014   if ($form->{FU_date}) {
1015     %follow_up = (
1016       'id'               => $form->{FU_id},
1017       'note_id'          => $note{id},
1018       'follow_up_date'   => $form->{FU_date},
1019       'created_for_user' => $form->{FU_created_for_user},
1020       'done'             => $form->{FU_done} ? 1 : 0,
1021       'subject'          => $form->{NOTE_subject},
1022       'body'             => $form->{NOTE_body},
1023       'LINKS'            => [
1024         {
1025           'trans_id'     => $form->{id},
1026           'trans_type'   => $form->{db} eq 'customer' ? 'customer' : 'vendor',
1027           'trans_info'   => $form->{name},
1028         },
1029       ],
1030     );
1031
1032     $follow_up{id} = FU->save(%follow_up);
1033
1034   } elsif ($form->{FU_id}) {
1035     do_query($form, $dbh, qq|DELETE FROM follow_up_links WHERE follow_up_id = ?|, conv_i($form->{FU_id}));
1036     do_query($form, $dbh, qq|DELETE FROM follow_ups      WHERE id = ?|,           conv_i($form->{FU_id}));
1037   }
1038
1039   delete @{$form}{grep { /^NOTE_|^FU_/ } keys %{ $form }};
1040
1041   $main::lxdebug->leave_sub();
1042 }
1043
1044 sub _delete_selected_notes {
1045   $main::lxdebug->enter_sub();
1046
1047   my $self   = shift;
1048   my %params = @_;
1049
1050   Common::check_params(\%params, 'dbh');
1051
1052   my $form = $main::form;
1053   my $dbh  = $params{dbh};
1054
1055   foreach my $i (1 .. $form->{NOTES_rowcount}) {
1056     next unless ($form->{"NOTE_delete_$i"} && $form->{"NOTE_id_$i"});
1057
1058     Notes->delete('dbh' => $params{dbh},
1059                   'id'  => $form->{"NOTE_id_$i"});
1060   }
1061
1062   $main::lxdebug->leave_sub();
1063 }
1064
1065 # TODO: remove in 2.7.0 stable
1066 sub delete_shipto {
1067   $main::lxdebug->enter_sub();
1068
1069   my $self      = shift;
1070   my $shipto_id = shift;
1071
1072   my $form      = $main::form;
1073   my %myconfig  = %main::myconfig;
1074   my $dbh       = $form->get_standard_dbh(\%myconfig);
1075
1076   do_query($form, $dbh, qq|UPDATE shipto SET trans_id = NULL WHERE shipto_id = ?|, $shipto_id);
1077
1078   $dbh->commit();
1079
1080   $main::lxdebug->leave_sub();
1081 }
1082
1083 # TODO: remove in 2.7.0 stable
1084 sub delete_contact {
1085   $main::lxdebug->enter_sub();
1086
1087   my $self      = shift;
1088   my $cp_id     = shift;
1089
1090   my $form      = $main::form;
1091   my %myconfig  = %main::myconfig;
1092   my $dbh       = $form->get_standard_dbh(\%myconfig);
1093
1094   do_query($form, $dbh, qq|UPDATE contacts SET cp_cv_id = NULL WHERE cp_id = ?|, $cp_id);
1095
1096   $dbh->commit();
1097
1098   $main::lxdebug->leave_sub();
1099 }
1100
1101 sub get_bank_info {
1102   $main::lxdebug->enter_sub();
1103
1104   my $self     = shift;
1105   my %params   = @_;
1106
1107   Common::check_params(\%params, qw(vc id));
1108
1109   my $myconfig = \%main::myconfig;
1110   my $form     = $main::form;
1111
1112   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
1113
1114   my $table        = $params{vc} eq 'customer' ? 'customer' : 'vendor';
1115   my @ids          = ref $params{id} eq 'ARRAY' ? @{ $params{id} } : ($params{id});
1116   my $placeholders = join ", ", ('?') x scalar @ids;
1117   my $query        = qq|SELECT id, name, account_number, bank, bank_code, iban, bic
1118                         FROM ${table}
1119                         WHERE id IN (${placeholders})|;
1120
1121   my $result       = selectall_hashref_query($form, $dbh, $query, map { conv_i($_) } @ids);
1122
1123   if (ref $params{id} eq 'ARRAY') {
1124     $result = { map { $_->{id} => $_ } @{ $result } };
1125   } else {
1126     $result = $result->[0] || { 'id' => $params{id} };
1127   }
1128
1129   $main::lxdebug->leave_sub();
1130
1131   return $result;
1132 }
1133
1134 sub parse_excel_file {
1135   $main::lxdebug->enter_sub();
1136
1137   my ($self, $myconfig, $form) = @_;
1138   my $locale = $main::locale;
1139
1140   $form->{formname}   = 'sales_quotation';
1141   $form->{type}   = 'sales_quotation';
1142   $form->{format} = 'excel';
1143   $form->{media}  = 'screen';
1144   $form->{quonumber} = 1;
1145
1146
1147   # $form->{"notes"} will be overridden by the customer's/vendor's "notes" field. So save it here.
1148   $form->{ $form->{"formname"} . "notes" } = $form->{"notes"};
1149
1150   my $inv                  = "quo";
1151   my $due                  = "req";
1152   $form->{"${inv}date"} = $form->{transdate};
1153   $form->{label}        = $locale->text('Quotation');
1154   my $numberfld            = "sqnumber";
1155   my $order                = 1;
1156
1157   # assign number
1158   $form->{what_done} = $form->{formname};
1159
1160   map({ delete($form->{$_}); } grep(/^cp_/, keys(%{ $form })));
1161
1162   my $output_dateformat = $myconfig->{"dateformat"};
1163   my $output_numberformat = $myconfig->{"numberformat"};
1164   my $output_longdates = 1;
1165
1166   # map login user variables
1167   map { $form->{"login_$_"} = $myconfig->{$_} } ("name", "email", "fax", "tel", "company");
1168
1169   # format item dates
1170   for my $field (qw(transdate_oe deliverydate_oe)) {
1171     map {
1172       $form->{$field}[$_] = $locale->date($myconfig, $form->{$field}[$_], 1);
1173     } 0 .. $#{ $form->{$field} };
1174   }
1175
1176   if ($form->{shipto_id}) {
1177     $form->get_shipto($myconfig);
1178   }
1179
1180   $form->{notes} =~ s/^\s+//g;
1181
1182   $form->{templates} = $myconfig->{templates};
1183
1184   delete $form->{printer_command};
1185
1186   $form->get_employee_info($myconfig);
1187
1188   my ($cvar_date_fields, $cvar_number_fields) = CVar->get_field_format_list('module' => 'CT', 'prefix' => 'vc_');
1189
1190   if (scalar @{ $cvar_date_fields }) {
1191     format_dates($output_dateformat, $output_longdates, @{ $cvar_date_fields });
1192   }
1193
1194   while (my ($precision, $field_list) = each %{ $cvar_number_fields }) {
1195     reformat_numbers($output_numberformat, $precision, @{ $field_list });
1196   }
1197
1198   $form->{excel} = 1;
1199   my $extension            = 'xls';
1200
1201   $form->{IN}         = "$form->{formname}.${extension}";
1202
1203   delete $form->{OUT};
1204
1205   $form->parse_template($myconfig);
1206
1207   $main::lxdebug->leave_sub();
1208 }
1209
1210 sub search_contacts {
1211   $::lxdebug->enter_sub;
1212
1213   my $self      = shift;
1214   my %params    = @_;
1215
1216   my $dbh       = $params{dbh} || $::form->get_standard_dbh;
1217   my $vc        = $params{db} eq 'customer' ? 'customer' : 'vendor';
1218
1219   my %sortspecs = (
1220     'cp_name'   => 'cp_name, cp_givenname',
1221     'vcname'    => 'vcname, cp_name, cp_givenname',
1222     'vcnumber'  => 'vcnumber, cp_name, cp_givenname',
1223     );
1224
1225   my %sortcols  = map { $_ => 1 } qw(cp_name cp_givenname cp_phone1 cp_phone2 cp_mobile1 cp_email vcname vcnumber);
1226
1227   my $order_by  = $sortcols{$::form->{sort}} ? $::form->{sort} : 'cp_name';
1228   $::form->{sort} = $order_by;
1229   $order_by     = $sortspecs{$order_by} if ($sortspecs{$order_by});
1230
1231   my $sortdir   = $::form->{sortdir} ? 'ASC' : 'DESC';
1232   $order_by     =~ s/,/ ${sortdir},/g;
1233   $order_by    .= " $sortdir";
1234
1235   my @where_tokens = ();
1236   my @values;
1237
1238   if ($params{search_term}) {
1239     my @tokens;
1240     push @tokens,
1241       'cp.cp_name      ILIKE ?',
1242       'cp.cp_givenname ILIKE ?',
1243       'cp.cp_email     ILIKE ?';
1244     push @values, ('%' . $params{search_term} . '%') x 3;
1245
1246     if (($params{search_term} =~ m/\d/) && ($params{search_term} !~ m/[^\d \(\)+\-]/)) {
1247       my $number =  $params{search_term};
1248       $number    =~ s/[^\d]//g;
1249       $number    =  join '[ /\(\)+\-]*', split(m//, $number);
1250
1251       push @tokens, map { "($_ ~ '$number')" } qw(cp_phone1 cp_phone2 cp_mobile1 cp_mobile2);
1252     }
1253
1254     push @where_tokens, map { "($_)" } join ' OR ', @tokens;
1255   }
1256
1257   my ($cvar_where, @cvar_values) = CVar->build_filter_query('module'         => 'Contacts',
1258                                                             'trans_id_field' => 'cp.cp_id',
1259                                                             'filter'         => $params{filter});
1260
1261   if ($cvar_where) {
1262     push @where_tokens, $cvar_where;
1263     push @values, @cvar_values;
1264   }
1265
1266   if (my $filter = $params{filter}) {
1267     for (qw(name title givenname email project abteilung)) {
1268       next unless $filter->{"cp_$_"};
1269       add_token(\@where_tokens, \@values, col =>  "cp.cp_$_", val => $filter->{"cp_$_"}, method => 'ILIKE', esc => 'substr');
1270     }
1271
1272     push @where_tokens, 'cp.cp_cv_id IS NOT NULL' if $filter->{status} eq 'active';
1273     push @where_tokens, 'cp.cp_cv_id IS NULL'     if $filter->{status} eq 'orphaned';
1274   }
1275
1276   my $where = @where_tokens ? 'WHERE ' . join ' AND ', @where_tokens : '';
1277
1278   my $query     = qq|SELECT cp.*,
1279                        COALESCE(c.id,             v.id)           AS vcid,
1280                        COALESCE(c.name,           v.name)         AS vcname,
1281                        COALESCE(c.customernumber, v.vendornumber) AS vcnumber,
1282                        CASE WHEN c.name IS NULL THEN 'vendor' ELSE 'customer' END AS db
1283                      FROM contacts cp
1284                      LEFT JOIN customer c ON (cp.cp_cv_id = c.id)
1285                      LEFT JOIN vendor v   ON (cp.cp_cv_id = v.id)
1286                      $where
1287                      ORDER BY $order_by|;
1288
1289   my $contacts  = selectall_hashref_query($::form, $dbh, $query, @values);
1290
1291   $::lxdebug->leave_sub;
1292
1293   return @{ $contacts };
1294 }
1295
1296
1297 1;