S:C:CustomerVendorTurnover: unnütze Zeile weg
[kivitendo-erp.git] / SL / Controller / CustomerVendorTurnover.pm
1 package SL::Controller::CustomerVendorTurnover;
2 use strict;
3 use parent qw(SL::Controller::Base);
4 use SL::DBUtils;
5 use SL::DB::AccTransaction;
6 use SL::DB::Invoice;
7 use SL::DB::Order;
8 use SL::DB::EmailJournal;
9 use SL::DB::Letter;
10 use SL::DB;
11
12 __PACKAGE__->run_before('check_auth');
13
14 sub action_list_turnover {
15   my ($self) = @_;
16
17   return $self->render('generic/error', { layout => 0 }, label_error => "list_transactions needs a trans_id") unless $::form->{id};
18
19   my $cv = $::form->{id};
20   my $open_invoices;
21   if ( $::form->{db} eq 'customer' ) {
22     $open_invoices = SL::DB::Manager::Invoice->get_all(
23       query        => [
24                         customer_id => $cv,
25                         or          => [
26                                          amount => { gt => \'paid'},
27                                          amount => { lt => \'paid'},
28                                        ],
29                       ],
30       with_objects => [ 'dunnings' ],
31     );
32   } else {
33     $open_invoices = SL::DB::Manager::PurchaseInvoice->get_all(
34       query   => [
35                    vendor_id => $cv,
36                    or        => [
37                                   amount => { gt => \'paid'},
38                                   amount => { lt => \'paid'},
39                                 ],
40                  ],
41       sort_by => 'invnumber DESC',
42     );
43   }
44   my $open_items;
45   if (@{$open_invoices}) {
46     $open_items = $self->_list_open_items($open_invoices);
47   }
48   my $open_orders = $self->_get_open_orders;
49   return $self->render('customer_vendor_turnover/turnover', { header => 0 },
50                        open_orders => $open_orders,
51                        open_items  => $open_items,
52                        id          => $cv,
53                       );
54 }
55
56 sub _list_open_items {
57   my ($self, $open_items) = @_;
58
59   return $self->render('customer_vendor_turnover/_list_open_items', { output => 0 },
60                         OPEN_ITEMS => $open_items,
61                         title      => $::locale->text('Open Items'),
62                       );
63 }
64
65 sub action_count_open_items_by_year {
66   my ($self) = @_;
67
68   return $self->render('generic/error', { layout => 0 }, label_error => "list_transactions needs a trans_id") unless $::form->{id};
69   my $dbh = SL::DB->client->dbh;
70
71   my $cv = $::form->{id};
72
73   my $query = <<SQL;
74    SELECT EXTRACT (YEAR FROM d.transdate),
75           count(d.id),
76           max(d.dunning_level)
77      FROM dunning d
78 LEFT JOIN ar a ON a.id = d.trans_id
79 LEFT JOIN customer c ON a.customer_id = c.id
80     WHERE c.id = ?
81  GROUP BY EXTRACT (YEAR FROM d.transdate), c.id
82  ORDER BY date_part DESC
83 SQL
84
85   $self->{dun_statistic} = selectall_hashref_query($::form, $dbh, $query, $cv);
86   $self->render('customer_vendor_turnover/count_open_items_by_year', { layout => 0 });
87 }
88
89 sub action_count_open_items_by_month {
90
91   my ($self) = @_;
92
93   return $self->render('generic/error', { layout => 0 }, label_error => "list_transactions needs a trans_id") unless $::form->{id};
94   my $dbh = SL::DB->client->dbh;
95
96   my $cv = $::form->{id};
97
98   my $query = <<SQL;
99    SELECT CONCAT(EXTRACT (MONTH FROM d.transdate),'/',EXTRACT (YEAR FROM d.transdate)) AS date_part,
100           count(d.id),
101           max(d.dunning_level)
102      FROM dunning d
103 LEFT JOIN ar a ON a.id = d.trans_id
104 LEFT JOIN customer c ON a.customer_id = c.id
105     WHERE c.id = ?
106  GROUP BY EXTRACT (YEAR FROM d.transdate), EXTRACT (MONTH FROM d.transdate), c.id
107  ORDER BY EXTRACT (YEAR FROM d.transdate) DESC
108 SQL
109
110    $self->{dun_statistic} = selectall_hashref_query($::form, $dbh, $query, $cv);
111    $self->render('customer_vendor_turnover/count_open_items_by_year', { layout => 0 });
112 }
113
114 sub action_turnover_by_month {
115
116   my ($self) = @_;
117
118   return $self->render('generic/error', { layout => 0 }, label_error => "list_transactions needs a trans_id") unless $::form->{id};
119
120   my $dbh = SL::DB->client->dbh;
121   my $cv = $::form->{id};
122   my ($db, $cv_type);
123   if ($::form->{db} eq 'customer') {
124     $db      = "ar";
125     $cv_type = "customer_id";
126   } else {
127     $db      = "ap";
128     $cv_type = "vendor_id";
129   }
130   my $query = <<SQL;
131   SELECT CONCAT(EXTRACT (MONTH FROM transdate),'/',EXTRACT (YEAR FROM transdate)) as date_part,
132          count(id)                                                                as count,
133          sum(amount)                                                              as amount,
134          sum(netamount)                                                           as netamount,
135          sum(paid)                                                                as paid
136     FROM $db WHERE $cv_type = ?
137 GROUP BY EXTRACT (YEAR FROM transdate), EXTRACT (MONTH FROM transdate)
138 ORDER BY EXTRACT (YEAR FROM transdate) DESC, EXTRACT (MONTH FROM transdate) DESC
139 SQL
140    $self->{turnover_statistic} = selectall_hashref_query($::form, $dbh, $query, $cv);
141    $self->render('customer_vendor_turnover/count_turnover', { layout => 0 });
142 }
143
144 sub action_turnover_by_year {
145   my ($self) = @_;
146
147   return $self->render('generic/error', { layout => 0 }, label_error => "list_transactions needs a trans_id") unless $::form->{id};
148
149   my $dbh = SL::DB->client->dbh;
150   my $cv = $::form->{id};
151   my ($db, $cv_type);
152   if ($::form->{db} eq 'customer') {
153     $db      = "ar";
154     $cv_type = "customer_id";
155   } else {
156     $db      = "ap";
157     $cv_type = "vendor_id";
158   }
159   my $query = <<SQL;
160   SELECT EXTRACT (YEAR FROM transdate) as date_part,
161          count(id)                     as count,
162          sum(amount)                   as amount,
163          sum(netamount)                as netamount,
164          sum(paid)                     as paid
165     FROM $db WHERE $cv_type = ?
166 GROUP BY date_part
167 ORDER BY date_part DESC
168 SQL
169    $self->{turnover_statistic} = selectall_hashref_query($::form, $dbh, $query, $cv);
170    $self->render('customer_vendor_turnover/count_turnover', { layout => 0 });
171 }
172
173 sub action_get_invoices {
174   my ($self) = @_;
175
176   return $self->render('generic/error', { layout => 0 }, label_error => "list_transactions needs a trans_id") unless $::form->{id};
177
178   my $cv = $::form->{id};
179   my $invoices;
180   if ( $::form->{db} eq 'customer' ) {
181     $invoices = SL::DB::Manager::Invoice->get_all(
182       query   => [ customer_id => $cv, ],
183       sort_by => 'invnumber DESC',
184     );
185   } else {
186     $invoices = SL::DB::Manager::PurchaseInvoice->get_all(
187       query   => [ vendor_id => $cv, ],
188       sort_by => 'invnumber DESC',
189     );
190   }
191   $self->render('customer_vendor_turnover/invoices_statistic', { layout => 0 }, invoices => $invoices);
192 }
193
194 sub action_get_orders {
195   my ($self) = @_;
196
197   return $self->render('generic/error', { layout => 0 }, label_error => "list_transactions needs a trans_id") unless $::form->{id};
198
199   my $cv = $::form->{id};
200   my $orders;
201   my $type = $::form->{type};
202   if ( $::form->{db} eq 'customer' ) {
203     $orders = SL::DB::Manager::Order->get_all(
204       query   => [
205                    customer_id => $cv,
206                    quotation   => ($type eq 'quotation' ? 'T' : 'F')
207                  ],
208       sort_by => ( $type eq 'order' ? 'ordnumber DESC' : 'quonumber DESC'),
209     );
210   } else {
211     $orders = SL::DB::Manager::Order->get_all(
212       query   => [
213                    vendor_id => $cv,
214                    quotation => ($type eq 'quotation' ? 'T' : 'F')
215                  ],
216       sort_by => ( $type eq 'order' ? 'ordnumber DESC' : 'quonumber DESC'),
217     );
218   }
219   if ( $type eq 'order') {
220     $self->render('customer_vendor_turnover/order_statistic', { layout => 0 }, orders => $orders);
221   } else {
222     $self->render('customer_vendor_turnover/quotation_statistic', { layout => 0 }, orders => $orders);
223   }
224 }
225
226 sub _get_open_orders {
227   my ( $self ) = @_;
228
229   return $self->render('generic/error', { layout => 0 }, label_error => "list_transactions needs a trans_id") unless $::form->{id};
230   my $open_orders;
231   my $cv = $::form->{id};
232
233   if ( $::form->{db} eq 'customer' ) {
234     $open_orders = SL::DB::Manager::Order->get_all(
235       query   => [
236                    customer_id => $cv,
237                    closed      => 'F',
238                  ],
239       sort_by => 'ordnumber DESC',
240     );
241   } else {
242     $open_orders = SL::DB::Manager::Order->get_all(
243       query   => [
244                    vendor_id => $cv,
245                    closed    => 'F',
246                  ],
247       sort_by => 'ordnumber DESC',
248     );
249   }
250
251   return 0 unless scalar @{$open_orders};
252   return $self->render('customer_vendor_turnover/_list_open_orders', { output => 0 },
253                         orders => $open_orders,
254                         title  => $::locale->text('Open Orders'),
255                       );
256 }
257
258 sub action_get_mails {
259   my ( $self ) = @_;
260
261   return $self->render('generic/error', { layout => 0 }, label_error => "list_transactions needs a trans_id") unless $::form->{id};
262   my $dbh = SL::DB->client->dbh;
263   my $query;
264   my $cv = $::form->{id};
265
266   if ( $::form->{db} eq 'customer') {
267     $query = <<SQL;
268 WITH
269 oe_emails_customer
270        AS (SELECT rc.to_id, rc.from_id, oe.quotation, oe.quonumber, oe.ordnumber, c.id
271      FROM record_links rc
272 LEFT JOIN oe oe      ON rc.from_id = oe.id
273 LEFT JOIN customer c ON oe.customer_id = c.id
274     WHERE rc.to_table = 'email_journal'
275       AND rc.from_table ='oe'),
276
277 do_emails_customer
278        AS (SELECT rc.to_id, rc.from_id, o.donumber, c.id
279      FROM record_links rc
280 LEFT JOIN delivery_orders o ON rc.from_id = o.id
281 LEFT JOIN customer c ON o.customer_id = c.id
282     WHERE rc.to_table = 'email_journal'
283       AND rc.from_table = 'delivery_orders'),
284
285 inv_emails_customer
286        AS (SELECT rc.to_id, rc.from_id, inv.type, inv.invnumber, c.id
287      FROM record_links rc
288 LEFT JOIN ar inv ON rc.from_id = inv.id
289 LEFT JOIN customer c ON inv.customer_id = c.id
290     WHERE rc.to_table = 'email_journal'
291       AND rc.from_table = 'ar'),
292
293 letter_emails_customer
294        AS (SELECT rc.to_id, rc.from_id, l.letternumber, c.id
295      FROM record_links rc
296 LEFT JOIN letter l ON rc.from_id = l.id
297 LEFT JOIN customer c ON l.customer_id = c.id
298     WHERE rc.to_table = 'email_journal'
299       AND rc.from_table = 'letter')
300
301 SELECT ej.*,
302  CASE
303   oec.quotation WHEN 'F' THEN 'Sales Order'
304                 ELSE 'Quotation'
305  END AS type,
306  CASE
307   oec.quotation WHEN 'F' THEN oec.ordnumber
308                 ELSE oec.quonumber
309  END    AS recordnumber,
310  oec.id AS record_id
311      FROM email_journal ej
312 LEFT JOIN oe_emails_customer oec ON ej.id = oec.to_id
313     WHERE oec.id = ?
314
315 UNION
316
317 SELECT ej.*, 'Delivery Order' AS type, dec.donumber AS recordnumber,dec.id AS record_id
318      FROM email_journal ej
319 LEFT JOIN do_emails_customer dec ON ej.id = dec.to_id
320     WHERE dec.id = ?
321
322 UNION
323
324 SELECT ej.*,
325  CASE
326   iec.type WHEN 'credit_note' THEN 'Credit Note'
327            WHEN 'invoice' THEN 'Invoice'
328            ELSE 'N/A'
329  END           AS type,
330  iec.invnumber AS recordnumber,
331         iec.id AS record_id
332      FROM email_journal ej
333 LEFT JOIN inv_emails_customer iec ON ej.id = iec.to_id
334     WHERE iec.id = ?
335
336 UNION
337
338 SELECT ej.*, 'Letter' AS type, lec.letternumber AS recordnumber,lec.id AS record_id
339      FROM email_journal ej
340 LEFT JOIN letter_emails_customer lec ON ej.id = lec.to_id
341     WHERE lec.id = ?
342  ORDER BY sent_on DESC
343 SQL
344   }
345   else {
346     $query = <<SQL;
347 WITH
348 oe_emails_vendor
349        AS (SELECT rc.to_id, rc.from_id, oe.quotation, oe.quonumber, oe.ordnumber, c.id
350      FROM record_links rc
351 LEFT JOIN oe oe ON rc.from_id = oe.id
352 LEFT JOIN vendor c ON oe.vendor_id = c.id
353     WHERE rc.to_table = 'email_journal'
354       AND rc.from_table ='oe'),
355
356 do_emails_vendor
357        AS (SELECT rc.to_id, rc.from_id, o.donumber, c.id
358      FROM record_links rc
359 LEFT JOIN delivery_orders o ON rc.from_id = o.id
360 LEFT JOIN vendor c ON o.vendor_id = c.id
361     WHERE rc.to_table = 'email_journal'
362       AND rc.from_table = 'delivery_orders'),
363
364 inv_emails_vendor
365        AS (SELECT rc.to_id, rc.from_id, inv.type, inv.invnumber, c.id
366      FROM record_links rc
367 LEFT JOIN ap inv ON rc.from_id = inv.id
368 LEFT JOIN vendor c ON inv.vendor_id = c.id
369     WHERE rc.to_table = 'email_journal'
370       AND rc.from_table = 'ar'),
371
372 letter_emails_vendor
373        AS (SELECT rc.to_id, rc.from_id, l.letternumber, c.id
374      FROM record_links rc
375 LEFT JOIN letter l ON rc.from_id = l.id
376 LEFT JOIN vendor c ON l.vendor_id = c.id
377     WHERE rc.to_table = 'email_journal'
378       AND rc.from_table = 'letter')
379
380 SELECT ej.*,
381  CASE
382   oec.quotation WHEN 'F' THEN 'Purchase Order'
383                 ELSE 'Request quotation'
384  END AS type,
385  CASE
386   oec.quotation WHEN 'F' THEN oec.ordnumber
387                 ELSE oec.quonumber
388  END   AS recordnumber,
389 oec.id AS record_id
390      FROM email_journal ej
391 LEFT JOIN oe_emails_vendor oec ON ej.id = oec.to_id
392     WHERE oec.id = ?
393
394 UNION
395
396 SELECT ej.*, 'Purchase Delivery Order' AS type, dec.donumber AS recordnumber, dec.id AS record_id
397      FROM email_journal ej
398 LEFT JOIN do_emails_vendor dec ON ej.id = dec.to_id
399     WHERE dec.id = ?
400
401 UNION
402
403 SELECT ej.*, iec.type AS type, iec.invnumber AS recordnumber, iec.id AS record_id
404      FROM email_journal ej
405 LEFT JOIN inv_emails_vendor iec ON ej.id = iec.to_id
406     WHERE iec.id = ?
407
408 UNION
409
410 SELECT ej.*, 'Letter' AS type, lec.letternumber AS recordnumber, lec.id AS record_id
411      FROM email_journal ej
412 LEFT JOIN letter_emails_vendor lec ON ej.id = lec.to_id
413     WHERE lec.id = ?
414  ORDER BY sent_on DESC
415 SQL
416   }
417   my $emails = selectall_hashref_query($::form, $dbh, $query, $cv, $cv, $cv, $cv);
418   $self->render('customer_vendor_turnover/email_statistic', { layout => 0 }, emails => $emails);
419 }
420
421 sub action_get_letters {
422   my ($self) = @_;
423
424   return $self->render('generic/error', { layout => 0 }, label_error => "list_transactions needs a trans_id") unless $::form->{id};
425
426   my $cv = $::form->{id};
427   my $letters;
428   my $type = $::form->{type};
429   if ( $::form->{db} eq 'customer' ) {
430     $letters = SL::DB::Manager::Letter->get_all(
431       query   => [ customer_id => $cv, ],
432       sort_by => 'date DESC',
433     );
434   } else {
435     $letters = SL::DB::Manager::Letter->get_all(
436       query   => [ vendor_id => $cv, ],
437       sort_by => 'date DESC',
438     );
439   }
440     $self->render('customer_vendor_turnover/letter_statistic', { layout => 0 }, letters => $letters);
441 }
442
443 sub check_auth {
444   $::auth->assert('show_extra_record_tab_customer | show_extra_record_tab_vendor');
445 }
446
447 1;
448
449 __END__
450
451 =encoding utf-8
452
453 =head1 NAME
454
455 SL::Controller::CustomerVendorTurnover
456
457 =head1 DESCRIPTION
458
459 Gets all kinds of records like orders, request orders, quotations, invoices, emails, letters
460
461 wich belong to customer/vendor and displays them in an extra tab "Records".
462
463 =head1 URL ACTIONS
464
465 =over 4
466
467 =item C<action_list_turnover>
468
469 Basic action wich displays open invoices and open orders if there are any and shows the tab menu for the other actions
470
471 =item C<action_count_open_items_by_month>
472
473 gets and shows a dunning statistic of the customer by month
474
475 =item C<action_count_open_items_by_year>
476
477 gets and shows a dunning statistic of the customer by year
478
479 =item C<action_turnover_by_month>
480
481 gets and shows an invoice statistic of customer/vendor by month
482
483 =item C<action_turnover_by_year>
484
485 gets and shows an invoice statistic of customer/vendor by year
486
487 =item C<action_get_invoices>
488
489 get and shows all invoices from the customer/vendor in an extra tab
490
491 =item C<action_get_orders>
492
493 get and shows all orders from the customer/vendor in an extra tab
494
495 =item C<action_get_letters>
496
497 get and shows all letters from the customer/vendor in an extra tab
498
499 =item C<action_get_mails>
500
501 get and shows all mails from the customer/vendor in an extra tab
502
503 =back
504
505 =head1 Functions
506
507 =over 4
508
509 =item C<_get_open_orders>
510
511 retrieves the open orders for customer/vendor to display them
512
513 =item C<_list_open_items>
514
515 retrieves open invoices with their dunnings to display them
516
517 =back
518
519 =head1 BUGS
520
521 None yet. :)
522
523 =head1 AUTHOR
524
525 W. Hahn E<lt>wh@futureworldsearch.netE<gt>
526
527 =cut