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