Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 79398e65

Von G. Richardson vor fast 14 Jahren hinzugefügt

  • ID 79398e65cd6534ca6ccd22f8ff7c67617e6ccc53
  • Vorgänger a9a6bc13
  • Nachfolger bef9fad9

Neuer Bericht "Verkaufsbericht" unter Verkauf->Berichte

Vor allem interessant für Wiederverkäufer, die ihre Margen anzeigen wollen und EK-Preis pflegen.

Neue Dateien bin/mozilla/vk.pl und SL/VK.pm, sowie template unter templates/webpages/vk

  • Auflistung aller verkauften Artikel mit VK-Preis, EK-Preis und Margen
  • Sortiert nach Kunden und Artikeln oder Artikeln und Kunden
  • Preisfaktor (Preis pro 100) bei Gesamtbetrag berücksichtigt
  • Anzahl der Dezimalstellen einstellbar (für bestimmte Spalten)
  • Einheit als Anzeigeoption (aber keine Umrechnung, z.B. kg->g)

Stornos und stornierte Rechnung aus VK-Bericht herausgefiltert

1) für Auswertungen gar nicht nötig
2) bei Storno wird in invoice marge_total und marge_percent nicht gesetzt
deshalb dynamisch für VK-Bericht berechnet, auch wenn es jetzt nicht mehr angezeigt wird
Macht es überhaupt Sinn bei Stornos dann invoice mit Margenwerten zu befüllen?

Nicht berücksichtigt:
  • Einkauf
Noch Fehlerhaft:
  • Abwechselndes grau/beige in Ansicht unregelmäßig, generelle Formatierung der Ausgabe (z.T. noch farbig)

Unterschiede anzeigen:

SL/VK.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
# Sold Items report
32
#
33
#======================================================================
34

  
35
package VK;
36

  
37
use SL::DBUtils;
38
use SL::IO;
39
use SL::MoreCommon;
40

  
41
use strict;
42

  
43
sub invoice_transactions {
44
  $main::lxdebug->enter_sub();
45

  
46
  my ($self, $myconfig, $form) = @_;
47

  
48
  # connect to database
49
  my $dbh = $form->get_standard_dbh($myconfig);
50

  
51
  my @values;
52

  
53
  my $query =
54
    qq|SELECT cus.name,ar.invnumber,ar.id,ar.transdate,p.partnumber,i.parts_id,i.qty,i.price_factor,i.discount,i.description,i.lastcost,i.sellprice,i.marge_total,i.marge_percent,i.unit | .
55
    qq|FROM invoice i | .  
56
    qq|join ar on (i.trans_id = ar.id) | .
57
    qq|join parts p on (i.parts_id = p.id) | .
58
    qq|join customer cus on (cus.id = ar.customer_id) |;
59

  
60
  my $where = "1 = 1";
61

  
62
  # Stornierte Rechnungen und Stornorechnungen in invoice rausfiltern
63
  $where .= " AND ar.storno is not true ";
64

  
65
  my $sortorder = "cus.name,i.parts_id,ar.transdate";
66
  if ($form->{sortby} eq 'artikelsort') {
67
    $sortorder = "i.parts_id,cus.name,ar.transdate";
68
  };
69

  
70
  if ($form->{customer_id}) {
71
    $where .= " AND ar.customer_id = ?";
72
    push(@values, $form->{customer_id});
73
  };
74
  if ($form->{partnumber}) {
75
    $where .= qq| AND (p.partnumber ILIKE ?)|;
76
    push(@values, '%' . $form->{partnumber} . '%');
77
  }
78
  # nimmt man description am Besten aus invoice oder parts?
79
  if ($form->{description}) {
80
    $where .= qq| AND (i.description ILIKE ?)|;
81
    push(@values, '%' . $form->{description} . '%');
82
  }
83
  if ($form->{transdatefrom}) {
84
    $where .= " AND ar.transdate >= ?";
85
    push(@values, $form->{transdatefrom});
86
  }
87
  if ($form->{transdateto}) {
88
    $where .= " AND ar.transdate <= ?";
89
    push(@values, $form->{transdateto});
90
  }
91
  if ($form->{department}) {
92
    my ($null, $department_id) = split /--/, $form->{department};
93
    $where .= " AND ar.department_id = ?";
94
    push(@values, $department_id);
95
  }
96
  if ($form->{project_id}) {
97
    $where .=
98
      qq|AND ((ar.globalproject_id = ?) OR EXISTS | .
99
      qq|  (SELECT * FROM invoice i | .
100
      qq|   WHERE i.project_id = ? AND i.trans_id = ar.id))|;
101
    push(@values, $form->{"project_id"}, $form->{"project_id"});
102
  }
103

  
104
  $query .= " WHERE $where ORDER BY $sortorder";
105

  
106
  my @result = selectall_hashref_query($form, $dbh, $query, @values);
107

  
108
  $form->{AR} = [ @result ];
109

  
110
  $main::lxdebug->leave_sub();
111
}
112

  
113
1;
114

  
bin/mozilla/vk.pl
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
#
16
# This program is free software; you can redistribute it and/or modify
17
# it under the terms of the GNU General Public License as published by
18
# the Free Software Foundation; either version 2 of the License, or
19
# (at your option) any later version.
20
#
21
# This program is distributed in the hope that it will be useful,
22
# but WITHOUT ANY WARRANTY; without even the implied warranty of
23
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
# GNU General Public License for more details.
25
# You should have received a copy of the GNU General Public License
26
# along with this program; if not, write to the Free Software
27
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28
#======================================================================
29
#
30
# Sales report
31
#
32
#======================================================================
33

  
34
use POSIX qw(strftime);
35
use List::Util qw(sum first);
36

  
37
use SL::VK;
38
use SL::ReportGenerator;
39
use Data::Dumper;
40

  
41
require "bin/mozilla/arap.pl";
42
require "bin/mozilla/common.pl";
43
require "bin/mozilla/drafts.pl";
44
require "bin/mozilla/reportgenerator.pl";
45

  
46
use strict;
47

  
48

  
49
sub search_invoice {
50
  $main::lxdebug->enter_sub();
51
  $main::auth->assert('general_ledger | invoice_edit');
52

  
53
  my $form     = $main::form;
54
  my %myconfig = %main::myconfig;
55
  my $locale   = $main::locale;
56
  my $cgi      = $main::cgi;
57

  
58
  my ($customer, $department);
59

  
60
  # setup customer selection
61
  $form->all_vc(\%myconfig, "customer", "AR");
62

  
63
  $form->{title}    = $locale->text('Sales Report');
64
  $form->{jsscript} = 1;
65

  
66
  $form->get_lists("projects"     => { "key" => "ALL_PROJECTS", "all" => 1 },
67
                   "departments"  => "ALL_DEPARTMENTS",
68
                   "customers"    => "ALL_VC");
69

  
70
  $form->{vc_keys}   = sub { "$_[0]->{name}--$_[0]->{id}" };
71

  
72
  $form->header;
73
  print $form->parse_html_template('vk/search_invoice', { %myconfig });
74

  
75
  $main::lxdebug->leave_sub();
76
}
77

  
78
sub invoice_transactions {
79
  $main::lxdebug->enter_sub();
80

  
81
  $main::auth->assert('general_ledger | invoice_edit');
82

  
83
  my $form     = $main::form;
84
  my %myconfig = %main::myconfig;
85
  my $locale   = $main::locale;
86

  
87
  my ($callback, $href, @columns);
88

  
89
  $form->{customer} = $form->unescape($form->{customer});
90
  
91
  ($form->{customername}, $form->{customer_id}) = split(/--/, $form->{customer});
92

  
93
  # decimalplaces überprüfen oder auf Default 2 setzen
94
  $form->{decimalplaces} = 2 unless $form->{decimalplaces} > 0 && $form->{decimalplaces} < 6;
95

  
96
#  report_generator_set_default_sort('transdate', 1);
97

  
98
  VK->invoice_transactions(\%myconfig, \%$form);
99

  
100
  # anhand von radio button die Sortierreihenfolge festlegen
101
  if ($form->{sortby} eq 'artikelsort') {
102
    $form->{'mainsort'} = 'parts_id';
103
    $form->{'subsort'}  = 'name';
104
  } else {
105
    $form->{'mainsort'} = 'name';
106
    $form->{'subsort'}  = 'parts_id';
107
  };
108

  
109
  $form->{title} = $locale->text('Sales Report');
110

  
111
  @columns =
112
    qw(description invnumber partnumber parts_id transdate qty unit sellprice sellprice_total discount lastcost lastcost_total marge_total marge_percent);
113

  
114
  # hidden variables für pdf/csv export übergeben
115
  # einmal mit l_ um zu bestimmen welche Spalten ausgegeben werden sollen
116
  # einmal optionen für die Überschrift (z.B. transdatefrom, partnumber, ...)
117
  my @hidden_variables  = (qw(l_headers l_subtotal l_total transdatefrom transdateto decimalplaces customer customername customer_id department partnumber description project_id), "$form->{db}number", map { "l_$_" } @columns);
118
  my @hidden_nondefault = grep({ $form->{$_} } @hidden_variables);
119
  # Variablen werden dann als Hidden Variable mitgegeben, z.B.
120
  # <input type="hidden" name="report_generator_hidden_transdateto" value="21.05.2010">
121

  
122
  $href = build_std_url('action=invoice_transactions', grep { $form->{$_} } @hidden_variables);
123
  # href = vk.pl?action=invoice_transactions&l_headers=Y&l_subtotal=Y&l_total=Y&transdatefrom=04.03.2010 ...
124

  
125
  my %column_defs = (
126
    'description'             => { 'text' => $locale->text('Description'), },
127
    'partnumber'              => { 'text' => $locale->text('Part Number'), },
128
    'invnumber'               => { 'text' => $locale->text('Invoice Number'), },
129
    'transdate'               => { 'text' => $locale->text('Invoice Date'), },
130
    'qty'                     => { 'text' => $locale->text('Quantity'), },
131
    'unit'                    => { 'text' => $locale->text('Unit'), },
132
    'sellprice'               => { 'text' => $locale->text('Sales price'), },
133
    'sellprice_total'         => { 'text' => $locale->text('Sales net amount'), },
134
    'lastcost_total'          => { 'text' => $locale->text('Purchase net amount'), },
135
    'discount'                => { 'text' => $locale->text('Discount'), },
136
    'lastcost'                => { 'text' => $locale->text('Purchase price'), },
137
    'marge_total'             => { 'text' => $locale->text('Sales margin'), },
138
    'marge_percent'           => { 'text' => $locale->text('Sales margin %'), },
139
  );
140
  
141
  my %column_alignment = map { $_ => 'right' } qw(lastcost sellprice sellprice_total lastcost_total unit discount marge_total marge_percent qty);
142

  
143
  $form->{"l_type"} = "Y";
144
  map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns;
145

  
146

  
147
  my @options;
148
  if ($form->{description}) {
149
    push @options, $locale->text('description') . " : $form->{description}";
150
  }
151
  if ($form->{customer}) {
152
    push @options, $locale->text('Customer') . " : $form->{customername}";
153
  }
154
  if ($form->{department}) {
155
    my ($department) = split /--/, $form->{department};
156
    push @options, $locale->text('Department') . " : $department";
157
  }
158
  if ($form->{invnumber}) {
159
    push @options, $locale->text('Invoice Number') . " : $form->{invnumber}";
160
  }
161
  if ($form->{invdate}) {
162
    push @options, $locale->text('Invoice Date') . " : $form->{invdate}";
163
  }
164
  if ($form->{partnumber}) {
165
    push @options, $locale->text('Part Number') . " : $form->{partnumber}";
166
  }
167
  if ($form->{ordnumber}) {
168
    push @options, $locale->text('Order Number') . " : $form->{ordnumber}";
169
  }
170
  if ($form->{notes}) {
171
    push @options, $locale->text('Notes') . " : $form->{notes}";
172
  }
173
  if ($form->{transaction_description}) {
174
    push @options, $locale->text('Transaction description') . " : $form->{transaction_description}";
175
  }
176
  if ($form->{transdatefrom}) {
177
    push @options, $locale->text('From') . " " . $locale->date(\%myconfig, $form->{transdatefrom}, 1);
178
  }
179
  if ($form->{transdateto}) {
180
    push @options, $locale->text('Bis') . " " . $locale->date(\%myconfig, $form->{transdateto}, 1);
181
  }
182

  
183
  my $report = SL::ReportGenerator->new(\%myconfig, $form);
184

  
185
  $report->set_options('top_info_text'        => join("\n", @options),
186
                       'output_format'        => 'HTML',
187
                       'title'                => $form->{title},
188
                       'attachment_basename'  => $locale->text('sales_report') . strftime('_%Y%m%d', localtime time),
189
    );
190
  $report->set_options_from_form();
191

  
192
  $report->set_columns(%column_defs);
193
  $report->set_column_order(@columns);
194

  
195
  $report->set_export_options('invoice_transactions', @hidden_variables, qw(mainsort sortdir));
196

  
197
  $report->set_sort_indicator($form->{mainsort}, $form->{sortdir});
198

  
199
  # add sort and escape callback, this one we use for the add sub
200
  $form->{callback} = $href .= "&sort=$form->{mainsort}";
201

  
202
  # escape callback for href
203
  $callback = $form->escape($href);
204

  
205
  my @subtotal_columns = qw(qty sellprice sellprice_total lastcost lastcost_total marge_total marge_percent discount);
206
  # Gesamtsumme:
207
  # Summe von sellprice_total, lastcost_total und marge_total
208
  # Durchschnitt von marge_percent
209
  my @total_columns = qw(sellprice_total lastcost_total marge_total marge_percent );
210

  
211
  my %totals    = map { $_ => 0 } @total_columns;
212
  my %subtotals1 = map { $_ => 0 } @subtotal_columns;
213
  my %subtotals2 = map { $_ => 0 } @subtotal_columns;
214

  
215
  my $idx = 0;
216

  
217
  foreach my $ar (@{ $form->{AR} }) {
218

  
219
    $ar->{price_factor} = 1 unless $ar->{price_factor};
220
    # calculate individual sellprice
221
    # discount was already accounted for in db sellprice
222
    $ar->{sellprice} = $ar->{sellprice} / $ar->{price_factor};
223
    $ar->{lastcost} = $ar->{lastcost} / $ar->{price_factor};
224
    $ar->{sellprice_total} = $ar->{qty} * $ar->{sellprice};
225
    $ar->{lastcost_total}  = $ar->{qty} * $ar->{lastcost}; 
226
    # marge_percent wird neu berechnet, da Wert in invoice leer ist (Bug)
227
    $ar->{marge_percent} = $ar->{sellprice_total} ? (($ar->{sellprice_total}-$ar->{lastcost_total}) / $ar->{sellprice_total}) : 0;
228
    # marge_total neu berechnen
229
    $ar->{marge_total} = $ar->{sellprice_total} ? $ar->{sellprice_total}-$ar->{lastcost_total}  : 0;
230
    $ar->{discount} *= 100;  # für Ausgabe formatieren, 10% stored as 0.1 in db
231

  
232
    # Anfangshauptüberschrift
233
    if ( $form->{l_headers} eq "Y" && ( $idx == 0 or $ar->{ $form->{'mainsort'} } ne $form->{AR}->[$idx - 1]->{ $form->{'mainsort'} } )) {
234
      my $name;
235
      my $headerrow;
236
      if ( $form->{mainsort} eq 'parts_id' ) {
237
	$headerrow->{description}->{data} = "$ar->{description}";
238
      } else {
239
	$headerrow->{description}->{data} = "$ar->{name}";
240
      };
241
      $headerrow->{description}->{class} = "listmainsortheader";
242
      my $headerrow_set = [ $headerrow ];
243
      $report->add_data($headerrow_set);
244

  
245
      # add empty row after main header
246
#      my $emptyheaderrow->{description}->{data} = ""; 
247
#      $emptyheaderrow->{description}->{class} = "listmainsortheader";
248
#      my $emptyheaderrow_set = [ $emptyheaderrow ];
249
#      $report->add_data($emptyheaderrow_set) if $form->{l_headers} eq "Y"; 
250
    };
251

  
252
    # subsort überschriften
253
    if ( $idx == 0 
254
      or $ar->{ $form->{'subsort'} }  ne $form->{AR}->[$idx - 1]->{ $form->{'subsort'} }
255
      or $ar->{ $form->{'mainsort'} } ne $form->{AR}->[$idx - 1]->{ $form->{'mainsort'} }
256
    ) {
257
      my $headerrow;
258
      my $name;
259
      if ( $form->{subsort} eq 'parts_id' ) {
260
        $name = 'description';
261
        $headerrow->{description}->{data} = "$ar->{$name}";
262
      } else {
263
        $name = 'name';
264
        $headerrow->{description}->{data} = "$ar->{$name}";
265
      };
266
      $headerrow->{description}->{class} = "listsubsortheader";
267
      my $headerrow_set = [ $headerrow ];
268
      $report->add_data($headerrow_set) if $form->{l_headers} eq "Y";
269
    };
270

  
271
    map { $subtotals1{$_} += $ar->{$_};
272
          $subtotals2{$_} += $ar->{$_};
273
        } @subtotal_columns;
274
         
275
    map { $totals{$_}    += $ar->{$_} } @total_columns;  
276

  
277
    $subtotals2{sellprice} = $subtotals2{sellprice_total} / $subtotals2{qty} if $subtotals2{qty} != 0;
278
    $subtotals1{sellprice} = $subtotals1{sellprice_total} / $subtotals1{qty} if $subtotals1{qty} != 0;
279
    $subtotals2{lastcost} = $subtotals2{lastcost_total} / $subtotals2{qty} if $subtotals2{qty} != 0;
280
    $subtotals1{lastcost} = $subtotals1{lastcost_total} / $subtotals1{qty} if $subtotals1{qty} != 0;
281

  
282
    # Ertrag prozentual in den Summen: (summe VK - summe Ertrag) / summe VK
283
    $subtotals1{marge_percent} = $subtotals1{sellprice_total} ? (($subtotals1{sellprice_total} - $subtotals1{lastcost_total}) / $subtotals1{sellprice_total}) : 0;
284
    $subtotals2{marge_percent} = $subtotals2{sellprice_total} ? (($subtotals2{sellprice_total} - $subtotals2{lastcost_total}) / $subtotals2{sellprice_total}) : 0;
285

  
286
    # Ertrag prozentual:  (Summe VK betrag - Summe EK betrag) / Summe VK betrag
287
    # wird laufend bei jeder Position neu berechnet
288
    $totals{marge_percent}    = $totals{sellprice_total}    ? ( ($totals{sellprice_total} - $totals{lastcost_total}) / $totals{sellprice_total}   ) : 0;
289

  
290
    map { $ar->{$_} = $form->format_amount(\%myconfig, $ar->{$_}, 2) } qw(marge_total marge_percent);
291
    map { $ar->{$_} = $form->format_amount(\%myconfig, $ar->{$_}, $form->{"decimalplaces"} )} qw(lastcost sellprice sellprice_total lastcost_total);
292

  
293
    my $row = { };
294

  
295
    foreach my $column (@columns) {
296
      $row->{$column} = {
297
        'data'  => $ar->{$column},
298
        'align' => $column_alignment{$column},
299
      };
300
    }
301
  
302
   $row->{description}->{class} = 'listsortdescription';
303

  
304
    $row->{invnumber}->{link} = build_std_url("script=is.pl", 'action=edit')
305
      . "&id=" . E($ar->{id}) . "&callback=${callback}";
306

  
307
    my $row_set = [ $row ];
308

  
309
    if (($form->{l_subtotal} eq 'Y')
310
        && (($idx == (scalar @{ $form->{AR} } - 1))   # last element always has a subtotal
311
          || ($ar->{ $form->{'subsort'} } ne $form->{AR}->[$idx + 1]->{ $form->{'subsort'}   })
312
          || ($ar->{ $form->{'mainsort'} } ne $form->{AR}->[$idx + 1]->{ $form->{'mainsort'} })
313
          )) {   # if value that is sorted by changes, print subtotal
314
      my $name;
315
      if ( $form->{subsort} eq 'parts_id' ) {
316
        $name = 'description';
317
      } else {
318
        $name = 'name';
319
      };
320
      
321
      if ($form->{l_subtotal} eq 'Y' ) {
322
        push @{ $row_set }, create_subtotal_row_invoice(\%subtotals2, \@columns, \%column_alignment, \@subtotal_columns, 'listsubsortsubtotal', $ar->{$name}) ;
323
        push @{ $row_set }, insert_empty_row();
324
      };
325
    }
326

  
327
    # if mainsort has changed, add mainsort subtotal and empty row 
328
    if (($form->{l_subtotal} eq 'Y')
329
        && (($idx == (scalar @{ $form->{AR} } - 1))   # last element always has a subtotal
330
            || ($ar->{ $form->{'mainsort'} } ne $form->{AR}->[$idx + 1]->{ $form->{'mainsort'} })
331
            )) {   # if value that is sorted by changes, print subtotal
332
      my $name;
333
      if ( $form->{mainsort} eq 'parts_id' ) {
334
        $name = 'description';
335
      } else {
336
        $name = 'name';
337
      };
338
      if ($form->{l_subtotal} eq 'Y' ) {
339
        push @{ $row_set }, create_subtotal_row_invoice(\%subtotals1, \@columns, \%column_alignment, \@subtotal_columns, 'listmainsortsubtotal', $ar->{$name});
340
        push @{ $row_set }, insert_empty_row();
341
      };
342
    }
343
  
344
    $report->add_data($row_set);
345

  
346
    $idx++;
347
  }
348
  if ( $form->{l_total} eq "Y" ) {
349
    $report->add_separator();
350
    $report->add_data(create_subtotal_row_invoice(\%totals, \@columns, \%column_alignment, \@total_columns, 'listtotal'))
351
  };
352

  
353
  $report->generate_with_headers();
354
  $main::lxdebug->leave_sub();
355
}
356

  
357

  
358
sub insert_empty_row {
359
    my $dummyrow;
360
    $dummyrow->{description}->{data} = "";
361
    my $dummyrowset = [ $dummyrow ];
362
    return $dummyrow;
363
};
364

  
365

  
366

  
367
sub create_subtotal_row_invoice {
368
  $main::lxdebug->enter_sub();
369

  
370
  my ($totals, $columns, $column_alignment, $subtotal_columns, $class, $name) = @_;
371

  
372
  my $form     = $main::form;
373
  my %myconfig = %main::myconfig;
374

  
375
  my $row = { map { $_ => { 'data' => '', 'class' => $class, 'align' => $column_alignment->{$_}, } } @{ $columns } };
376
  
377
  $row->{description}->{data} = "Summe " . $name;
378

  
379
  map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, 2) } qw(marge_total marge_percent);
380
  map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, 0) } qw(qty);
381
  map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, $form->{decimalplaces}) } qw(lastcost sellprice sellprice_total lastcost_total);
382

  
383

  
384
  map { $totals->{$_} = 0 } @{ $subtotal_columns };
385

  
386
  $main::lxdebug->leave_sub();
387

  
388
  return $row;
389
}
390

  
391
1;
392

  
css/lx-office-erp.css
211 211

  
212 212
.listtotal, .listtotal td { font-size: 8pt; background-color: rgb(236,233,216); color: black; font-weight: bolder;}
213 213

  
214
/* Verkaufsbericht */
215
.listmainsortheader { font-size: 8pt; background-color: rgb(236,233,216); color: red; font-weight: bolder; padding-left: 10px; padding-top: 0px;}
216
.listmainsortsubtotal { font-size: 8pt; background-color: rgb(236,233,216); color: red; font-weight: bolder; padding-left: 10px;}
217
.listsubsortheader { font-size: 8pt; background-color: rgb(236,233,216); color: green; font-weight: bolder; padding-left: 20px}
218
.listsubsortsubtotal { font-size: 8pt; background-color: rgb(236,233,216); color: green; font-weight: bolder; padding-left: 20px}
219
.listsortdescription { font-size: 8pt; background-color: rgb(236,233,216); color: black; font-weight: normal; padding-left: 30px}
220

  
221

  
214 222
.submit {
215 223
  font-family: Verdana, Arial, Helvetica;
216 224
  color: #000000;
doc/changelog
21 21
  - Ansprechpartner für abweichende Lieferadresse, um das Attribut Geschlecht erweitert
22 22
  - FiBu -> Bericht -> Offene Forderung | Offene Verbindlichkeiten um Altersstrukturliste (30, 60, 90, 120) erweitert
23 23
  - SEPA Hinzufügen von Überweisungen um das Infofeld Fälligkeitsdatum erweitert
24
  - Verkaufsbericht mit Statistiken zu Margen
24 25

  
25 26
  API Änderungen:
26 27

  
locale/de/all
595 595
  'EAN-Code'                    => 'EAN-Code',
596 596
  'EB-Wert'                     => 'EB-Wert',
597 597
  'EK'                          => 'EK',
598
  'EK-Preis'                    => 'Purchase price',
598 599
  'ELSE'                        => 'Zusatz',
599 600
  'ELSTER Export (Taxbird)'     => 'ELSTER-Export nach Taxbird',
600 601
  'ELSTER Export (Winston)'     => 'ELSTER Export nach Winston',
......
792 793
  'Hardcopy'                    => 'Seite drucken',
793 794
  'Has serial number'           => 'Hat eine Serienummer',
794 795
  'Header'                      => '?berschrift',
796
  'Headers'                     => '?berschriften',
795 797
  'Heading'                     => '?berschrift',
796 798
  'Help'                        => 'Hilfe',
797 799
  'Help Template Variables'     => 'Hilfe zu Dokumenten-Variablen',
......
976 978
  'MAILED'                      => 'Gesendet',
977 979
  'MSG_BROWSER_DOES_NOT_SUPPORT_IFRAMES' => 'Ihr Browser kann leider keine eingebetteten Frames anzeigen. Bitte w&auml;hlen Sie ein anderes Men&uuml; in der Benutzerkonfiguration im Administrationsmen&uuml; aus.',
978 980
  'Main Preferences'            => 'Grundeinstellungen',
981
  'Main sorting'                => 'Hauptsortierung',
979 982
  'Make'                        => 'Lieferant',
980 983
  'Manage Custom Variables'     => 'Benutzerdefinierte Variablen',
981 984
  'Manage license keys'         => 'Lizenzschl&uuml;ssel verwalten',
......
983 986
  'Mandatory Departments'       => 'Benutzer muss Abteilungen vergeben',
984 987
  'Mar'                         => 'M?rz',
985 988
  'March'                       => 'M?rz',
989
  'Margepercent'                => 'Ertrag prozentual',
990
  'Margetotal'                  => 'Ertrag',
986 991
  'Margins'                     => 'Seitenr&auml;nder',
987 992
  'Mark as closed'              => 'Abschlie?en',
988 993
  'Mark as paid?'               => 'Als bezahlt markieren?',
......
1285 1290
  'Purchase Prices'             => 'Einkaufspreise',
1286 1291
  'Purchase delivery order'     => 'Lieferschein (Einkauf)',
1287 1292
  'Purchase invoices'           => 'Einkaufsrechnungen',
1293
  'Purchase net amount'         => 'EK-Betrag',
1294
  'Purchase price'              => 'EK-Preis',
1295
  'Purchase price total'        => 'EK-Betrag',
1288 1296
  'Purpose'                     => 'Verwendungszweck',
1289 1297
  'Qty'                         => 'Menge',
1290 1298
  'Qty according to delivery order' => 'Menge laut Lieferschein',
......
1374 1382
  'Sales Invoices'              => 'Kundenrechnung',
1375 1383
  'Sales Order'                 => 'Kundenauftrag',
1376 1384
  'Sales Orders'                => 'Auftr?ge',
1385
  'Sales Report'                => 'Verkaufsbericht',
1377 1386
  'Sales and purchase invoices with inventory transactions with taxkeys' => 'Einkaufs- und Verkaufsrechnungen mit Warenbestandsbuchungen mit Steuerschl?sseln',
1378 1387
  'Sales delivery order'        => 'Lieferschein (Verkauf)',
1379 1388
  'Sales invoice number'        => 'Ausgangsrechnungsnummer',
1380 1389
  'Sales invoices'              => 'Verkaufsrechnungen',
1390
  'Sales margin'                => 'Marge',
1391
  'Sales margin %'              => 'Marge prozentual',
1392
  'Sales net amount'            => 'VK-Betrag',
1393
  'Sales price'                 => 'VK-Preis',
1394
  'Sales price total'           => 'VK-Betrag',
1381 1395
  'Sales quotation'             => 'Angebot',
1382 1396
  'Salesman'                    => 'Verk?ufer/in',
1383 1397
  'Salesperson'                 => 'Verk?ufer',
......
1951 1965
  'debug'                       => 'Debug',
1952 1966
  'delete'                      => 'L?schen',
1953 1967
  'deliverydate'                => 'Lieferdatum',
1968
  'description'                 => 'Beschreibung',
1954 1969
  'direct debit'                => 'Lastschrift',
1955 1970
  'disposed'                    => 'Entsorgung',
1956 1971
  'done'                        => 'erledigt',
......
2026 2041
  'sales_order'                 => 'Kundenauftrag',
2027 2042
  'sales_order_list'            => 'auftragsliste',
2028 2043
  'sales_quotation'             => 'Verkaufsangebot',
2044
  'sales_report'                => 'verkaufsbericht',
2029 2045
  'saved'                       => 'gespeichert',
2030 2046
  'saved!'                      => 'gespeichert',
2031 2047
  'sent'                        => 'gesendet',
menu.ini
159 159
action=search
160 160
nextsub=ar_transactions
161 161

  
162
[AR--Reports--Sales Report]
163
ACCESS=invoice_edit
164
module=vk.pl
165
action=search_invoice
166
nextsub=invoice_transactions
167

  
162 168
[AR--Reports--Dunnings]
163 169
ACCESS=dunning_edit
164 170
module=dn.pl
templates/webpages/vk/search_invoice.html
1
[%- USE T8 %]
2
<body>
3

  
4
 <form method=post name="search_invoice" action=[% script %]>
5

  
6
  <table width=100%>
7
  <tr><th class=listtop>[% title %]</th></tr>
8
  <tr height="5"></tr>
9
  <tr>
10
   <td>
11
    <table>
12
     <tr>
13
       <td>[% 'Main sorting' | $T8 %]</td>
14
       <td colspan="3">
15
        <input name="sortby" id="artikelsort" class="radio" type="radio" value="artikelsort" checked>
16
        <label for="artikelsort">[% 'Artikel' | $T8 %]</label>
17
        <input name="sortby" id="customersort" class="radio" type="radio" value="customersort">
18
        <label for="customersort">[% 'Customer' | $T8 %]</label>
19
       </td>
20
      </tr>
21

  
22

  
23

  
24
     <tr>
25
      <th align=right>[% 'Customer' | $T8 %]</th>
26
      <td colspan=3>
27
            [%- INCLUDE 'generic/multibox.html'
28
                 name          = 'customer',
29
                 default       = oldcustomer,
30
                 style         = 'width: 250px',
31
                 DATA          = ALL_VC,
32
                 id_sub        = 'vc_keys',
33
                 label_key     = 'name',
34
                 select        = vc_select,
35
                 limit         = vclimit,
36
                 show_empty    = 1,
37
                 allow_textbox = 1,
38
                 -%]
39
      </td>
40
     </tr>
41
     <tr>
42
      <th align=right nowrap>[% 'Department' | $T8 %]</th>
43
      <td>
44
            [%- INCLUDE 'generic/multibox.html'
45
                 name          = 'department',
46
                 style         = 'width: 250px',
47
                 DATA          = ALL_DEPARTMENTS,
48
                 id_key        = 'id',
49
                 label_key     = 'description',
50
                 show_empty    = 1,
51
                 allow_textbox = 0,
52
            -%]
53
      </td>
54
     </tr>
55
     <tr>
56
      <th align="right">[% 'Project Number' | $T8 %]</th>
57
      <td colspan="3">
58
            [%- INCLUDE 'generic/multibox.html'
59
                 name          =  'project_id',
60
                 style         = "width: 250px",
61
                 DATA          =  ALL_PROJECTS,
62
                 id_key        = 'id',
63
                 label_key     = 'projectnumber',
64
                 limit         = vclimit,
65
                 show_empty    = 1,
66
                 allow_textbox = 0,
67
            -%]
68
      </td>
69
     </tr>
70
      <tr>
71
       <th align="right" nowrap>[% 'Part Number' | $T8 %]</th>
72
       <td><input name="partnumber" size="20"></td>
73
      </tr>
74
      <tr>
75
       <th align="right" nowrap>[% 'Part Description' | $T8 %]</th>
76
       <td colspan="3"><input name="description" size="40"></td>
77
      </tr>
78
     <tr>
79
      <th align=right nowrap>[% 'From' | $T8 %]</th>
80
      <td>
81
       <input name=transdatefrom id=transdatefrom size=11 title="[% dateformat | html %]" onBlur="check_right_date_format(this)">
82
       <input type=button name=transdatefrom id="trigger1" value=[% 'button' | $T8 %]>
83
      </td>
84
     <th align=right>[% 'Bis' | $T8 %]</th>
85
     <td>
86
      <input name=transdateto id=transdateto size=11 title="[% dateformat | html %]" onBlur="check_right_date_format(this)">
87
      <input type=button name=transdateto name=transdateto id="trigger2" value=[% 'button' | $T8 %]>
88
     </td>
89
    </tr>
90
   <input type=hidden name=sort value=transdate>
91
   </table>
92
    </td>
93
    </tr>
94
    <tr>
95
     <td>
96
      <table>
97
       <tr>
98
        <th align=right nowrap>[% 'Include in Report' | $T8 %]</th>
99
        <td>
100
         <table width=100%>
101
          <tr>
102
           <td align=right><input name="l_description" class=checkbox type=checkbox value=Y checked></td>
103
           <td nowrap>[% 'Description' | $T8 %]</td>
104
           <td align=right><input name="l_partnumber" class=checkbox type=checkbox value=Y></td>
105
           <td nowrap>[% 'Part Number' | $T8 %]</td>
106
           <td align=right><input name="l_invnumber" class=checkbox type=checkbox value=Y checked></td>
107
           <td nowrap>[% 'Invnumber' | $T8 %]</td>
108
           <td align=right><input name="l_transdate" class=checkbox type=checkbox value="Y" checked></td>
109
           <td nowrap>[% 'Invdate' | $T8 %]</td>
110
          </tr>
111
          <tr>
112
           <td align=right><input name="l_qty" class=checkbox type=checkbox value="Y" checked></td>
113
           <td nowrap>[% 'Quantity' | $T8 %]</td>
114
           <td align=right><input name="l_discount" class=checkbox type=checkbox value="Y"></td>
115
           <td nowrap>[% 'Discount' | $T8 %]</td>
116
           <td align=right><input name="l_unit" class=checkbox type=checkbox value="Y"></td>
117
           <td nowrap>[% 'Unit' | $T8 %]</td>
118
          </tr>
119
          <tr>
120
           <td align=right><input name="l_sellprice" class=checkbox type=checkbox value=Y checked></td>
121
           <td nowrap>[% 'Sales price' | $T8 %]</td>
122
           <td align=right><input name="l_sellprice_total" class=checkbox type=checkbox value=Y checked></td>
123
           <td nowrap>[% 'Sales price total' | $T8 %]</td>
124
           <td align=right><input name="l_lastcost" class=checkbox type=checkbox value=Y checked></td>
125
           <td nowrap>[% 'Purchase price' | $T8 %]</td>
126
           <td align=right><input name="l_lastcost_total" class=checkbox type=checkbox value=Y checked></td>
127
           <td nowrap>[% 'Purchase price total' | $T8 %]</td>
128
          </tr>
129
          <tr>
130
           <td align=right><input name="l_marge_total" class=checkbox type=checkbox value=Y checked></td>
131
           <td nowrap>[% 'Margetotal' | $T8 %]</td>
132
           <td align=right><input name="l_marge_percent" class=checkbox type=checkbox value=Y checked></td>
133
           <td nowrap>[% 'Margepercent' | $T8 %]</td>
134
          </tr>
135
          <tr>
136
           <td align=right><input name="l_subtotal" class=checkbox type=checkbox value=Y checked></td>
137
           <td nowrap>[% 'Subtotal' | $T8 %]</td>
138
           <td align=right><input name="l_total" class=checkbox type=checkbox value="Y" checked></td>
139
           <td nowrap>[% 'Total' | $T8 %]</td>
140
           <td align=right><input name="l_headers" class=checkbox type=checkbox value="Y" checked></td>
141
           <td nowrap>[% 'Headers' | $T8 %]</td>
142
          </tr>
143
          <tr>
144
            <th align="right" nowrap>[% 'Decimalplaces' | $T8 %]</th>
145
            <td colspan="4"><input name="decimalplaces" size="2" value="2"></td>
146
          </tr>
147
         </table>
148
        </td>
149
       </tr>
150
      </table>
151
     </td>
152
    </tr>
153
    <tr>
154
     <td><hr size=3 noshade></td>
155
    </tr>
156
   </table>
157
   <input type=hidden name=nextsub value=[% nextsub %]>
158
   <br>
159
   <input class=submit type=submit name=action value="[% 'Continue' | $T8 %]">
160
  </form>
161
 <script type="text/javascript">
162
 <!--
163
   Calendar.setup( { inputField : "transdatefrom", ifFormat :"[% myconfig_jsc_dateformat %]", align : "BR", button : "trigger1" });
164
   Calendar.setup( { inputField : "transdateto", ifFormat :"[% myconfig_jsc_dateformat %]", align : "BL", button : "trigger2" });
165
   $(document).ready(function(){
166
    $('customer').focus();
167
    setupDateFormat('[% dateformat | html %]','[% 'Falsches Datumsformat!' | $T8 %]');
168
    setupPoints('[% numberformat | html %]','[% 'wrongformat' | $T8 %]');
169
   })
170
 //-->
171
 </script>
172
 </body>
173
</html>
vk.pl
1
am.pl

Auch abrufbar als: Unified diff