]> wagnertech.de Git - mfinanz.git/commitdiff
Merge branch 'master' of ssh://git-jbueren@lx-office.linet-services.de/~/lx-office-erp
authorJan Büren <jan@lx-office-hosting.de>
Mon, 6 Dec 2010 11:45:31 +0000 (12:45 +0100)
committerJan Büren <jan@lx-office-hosting.de>
Mon, 6 Dec 2010 11:45:31 +0000 (12:45 +0100)
Conflicts:

doc/changelog

36 files changed:
SL/Dispatcher.pm
SL/IC.pm
SL/ReportGenerator.pm
SL/SEPA.pm
SL/SEPA/XML.pm
SL/SEPA/XML/Transaction.pm
SL/Template/Simple.pm
SL/User.pm
SL/VK.pm [new file with mode: 0644]
bin/mozilla/generictranslations.pl
bin/mozilla/sepa.pl
bin/mozilla/vk.pl [new file with mode: 0644]
css/lx-office-erp.css
doc/changelog
locale/de/all
lxo-import/addressB.php
lxo-import/import_lib.php
lxo-import/partsB.php
lxo-import/parts_import.php
lxo-import/partshead.csv [new file with mode: 0644]
menu.ini
sql/Pg-upgrade2/sepa_in.sql [new file with mode: 0644]
templates/webpages/admin/edit_user.html
templates/webpages/am/config.html
templates/webpages/ct/form_header.html
templates/webpages/generictranslations/edit_sepa_strings.html [new file with mode: 0644]
templates/webpages/sepa/bank_transfer_add.html
templates/webpages/sepa/bank_transfer_create.html
templates/webpages/sepa/bank_transfer_created.html
templates/webpages/sepa/bank_transfer_edit.html
templates/webpages/sepa/bank_transfer_list_bottom.html
templates/webpages/sepa/bank_transfer_mark_as_closed_step1.html
templates/webpages/sepa/bank_transfer_search.html
templates/webpages/vk/search_invoice.html [new file with mode: 0644]
users/partshead.csv [deleted file]
vk.pl [new symlink]

index 8bd296804c3ea087e6d47728034c0e9593448fd2..98c93d4f4092ed68eb3493f9fc471bff1fa88830 100644 (file)
@@ -155,7 +155,7 @@ sub handle_request {
       $::form->{titlebar} = "Lx-Office " . $::locale->text('Version') . " $::form->{version}";
       ::run($::auth->restore_session);
 
-    } elsif ($action) {
+    } else {
       # copy from am.pl routines
       my $session_result = $::auth->restore_session;
 
@@ -172,14 +172,15 @@ sub handle_request {
       $::auth->create_or_refresh_session;
       delete $::form->{password};
 
-      map { $::form->{$_} = $::myconfig{$_} } qw(stylesheet charset)
-        unless $action eq 'save' && $::form->{type} eq 'preferences';
-
-      $::form->set_standard_title;
-      ::call_sub('::' . $::locale->findsub($action));
+      if ($action) {
+        map { $::form->{$_} = $::myconfig{$_} } qw(stylesheet charset)
+          unless $action eq 'save' && $::form->{type} eq 'preferences';
 
-    } else {
-      $::form->error($::locale->text('action= not defined!'));
+        $::form->set_standard_title;
+        ::call_sub('::' . $::locale->findsub($action));
+      } else {
+        $::form->error($::locale->text('action= not defined!'));
+      }
     }
 
     1;
index f1840d8cbd7b1260ba76695b99618e5e6f2c5eb1..ad17036509d04c4965a6075938f228688e2a61ea 100644 (file)
--- a/SL/IC.pm
+++ b/SL/IC.pm
@@ -504,7 +504,11 @@ sub save {
         $value = $form->parse_amount($myconfig, $form->{"lastcost_$i"});
         if ($value == $form->{"old_lastcost_$i"}) 
         {
-            $lastupdate = $dbh->quote($form->{"lastupdate_$i"});
+            if ($form->{"lastupdate_$i"} eq "") { 
+                $lastupdate = 'now()';
+            } else {
+                $lastupdate = $dbh->quote($form->{"lastupdate_$i"});
+            }
         } else {
             $lastupdate = 'now()';
         }
@@ -1467,8 +1471,8 @@ sub follow_account_chain {
 
   $form->{ACCOUNT_CHAIN_BY_ID} ||= {
     map { $_->{id} => $_ }
-      selectall_hashref_query($form, $dbh, <<SQL) };
-    SELECT c.id, c.new_chart_id, ${transdate} >= c.valid_from AS is_valid, cnew.accno
+      selectall_hashref_query($form, $dbh, <<SQL, $transdate) };
+    SELECT c.id, c.new_chart_id, date(?) >= c.valid_from AS is_valid, cnew.accno
     FROM chart c
     LEFT JOIN chart cnew ON c.new_chart_id = cnew.id
     WHERE NOT c.new_chart_id IS NULL AND (c.new_chart_id > 0)
@@ -1518,7 +1522,7 @@ sub retrieve_accounts {
   if ($transdate eq "") {
     $transdate = "current_date";
   } else {
-    $transdate = 'date(' . $dbh->quote($transdate) . ')';
+    $transdate = $dbh->quote($transdate);
   }
   #/transdate
   my $inc_exp = $form->{"vc"} eq "customer" ? "income_accno_id" : "expense_accno_id";
@@ -1551,7 +1555,7 @@ SQL
     WHERE t.id IN
       (SELECT tk.tax_id
        FROM taxkeys tk
-       WHERE tk.chart_id = ? AND startdate <= ${transdate}
+       WHERE tk.chart_id = ? AND startdate <= ?
        ORDER BY startdate DESC LIMIT 1)
 SQL
 
@@ -1569,7 +1573,7 @@ SQL
 
     $form->{"${_}_accno_$index"} = $accounts{"${_}_accno"} for qw(inventory income expense);
 
-    $sth_tax->execute($accounts{$inc_exp});
+    $sth_tax->execute($accounts{$inc_exp}, quote_db_date($transdate));
     $ref = $sth_tax->fetchrow_hashref or next;
 
     $form->{"taxaccounts_$index"} = $ref->{"accno"};
index afae8633302b43e72d4495d14a8288a167bcd78e..f02f568754fda2e9176ce5374d4eddf725cb3f40 100644 (file)
@@ -425,7 +425,7 @@ sub generate_pdf_content {
   my (@data, @column_props, @cell_props);
 
   my ($data_row, $cell_props_row);
-  my @visible_columns = $self->get_visible_columns('HTML');
+  my @visible_columns = $self->get_visible_columns('PDF');
   my $num_columns     = scalar @visible_columns;
   my $num_header_rows = 1;
 
index a5fd4e1ed60049a5a71a020f0c67ba1d3868c9bf..9a2978314a66e51194747bc6f5b2b77613d451c0 100644 (file)
@@ -16,28 +16,31 @@ sub retrieve_open_invoices {
   my $form     = $main::form;
 
   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
+  my $arap     = $params{vc} eq 'customer' ? 'ar'       : 'ap';
+  my $vc       = $params{vc} eq 'customer' ? 'customer' : 'vendor';
 
   my $query =
     qq|
-       SELECT ap.id, ap.invnumber, ap.vendor_id, ap.amount AS invoice_amount, ap.invoice,
-         v.name AS vendorname, ap.duedate as duedate,
+       SELECT ${arap}.id, ${arap}.invnumber, ${arap}.${vc}_id, ${arap}.amount AS invoice_amount, ${arap}.invoice,
+         vc.name AS vcname, vc.language_id, ${arap}.duedate as duedate,
 
-         COALESCE(v.iban, '') <> '' AND COALESCE(v.bic, '') <> '' AS vendor_bank_info_ok,
+         COALESCE(vc.iban, '') <> '' AND COALESCE(vc.bic, '') <> '' AS vc_bank_info_ok,
 
-         ap.amount - ap.paid - COALESCE(open_transfers.amount, 0) AS open_amount
+         ${arap}.amount - ${arap}.paid - COALESCE(open_transfers.amount, 0) AS open_amount
 
-       FROM ap
-       LEFT JOIN vendor v ON (ap.vendor_id = v.id)
+       FROM ${arap}
+       LEFT JOIN ${vc} vc ON (${arap}.${vc}_id = vc.id)
        LEFT JOIN (SELECT sei.ap_id, SUM(sei.amount) AS amount
                   FROM sepa_export_items sei
                   LEFT JOIN sepa_export se ON (sei.sepa_export_id = se.id)
                   WHERE NOT se.closed
+                    AND (se.vc = '${vc}')
                   GROUP BY sei.ap_id)
-         AS open_transfers ON (ap.id = open_transfers.ap_id)
+         AS open_transfers ON (${arap}.id = open_transfers.ap_id)
 
-       WHERE ap.amount > (COALESCE(open_transfers.amount, 0) + ap.paid)
+       WHERE ${arap}.amount > (COALESCE(open_transfers.amount, 0) + ${arap}.paid)
 
-       ORDER BY lower(v.name) ASC, lower(ap.invnumber) ASC
+       ORDER BY lower(vc.name) ASC, lower(${arap}.invnumber) ASC
 |;
 
   my $results = selectall_hashref_query($form, $dbh, $query);
@@ -53,46 +56,49 @@ sub create_export {
   my $self     = shift;
   my %params   = @_;
 
-  Common::check_params(\%params, qw(employee bank_transfers));
+  Common::check_params(\%params, qw(employee bank_transfers vc));
 
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
+  my $arap     = $params{vc} eq 'customer' ? 'ar'       : 'ap';
+  my $vc       = $params{vc} eq 'customer' ? 'customer' : 'vendor';
+  my $ARAP     = uc $arap;
 
   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
 
   my ($export_id) = selectfirst_array_query($form, $dbh, qq|SELECT nextval('sepa_export_id_seq')|);
   my $query       =
-    qq|INSERT INTO sepa_export (id, employee_id)
+    qq|INSERT INTO sepa_export (id, employee_id, vc)
        VALUES (?, (SELECT id
                    FROM employee
-                   WHERE login = ?))|;
-  do_query($form, $dbh, $query, $export_id, $params{employee});
+                   WHERE login = ?), ?)|;
+  do_query($form, $dbh, $query, $export_id, $params{employee}, $vc);
 
   my $q_item_id = qq|SELECT nextval('id')|;
   my $h_item_id = prepare_query($form, $dbh, $q_item_id);
 
   my $q_insert =
-    qq|INSERT INTO sepa_export_items (id,          sepa_export_id,           ap_id,       chart_id,
+    qq|INSERT INTO sepa_export_items (id,          sepa_export_id,           ${arap}_id,  chart_id,
                                       amount,      requested_execution_date, reference,   end_to_end_id,
-                                      our_iban,    our_bic,                  vendor_iban, vendor_bic)
+                                      our_iban,    our_bic,                  vc_iban,     vc_bic)
        VALUES                        (?,           ?,                        ?,           ?,
                                       ?,           ?,                        ?,           ?,
                                       ?,           ?,                        ?,           ?)|;
   my $h_insert = prepare_query($form, $dbh, $q_insert);
 
   my $q_reference =
-    qq|SELECT ap.invnumber,
+    qq|SELECT arap.invnumber,
          (SELECT COUNT(at.*)
           FROM acc_trans at
           LEFT JOIN chart c ON (at.chart_id = c.id)
           WHERE (at.trans_id = ?)
-            AND (c.link LIKE '%AP_paid%'))
+            AND (c.link LIKE '%${ARAP}_paid%'))
          +
          (SELECT COUNT(sei.*)
           FROM sepa_export_items sei
           WHERE (sei.ap_id = ?))
          AS num_payments
-       FROM ap
+       FROM ${arap} arap
        WHERE id = ?|;
   my $h_reference = prepare_query($form, $dbh, $q_reference);
 
@@ -100,7 +106,7 @@ sub create_export {
 
   foreach my $transfer (@{ $params{bank_transfers} }) {
     if (!$transfer->{reference}) {
-      do_statement($form, $h_reference, $q_reference, (conv_i($transfer->{ap_id})) x 3);
+      do_statement($form, $h_reference, $q_reference, (conv_i($transfer->{"${arap}_id"})) x 3);
 
       my ($invnumber, $num_payments) = $h_reference->fetchrow_array();
       $num_payments++;
@@ -118,11 +124,11 @@ sub create_export {
     $end_to_end_id    .= $item_id;
     $end_to_end_id     = substr $end_to_end_id, 0, 35;
 
-    my @values = ($item_id,                   $export_id,
-                  conv_i($transfer->{ap_id}), conv_i($transfer->{chart_id}),
-                  $transfer->{amount},        conv_date($transfer->{requested_execution_date}),
-                  $transfer->{reference},     $end_to_end_id,
-                  map { my $pfx = $_; map { $transfer->{"${pfx}_${_}"} } qw(iban bic) } qw(our vendor));
+    my @values = ($item_id,                          $export_id,
+                  conv_i($transfer->{"${arap}_id"}), conv_i($transfer->{chart_id}),
+                  $transfer->{amount},               conv_date($transfer->{requested_execution_date}),
+                  $transfer->{reference},            $end_to_end_id,
+                  map { my $pfx = $_; map { $transfer->{"${pfx}_${_}"} } qw(iban bic) } qw(our vc));
 
     do_statement($form, $h_insert, $q_insert, @values);
   }
@@ -143,18 +149,20 @@ sub retrieve_export {
   my $self     = shift;
   my %params   = @_;
 
-  Common::check_params(\%params, qw(id));
+  Common::check_params(\%params, qw(id vc));
 
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
+  my $vc       = $params{vc} eq 'customer' ? 'customer' : 'vendor';
+  my $arap     = $params{vc} eq 'customer' ? 'ar'       : 'ap';
 
   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
 
   my ($joins, $columns);
 
   if ($params{details}) {
-    $columns = ', ap.invoice';
-    $joins   = 'LEFT JOIN ap ON (se.ap_id = ap.id)';
+    $columns = ', arap.invoice';
+    $joins   = "LEFT JOIN ${arap} arap ON (se.${arap}_id = arap.id)";
   }
 
   my $query =
@@ -170,10 +178,10 @@ sub retrieve_export {
     my ($columns, $joins);
 
     if ($params{details}) {
-      $columns = qq|, ap.invnumber, ap.invoice, v.name AS vendor_name, c.accno AS chart_accno, c.description AS chart_description|;
-      $joins   = qq|LEFT JOIN ap       ON (sei.ap_id    = ap.id)
-                    LEFT JOIN vendor v ON (ap.vendor_id = v.id)
-                    LEFT JOIN chart c  ON (sei.chart_id = c.id)|;
+      $columns = qq|, arap.invnumber, arap.invoice, arap.transdate AS reference_date, vc.name AS vc_name, c.accno AS chart_accno, c.description AS chart_description|;
+      $joins   = qq|LEFT JOIN ${arap} arap ON (sei.${arap}_id = arap.id)
+                    LEFT JOIN ${vc} vc     ON (arap.${vc}_id  = vc.id)
+                    LEFT JOIN chart c      ON (sei.chart_id   = c.id)|;
     }
 
     $query = qq|SELECT sei.*
@@ -181,6 +189,7 @@ sub retrieve_export {
                 FROM sepa_export_items sei
                 $joins
                 WHERE sei.sepa_export_id = ?|;
+
     $export->{items} = selectall_hashref_query($form, $dbh, $query, conv_i($params{id}));
 
   } else {
@@ -224,6 +233,8 @@ sub list_exports {
 
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
+  my $vc       = $params{vc} eq 'customer' ? 'customer' : 'vendor';
+  my $arap     = $params{vc} eq 'customer' ? 'ar'       : 'ap';
 
   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
 
@@ -255,16 +266,16 @@ sub list_exports {
   }
 
   if ($filter->{invnumber}) {
-    push @where_sub,  "ap.invnumber ILIKE ?";
+    push @where_sub,  "arap.invnumber ILIKE ?";
     push @values_sub, '%' . $filter->{invnumber} . '%';
-    $joins_sub{ap} = 1;
+    $joins_sub{$arap} = 1;
   }
 
-  if ($filter->{vendor}) {
-    push @where_sub,  "v.name ILIKE ?";
-    push @values_sub, '%' . $filter->{vendor} . '%';
-    $joins_sub{ap}     = 1;
-    $joins_sub{vendor} = 1;
+  if ($filter->{vc}) {
+    push @where_sub,  "vc.name ILIKE ?";
+    push @values_sub, '%' . $filter->{vc} . '%';
+    $joins_sub{$arap} = 1;
+    $joins_sub{vc}    = 1;
   }
 
   foreach my $type (qw(requested_execution execution)) {
@@ -277,8 +288,8 @@ sub list_exports {
 
   if (@where_sub) {
     my $joins_sub  = '';
-    $joins_sub    .= ' LEFT JOIN ap       ON (items.ap_id  = ap.id)' if ($joins_sub{ap});
-    $joins_sub    .= ' LEFT JOIN vendor v ON (ap.vendor_id = v.id)'  if ($joins_sub{vendor});
+    $joins_sub    .= " LEFT JOIN ${arap} arap ON (items.${arap}_id = arap.id)" if ($joins_sub{$arap});
+    $joins_sub    .= " LEFT JOIN ${vc} vc      ON (arap.${vc}_id   = vc.id)"   if ($joins_sub{vc});
 
     my $where_sub  = join(' AND ', map { "(${_})" } @where_sub);
 
@@ -291,6 +302,9 @@ sub list_exports {
     push @values, @values_sub;
   }
 
+  push @where,  'se.vc = ?';
+  push @values, $vc;
+
   my $where = ' WHERE ' . join(' AND ', map { "(${_})" } @where) if (@where);
 
   my $query =
@@ -322,6 +336,10 @@ sub post_payment {
 
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
+  my $vc       = $params{vc} eq 'customer' ? 'customer' : 'vendor';
+  my $arap     = $params{vc} eq 'customer' ? 'ar'       : 'ap';
+  my $mult     = $params{vc} eq 'customer' ? -1         : 1;
+  my $ARAP     = uc $arap;
 
   my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
 
@@ -332,17 +350,17 @@ sub post_payment {
                              FROM sepa_export_items sei
                              WHERE sei.id = ?| ],
 
-    'get_ap'         => [ qq|SELECT at.chart_id
+    'get_arap'       => [ qq|SELECT at.chart_id
                              FROM acc_trans at
                              LEFT JOIN chart c ON (at.chart_id = c.id)
                              WHERE (trans_id = ?)
-                               AND ((c.link LIKE '%:AP') OR (c.link LIKE 'AP:%') OR (c.link = 'AP'))
+                               AND ((c.link LIKE '%:${ARAP}') OR (c.link LIKE '${ARAP}:%') OR (c.link = '${ARAP}'))
                              LIMIT 1| ],
 
     'add_acc_trans'  => [ qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate, gldate,       source, memo)
                              VALUES                (?,        ?,        ?,      ?,         current_date, ?,      '')| ],
 
-    'update_ap'      => [ qq|UPDATE ap
+    'update_arap'    => [ qq|UPDATE ${arap}
                              SET paid = paid + ?
                              WHERE id = ?| ],
 
@@ -374,16 +392,16 @@ sub post_payment {
 
     next if (!$orig_item);
 
-    # Retrieve the invoice's AP chart ID.
-    do_statement($form, @{ $handles{get_ap} }, $orig_item->{ap_id});
-    my ($ap_chart_id) = $handles{get_ap}->[0]->fetchrow_array();
+    # Retrieve the invoice's AR/AP chart ID.
+    do_statement($form, @{ $handles{get_arap} }, $orig_item->{"${arap}_id"});
+    my ($arap_chart_id) = $handles{get_arap}->[0]->fetchrow_array();
 
-    # Record the payment in acc_trans offsetting AP.
-    do_statement($form, @{ $handles{add_acc_trans} }, $orig_item->{ap_id}, $ap_chart_id,           -1 * $orig_item->{amount}, $item->{execution_date}, '');
-    do_statement($form, @{ $handles{add_acc_trans} }, $orig_item->{ap_id}, $orig_item->{chart_id},      $orig_item->{amount}, $item->{execution_date}, $orig_item->{reference});
+    # Record the payment in acc_trans offsetting AR/AP.
+    do_statement($form, @{ $handles{add_acc_trans} }, $orig_item->{"${arap}_id"}, $arap_chart_id,         -1 * $mult * $orig_item->{amount}, $item->{execution_date}, '');
+    do_statement($form, @{ $handles{add_acc_trans} }, $orig_item->{"${arap}_id"}, $orig_item->{chart_id},      $mult * $orig_item->{amount}, $item->{execution_date}, $orig_item->{reference});
 
     # Update the invoice to reflect the new paid amount.
-    do_statement($form, @{ $handles{update_ap} }, $orig_item->{amount}, $orig_item->{ap_id});
+    do_statement($form, @{ $handles{update_arap} }, $orig_item->{amount}, $orig_item->{"${arap}_id"});
 
     # Update the item to reflect that it has been posted.
     do_statement($form, @{ $handles{finish_item} }, $item->{execution_date}, $item_id);
index ddac25e26eed009c48bdc112822f7a635242616a..2c7f6325317a62412c9034e414d6c8dc50b8c1be 100644 (file)
@@ -32,14 +32,15 @@ sub _init {
   $self->{src_charset}  = 'UTF-8';
   $self->{grouped}      = 0;
 
-  map { $self->{$_} = $params{$_} if (exists $params{$_}) } qw(src_charset company message_id grouped);
+  map { $self->{$_} = $params{$_} if (exists $params{$_}) } qw(src_charset company creditor_id message_id grouped collection);
 
   $self->{iconv} = SL::Iconv->new($self->{src_charset}, "UTF-8") || croak "Unsupported source charset $self->{src_charset}.";
 
   my $missing_parameter = first { !$self->{$_} } qw(company message_id);
   croak "Missing parameter: $missing_parameter" if ($missing_parameter);
+  croak "Missing parameter: creditor_id"        if !$self->{creditor_id} && $self->{collection};
 
-  map { $self->{$_} = $self->_replace_special_chars($self->{iconv}->convert($self->{$_})) } qw(company message_id);
+  map { $self->{$_} = $self->_replace_special_chars($self->{iconv}->convert($self->{$_})) } qw(company message_id creditor_id);
 }
 
 sub add_transaction {
@@ -77,7 +78,7 @@ sub _format_amount {
   my $self   = shift;
   my $amount = shift;
 
-  return sprintf '%d.%02d', int($amount), int($amount * 100) % 100;
+  return sprintf '%.02f', $amount;
 }
 
 sub _group_transactions {
@@ -116,19 +117,27 @@ sub to_xml {
                                 DATA_INDENT => 2,
                                 ENCODING    => 'utf-8');
 
-  my @now        = localtime;
-  my $time_zone  = strftime "%z", @now;
-  my $now_str    = strftime('%Y-%m-%dT%H:%M:%S', @now) . substr($time_zone, 0, 3) . ':' . substr($time_zone, 3, 2);
+  my @now       = localtime;
+  my $time_zone = strftime "%z", @now;
+  my $now_str   = strftime('%Y-%m-%dT%H:%M:%S', @now) . substr($time_zone, 0, 3) . ':' . substr($time_zone, 3, 2);
+
+  my $is_coll   = $self->{collection};
+  my $cd_src    = $is_coll ? 'Cdtr' : 'Dbtr';
+  my $cd_dst    = $is_coll ? 'Dbtr' : 'Cdtr';
+  my $pain_id   = $is_coll ? 'pain.008.002.01' : 'pain.001.001.02';
+  my $pain_elmt = $is_coll ? 'pain.008.001.01' : 'pain.001.001.02';
+  my @pii_base  = (strftime('PII%Y%m%d%H%M%S', @now), rand(1000000000));
 
   my $grouped_transactions = $self->_group_transactions();
 
   $xml->xmlDecl();
+
   $xml->startTag('Document',
-                 'xmlns'              => 'urn:sepade:xsd:pain.001.001.02.grp',
+                 'xmlns'              => "urn:swift:xsd:\$${pain_id}",
                  'xmlns:xsi'          => 'http://www.w3.org/2001/XMLSchema-instance',
-                 'xsi:schemaLocation' => 'urn:sepade:xsd:pain.001.001.02.grp pain.001.001.02.grp.xsd');
+                 'xsi:schemaLocation' => "urn:swift:xsd:\$${pain_id} ${pain_id}.xsd");
 
-  $xml->startTag('pain.001.001.02');
+  $xml->startTag($pain_elmt);
 
   $xml->startTag('GrpHdr');
   $xml->dataElement('MsgId', encode('UTF-8', substr($self->{message_id}, 0, 35)));
@@ -148,73 +157,111 @@ sub to_xml {
     my $master_transaction = $transaction_group->{transactions}->[0];
 
     $xml->startTag('PmtInf');
-    $xml->dataElement('PmtMtd', 'TRF');
+    if ($is_coll) {
+      $xml->dataElement('PmtInfId', sprintf('%s%010d', @pii_base));
+      $pii_base[1]++;
+    }
+    $xml->dataElement('PmtMtd', $is_coll ? 'DD' : 'TRF');
 
     $xml->startTag('PmtTpInf');
     $xml->startTag('SvcLvl');
     $xml->dataElement('Cd', 'SEPA');
     $xml->endTag('SvcLvl');
+
+    if ($is_coll) {
+      $xml->startTag('LclInstrm');
+      $xml->dataElement('Cd', 'CORE');
+      $xml->endTag('LclInstrm');
+      $xml->dataElement('SeqTp', 'OOFF');
+    }
     $xml->endTag('PmtTpInf');
 
-    $xml->dataElement('ReqdExctnDt', $master_transaction->get('execution_date'));
-    $xml->startTag('Dbtr');
+    $xml->dataElement($is_coll ? 'ReqdColltnDt' : 'ReqdExctnDt', $master_transaction->get('execution_date'));
+    $xml->startTag($cd_src);
     $xml->dataElement('Nm', encode('UTF-8', substr($self->{company}, 0, 70)));
-    $xml->endTag('Dbtr');
+    $xml->endTag($cd_src);
 
-    $xml->startTag('DbtrAcct');
+    $xml->startTag($cd_src . 'Acct');
     $xml->startTag('Id');
     $xml->dataElement('IBAN', $master_transaction->get('src_iban', 34));
     $xml->endTag('Id');
-    $xml->endTag('DbtrAcct');
+    $xml->endTag($cd_src . 'Acct');
 
-    $xml->startTag('DbtrAgt');
+    $xml->startTag($cd_src . 'Agt');
     $xml->startTag('FinInstnId');
     $xml->dataElement('BIC', $master_transaction->get('src_bic', 20));
     $xml->endTag('FinInstnId');
-    $xml->endTag('DbtrAgt');
+    $xml->endTag($cd_src . 'Agt');
 
     $xml->dataElement('ChrgBr', 'SLEV');
 
     foreach my $transaction (@{ $transaction_group->{transactions} }) {
-      $xml->startTag('CdtTrfTxInf');
+      $xml->startTag($is_coll ? 'DrctDbtTxInf' : 'CdtTrfTxInf');
 
       $xml->startTag('PmtId');
       $xml->dataElement('EndToEndId', $transaction->get('end_to_end_id', 35));
       $xml->endTag('PmtId');
 
-      $xml->startTag('Amt');
-      $xml->startTag('InstdAmt', 'Ccy' => 'EUR');
-      $xml->characters($self->_format_amount($transaction->{amount}));
-      $xml->endTag('InstdAmt');
-      $xml->endTag('Amt');
-
-      $xml->startTag('CdtrAgt');
+      if ($is_coll) {
+        $xml->startTag('InstdAmt', 'Ccy' => 'EUR');
+        $xml->characters($self->_format_amount($transaction->{amount}));
+        $xml->endTag('InstdAmt');
+
+        $xml->startTag('DrctDbtTx');
+
+        $xml->startTag('MndtRltdInf');
+        $xml->dataElement('MndtId', $transaction->get('reference', 35));
+        $xml->dataElement('DtOfSgntr', $transaction->get('reference_date', 2010-12-02));
+        $xml->endTag('MndtRltdInf');
+
+        $xml->startTag('CdtrSchmeId');
+        $xml->startTag('Id');
+        $xml->startTag('PrvtId');
+        $xml->startTag('OthrId');
+        $xml->dataElement('Id', encode('UTF-8', substr($self->{creditor_id}, 0, 35)));
+        $xml->dataElement('IdTp', 'SEPA');
+        $xml->endTag('OthrId');
+        $xml->endTag('PrvtId');
+        $xml->endTag('Id');
+        $xml->endTag('CdtrSchmeId');
+
+        $xml->endTag('DrctDbtTx');
+
+      } else {
+        $xml->startTag('Amt');
+        $xml->startTag('InstdAmt', 'Ccy' => 'EUR');
+        $xml->characters($self->_format_amount($transaction->{amount}));
+        $xml->endTag('InstdAmt');
+        $xml->endTag('Amt');
+      }
+
+      $xml->startTag("${cd_dst}Agt");
       $xml->startTag('FinInstnId');
       $xml->dataElement('BIC', $transaction->get('dst_bic', 20));
       $xml->endTag('FinInstnId');
-      $xml->endTag('CdtrAgt');
+      $xml->endTag("${cd_dst}Agt");
 
-      $xml->startTag('Cdtr');
-      $xml->dataElement('Nm', $transaction->get('recipient', 70));
-      $xml->endTag('Cdtr');
+      $xml->startTag("${cd_dst}");
+      $xml->dataElement('Nm', $transaction->get('company', 70));
+      $xml->endTag("${cd_dst}");
 
-      $xml->startTag('CdtrAcct');
+      $xml->startTag("${cd_dst}Acct");
       $xml->startTag('Id');
       $xml->dataElement('IBAN', $transaction->get('dst_iban', 34));
       $xml->endTag('Id');
-      $xml->endTag('CdtrAcct');
+      $xml->endTag("${cd_dst}Acct");
 
       $xml->startTag('RmtInf');
       $xml->dataElement('Ustrd', $transaction->get('reference', 140));
       $xml->endTag('RmtInf');
 
-      $xml->endTag('CdtTrfTxInf');
+      $xml->endTag($is_coll ? 'DrctDbtTxInf' : 'CdtTrfTxInf');
     }
 
     $xml->endTag('PmtInf');
   }
 
-  $xml->endTag('pain.001.001.02');
+  $xml->endTag($pain_elmt);
   $xml->endTag('Document');
 
   return $output;
index be444af8bfa2cb6312316e548ae2d031ae5209bb..83a749e375d3a0a538c759abc8b5aa72fc61ce29 100644 (file)
@@ -25,7 +25,7 @@ sub _init {
   $self->{sepa}  = $params{sepa};
   delete $params{sepa};
 
-  my $missing_parameter = first { !$params{$_} } qw(src_iban src_bic dst_iban dst_bic recipient reference amount end_to_end_id);
+  my $missing_parameter = first { !$params{$_} } qw(src_iban src_bic dst_iban dst_bic company reference amount end_to_end_id);
   croak "Missing parameter: $missing_parameter" if ($missing_parameter);
 
   $params{end_to_end_id}  ||= 'NOTPROVIDED';
@@ -35,7 +35,7 @@ sub _init {
 
   map { $self->{$_} = $self->{sepa}->{iconv}->convert($params{$_})       } keys %params;
   map { $self->{$_} =~ s/\s+//g                                          } qw(src_iban src_bic dst_iban dst_bic);
-  map { $self->{$_} = $self->{sepa}->_replace_special_chars($self->{$_}) } qw(recipient reference end_to_end_id);
+  map { $self->{$_} = $self->{sepa}->_replace_special_chars($self->{$_}) } qw(company reference end_to_end_id);
 }
 
 sub get {
index 3baeaac2d32a3d8bce59abcc2762fb8aa09342c2..d7a7c3525d7525a56d16e0cfcab817b12588e58c 100644 (file)
@@ -163,6 +163,7 @@ sub _parse_block_if {
 
   my $not           = $1;
   my $var           = $2;
+  my $comparison    = $3; # Optionaler Match um $4..$8
   my $operator_neg  = $4; # '=' oder '!' oder undef, wenn kein Vergleich erkannt
   my $operator_type = $5; # '=' oder '~' für Stringvergleich oder Regex
   my $quoted_word   = $7; # nur gültig, wenn quoted string angegeben (siehe unten); dann "value" aus <%if var == "value" %>
@@ -173,7 +174,7 @@ sub _parse_block_if {
   substr($$contents, 0, length($&)) = "";
 
   my $block;
-  ($block, $$contents) = $self->find_end($$contents, 0, $var, $not);
+  ($block, $$contents) = $self->find_end($$contents, 0, "$var $comparison", $not);
   if (!$block) {
     $self->{"error"} = "Unclosed $self->{tag_start}if$self->{tag_end}." unless ($self->{"error"});
     $main::lxdebug->leave_sub();
index 46fe855810691cc738cfbfd941f28db0a14324dc..b1a904afd09bce086f89243bde9ef1deb409ca8a 100644 (file)
@@ -1000,7 +1000,8 @@ sub config_vars {
     bestellungen rechnungen anfragen lieferantenbestellungen einkaufsrechnungen
     taxnumber co_ustid duns menustyle template_format default_media
     default_printer_id copies show_form_details favorites
-    pdonumber sdonumber hide_cvar_search_options mandatory_departments);
+    pdonumber sdonumber hide_cvar_search_options mandatory_departments
+    sepa_creditor_id);
 
   $main::lxdebug->leave_sub();
 
diff --git a/SL/VK.pm b/SL/VK.pm
new file mode 100644 (file)
index 0000000..458c351
--- /dev/null
+++ b/SL/VK.pm
@@ -0,0 +1,114 @@
+#=====================================================================
+# LX-Office ERP
+# Copyright (C) 2004
+# Based on SQL-Ledger Version 2.1.9
+# Web http://www.lx-office.org
+#
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (C) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#  Contributors:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Sold Items report
+#
+#======================================================================
+
+package VK;
+
+use SL::DBUtils;
+use SL::IO;
+use SL::MoreCommon;
+
+use strict;
+
+sub invoice_transactions {
+  $main::lxdebug->enter_sub();
+
+  my ($self, $myconfig, $form) = @_;
+
+  # connect to database
+  my $dbh = $form->get_standard_dbh($myconfig);
+
+  my @values;
+
+  my $query =
+    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 | .
+    qq|FROM invoice i | .  
+    qq|join ar on (i.trans_id = ar.id) | .
+    qq|join parts p on (i.parts_id = p.id) | .
+    qq|join customer cus on (cus.id = ar.customer_id) |;
+
+  my $where = "1 = 1";
+
+  # Stornierte Rechnungen und Stornorechnungen in invoice rausfiltern
+  $where .= " AND ar.storno is not true ";
+
+  my $sortorder = "cus.name,i.parts_id,ar.transdate";
+  if ($form->{sortby} eq 'artikelsort') {
+    $sortorder = "i.parts_id,cus.name,ar.transdate";
+  };
+
+  if ($form->{customer_id}) {
+    $where .= " AND ar.customer_id = ?";
+    push(@values, $form->{customer_id});
+  };
+  if ($form->{partnumber}) {
+    $where .= qq| AND (p.partnumber ILIKE ?)|;
+    push(@values, '%' . $form->{partnumber} . '%');
+  }
+  # nimmt man description am Besten aus invoice oder parts?
+  if ($form->{description}) {
+    $where .= qq| AND (i.description ILIKE ?)|;
+    push(@values, '%' . $form->{description} . '%');
+  }
+  if ($form->{transdatefrom}) {
+    $where .= " AND ar.transdate >= ?";
+    push(@values, $form->{transdatefrom});
+  }
+  if ($form->{transdateto}) {
+    $where .= " AND ar.transdate <= ?";
+    push(@values, $form->{transdateto});
+  }
+  if ($form->{department}) {
+    my ($null, $department_id) = split /--/, $form->{department};
+    $where .= " AND ar.department_id = ?";
+    push(@values, $department_id);
+  }
+  if ($form->{project_id}) {
+    $where .=
+      qq|AND ((ar.globalproject_id = ?) OR EXISTS | .
+      qq|  (SELECT * FROM invoice i | .
+      qq|   WHERE i.project_id = ? AND i.trans_id = ar.id))|;
+    push(@values, $form->{"project_id"}, $form->{"project_id"});
+  }
+
+  $query .= " WHERE $where ORDER BY $sortorder";
+
+  my @result = selectall_hashref_query($form, $dbh, $query, @values);
+
+  $form->{AR} = [ @result ];
+
+  $main::lxdebug->leave_sub();
+}
+
+1;
+
index 385ce80947c06ace3969c204635113ff253817b1..7b8d4a196a8d4f9358ca667ed9965d143f08fd82 100644 (file)
@@ -71,4 +71,56 @@ sub save_greetings {
   $main::lxdebug->leave_sub();
 }
 
+sub edit_sepa_strings {
+  $main::lxdebug->enter_sub();
+
+  $main::auth->assert('config');
+
+  my $form     = $main::form;
+  my $locale   = $main::locale;
+
+  $form->get_lists('languages' => 'LANGUAGES');
+
+  my $translation_list = GenericTranslations->list(translation_type => 'sepa_remittance_info_pfx');
+  my %translations     = map { ( ($_->{language_id} || 'default') => $_->{translation} ) } @{ $translation_list };
+
+  unshift @{ $form->{LANGUAGES} }, { 'id' => 'default', };
+
+  foreach my $language (@{ $form->{LANGUAGES} }) {
+    $language->{translation} = $translations{$language->{id}};
+  }
+
+  $form->{title} = $locale->text('Edit SEPA strings');
+  $form->header();
+  print $form->parse_html_template('generictranslations/edit_sepa_strings');
+
+  $main::lxdebug->leave_sub();
+}
+
+sub save_sepa_strings {
+  $main::lxdebug->enter_sub();
+
+  $main::auth->assert('config');
+
+  my $form     = $main::form;
+  my $locale   = $main::locale;
+
+  $form->get_lists('languages' => 'LANGUAGES');
+
+  unshift @{ $form->{LANGUAGES} }, { };
+
+  foreach my $language (@{ $form->{LANGUAGES} }) {
+    GenericTranslations->save('translation_type' => 'sepa_remittance_info_pfx',
+                              'translation_id'   => undef,
+                              'language_id'      => $language->{id},
+                              'translation'      => $form->{"translation__" . ($language->{id} || 'default')},);
+  }
+
+  $form->{message} = $locale->text('The SEPA strings have been saved.');
+
+  edit_sepa_strings();
+
+  $main::lxdebug->leave_sub();
+}
+
 1;
index bf220e380a1e08bc28080ccbe5db1a9de995ce08..f6041fbcde8a851a825ad5334d298dd943133083 100755 (executable)
@@ -8,6 +8,7 @@ use SL::BankAccount;
 use SL::Chart;
 use SL::CT;
 use SL::Form;
+use SL::GenericTranslations;
 use SL::ReportGenerator;
 use SL::SEPA;
 use SL::SEPA::XML;
@@ -20,8 +21,9 @@ sub bank_transfer_add {
 
   my $form          = $main::form;
   my $locale        = $main::locale;
+  my $vc            = $form->{vc} eq 'customer' ? 'customer' : 'vendor';
 
-  $form->{title}    = $locale->text('Prepare bank transfer via SEPA XML');
+  $form->{title}    = $vc eq 'customer' ? $::locale->text('Prepare bank collection via SEPA XML') : $locale->text('Prepare bank transfer via SEPA XML');
 
   my $bank_accounts = SL::BankAccount->list();
 
@@ -29,7 +31,7 @@ sub bank_transfer_add {
     $form->error($locale->text('You have not added bank accounts yet.'));
   }
 
-  my $invoices = SL::SEPA->retrieve_open_invoices();
+  my $invoices = SL::SEPA->retrieve_open_invoices(vc => $vc);
 
   if (!scalar @{ $invoices }) {
     $form->show_generic_information($locale->text('Either there are no open invoices, or you have already initiated bank transfers ' .
@@ -40,11 +42,22 @@ sub bank_transfer_add {
 
   my $bank_account_label_sub = sub { $locale->text('Account number #1, bank code #2, #3', $_[0]->{account_number}, $_[0]->{bank_code}, $_[0]->{bank}) };
 
+  my $translation_list = GenericTranslations->list(translation_type => 'sepa_remittance_info_pfx');
+  my %translations     = map { ( ($_->{language_id} || 'default') => $_->{translation} ) } @{ $translation_list };
+
+  foreach my $invoice (@{ $invoices }) {
+    my $prefix                    = $translations{ $invoice->{language_id} } || $translations{default} || $::locale->text('Invoice');
+    $prefix                      .= ' ' unless $prefix =~ m/ $/;
+    $invoice->{reference_prefix}  = $prefix;
+  }
+
   $form->header();
   print $form->parse_html_template('sepa/bank_transfer_add',
                                    { 'INVOICES'           => $invoices,
                                      'BANK_ACCOUNTS'      => $bank_accounts,
-                                     'bank_account_label' => $bank_account_label_sub, });
+                                     'bank_account_label' => $bank_account_label_sub,
+                                     'vc'                 => $vc,
+                                   });
 
   $main::lxdebug->leave_sub();
 }
@@ -55,8 +68,9 @@ sub bank_transfer_create {
   my $form          = $main::form;
   my $locale        = $main::locale;
   my $myconfig      = \%main::myconfig;
+  my $vc            = $form->{vc} eq 'customer' ? 'customer' : 'vendor';
 
-  $form->{title}    = $locale->text('Create bank transfer via SEPA XML');
+  $form->{title}    = $vc eq 'customer' ? $::locale->text('Create bank collection via SEPA XML') : $locale->text('Create bank transfer via SEPA XML');
 
   my $bank_accounts = SL::BankAccount->list();
 
@@ -70,11 +84,13 @@ sub bank_transfer_create {
     $form->error($locale->text('The selected bank account does not exist anymore.'));
   }
 
-  my $invoices       = SL::SEPA->retrieve_open_invoices();
+  my $arap_id        = $vc eq 'customer' ? 'ar_id' : 'ap_id';
+  my $invoices       = SL::SEPA->retrieve_open_invoices(vc => $vc);
+
   my %invoices_map   = map { $_->{id} => $_ } @{ $invoices };
   my @bank_transfers =
-    map  +{ %{ $invoices_map{ $_->{ap_id} } }, %{ $_ } },
-    grep  { $_->{selected} && (0 < $_->{amount}) && $invoices_map{ $_->{ap_id} } }
+    map  +{ %{ $invoices_map{ $_->{$arap_id} } }, %{ $_ } },
+    grep  { $_->{selected} && (0 < $_->{amount}) && $invoices_map{ $_->{$arap_id} } }
     map   { $_->{amount} = $form->parse_amount($myconfig, $_->{amount}); $_ }
           @{ $form->{bank_transfers} || [] };
 
@@ -82,13 +98,13 @@ sub bank_transfer_create {
     $form->error($locale->text('You have selected none of the invoices.'));
   }
 
-  my ($vendor_bank_info);
+  my ($vc_bank_info);
   my $error_message;
 
   if ($form->{confirmation}) {
-    $vendor_bank_info = { map { $_->{id} => $_ } @{ $form->{vendor_bank_info} || [] } };
+    $vc_bank_info = { map { $_->{id} => $_ } @{ $form->{vc_bank_info} || [] } };
 
-    foreach my $info (values %{ $vendor_bank_info }) {
+    foreach my $info (values %{ $vc_bank_info }) {
       if (any { !$info->{$_} } qw(iban bic)) {
         $error_message = $locale->text('The bank information must not be empty.');
         last;
@@ -97,10 +113,10 @@ sub bank_transfer_create {
   }
 
   if ($error_message || !$form->{confirmation}) {
-    my @vendor_ids             = uniq map { $_->{vendor_id} } @bank_transfers;
-    $vendor_bank_info        ||= CT->get_bank_info('vc' => 'vendor',
-                                                   'id' => \@vendor_ids);
-    my @vendor_bank_info       = sort { lc $a->{name} cmp lc $b->{name} } values %{ $vendor_bank_info };
+    my @vc_ids                 = uniq map { $_->{"${vc}_id"} } @bank_transfers;
+    $vc_bank_info            ||= CT->get_bank_info('vc' => $vc,
+                                                   'id' => \@vc_ids);
+    my @vc_bank_info           = sort { lc $a->{name} cmp lc $b->{name} } values %{ $vc_bank_info };
 
     my $bank_account_label_sub = sub { $locale->text('Account number #1, bank code #2, #3', $_[0]->{account_number}, $_[0]->{bank_code}, $_[0]->{bank}) };
 
@@ -110,27 +126,29 @@ sub bank_transfer_create {
     print $form->parse_html_template('sepa/bank_transfer_create',
                                      { 'BANK_TRANSFERS'     => \@bank_transfers,
                                        'BANK_ACCOUNTS'      => $bank_accounts,
-                                       'VENDOR_BANK_INFO'   => \@vendor_bank_info,
+                                       'VC_BANK_INFO'       => \@vc_bank_info,
                                        'bank_account'       => $bank_account,
                                        'bank_account_label' => $bank_account_label_sub,
                                        'error_message'      => $error_message,
+                                       'vc'                 => $vc,
                                      });
 
   } else {
     foreach my $bank_transfer (@bank_transfers) {
       foreach (qw(iban bic)) {
-        $bank_transfer->{"vendor_${_}"} = $vendor_bank_info->{ $bank_transfer->{vendor_id} }->{$_};
-        $bank_transfer->{"our_${_}"}    = $bank_account->{$_};
+        $bank_transfer->{"vc_${_}"}  = $vc_bank_info->{ $bank_transfer->{"${vc}_id"} }->{$_};
+        $bank_transfer->{"our_${_}"} = $bank_account->{$_};
       }
 
       $bank_transfer->{chart_id} = $bank_account->{chart_id};
     }
 
     my $id = SL::SEPA->create_export('employee'       => $form->{login},
-                                     'bank_transfers' => \@bank_transfers);
+                                     'bank_transfers' => \@bank_transfers,
+                                     'vc'             => $vc);
 
     $form->header();
-    print $form->parse_html_template('sepa/bank_transfer_created', { 'id' => $id });
+    print $form->parse_html_template('sepa/bank_transfer_created', { 'id' => $id, 'vc' => $vc });
   }
 
   $main::lxdebug->leave_sub();
@@ -141,12 +159,13 @@ sub bank_transfer_search {
 
   my $form   = $main::form;
   my $locale = $main::locale;
+  my $vc     = $form->{vc} eq 'customer' ? 'customer' : 'vendor';
 
-  $form->{title}    = $locale->text('List of bank transfers');
+  $form->{title}    = $vc eq 'customer' ? $::locale->text('List of bank collections') : $locale->text('List of bank transfers');
   $form->{jsscript} = 1;
 
   $form->header();
-  print $form->parse_html_template('sepa/bank_transfer_search');
+  print $form->parse_html_template('sepa/bank_transfer_search', { vc => $vc });
 
   $main::lxdebug->leave_sub();
 }
@@ -158,17 +177,18 @@ sub bank_transfer_list {
   my $form   = $main::form;
   my $locale = $main::locale;
   my $cgi    = $main::cgi;
+  my $vc     = $form->{vc} eq 'customer' ? 'customer' : 'vendor';
 
-  $form->{title}     = $locale->text('List of bank transfers');
+  $form->{title}     = $vc eq 'customer' ? $::locale->text('List of bank collections') : $locale->text('List of bank transfers');
 
   $form->{sort}    ||= 'id';
   $form->{sortdir}   = '1' if (!defined $form->{sortdir});
 
-  $form->{callback}  = build_std_url('action=bank_transfer_list', 'sort', 'sortdir');
+  $form->{callback}  = build_std_url('action=bank_transfer_list', 'sort', 'sortdir', 'vc');
 
   my %filter         = map  +( $_ => $form->{"f_${_}"} ),
                        grep  { $form->{"f_${_}"} }
-                             (qw(vendor invnumber),
+                             (qw(vc invnumber),
                               map { ("${_}_date_from", "${_}_date_to") }
                                   qw(export requested_execution execution));
   $filter{executed}  = $form->{l_executed} ? 1 : 0 if ($form->{l_executed} != $form->{l_not_executed});
@@ -176,13 +196,14 @@ sub bank_transfer_list {
 
   my $exports        = SL::SEPA->list_exports('filter'    => \%filter,
                                               'sortorder' => $form->{sort},
-                                              'sortdir'   => $form->{sortdir});
+                                              'sortdir'   => $form->{sortdir},
+                                              'vc'        => $vc);
 
   my $open_available = any { !$_->{closed} } @{ $exports };
 
   my $report         = SL::ReportGenerator->new(\%main::myconfig, $form);
 
-  my @hidden_vars    = grep { m/^[fl]_/ && $form->{$_} } keys %{ $form };
+  my @hidden_vars    = ('vc', grep { m/^[fl]_/ && $form->{$_} } keys %{ $form });
 
   my $href           = build_std_url('action=bank_transfer_list', @hidden_vars);
 
@@ -202,12 +223,12 @@ sub bank_transfer_list {
     $column_defs{$name}->{link} = $href . "&sort=$name&sortdir=$sortdir";
   }
 
-  $column_defs{selected}->{visible} = $open_available                                ? 1 : 0;
+  $column_defs{selected}->{visible} = $open_available                                ? 'HTML' : 0;
   $column_defs{executed}->{visible} = $form->{l_executed} && $form->{l_not_executed} ? 1 : 0;
   $column_defs{closed}->{visible}   = $form->{l_closed}   && $form->{l_open}         ? 1 : 0;
 
   my @options = ();
-  push @options, $locale->text('Vendor')                        . ' : ' . $form->{f_vendor}                        if ($form->{f_vendor});
+  push @options, ($vc eq 'customer' ? $::locale->text('Customer') : $locale->text('Vendor')) . ' : ' . $form->{f_vc} if ($form->{f_vc});
   push @options, $locale->text('Invoice number')                . ' : ' . $form->{f_invnumber}                     if ($form->{f_invnumber});
   push @options, $locale->text('Export date from')              . ' : ' . $form->{f_export_date_from}              if ($form->{f_export_date_from});
   push @options, $locale->text('Export date to')                . ' : ' . $form->{f_export_date_to}                if ($form->{f_export_date_to});
@@ -220,7 +241,7 @@ sub bank_transfer_list {
 
   $report->set_options('top_info_text'         => join("\n", @options),
                        'raw_top_info_text'     => $form->parse_html_template('sepa/bank_transfer_list_top'),
-                       'raw_bottom_info_text'  => $form->parse_html_template('sepa/bank_transfer_list_bottom', { 'show_buttons' => $open_available }),
+                       'raw_bottom_info_text'  => $form->parse_html_template('sepa/bank_transfer_list_bottom', { 'show_buttons' => $open_available, vc => $vc }),
                        'std_column_visibility' => 1,
                        'output_format'         => 'HTML',
                        'title'                 => $form->{title},
@@ -240,7 +261,7 @@ sub bank_transfer_list {
 
     map { $row->{$_}->{data} = $export->{$_} ? $locale->text('yes') : $locale->text('no') } qw(executed closed);
 
-    $row->{id}->{link} = $edit_url . '&id=' . E($export->{id});
+    $row->{id}->{link} = $edit_url . '&id=' . E($export->{id}) . '&vc=' . E($vc);
 
     if (!$export->{closed}) {
       $row->{selected}->{raw_data} =
@@ -261,6 +282,7 @@ sub bank_transfer_edit {
 
   my $form   = $main::form;
   my $locale = $main::locale;
+  my $vc     = $form->{vc} eq 'customer' ? 'customer' : 'vendor';
 
   my @ids    = ();
   if (!$form->{mode} || ($form->{mode} eq 'single')) {
@@ -276,7 +298,7 @@ sub bank_transfer_edit {
   my $export;
 
   foreach my $id (@ids) {
-    my $curr_export = SL::SEPA->retrieve_export('id' => $id, 'details' => 1);
+    my $curr_export = SL::SEPA->retrieve_export('id' => $id, 'details' => 1, 'vc' => $vc);
 
     foreach my $item (@{ $curr_export->{items} }) {
       map { $item->{"export_${_}"} = $curr_export->{$_} } grep { !ref $curr_export->{$_} } keys %{ $curr_export };
@@ -318,6 +340,7 @@ sub bank_transfer_post_payments {
 
   my $form   = $main::form;
   my $locale = $main::locale;
+  my $vc     = $form->{vc} eq 'customer' ? 'customer' : 'vendor';
 
   my @items  = grep { $_->{selected} } @{ $form->{items} || [] };
 
@@ -325,7 +348,7 @@ sub bank_transfer_post_payments {
     $form->show_generic_error($locale->text('You have not selected any item.'), 'back_button' => 1);
   }
   my @export_ids    = uniq map { $_->{sepa_export_id} } @items;
-  my %exports       = map { $_ => SL::SEPA->retrieve_export('id' => $_, 'details' => 1) } @export_ids;
+  my %exports       = map { $_ => SL::SEPA->retrieve_export('id' => $_, 'details' => 1, vc => $vc) } @export_ids;
   my @items_to_post = ();
 
   foreach my $item (@items) {
@@ -343,7 +366,7 @@ sub bank_transfer_post_payments {
     $form->show_generic_error($locale->text('You have to specify an execution date for each antry.'), 'back_button' => 1);
   }
 
-  SL::SEPA->post_payment('items' => \@items_to_post);
+  SL::SEPA->post_payment('items' => \@items_to_post, vc => $vc);
 
   $form->show_generic_information($locale->text('The payments have been posted.'));
 
@@ -356,13 +379,14 @@ sub bank_transfer_payment_list_as_pdf {
   my $form       = $main::form;
   my %myconfig   = %main::myconfig;
   my $locale     = $main::locale;
+  my $vc         = $form->{vc} eq 'customer' ? 'customer' : 'vendor';
 
   my @ids        = @{ $form->{items} || [] };
   my @export_ids = uniq map { $_->{export_id} } @ids;
 
   $form->show_generic_error($locale->text('Multi mode not supported.'), 'back_button' => 1) if 1 != scalar @export_ids;
 
-  my $export = SL::SEPA->retrieve_export('id' => $export_ids[0], 'details' => 1);
+  my $export = SL::SEPA->retrieve_export('id' => $export_ids[0], 'details' => 1, vc => $vc);
   my @items  = ();
 
   foreach my $id (@ids) {
@@ -375,25 +399,25 @@ sub bank_transfer_payment_list_as_pdf {
   my $report         =  SL::ReportGenerator->new(\%main::myconfig, $form);
 
   my %column_defs    =  (
-    'invnumber'      => { 'text' => $locale->text('Invoice'), },
-    'vendor_name'    => { 'text' => $locale->text('Vendor'), },
-    'our_iban'       => { 'text' => $locale->text('Source IBAN'), },
-    'our_bic'        => { 'text' => $locale->text('Source BIC'), },
-    'vendor_iban'    => { 'text' => $locale->text('Destination IBAN'), },
-    'vendor_bic'     => { 'text' => $locale->text('Destination BIC'), },
-    'amount'         => { 'text' => $locale->text('Amount'), },
-    'reference'      => { 'text' => $locale->text('Reference'), },
-    'execution_date' => { 'text' => $locale->text('Execution date'), },
+    'invnumber'      => { 'text' => $locale->text('Invoice'),                                                                  },
+    'vc_name'        => { 'text' => $vc eq 'customer' ? $locale->text('Customer')         : $locale->text('Vendor'),           },
+    'our_iban'       => { 'text' => $vc eq 'customer' ? $locale->text('Destination IBAN') : $locale->text('Source IBAN'),      },
+    'our_bic'        => { 'text' => $vc eq 'customer' ? $locale->text('Destination BIC')  : $locale->text('Source BIC'),       },
+    'vc_iban'        => { 'text' => $vc eq 'customer' ? $locale->text('Source IBAN')      : $locale->text('Destination IBAN'), },
+    'vc_bic'         => { 'text' => $vc eq 'customer' ? $locale->text('Source BIC')       : $locale->text('Destination BIC'),  },
+    'amount'         => { 'text' => $locale->text('Amount'),                                                                   },
+    'reference'      => { 'text' => $locale->text('Reference'),                                                                },
+    'execution_date' => { 'text' => $locale->text('Execution date'),                                                           },
   );
 
   map { $column_defs{$_}->{align} = 'right' } qw(amount execution_date);
 
-  my @columns        =  qw(invnumber vendor_name our_iban our_bic vendor_iban vendor_bic amount reference execution_date);
+  my @columns        =  qw(invnumber vc_name our_iban our_bic vc_iban vc_bic amount reference execution_date);
 
   $report->set_options('std_column_visibility' => 1,
                        'output_format'         => 'PDF',
-                       'title'                 => $locale->text('Bank transfer payment list for export #1', $export->{id}),
-                       'attachment_basename'   => $locale->text('bank_transfer_payment_list_#1', $export->{id}) . strftime('_%Y%m%d', localtime time),
+                       'title'                 =>  $vc eq 'customer' ? $locale->text('Bank collection payment list for export #1', $export->{id}) : $locale->text('Bank transfer payment list for export #1', $export->{id}),
+                       'attachment_basename'   => ($vc eq 'customer' ? $locale->text('bank_collection_payment_list_#1', $export->{id}) : $locale->text('bank_transfer_payment_list_#1', $export->{id})) . strftime('_%Y%m%d', localtime time),
     );
 
   $report->set_columns(%column_defs);
@@ -411,6 +435,7 @@ sub bank_transfer_payment_list_as_pdf {
   $main::lxdebug->leave_sub();
 }
 
+# TODO
 sub bank_transfer_download_sepa_xml {
   $main::lxdebug->enter_sub();
 
@@ -418,11 +443,16 @@ sub bank_transfer_download_sepa_xml {
   my $myconfig = \%main::myconfig;
   my $locale   =  $main::locale;
   my $cgi      =  $main::cgi;
+  my $vc       = $form->{vc} eq 'customer' ? 'customer' : 'vendor';
 
   if (!$myconfig->{company}) {
     $form->show_generic_error($locale->text('You have to enter a company name in your user preferences (see the "Program" menu, "Preferences").'), 'back_button' => 1);
   }
 
+  if (($vc eq 'customer') && !$myconfig->{sepa_creditor_id}) {
+    $form->show_generic_error($locale->text('You have to enter the SEPA creditor ID in your user preferences (see the "Program" menu, "Preferences").'), 'back_button' => 1);
+  }
+
   my @ids;
   if ($form->{mode} && ($form->{mode} eq 'multi')) {
      @ids = map $_->{id}, grep { $_->{selected} } @{ $form->{exports} || [] };
@@ -438,7 +468,7 @@ sub bank_transfer_download_sepa_xml {
   my @items = ();
 
   foreach my $id (@ids) {
-    my $export = SL::SEPA->retrieve_export('id' => $id, 'details' => 1);
+    my $export = SL::SEPA->retrieve_export('id' => $id, 'details' => 1, vc => $vc);
     push @items, grep { !$_->{executed} } @{ $export->{items} } if ($export && !$export->{closed});
   }
 
@@ -449,9 +479,11 @@ sub bank_transfer_download_sepa_xml {
   my $message_id = strftime('MSG%Y%m%d%H%M%S', localtime) . sprintf('%06d', $$);
 
   my $sepa_xml   = SL::SEPA::XML->new('company'     => $myconfig->{company},
+                                      'creditor_id' => $myconfig->{sepa_creditor_id},
                                       'src_charset' => $main::dbcharset || 'ISO-8859-15',
                                       'message_id'  => $message_id,
                                       'grouped'     => 1,
+                                      'collection'  => $vc eq 'customer',
     );
 
   foreach my $item (@items) {
@@ -461,13 +493,19 @@ sub bank_transfer_download_sepa_xml {
       $requested_execution_date = sprintf '%04d-%02d-%02d', $yy, $mm, $dd;
     }
 
+    if ($vc eq 'customer') {
+      my ($yy, $mm, $dd)      = $locale->parse_date($myconfig, $item->{reference_date});
+      $item->{reference_date} = sprintf '%04d-%02d-%02d', $yy, $mm, $dd;
+    }
+
     $sepa_xml->add_transaction({ 'src_iban'       => $item->{our_iban},
                                  'src_bic'        => $item->{our_bic},
-                                 'dst_iban'       => $item->{vendor_iban},
-                                 'dst_bic'        => $item->{vendor_bic},
-                                 'recipient'      => $item->{vendor_name},
+                                 'dst_iban'       => $item->{vc_iban},
+                                 'dst_bic'        => $item->{vc_bic},
+                                 'company'        => $item->{vc_name},
                                  'amount'         => $item->{amount},
                                  'reference'      => $item->{reference},
+                                 'reference_date' => $item->{reference_date},
                                  'execution_date' => $requested_execution_date,
                                  'end_to_end_id'  => $item->{end_to_end_id} });
   }
@@ -475,7 +513,7 @@ sub bank_transfer_download_sepa_xml {
   my $xml = $sepa_xml->to_xml();
 
   print $cgi->header('-type'                => 'application/octet-stream',
-                     '-content-disposition' => 'attachment; filename="SEPA_' . $message_id . '.cct"',
+                     '-content-disposition' => 'attachment; filename="SEPA_' . $message_id . ($vc eq 'customer' ? '.cdd' : '.cct') . '"',
                      '-content-length'      => length $xml);
   print $xml;
 
@@ -487,6 +525,7 @@ sub bank_transfer_mark_as_closed_step1 {
 
   my $form       = $main::form;
   my $locale     = $main::locale;
+  my $vc         = $form->{vc} eq 'customer' ? 'customer' : 'vendor';
 
   my @export_ids = map { $_->{id} } grep { $_->{selected} } @{ $form->{exports} || [] };
 
@@ -496,7 +535,7 @@ sub bank_transfer_mark_as_closed_step1 {
 
   my @open_export_ids = ();
   foreach my $id (@export_ids) {
-    my $export = SL::SEPA->retrieve_export('id' => $id);
+    my $export = SL::SEPA->retrieve_export('id' => $id, vc => $vc);
     push @open_export_ids, $id if (!$export->{closed});
   }
 
@@ -506,7 +545,7 @@ sub bank_transfer_mark_as_closed_step1 {
 
   $form->{title} = $locale->text('Close SEPA exports');
   $form->header();
-  print $form->parse_html_template('sepa/bank_transfer_mark_as_closed_step1', { 'OPEN_EXPORT_IDS' => \@open_export_ids });
+  print $form->parse_html_template('sepa/bank_transfer_mark_as_closed_step1', { 'OPEN_EXPORT_IDS' => \@open_export_ids, vc => $vc });
 
   $main::lxdebug->leave_sub();
 }
diff --git a/bin/mozilla/vk.pl b/bin/mozilla/vk.pl
new file mode 100644 (file)
index 0000000..dbbc2bd
--- /dev/null
@@ -0,0 +1,392 @@
+#=====================================================================
+# LX-Office ERP
+# Copyright (C) 2004
+# Based on SQL-Ledger Version 2.1.9
+# Web http://www.lx-office.org
+#
+#=====================================================================
+# SQL-Ledger Accounting
+# Copyright (c) 2001
+#
+#  Author: Dieter Simader
+#   Email: dsimader@sql-ledger.org
+#     Web: http://www.sql-ledger.org
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#======================================================================
+#
+# Sales report
+#
+#======================================================================
+
+use POSIX qw(strftime);
+use List::Util qw(sum first);
+
+use SL::VK;
+use SL::ReportGenerator;
+use Data::Dumper;
+
+require "bin/mozilla/arap.pl";
+require "bin/mozilla/common.pl";
+require "bin/mozilla/drafts.pl";
+require "bin/mozilla/reportgenerator.pl";
+
+use strict;
+
+
+sub search_invoice {
+  $main::lxdebug->enter_sub();
+  $main::auth->assert('general_ledger | invoice_edit');
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
+  my $cgi      = $main::cgi;
+
+  my ($customer, $department);
+
+  # setup customer selection
+  $form->all_vc(\%myconfig, "customer", "AR");
+
+  $form->{title}    = $locale->text('Sales Report');
+  $form->{jsscript} = 1;
+
+  $form->get_lists("projects"     => { "key" => "ALL_PROJECTS", "all" => 1 },
+                   "departments"  => "ALL_DEPARTMENTS",
+                   "customers"    => "ALL_VC");
+
+  $form->{vc_keys}   = sub { "$_[0]->{name}--$_[0]->{id}" };
+
+  $form->header;
+  print $form->parse_html_template('vk/search_invoice', { %myconfig });
+
+  $main::lxdebug->leave_sub();
+}
+
+sub invoice_transactions {
+  $main::lxdebug->enter_sub();
+
+  $main::auth->assert('general_ledger | invoice_edit');
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+  my $locale   = $main::locale;
+
+  my ($callback, $href, @columns);
+
+  $form->{customer} = $form->unescape($form->{customer});
+  
+  ($form->{customername}, $form->{customer_id}) = split(/--/, $form->{customer});
+
+  # decimalplaces überprüfen oder auf Default 2 setzen
+  $form->{decimalplaces} = 2 unless $form->{decimalplaces} > 0 && $form->{decimalplaces} < 6;
+
+#  report_generator_set_default_sort('transdate', 1);
+
+  VK->invoice_transactions(\%myconfig, \%$form);
+
+  # anhand von radio button die Sortierreihenfolge festlegen
+  if ($form->{sortby} eq 'artikelsort') {
+    $form->{'mainsort'} = 'parts_id';
+    $form->{'subsort'}  = 'name';
+  } else {
+    $form->{'mainsort'} = 'name';
+    $form->{'subsort'}  = 'parts_id';
+  };
+
+  $form->{title} = $locale->text('Sales Report');
+
+  @columns =
+    qw(description invnumber partnumber parts_id transdate qty unit sellprice sellprice_total discount lastcost lastcost_total marge_total marge_percent);
+
+  # hidden variables für pdf/csv export übergeben
+  # einmal mit l_ um zu bestimmen welche Spalten ausgegeben werden sollen
+  # einmal optionen für die Überschrift (z.B. transdatefrom, partnumber, ...)
+  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);
+  my @hidden_nondefault = grep({ $form->{$_} } @hidden_variables);
+  # Variablen werden dann als Hidden Variable mitgegeben, z.B.
+  # <input type="hidden" name="report_generator_hidden_transdateto" value="21.05.2010">
+
+  $href = build_std_url('action=invoice_transactions', grep { $form->{$_} } @hidden_variables);
+  # href = vk.pl?action=invoice_transactions&l_headers=Y&l_subtotal=Y&l_total=Y&transdatefrom=04.03.2010 ...
+
+  my %column_defs = (
+    'description'             => { 'text' => $locale->text('Description'), },
+    'partnumber'              => { 'text' => $locale->text('Part Number'), },
+    'invnumber'               => { 'text' => $locale->text('Invoice Number'), },
+    'transdate'               => { 'text' => $locale->text('Invoice Date'), },
+    'qty'                     => { 'text' => $locale->text('Quantity'), },
+    'unit'                    => { 'text' => $locale->text('Unit'), },
+    'sellprice'               => { 'text' => $locale->text('Sales price'), },
+    'sellprice_total'         => { 'text' => $locale->text('Sales net amount'), },
+    'lastcost_total'          => { 'text' => $locale->text('Purchase net amount'), },
+    'discount'                => { 'text' => $locale->text('Discount'), },
+    'lastcost'                => { 'text' => $locale->text('Purchase price'), },
+    'marge_total'             => { 'text' => $locale->text('Sales margin'), },
+    'marge_percent'           => { 'text' => $locale->text('Sales margin %'), },
+  );
+  
+  my %column_alignment = map { $_ => 'right' } qw(lastcost sellprice sellprice_total lastcost_total unit discount marge_total marge_percent qty);
+
+  $form->{"l_type"} = "Y";
+  map { $column_defs{$_}->{visible} = $form->{"l_${_}"} ? 1 : 0 } @columns;
+
+
+  my @options;
+  if ($form->{description}) {
+    push @options, $locale->text('description') . " : $form->{description}";
+  }
+  if ($form->{customer}) {
+    push @options, $locale->text('Customer') . " : $form->{customername}";
+  }
+  if ($form->{department}) {
+    my ($department) = split /--/, $form->{department};
+    push @options, $locale->text('Department') . " : $department";
+  }
+  if ($form->{invnumber}) {
+    push @options, $locale->text('Invoice Number') . " : $form->{invnumber}";
+  }
+  if ($form->{invdate}) {
+    push @options, $locale->text('Invoice Date') . " : $form->{invdate}";
+  }
+  if ($form->{partnumber}) {
+    push @options, $locale->text('Part Number') . " : $form->{partnumber}";
+  }
+  if ($form->{ordnumber}) {
+    push @options, $locale->text('Order Number') . " : $form->{ordnumber}";
+  }
+  if ($form->{notes}) {
+    push @options, $locale->text('Notes') . " : $form->{notes}";
+  }
+  if ($form->{transaction_description}) {
+    push @options, $locale->text('Transaction description') . " : $form->{transaction_description}";
+  }
+  if ($form->{transdatefrom}) {
+    push @options, $locale->text('From') . " " . $locale->date(\%myconfig, $form->{transdatefrom}, 1);
+  }
+  if ($form->{transdateto}) {
+    push @options, $locale->text('Bis') . " " . $locale->date(\%myconfig, $form->{transdateto}, 1);
+  }
+
+  my $report = SL::ReportGenerator->new(\%myconfig, $form);
+
+  $report->set_options('top_info_text'        => join("\n", @options),
+                       'output_format'        => 'HTML',
+                       'title'                => $form->{title},
+                       'attachment_basename'  => $locale->text('sales_report') . strftime('_%Y%m%d', localtime time),
+    );
+  $report->set_options_from_form();
+
+  $report->set_columns(%column_defs);
+  $report->set_column_order(@columns);
+
+  $report->set_export_options('invoice_transactions', @hidden_variables, qw(mainsort sortdir));
+
+  $report->set_sort_indicator($form->{mainsort}, $form->{sortdir});
+
+  # add sort and escape callback, this one we use for the add sub
+  $form->{callback} = $href .= "&sort=$form->{mainsort}";
+
+  # escape callback for href
+  $callback = $form->escape($href);
+
+  my @subtotal_columns = qw(qty sellprice sellprice_total lastcost lastcost_total marge_total marge_percent discount);
+  # Gesamtsumme:
+  # Summe von sellprice_total, lastcost_total und marge_total
+  # Durchschnitt von marge_percent
+  my @total_columns = qw(sellprice_total lastcost_total marge_total marge_percent );
+
+  my %totals    = map { $_ => 0 } @total_columns;
+  my %subtotals1 = map { $_ => 0 } @subtotal_columns;
+  my %subtotals2 = map { $_ => 0 } @subtotal_columns;
+
+  my $idx = 0;
+
+  foreach my $ar (@{ $form->{AR} }) {
+
+    $ar->{price_factor} = 1 unless $ar->{price_factor};
+    # calculate individual sellprice
+    # discount was already accounted for in db sellprice
+    $ar->{sellprice} = $ar->{sellprice} / $ar->{price_factor};
+    $ar->{lastcost} = $ar->{lastcost} / $ar->{price_factor};
+    $ar->{sellprice_total} = $ar->{qty} * $ar->{sellprice};
+    $ar->{lastcost_total}  = $ar->{qty} * $ar->{lastcost}; 
+    # marge_percent wird neu berechnet, da Wert in invoice leer ist (Bug)
+    $ar->{marge_percent} = $ar->{sellprice_total} ? (($ar->{sellprice_total}-$ar->{lastcost_total}) / $ar->{sellprice_total}) : 0;
+    # marge_total neu berechnen
+    $ar->{marge_total} = $ar->{sellprice_total} ? $ar->{sellprice_total}-$ar->{lastcost_total}  : 0;
+    $ar->{discount} *= 100;  # für Ausgabe formatieren, 10% stored as 0.1 in db
+
+    # Anfangshauptüberschrift
+    if ( $form->{l_headers} eq "Y" && ( $idx == 0 or $ar->{ $form->{'mainsort'} } ne $form->{AR}->[$idx - 1]->{ $form->{'mainsort'} } )) {
+      my $name;
+      my $headerrow;
+      if ( $form->{mainsort} eq 'parts_id' ) {
+       $headerrow->{description}->{data} = "$ar->{description}";
+      } else {
+       $headerrow->{description}->{data} = "$ar->{name}";
+      };
+      $headerrow->{description}->{class} = "listmainsortheader";
+      my $headerrow_set = [ $headerrow ];
+      $report->add_data($headerrow_set);
+
+      # add empty row after main header
+#      my $emptyheaderrow->{description}->{data} = ""; 
+#      $emptyheaderrow->{description}->{class} = "listmainsortheader";
+#      my $emptyheaderrow_set = [ $emptyheaderrow ];
+#      $report->add_data($emptyheaderrow_set) if $form->{l_headers} eq "Y"; 
+    };
+
+    # subsort überschriften
+    if ( $idx == 0 
+      or $ar->{ $form->{'subsort'} }  ne $form->{AR}->[$idx - 1]->{ $form->{'subsort'} }
+      or $ar->{ $form->{'mainsort'} } ne $form->{AR}->[$idx - 1]->{ $form->{'mainsort'} }
+    ) {
+      my $headerrow;
+      my $name;
+      if ( $form->{subsort} eq 'parts_id' ) {
+        $name = 'description';
+        $headerrow->{description}->{data} = "$ar->{$name}";
+      } else {
+        $name = 'name';
+        $headerrow->{description}->{data} = "$ar->{$name}";
+      };
+      $headerrow->{description}->{class} = "listsubsortheader";
+      my $headerrow_set = [ $headerrow ];
+      $report->add_data($headerrow_set) if $form->{l_headers} eq "Y";
+    };
+
+    map { $subtotals1{$_} += $ar->{$_};
+          $subtotals2{$_} += $ar->{$_};
+        } @subtotal_columns;
+         
+    map { $totals{$_}    += $ar->{$_} } @total_columns;  
+
+    $subtotals2{sellprice} = $subtotals2{sellprice_total} / $subtotals2{qty} if $subtotals2{qty} != 0;
+    $subtotals1{sellprice} = $subtotals1{sellprice_total} / $subtotals1{qty} if $subtotals1{qty} != 0;
+    $subtotals2{lastcost} = $subtotals2{lastcost_total} / $subtotals2{qty} if $subtotals2{qty} != 0;
+    $subtotals1{lastcost} = $subtotals1{lastcost_total} / $subtotals1{qty} if $subtotals1{qty} != 0;
+
+    # Ertrag prozentual in den Summen: (summe VK - summe Ertrag) / summe VK
+    $subtotals1{marge_percent} = $subtotals1{sellprice_total} ? (($subtotals1{sellprice_total} - $subtotals1{lastcost_total}) / $subtotals1{sellprice_total}) : 0;
+    $subtotals2{marge_percent} = $subtotals2{sellprice_total} ? (($subtotals2{sellprice_total} - $subtotals2{lastcost_total}) / $subtotals2{sellprice_total}) : 0;
+
+    # Ertrag prozentual:  (Summe VK betrag - Summe EK betrag) / Summe VK betrag
+    # wird laufend bei jeder Position neu berechnet
+    $totals{marge_percent}    = $totals{sellprice_total}    ? ( ($totals{sellprice_total} - $totals{lastcost_total}) / $totals{sellprice_total}   ) : 0;
+
+    map { $ar->{$_} = $form->format_amount(\%myconfig, $ar->{$_}, 2) } qw(marge_total marge_percent);
+    map { $ar->{$_} = $form->format_amount(\%myconfig, $ar->{$_}, $form->{"decimalplaces"} )} qw(lastcost sellprice sellprice_total lastcost_total);
+
+    my $row = { };
+
+    foreach my $column (@columns) {
+      $row->{$column} = {
+        'data'  => $ar->{$column},
+        'align' => $column_alignment{$column},
+      };
+    }
+  
+   $row->{description}->{class} = 'listsortdescription';
+
+    $row->{invnumber}->{link} = build_std_url("script=is.pl", 'action=edit')
+      . "&id=" . E($ar->{id}) . "&callback=${callback}";
+
+    my $row_set = [ $row ];
+
+    if (($form->{l_subtotal} eq 'Y')
+        && (($idx == (scalar @{ $form->{AR} } - 1))   # last element always has a subtotal
+          || ($ar->{ $form->{'subsort'} } ne $form->{AR}->[$idx + 1]->{ $form->{'subsort'}   })
+          || ($ar->{ $form->{'mainsort'} } ne $form->{AR}->[$idx + 1]->{ $form->{'mainsort'} })
+          )) {   # if value that is sorted by changes, print subtotal
+      my $name;
+      if ( $form->{subsort} eq 'parts_id' ) {
+        $name = 'description';
+      } else {
+        $name = 'name';
+      };
+      
+      if ($form->{l_subtotal} eq 'Y' ) {
+        push @{ $row_set }, create_subtotal_row_invoice(\%subtotals2, \@columns, \%column_alignment, \@subtotal_columns, 'listsubsortsubtotal', $ar->{$name}) ;
+        push @{ $row_set }, insert_empty_row();
+      };
+    }
+
+    # if mainsort has changed, add mainsort subtotal and empty row 
+    if (($form->{l_subtotal} eq 'Y')
+        && (($idx == (scalar @{ $form->{AR} } - 1))   # last element always has a subtotal
+            || ($ar->{ $form->{'mainsort'} } ne $form->{AR}->[$idx + 1]->{ $form->{'mainsort'} })
+            )) {   # if value that is sorted by changes, print subtotal
+      my $name;
+      if ( $form->{mainsort} eq 'parts_id' ) {
+        $name = 'description';
+      } else {
+        $name = 'name';
+      };
+      if ($form->{l_subtotal} eq 'Y' ) {
+        push @{ $row_set }, create_subtotal_row_invoice(\%subtotals1, \@columns, \%column_alignment, \@subtotal_columns, 'listmainsortsubtotal', $ar->{$name});
+        push @{ $row_set }, insert_empty_row();
+      };
+    }
+  
+    $report->add_data($row_set);
+
+    $idx++;
+  }
+  if ( $form->{l_total} eq "Y" ) {
+    $report->add_separator();
+    $report->add_data(create_subtotal_row_invoice(\%totals, \@columns, \%column_alignment, \@total_columns, 'listtotal'))
+  };
+
+  $report->generate_with_headers();
+  $main::lxdebug->leave_sub();
+}
+
+
+sub insert_empty_row {
+    my $dummyrow;
+    $dummyrow->{description}->{data} = "";
+    my $dummyrowset = [ $dummyrow ];
+    return $dummyrow;
+};
+
+
+
+sub create_subtotal_row_invoice {
+  $main::lxdebug->enter_sub();
+
+  my ($totals, $columns, $column_alignment, $subtotal_columns, $class, $name) = @_;
+
+  my $form     = $main::form;
+  my %myconfig = %main::myconfig;
+
+  my $row = { map { $_ => { 'data' => '', 'class' => $class, 'align' => $column_alignment->{$_}, } } @{ $columns } };
+  
+  $row->{description}->{data} = "Summe " . $name;
+
+  map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, 2) } qw(marge_total marge_percent);
+  map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, 0) } qw(qty);
+  map { $row->{$_}->{data} = $form->format_amount(\%myconfig, $totals->{$_}, $form->{decimalplaces}) } qw(lastcost sellprice sellprice_total lastcost_total);
+
+
+  map { $totals->{$_} = 0 } @{ $subtotal_columns };
+
+  $main::lxdebug->leave_sub();
+
+  return $row;
+}
+
+1;
+
index 404c76725cefcc6223a9f40f9c0f3e82ed7084ad..8d09f8e965ef4a9ff07cdd57f8f48423aa93856f 100644 (file)
@@ -211,6 +211,14 @@ body.menu {
 
 .listtotal, .listtotal td { font-size: 8pt; background-color: rgb(236,233,216); color: black; font-weight: bolder;}
 
+/* Verkaufsbericht */
+.listmainsortheader { font-size: 8pt; background-color: rgb(236,233,216); color: red; font-weight: bolder; padding-left: 10px; padding-top: 0px;}
+.listmainsortsubtotal { font-size: 8pt; background-color: rgb(236,233,216); color: red; font-weight: bolder; padding-left: 10px;}
+.listsubsortheader { font-size: 8pt; background-color: rgb(236,233,216); color: green; font-weight: bolder; padding-left: 20px}
+.listsubsortsubtotal { font-size: 8pt; background-color: rgb(236,233,216); color: green; font-weight: bolder; padding-left: 20px}
+.listsortdescription { font-size: 8pt; background-color: rgb(236,233,216); color: black; font-weight: normal; padding-left: 30px}
+
+
 .submit {
   font-family: Verdana, Arial, Helvetica;
   color: #000000;
index 757c00661d834c00c6bd4cf7b8902ff023324d02..e3acfd4037bba381679de3f615ed3042a0b9251a 100644 (file)
@@ -21,6 +21,7 @@
   - Ansprechpartner für abweichende Lieferadresse, um das Attribut Geschlecht erweitert
   - FiBu -> Bericht -> Offene Forderung | Offene Verbindlichkeiten um Altersstrukturliste (30, 60, 90, 120) erweitert
   - SEPA Hinzufügen von Überweisungen um das Infofeld Fälligkeitsdatum erweitert
+  - Verkaufsbericht mit Statistiken zu Margen
   - Wenn ein Auftrag komplett geliefert ist, den Workflow-Knopf 'Lieferschein' ausblenden
 
   API Änderungen:
index 97a43668592c5f95743d583bfcd6587e2aa92a5a..d4255175c49708d1dcd09d523223f88ffda37cce 100644 (file)
@@ -197,6 +197,7 @@ $self->{texts} = {
   'Are you sure you want to update the prices' => 'Sind Sie sicher, dass Sie die Preise aktualisieren wollen?',
   'Article Code'                => 'Artikelkürzel',
   'Article Code missing!'       => 'Artikelkürzel fehlt',
+  'Artikel'                     => '',
   'As a result, the saved onhand values of the present goods can be stored into a warehouse designated by you, or will be reset for a proper warehouse tracking' => 'Als Konsequenz k&ouml;nnen die gespeicherten Mengen entweder in ein Lager &uuml;berf&uuml;hrt werden, oder f&uuml;r eine frische Lagerverwaltung resettet werden.',
   'Assemblies'                  => 'Erzeugnisse',
   'Assembly Description'        => 'Erzeugnis-Beschreibung',
@@ -242,6 +243,10 @@ $self->{texts} = {
   'Bank Connections'            => 'Bankverbindungen',
   'Bank accounts'               => 'Bankkonten',
   'Bank code'                   => 'Bankleitzahl',
+  'Bank collection amount'      => 'Einzugsbetrag',
+  'Bank collection payment list for export #1' => 'Bankeinzugszahlungsliste für SEPA-Export #1',
+  'Bank collection via SEPA'    => 'Bankeinzug via SEPA',
+  'Bank collections via SEPA'   => 'Bankeinzüge via SEPA',
   'Bank transfer amount'        => 'Überweisungssumme',
   'Bank transfer payment list for export #1' => 'Überweisungszahlungsliste für SEPA-Export #1',
   'Bank transfer via SEPA'      => 'Überweisung via SEPA',
@@ -416,6 +421,8 @@ $self->{texts} = {
   'Create and edit sales orders' => 'Auftragsbest&auml;tigungen erfassen und bearbeiten',
   'Create and edit sales quotations' => 'Angebote erfassen und bearbeiten',
   'Create and edit vendor invoices' => 'Eingangsrechnungen erfassen und bearbeiten',
+  'Create bank collection'      => 'Bankeinzug erstellen',
+  'Create bank collection via SEPA XML' => 'Bankeinzug via SEPA XML erstellen',
   'Create bank transfer'        => 'Überweisung erstellen',
   'Create bank transfer via SEPA XML' => 'Überweisung via SEPA XML erzeugen',
   'Create invoice?'             => 'Rechnung erstellen?',
@@ -550,6 +557,7 @@ $self->{texts} = {
   'Display'                     => 'Anzeigen',
   'Display file'                => 'Datei anzeigen',
   'Display options'             => 'Anzeigeoptionen',
+  'Do you really want to close the following SEPA exports? No payment will be recorded for bank collections that haven\'t been marked as executed yet.' => 'Wollen Sie wirklich die folgenden SEPA-Exporte abschließen? Für Überweisungen, die noch nicht gebucht wurden, werden dann keine Zahlungen verbucht.',
   'Do you really want to close the following SEPA exports? No payment will be recorded for bank transfers that haven\'t been marked as executed yet.' => 'Wollen Sie wirklich die folgenden SEPA-Exporte abschließen? Für Überweisungen, die noch nicht gebucht wurden, werden dann keine Zahlungen verbucht.',
   'Do you really want to delete AP transaction #1?' => 'Wollen Sie wirklich die Kreditorenbuchung #1 löschen?',
   'Do you really want to delete AR transaction #1?' => 'Wollen Sie wirklich die Debitorenbuchung #1 löschen?',
@@ -639,6 +647,7 @@ $self->{texts} = {
   'Edit Purchase Order'         => 'Lieferantenaufrag bearbeiten',
   'Edit Quotation'              => 'Angebot bearbeiten',
   'Edit Request for Quotation'  => 'Anfrage bearbeiten',
+  'Edit SEPA strings'           => 'Begriffe bei SEPA-Überweisungen bearbeiten',
   'Edit Sales Delivery Order'   => 'Lieferschein (Verkauf) bearbeiten',
   'Edit Sales Invoice'          => 'Rechnung bearbeiten',
   'Edit Sales Order'            => 'Auftrag bearbeiten',
@@ -792,6 +801,7 @@ $self->{texts} = {
   'Hardcopy'                    => 'Seite drucken',
   'Has serial number'           => 'Hat eine Serienummer',
   'Header'                      => 'Überschrift',
+  'Headers'                     => 'Überschriften',
   'Heading'                     => 'Überschrift',
   'Help'                        => 'Hilfe',
   'Help Template Variables'     => 'Hilfe zu Dokumenten-Variablen',
@@ -950,6 +960,7 @@ $self->{texts} = {
   'List bank accounts'          => 'Bankkonten anzeigen',
   'List export'                 => 'Export anzeigen',
   'List of bank accounts'       => 'Liste der Bankkonten',
+  'List of bank collections'    => 'Bankeinzugsliste',
   'List of bank transfers'      => 'Überweisungsliste',
   'List of custom variables'    => 'Liste der benutzerdefinierten Variablen',
   'List open SEPA exports'      => 'Noch nicht ausgeführte SEPA-Exporte anzeigen',
@@ -976,6 +987,7 @@ $self->{texts} = {
   'MAILED'                      => 'Gesendet',
   '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.',
   'Main Preferences'            => 'Grundeinstellungen',
+  'Main sorting'                => 'Hauptsortierung',
   'Make'                        => 'Lieferant',
   'Manage Custom Variables'     => 'Benutzerdefinierte Variablen',
   'Manage license keys'         => 'Lizenzschl&uuml;ssel verwalten',
@@ -983,6 +995,8 @@ $self->{texts} = {
   'Mandatory Departments'       => 'Benutzer muss Abteilungen vergeben',
   'Mar'                         => 'März',
   'March'                       => 'März',
+  'Margepercent'                => 'Ertrag prozentual',
+  'Margetotal'                  => 'Ertrag',
   'Margins'                     => 'Seitenr&auml;nder',
   'Mark as closed'              => 'Abschließen',
   'Mark as paid?'               => 'Als bezahlt markieren?',
@@ -1056,6 +1070,7 @@ $self->{texts} = {
   'No Vendor was found matching the search parameters.' => 'Zu dem Suchbegriff wurde kein Händler gefunden',
   'No action defined.'          => 'Keine Aktion definiert.',
   'No backup file has been uploaded.' => 'Es wurde keine Sicherungsdatei hochgeladen.',
+  'No bank information has been entered in this customer\'s master data entry. You cannot create bank collections unless you enter bank information.' => 'Für diesen Kunden wurden in seinen Stammdaten keine Kontodaten hinterlegt. Solange dies nicht geschehen ist, können Sie keine Überweisungen für den Lieferanten anlegen.',
   'No bank information has been entered in this vendor\'s master data entry. You cannot create bank transfers unless you enter bank information.' => 'Für diesen Lieferanten wurden in seinen Stammdaten keine Kontodaten hinterlegt. Solange dies nicht geschehen ist, können Sie keine Überweisungen für den Lieferanten anlegen.',
   'No bins have been added to this warehouse yet.' => 'Es wurden zu diesem Lager noch keine Lagerpl&auml;tze angelegt.',
   'No customer has been selected yet.' => 'Es wurde noch kein Kunde ausgewählt.',
@@ -1193,6 +1208,7 @@ $self->{texts} = {
   'Phone1'                      => 'Telefon 1 ',
   'Phone2'                      => 'Telefon 2',
   'Pick List'                   => 'Sammelliste',
+  'Please Check the bank information for each customer:' => 'Bitte überprüfen Sie die Bankinformationen der Kunden:',
   'Please Check the bank information for each vendor:' => 'Bitte überprüfen Sie die Kontoinformationen der Lieferanten:',
   'Please ask your administrator to create warehouses and bins.' => 'Bitten Sie Ihren Administrator, dass er Lager und Lagerpl&auml;tze anlegt.',
   'Please enter a license key.' => 'Bitte geben Sie einen Lizenzschlüssel an.',
@@ -1214,6 +1230,7 @@ $self->{texts} = {
   'Please select a vendor from the list below.' => 'Bitte einen Händler aus der Liste auswählen',
   'Please select the chart of accounts this installation is using from the list below.' => 'Bitte w&auml;hlen Sie den Kontenrahmen aus, der bei dieser Installation verwendet wird.',
   'Please select the database you want to backup' => 'Bitte w&auml;hlen Sie die zu sichernde Datenbank gefunden',
+  'Please select the destination bank account for the collections:' => 'Bitte wählen Sie das Bankkonto als Ziel für die Einzüge aus:',
   'Please select the source bank account for the transfers:' => 'Bitte wählen Sie das Bankkonto als Quelle für die Überweisungen aus:',
   'Please seletct the dataset you want to delete:' => 'Bitte w&auml;hlen Sie die zu l&ouml;schende Datenbank aus:',
   'Please specify a description for the warehouse designated for these goods.' => 'Bitte geben Sie den Namen des Ziellagers f&uuml;r die &uuml;bernommenen Daten ein.',
@@ -1231,6 +1248,7 @@ $self->{texts} = {
   'Preis'                       => 'Preis',
   'Preisgruppe'                 => 'Preisgruppe',
   'Preisklasse'                 => 'Preisgruppe',
+  'Prepare bank collection via SEPA XML' => 'Einzug via SEPA XML vorbereiten',
   'Prepare bank transfer via SEPA XML' => 'Überweisung via SEPA XML vorbereiten',
   'Prepayment'                  => 'Vorauszahlung',
   'Preview'                     => 'Druckvorschau',
@@ -1285,6 +1303,9 @@ $self->{texts} = {
   'Purchase Prices'             => 'Einkaufspreise',
   'Purchase delivery order'     => 'Lieferschein (Einkauf)',
   'Purchase invoices'           => 'Einkaufsrechnungen',
+  'Purchase net amount'         => 'EK-Betrag',
+  'Purchase price'              => 'EK-Preis',
+  'Purchase price total'        => 'EK-Betrag',
   'Purpose'                     => 'Verwendungszweck',
   'Qty'                         => 'Menge',
   'Qty according to delivery order' => 'Menge laut Lieferschein',
@@ -1327,6 +1348,7 @@ $self->{texts} = {
   'Reference missing!'          => 'Referenz fehlt!',
   'Release From Stock'          => 'Lagerausgang',
   'Remaining'                   => 'Rest',
+  'Remittance information prefix' => 'Verwendungszweckvorbelegung (Präfix)',
   'Removal'                     => 'Entnahme',
   'Removal from Warehouse'      => 'Lagerentnahme',
   'Removal from warehouse'      => 'Entnahme aus Lager',
@@ -1364,7 +1386,9 @@ $self->{texts} = {
   'SAVED FOR DUNNING'           => 'Gespeichert',
   'SCREENED'                    => 'Angezeigt',
   'SEPA XML download'           => 'SEPA-XML-Download',
+  'SEPA creditor ID'            => 'SEPA-Kreditoren-Identifikation',
   'SEPA exports:'               => 'SEPA-Exporte:',
+  'SEPA strings'                => 'SEPA-Überweisungen',
   'Saldo Credit'                => 'Saldo Haben',
   'Saldo Debit'                 => 'Saldo Soll',
   'Saldo neu'                   => 'Saldo neu',
@@ -1374,10 +1398,16 @@ $self->{texts} = {
   'Sales Invoices'              => 'Kundenrechnung',
   'Sales Order'                 => 'Kundenauftrag',
   'Sales Orders'                => 'Aufträge',
+  'Sales Report'                => 'Verkaufsbericht',
   'Sales and purchase invoices with inventory transactions with taxkeys' => 'Einkaufs- und Verkaufsrechnungen mit Warenbestandsbuchungen mit Steuerschlüsseln',
   'Sales delivery order'        => 'Lieferschein (Verkauf)',
   'Sales invoice number'        => 'Ausgangsrechnungsnummer',
   'Sales invoices'              => 'Verkaufsrechnungen',
+  'Sales margin'                => 'Marge',
+  'Sales margin %'              => 'Marge prozentual',
+  'Sales net amount'            => 'VK-Betrag',
+  'Sales price'                 => 'VK-Preis',
+  'Sales price total'           => 'VK-Betrag',
   'Sales quotation'             => 'Angebot',
   'Salesman'                    => 'Verkäufer/in',
   'Salesperson'                 => 'Verkäufer',
@@ -1562,6 +1592,7 @@ $self->{texts} = {
   'The GL transaction #1 has been deleted.' => 'Die Dialogbuchung #1 wurde gelöscht.',
   'The LDAP server "#1:#2" is unreachable. Please check config/authentication.pl.' => 'Der LDAP-Server "#1:#2" ist nicht erreichbar. Bitte &uuml;berpr&uuml;fen Sie die Angaben in config/authentication.pl.',
   'The SEPA export has been created.' => 'Der SEPA-Export wurde erstellt',
+  'The SEPA strings have been saved.' => 'Die bei SEPA-Überweisungen verwendeten Begriffe wurden gespeichert.',
   'The access rights have been saved.' => 'Die Zugriffsrechte wurden gespeichert.',
   'The account 3804 already exists, the update will be skipped.' => 'Das Konto 3804 existiert schon, das Update wird übersprungen.',
   'The account 3804 will not be added automatically.' => 'Das Konto 3804 wird nicht automatisch hinzugefügt.',
@@ -1896,6 +1927,7 @@ $self->{texts} = {
   'You have to create at least one group, grant it access to Lx-Office\'s functions and assign users to it.' => 'Sie m&uuml;ssen mindestens eine Benutzergruppe anlegen, ihr Zugriff auf die verschiedenen Funktionsbereiche von Lx-Office gew&auml;hren und Benutzer dieser Gruppe zuordnen.',
   'You have to create new Buchungsgruppen for all the combinations of inventory, income and expense accounts that have been used already.' => 'Sie m&uuml;ssen neue Buchungsgruppen f&uuml;r alle Kombinationen aus Inventar-, Erl&ouml;s- und Aufwandskonto, die bereits benutzt wurden.',
   'You have to enter a company name in your user preferences (see the "Program" menu, "Preferences").' => 'Sie müssen einen Firmennamen in Ihren Einstellungen angeben (siehe Menü "Programm", "Einstellungen").',
+  'You have to enter the SEPA creditor ID in your user preferences (see the "Program" menu, "Preferences").' => 'Sie müssen die SEPA-Kreditoren-Identifikation in Ihren Einstellungen angeben (siehe Menü "Programm", "Einstellungen").',
   'You have to fill in at least an account number, the bank code, the IBAN and the BIC.' => 'Sie müssen zumindest die Kontonummer, die Bankleitzahl, die IBAN und den BIC angeben.',
   'You have to specify a department.' => 'Sie müssen eine Abteilung wählen.',
   'You have to specify an execution date for each antry.' => 'Sie müssen für jeden zu buchenden Eintrag ein Ausführungsdatum angeben.',
@@ -1923,7 +1955,8 @@ $self->{texts} = {
   'as at'                       => 'zum Stand',
   'assembly_list'               => 'erzeugnisliste',
   'back'                        => 'zurück',
-  'bank_transfer_payment_list_#1' => 'ueberweisungs_zahlungsliste_#1',
+  'bank_collection_payment_list_#1' => 'bankeinzugszahlungsliste_#1',
+  'bank_transfer_payment_list_#1' => 'ueberweisungszahlungsliste_#1',
   'bankaccounts'                => 'Bankkonten',
   'banktransfers'               => 'ueberweisungen',
   'bestbefore #1'               => 'Mindesthaltbarkeit #1',
@@ -1951,6 +1984,7 @@ $self->{texts} = {
   'debug'                       => 'Debug',
   'delete'                      => 'Löschen',
   'deliverydate'                => 'Lieferdatum',
+  'description'                 => 'Beschreibung',
   'direct debit'                => 'Lastschrift',
   'disposed'                    => 'Entsorgung',
   'done'                        => 'erledigt',
@@ -2026,6 +2060,7 @@ $self->{texts} = {
   'sales_order'                 => 'Kundenauftrag',
   'sales_order_list'            => 'auftragsliste',
   'sales_quotation'             => 'Verkaufsangebot',
+  'sales_report'                => 'verkaufsbericht',
   'saved'                       => 'gespeichert',
   'saved!'                      => 'gespeichert',
   'sent'                        => 'gesendet',
index bd5317f05836800d95a383d110aafe432ba11fe7..df0cfc50e7c84939be67271854479dd846ccb68a 100644 (file)
@@ -69,12 +69,11 @@ if (!$file) ende ("Kein Datenfile");
 $trenner=($_POST["trenner"])?$_POST["trenner"]:",";
 if ($trenner=="other") {
     $trenner=trim($trennzeichen);
-    if (substr($trenner,0,1)=="#") if (strlen($trenner)>1) $trenner=chr(substr($trenner,1));
 } 
+if (substr($trenner,0,1)=="#") if (strlen($trenner)>1) $trenner=chr(substr($trenner,1));
 
 if (!file_exists($dir.$file.".csv")) ende("$file.csv nicht im Ordner oder leer");
 
-
 if (!$db->chkcol($file)) ende("Importspalte kann nicht angelegt werden");
 
 $employee=chkUsr($_SESSION["employee"]);
@@ -114,18 +113,54 @@ $kunde_fld = array_keys($address);
          }
     }
 
+function chkBusiness($data,$id=true) {
+global $db;
+    if ($id) {
+        $rs = $db->getAll("select id from business where id =$data");
+    } else {
+        $rs = $db->getAll("select id from business where decription ilike '$data'");
+    }
+    if ($rs[0]["id"]) {
+        return $rs[0]["id"];
+    } else {
+        return "null";
+    }
+}
+
+function chkSalesman($data,$id=true) {
+global $db;
+    if ($id) {
+        $rs = $db->getAll("select id from employee where id =$data");
+    } else {
+        $rs = $db->getAll("select id from employee where login ilike '$data'");
+    }
+    if ($rs[0]["id"]) {
+        return $rs[0]["id"];
+    } else {
+        return "null";
+    }
+}
+
 $f=fopen($dir.$file.".csv","r");
 $zeile=fgets($f,1200);
 $infld=explode($trenner,strtolower($zeile));
 $first=true;
 $ok=true;
+$p=0;
 foreach ($infld as $fld) {
     $fld = strtolower(trim(strtr($fld,array("\""=>"","'"=>""))));
-    if ($fld=="branche" && !$crm) { $in_fld[]=""; continue; };
-    if ($fld=="sw" && !$crm) { $in_fld[]=""; continue; };
-    $in_fld[]=$fld;
+    if (in_array($fld,$kunde_fld)) {
+        if ($fld=="branche" && !$crm) {  continue; };
+        if ($fld=="sw" && !$crm) {  continue; };
+        $in_fld[$fld]=$p;
+        //$fldpos[$fld]=$p;
+        //$in_fld[]=$fld;
+    }
+    $p++;
 }
-
+$infld = array_keys($in_fld);
+$infld[] = "import";
+$infld = implode(",",$infld);
 $j=0;
 $m=0;
 $zeile=fgetcsv($f,1200,$trenner);
@@ -135,16 +170,75 @@ if ($ok) while (!feof($f)){
     $anrede="";
     $Matchcode="";
     $sql="insert into $file ";
-    $keys="(";
-    $vals=" values (";
+    $keys=array();
+    $vals=array();
     $number=false;
-    foreach($zeile as $data) {
-        if (!in_array(trim($in_fld[$i]),$kunde_fld)) {
-            if ($in_fld[$i]=="anrede") {  $anrede=addslashes(trim($data)); }
-            $i++;
-            continue;
-        };
-        $data=trim($data);
+    //foreach($zeile as $data) {
+    
+    foreach($in_fld as $fld => $pos) {
+        switch ($fld) {
+            case "name"         :
+            case "department_1" :
+            case "department_2" :
+            case "matchcode"    : 
+            case "street"       :
+            case "city"         :
+            case "notes"        :
+            case "sw"           :
+            case "branche"      :
+            case "country"      :
+            case "contact"      :
+            case "homepage"     :
+            case "email"        :
+            case "bank"         : $data = addslashes(trim($zeile[$pos]));
+                                  if (Translate) translate($data);
+            case "ustid"        : $data = strtr(trim($zeile[$pos])," ","");
+            case "bank_code"    : $data = trim($zeile[$pos]);
+            case "account_number":
+            case "greeting"     :
+            case "taxnumber"    :
+            case "zipcode"      : 
+            case "phone"        :
+            case "fax"          : $data = trim($zeile[$pos]);
+                                  $data = "'$data'";
+                                  if ($data=="''") {
+                                        $vals[] = "null";
+                                  } else {
+                                        $vals[] = $data;
+                                  }
+                                  break;
+            case "business_id"  : $vals[] = chkBusiness(trim($zeile[$pos]));
+                                  break;
+            case "salesman_id"  : $vals[] = chkSalesman(trim($zeile[$pos]));
+                                  break;
+            case "taxincluded"  : $data = strtolower(substr($zeile[$pos],0,1));
+                                  if ($data!="f" && $data!="t") { $vals[] = "'f'"; }
+                                  else { $vals[] = "'".$data."'";}
+                                  break;
+            case "taxzone_id"   : $data = trim($zeile[$pos])*1;
+                                  if ($data>3 && $data<0) $data = 0;
+                                  $vals[] = $data;
+                                  break;
+            case "creditlimit"  : 
+            case "discount"     :
+            case "terms"        : $vals[] = trim($zeile[$pos])*1;
+                                  break;
+            case "customernumber":
+            case "vendornumber" : $data = trim($zeile[$pos]);
+                                  if (empty($data) or !$data) {
+                                      $vals[] = getKdId();
+                                      $number = true;
+                                  } else {
+                                      $vals[] = chkKdId($data);
+                                      $number = true;
+                                  }
+                                  break;
+        }
+    };
+    if (!in_array("taxzone_id",$in_fld)) {
+        $in_fld[] = "taxzone_id";
+        $vals[] = 0;
+    }
         // seit 2.6 ist die DB-Kodierung UTF-8 @holger Ansonsten einmal vorher die DB-Encoding auslesen
         // Falls die Daten ISO-kodiert kommen entsprechend wandeln
         // done!
@@ -152,78 +246,26 @@ if ($ok) while (!feof($f)){
         // die blöde mb_detect... tut leider nicht immer, daher die Möglichkeit der Auswahl
         // TODO Umlaute am Anfang wurden bei meinem Test nicht übernommen (Österreich). S.a.:
         // http://forum.de.selfhtml.org/archiv/2007/1/t143904/
-
-        if (Translate) translate($data);
-
-        //$data=htmlentities($data);
-        $data=addslashes($data);
-        if ($in_fld[$i]==$file."number") {  // customernumber || vendornumber
-            if (empty($data) or !$data) {
-                $data=getKdId();
-                $number=true;
-            } else {
-                $data=chkKdId($data);
-                $number=true;
-            }
-        } else if ($in_fld[$i]=="taxincluded"){
-            $data=strtolower(substr($data,0,1));
-            if ($data!="f" && $data!="t") $data="f";
-        } else if ($in_fld[$i]=="ustid"){
-            $data=strtr($data," ","");
-        } /*else if ($in_fld[$i]=="matchcode") {
-                  $matchcode=$data;
-                  $i++;
-                  continue;
-                if ($data==false or empty($data) or !$data) {
-            if (in_array($in_fld[$i],array("name"))) {
-                $data=$matchcode;
-            }
-        }
-            }*/
-
-        $keys.=$in_fld[$i].",";
-        if ($data==false or empty($data) or !$data) {
-            $vals.="null,";
-        } else {
-            if ($in_fld[$i]=="contact"){
-                if ($anrede) {
-                    $vals.="'$anrede $data',";
-                } else {
-                    $vals.="'$data',";
-                }
-            } else {
-                $vals.="'".$data."',";
-            }
-        }
-        $i++;
-    }
-    if (!$number) {
-        $keys.=$file."number,";
-        $vals.="'".getKdId()."',";
-    }
-    if ($keys<>"(") {
-        if ($test) {
+    if ($test) {
             if ($first) {
-                echo "<table border='1'>\n";
-                echo "<tr><th>".str_replace(",","</th><th>",substr($keys,1,-1))."</th></tr>\n";
+                echo "<table border='1'>\n<tr><td>";
+                echo implode('</th><th>',array_keys($in_fld));
+                echo "</td></tr>\n";
                 $first=false;
             };
-            $vals=str_replace("',","'</td><td>",substr($vals,9,-1));
-            echo "<tr><td>".str_replace("null,","null</td><td>",$vals)."</td></tr>\n";
+            echo "<tr><td>";
+            echo implode('</td><td>',$vals);
+            echo "</td></tr>\n";
             //echo "Import $j<br>\n";
             flush();
-        } else {
-            $sql.=$keys."taxzone_id,import)";
-            $sql.=$vals."0,$nun)";
-            $rc=$db->query($sql);
-            if (!$rc) echo "Fehler: ".$sql."<br>";
-        }
-        $j++;
     } else {
-          $vals=str_replace("',","'</td><td>",substr($vals,9,-1));
-          echo "<tr><td style=\"color:red\">".str_replace("null,","null</td><td style=\"color:red\">",$vals)."</td></tr>\n";
-          flush();
-        }
+            $vals[] = $nun;
+            $sql = "INSERT INTO $file (".$infld.") values (".implode(",",$vals).")";
+            $rc=$db->query($sql);
+            if ($j % 10 == 0) { echo "."; flush(); };
+            if (!$rc) {  echo "<br />Fehler: ".$sql."<br />"; flush(); };
+    }
+    $j++;
     $zeile=fgetcsv($f,1200,$trenner);
 }
 fclose($f);
index 36cf30f14a6d3e078820ca2942f9b738e0e5118c..996d21e642632d5bf368310ef389b9c111175ec0 100644 (file)
@@ -36,6 +36,8 @@ $address = array(
     "bank_code" => "Bankleitzahl",
     "bank" => "Bankname",
     "branche" => "Branche",
+    "business_id" => "BranchenID",
+    "salesman_id" => "VerkäuferID",
     //"language" => "Sprache (de,en,fr)",
     "sw" => "Stichwort",
     "creditlimit" => "Kreditlimit (nnnnnn.nn)"); /*,
index 1d280d86375f976c85c88a1d7a3bd1e37108caf2..cb9de67635ab33f180076b2ec7a4afa786159dc1 100644 (file)
@@ -56,7 +56,7 @@ if ($_POST["ok"] || $_GET["cron"]=="1") {
     //DB und LxO müssen ja nicht auf der gleichen Maschine sein.
     if($tmpcode<>$db->getClientCode()) {
         $rc = $db->setClientCode($tmpcode);
-    } 
+    }
 
     // Zeichenkodierung File
     if ($_POST["encoding"] == "auto") {
@@ -83,7 +83,7 @@ if ($_POST["ok"] || $_GET["cron"]=="1") {
         echo $header;
         echo "<br><br>Die erste Zeile enth&auml;lt die Feldnamen der Daten in ihrer richtigen Reihenfolge<br>";
         echo "Geben Sie das Trennzeichen der Datenspalten ein. Steuerzeichen k&ouml;nnen mit ihrem Dezimalwert ";
-        echo "gef&uuml;hrt von einem &quot;#&quot; eingegebn werden (#11).<br><br>"; 
+        echo "gef&uuml;hrt von einem &quot;#&quot; eingegebn werden (#11).<br><br>";
         echo "Wird bei &quot;Art&quot; in der Maske &quot;gemischt&quot; gew&auml;hlt, muss die Spalte &quot;art&quot; vor der Einheit stehen.<br><br>";
         echo "Der &quot;sellprice&quot; kann um den eingegeben Wert  ge&auml;ndert werden.<br><br>";
         echo "Bei vorhandenen Artikelnummern (in der db), kann entweder ein Update auf den Preis (und Text) durchgef&uuml;hrt werden oder ";
@@ -92,7 +92,8 @@ if ($_POST["ok"] || $_GET["cron"]=="1") {
         echo "Dazu mu&szlig; entweder in der Maske eine Standardbuchungsgruppe gew&auml;hlt werden <br>";
         echo "oder es wird ein g&uuml;ltiges Konto in 'income_accno_id' und 'expense_accno_id' eingegeben. ";
         echo "Das Programm versucht dann eine passende Buchungsgruppe zu finden.<br>";
-       echo "Preisgruppen müssen zunächst angelegt werden. Die Spalten für die Preisgruppen beginnen mit 'pg_' gefolgt vom Preisgruppenname.";
+           echo "Preisgruppen müssen zunächst angelegt werden. Die Spalten für die Preisgruppen beginnen mit 'pg_' gefolgt vom Preisgruppenname.<br>";
+        echo "Wenn eine Datei <code>users/partshead.csv</code> existiert, wird die erste Zeile aus dieser benutzt um das Format zu bestimmen. Die erste Zeile aus der eigentlichen Importdatei wird dann ignoriert.<br>";
         exit(0);
     };
 
@@ -129,7 +130,7 @@ if ($_POST["ok"] || $_GET["cron"]=="1") {
         $_POST["ware"] = "W";             // Ist ein Artikel
         $_POST["encoding"] = "";
     } else {
-            
+
         /* no data? */
         if (empty($_FILES["Datei"]["name"]))
             ende ("Kein Datenfile angegeben");
@@ -150,15 +151,15 @@ if ($_POST["ok"] || $_GET["cron"]=="1") {
             };
         } else if (!move_uploaded_file($_FILES["Datei"]["tmp_name"],$dir.$file.".csv")) {
             ende ("Upload von Datei fehlerhaft.".$_FILES["Datei"]["error"]);
-        }; 
+        };
     }
 
     /* check if file is really there */
-    if (!file_exists($dir.$file.'.csv') or filesize($dir.$file.'.csv')==0) 
+    if (!file_exists($dir.$file.'.csv') or filesize($dir.$file.'.csv')==0)
         ende("Datenfile ($file.csv) nicht im Ordner gefunden oder leer");
 
     /* Zu diesem Zeitpunkt wurde der Artikel Importiert */
-    if (!$db->chkcol($file)) 
+    if (!$db->chkcol($file))
         ende("Importspalte konnte nicht angelegt werden");
 
     /* just print data or insert it, if test is false */
@@ -178,22 +179,22 @@ if ($_POST["ok"] || $_GET["cron"]=="1") {
 <table>
 <tr><td><input type="submit" name="ok" value="Hilfe"></td><td></td></tr>
 <tr><td>Trennzeichen</td><td>
-        <input type="radio" name="trenner" value=";" checked>Semikolon 
-        <input type="radio" name="trenner" value=",">Komma 
+        <input type="radio" name="trenner" value=";" checked>Semikolon
+        <input type="radio" name="trenner" value=",">Komma
         <input type="radio" name="trenner" value="#9" checked>Tabulator
         <input type="radio" name="trenner" value=" ">Leerzeichen
-        <input type="radio" name="trenner" value="other"> 
-        <input type="text" size="2" name="trennzeichen" value=""> 
+        <input type="radio" name="trenner" value="other">
+        <input type="text" size="2" name="trennzeichen" value="">
 </td></tr>
-<tr><td>VK-Preis<br>Nachkomma:</td><td><input type="Radio" name="precision" value="0">0  
-            <input type="Radio" name="precision" value="1">1 
-            <input type="Radio" name="precision" value="2" checked>2 
-            <input type="Radio" name="precision" value="3">3 
-            <input type="Radio" name="precision" value="4">4 
-            <input type="Radio" name="precision" value="5">5 
+<tr><td>VK-Preis<br>Nachkomma:</td><td><input type="Radio" name="precision" value="0">0
+            <input type="Radio" name="precision" value="1">1
+            <input type="Radio" name="precision" value="2" checked>2
+            <input type="Radio" name="precision" value="3">3
+            <input type="Radio" name="precision" value="4">4
+            <input type="Radio" name="precision" value="5">5
     </td></tr>
-<tr><td>VK-Preis<br>Aufschlag:</td><td><input type="text" name="quotation" size="5" value="0"> 
-            <input type="radio" name="quottype" value="P" checked>% 
+<tr><td>VK-Preis<br>Aufschlag:</td><td><input type="text" name="quotation" size="5" value="0">
+            <input type="radio" name="quottype" value="P" checked>%
             <input type="radio" name="quottype" value="A">Absolut</td></tr>
 <tr><td>Vorhandene<br>Artikelnummer:</td><td><input type="radio" name="update" value="U" checked>Preis update durchf&uuml;hren<br>
                     <input type="radio" name="update" value="I">mit neuer Nummer einf&uuml;gen</td></tr>
@@ -202,6 +203,8 @@ if ($_POST["ok"] || $_GET["cron"]=="1") {
 <tr><td>Textupdate</td><td><input type="checkbox" name="TextUpd" value="1">ja</td></tr>
 <tr><td>Warengruppen<br>verbinder</td><td><input type="text" name="wgtrenner" value="!" size="3"></td></tr>
 <tr><td>Shopartikel<br />falls nicht &uuml;bergeben</td><td><input type="radio" name="shop" value="t">ja <input type="radio" name="shop" value="f" checked>nein</td></tr>
+<tr><td>Eintrag in<br />Makemodel ist</td><td><input type="radio" name="vendnr" value="t">Lieferantennummer <input type="radio" name="vendnr" value="f" checked>Lieferantenname</td></tr>
+<tr><td>auch ohne<br />Model-Nr.</td><td><input type="radio" name="modnr" value="t">ja <input type="radio" name="modnr" value="f" checked>nein</td></tr>
 <tr><td>Art</td><td><input type="Radio" name="ware" value="W" checked>Ware &nbsp; 
             <input type="Radio" name="ware" value="D">Dienstleistung
             <input type="Radio" name="ware" value="G">gemischt (Spalte 'art' vorhanden)</td></tr>
index 0db931230016d76c2a41bb932b50a11e7cad2c28..94f2b6f15fc9db8ef8a77bf68808154b32a3f998 100644 (file)
@@ -128,11 +128,13 @@ function updParts($db,$insert,$show,$partnumber,$lastcost,$sellprice,$listprice,
     return $rc;
 }
 
-function getMakemodel($db,$check,$hersteller,$model,$partsid,$add=true) {
+function getMakemodel($db,$check,$hersteller,$model,$partsid,$lastcost,$add=true) {
     $sql="select * from makemodel where make = $hersteller and model = '$model' and parts_id = $partsid";
     $rs=$db->getAll($sql);
     if (empty($rs[0]["id"]) && $add) {
-        $sql="insert into makemodel (parts_id,make,model) values ($partsid,'$hersteller','$model')";    
+        if (!$lastcost) $lastcost=0.00;
+        $sql="insert into makemodel (parts_id,make,model,lastcost,lastupdate,sortorder) ";
+        $sql.="values ($partsid,'$hersteller','$model',$lastcost,now(),1)";    
         $rc=$db->query($sql);
     }
 }
@@ -251,6 +253,8 @@ function import_parts($db, $file, $fields, $check, $maske) {
     $wgtrenner=$maske["wgtrenner"];
     $Update=($maske["update"]=="U")?true:false;
     $UpdText=($maske["TextUpd"]=="1")?true:false;
+    $vendnr=($maske["vendnr"]=="t")?true:false;
+    $modnr=($maske["modnr"]=="t")?true:false;
 
     //$stdunitW=getStdUnit($db,"dimension");
     //$stdunitD=getStdUnit($db,"service");
@@ -293,12 +297,12 @@ function import_parts($db, $file, $fields, $check, $maske) {
      */
     if ($show) {
         show('<tr>',false);
-        show("partnumber"); show("lastcost");   show("sellprice");     show("listprice");
-        show("description");show("notes");      show("ean");
-        show("weight");     show("image");      show("partsgroup_id");
-        show("bg");         show("income_accno"); show("expense_accno");
-        show("inventory_accno"); show("microfiche");show("drawing");show("rop");
-        show("assembly");show("makemodel");  show("shop"); show("");
+        show("partnumber");     show("lastcost");       show("sellprice");     show("listprice");
+        show("description");    show("notes");          show("ean");
+        show("weight");         show("image");          show("partsgroup_id");
+        show("bg");             show("income_accno");   show("expense_accno");
+        show("inventory_accno"); show("microfiche");    show("drawing");
+        show("rop");            show("assembly");       show("makemodel");  show("shop"); show("");
         show("</tr>\n",false);
     }
 
@@ -342,8 +346,8 @@ function import_parts($db, $file, $fields, $check, $maske) {
                foreach ($prices as $pkey=>$val) {
                 if (array_key_exists($pkey,$fldpos))  
                        $pricegroup[$val] = str_replace(",", ".", $zeile[$fldpos[$pkey]]);
-           }
-       }
+            }
+        }
         if ($quotation<>0) {
             if ($quottype=="A") { $sellprice += $quotation; }
             else { $sellprice = $sellprice * $quotation; }
@@ -383,32 +387,39 @@ function import_parts($db, $file, $fields, $check, $maske) {
                 $partsgroup_id = getPartsgroupId($db, $pgname, $insert);
         }
 
+        /* Ware oder Dienstleistung */
+        if (($maske["ware"]=="G" and strtoupper($zeile[$fldpos["art"]])=="D") or $maske["ware"]=="D") { 
+            $artikel = false; 
+        } else if (($maske["ware"]=="G" and strtoupper($zeile[$fldpos["art"]])=="W") or $maske["ware"]=="W") { 
+            $artikel = true;
+        }
+
         /* sind Hersteller und Modelnummer hinterlegt 
             wenn ja, erfolgt er insert später */
         $makemodel = 'f';
-        if (!empty($zeile[$fldpos["makemodel"]]) and !$artikel) { 
+        if (!empty($zeile[$fldpos["makemodel"]]) and $artikel) { 
             $mm = $zeile[$fldpos["makemodel"]];
             if (Translate) translate($mm);
-            $hersteller=suchFirma("vendor",$mm);
-            $hersteller=$hersteller["cp_cv_id"];
-            if (!empty($zeile[$fldpos["model"]])) {
+            if ($vendnr) {
+                $hersteller=getFirma($mm,"vendor");
+            } else {
+                $hersteller=suchFirma("vendor",$mm);
+                $hersteller=$hersteller["cp_cv_id"];
+            }
+            if (!empty($zeile[$fldpos["model"]]) and $hersteller>0) {
                 $mo = $zeile[$fldpos["model"]];
                 if (Translate) translate($mo);
                 $model = $mo;
                 $makemodel = 't';
-            } else { 
+            } else if ($modnr and $hersteller>0) { 
+                $model = ''; 
+                $makemodel = 't';
+            } else {
                 unset($hersteller);
                 $makemodel = 'f';
             }
         }
 
-        /* Ware oder Dienstleistung */
-        if (($maske["ware"]=="G" and strtoupper($zeile[$fldpos["art"]])=="D") or $maske["ware"]=="D") { 
-            $artikel = false; 
-        } else if (($maske["ware"]=="G" and strtoupper($zeile[$fldpos["art"]])=="W") or $maske["ware"]=="W") { 
-            $artikel = true;
-        }
-
         /* Einheit ermitteln */
         if ($zeile[$fldpos["unit"]]=="") {
             //Keine Einheit mitgegeben
@@ -523,10 +534,10 @@ function import_parts($db, $file, $fields, $check, $maske) {
                     "rop"=>$rop,"assembly"=>$assembly,
                     "shop"=>$shop,"makemodel"=>$makemodel),$pricegroup
                 );
-        if ($hersteller>0 && $model) {
+        if ($hersteller>0 ) { // && $model) {
             $partsid=getPartsid($db,$zeile[$fldpos["partnumber"]]);
-            if ($partsid) {
-                getMakemodel($db,$check,$hersteller,$model,$partsid,true);
+            if ($partsid) { 
+                getMakemodel($db,$check,$hersteller,$model,$partsid,$lastcost,true);
             }
         }
         unset($zeile);
diff --git a/lxo-import/partshead.csv b/lxo-import/partshead.csv
new file mode 100644 (file)
index 0000000..53793b4
--- /dev/null
@@ -0,0 +1 @@
+partnumber     fvId    wgr     partsgroup      ean     model   ErsatzArt       makemodel       MarkeText       description     cat01   cat01Text       cat02   cat02Text       cat03   cat03Text       cat04   cat04Text       KzStueck        KzAL    KzAktion        KzSperre        pg_1    pg_2    listprice       lastcost        InfLagME        InfLagWE\r
index cf95938086c42d896cb24d16d71c918159588254..7ca0fa17345254b96d9413b2c0539c41806621b1 100644 (file)
--- a/menu.ini
+++ b/menu.ini
@@ -159,6 +159,12 @@ module=ar.pl
 action=search
 nextsub=ar_transactions
 
+[AR--Reports--Sales Report]
+ACCESS=invoice_edit
+module=vk.pl
+action=search_invoice
+nextsub=invoice_transactions
+
 [AR--Reports--Dunnings]
 ACCESS=dunning_edit
 module=dn.pl
@@ -339,9 +345,15 @@ ACCESS=cash
 module=rc.pl
 action=reconciliation
 
+[Cash--Bank collection via SEPA]
+module=sepa.pl
+action=bank_transfer_add
+vc=customer
+
 [Cash--Bank transfer via SEPA]
 module=sepa.pl
 action=bank_transfer_add
+vc=vendor
 
 [Cash--Reports]
 module=menu.pl
@@ -359,9 +371,15 @@ module=rp.pl
 action=report
 report=payments
 
+[Cash--Reports--Bank collections via SEPA]
+module=sepa.pl
+action=bank_transfer_search
+vc=customer
+
 [Cash--Reports--Bank transfers via SEPA]
 module=sepa.pl
 action=bank_transfer_search
+vc=vendor
 
 [Reports]
 
@@ -667,6 +685,10 @@ action=list_language
 module=generictranslations.pl
 action=edit_greetings
 
+[System--Languages--SEPA strings]
+module=generictranslations.pl
+action=edit_sepa_strings
+
 
 [System--Payment Terms]
 module=menu.pl
diff --git a/sql/Pg-upgrade2/sepa_in.sql b/sql/Pg-upgrade2/sepa_in.sql
new file mode 100644 (file)
index 0000000..6373b8f
--- /dev/null
@@ -0,0 +1,12 @@
+-- @tag: sepa_in
+-- @description: Erweiterung SEPA für Kontoeinzüge
+-- @depends: release_2_6_1
+-- @charset: utf-8
+ALTER TABLE sepa_export ADD COLUMN vc varchar(10);
+UPDATE sepa_export SET vc = 'vendor';
+
+ALTER TABLE sepa_export_items ALTER COLUMN ap_id DROP NOT NULL;
+ALTER TABLE sepa_export_items ADD COLUMN ar_id integer;
+ALTER TABLE sepa_export_items ADD FOREIGN KEY (ar_id) REFERENCES ar (id);
+ALTER TABLE sepa_export_items RENAME vendor_iban TO vc_iban;
+ALTER TABLE sepa_export_items RENAME vendor_bic TO vc_bic;
index 4cd24ca08f906f4b8e14a08949bc23023660c8c7..161c5d2a9bf8020e48f08201a7c0b73f76b206c2 100644 (file)
        <th align="right">[% 'DUNS-Nr' | $T8 %]</th>
        <td><input name="duns" size="14" value="[% HTML.escape(myc_duns) %]"></td>
       </tr>
+
+      <tr>
+       <th align="right">[% 'SEPA creditor ID' | $T8 %]</th>
+       <td><input name="sepa_creditor_id" size="35" maxlength="35" value="[% HTML.escape(myc_sepa_creditor_id) %]"></td>
+      </tr>
      </table>
     </td>
 
index 3d5aba29ad184b3234ef742f6b5fbdf83d02c050..4ed5a07e8161023d45c713316ff8ef3d0fbe487e 100644 (file)
       <th align="right">[% 'Address' | $T8 %]</th>
       <td><textarea name="address" rows="4" cols="50">[% HTML.escape(myconfig_address) %]</textarea></td>
      </tr>
+     <tr>
+      <th align="right">[% 'SEPA creditor ID' | $T8 %]</th>
+      <td><input name="sepa_creditor_id" size="30" maxlength="35" value="[% HTML.escape(myconfig_sepa_creditor_id) %]"></td>
+     </tr>
     </table>
 
     <br style="clear: left" />
index a6f2ceb5610fd0e54c454f1c385dd899a0be5d63..e8183f276e595c02d47a7f1296d8d3946c42e246 100644 (file)
       </th>
       <td><input name="homepage" size="45" title="[% 'Example: http://lx-office.org' | $T8 %]" value="[% HTML.escape(homepage) %]"></td>
      </tr>
+
+     <tr>
+      <th align="right" nowrap>[% 'Username' | $T8 %]</th>
+      <td><input name="username" size="45" value="[% HTML.escape(username) %]"></td>
+     </tr>
+
+     <tr>
+      <th align="right" nowrap>[% 'Password' | $T8 %]</th>
+      <td><input name="user_password" size="45" value="[% HTML.escape(user_password) %]"></td>
+     </tr>
     </table>
 
     <table>
       <td><input name="bic" size="10" maxlength="100" value="[% HTML.escape(bic) %]"></td>
      </tr>
 
-     [%- IF conf_vertreter %]
-      <tr>
-       <th align="right">[% 'Username' | $T8 %]</th>
-       <td><input name="username" maxlength="50" value="[% HTML.escape(username) %]"></td>
-       <th align="right">[% 'Password' | $T8 %]</th>
-       <td><input name="user_password" value="[% HTML.escape(user_password) %]"></td>
-      </tr>
-     [%- END %]
-
      <tr>
       [% UNLESS conf_vertreter %]
        <th align="right">[% IF is_customer %][% 'Type of Customer' | $T8 %][% ELSE %][% 'Type of Vendor' | $T8 %][%- END %]</th>
diff --git a/templates/webpages/generictranslations/edit_sepa_strings.html b/templates/webpages/generictranslations/edit_sepa_strings.html
new file mode 100644 (file)
index 0000000..c6acd84
--- /dev/null
@@ -0,0 +1,46 @@
+[%- USE T8 %]
+[% USE HTML %]<body>
+
+ <p>
+  <div class="listtop">[% HTML.escape(title) %]</div>
+ </p>
+
+ [%- IF message %]
+ <p>
+  [% HTML.escape(message) %]
+ </p>
+ [%- END %]
+
+ <form method="post" action="generictranslations.pl">
+
+  <table>
+
+   <tr>
+    <th class="listheading">&nbsp;</th>
+    <th class="listheading">[% 'Remittance information prefix' | $T8 %]</th>
+   </tr>
+
+   [%- FOREACH language = LANGUAGES %]
+   <tr>
+    <td>
+     [%- IF language.id == 'default' %]
+     [% 'Default (no language selected)' | $T8 %]
+     [%- ELSE %]
+     [%- HTML.escape(language.description) %]
+     [%- END %]
+    </td>
+    <td><input name="translation__[% language.id %]" size="40" value="[% HTML.escape(language.translation) %]"></td>
+   </tr>
+   [%- END %]
+
+  </table>
+
+  <p>
+   <input type="hidden" name="action" value="save_sepa_strings">
+   <input type="submit" class="submit" value="[% 'Save' | $T8 %]">
+  </p>
+
+ </form>
+
+</body>
+</html>
index 1eb34be40a702de72ace114780febc3db0d8b142..56d36d042df8acd6a8c912760f5594de2df537c8 100644 (file)
@@ -1,12 +1,25 @@
 [%- USE T8 %]
 [% USE HTML %][% USE LxERP %]
+[% IF vc == 'vendor' %]
+ [% SET is_vendor = 1 %]
+ [% SET arap = 'ap' %]
+ [% SET iris = 'ir' %]
+[% ELSE %]
+ [% SET is_vendor = 0 %]
+ [% SET arap = 'ar' %]
+ [% SET iris = 'is' %]
+[%- END %]
 <body>
 
  <p><div class="listtop">[% title %]</div></p>
 
  <form action="sepa.pl" method="post">
   <p>
-   [% 'Please select the source bank account for the transfers:' | $T8 %]
+   [%- IF is_vendor %]
+    [% 'Please select the source bank account for the transfers:' | $T8 %]
+   [%- ELSE %]
+    [% 'Please select the destination bank account for the collections:' | $T8 %]
+   [%- END %]
    <br>
    [%- INCLUDE generic/multibox.html
          name      = 'bank_account.id',
@@ -20,7 +33,7 @@
    <table border="0">
     <tr>
      <th class="listheading" align="center"><input type="checkbox" id="select_all"></th>
-     <th class="listheading">[% 'Vendor' | $T8 %]</th>
+     <th class="listheading">[% IF is_vendor %][% 'Vendor' | $T8 %][%- ELSE %][%- LxERP.t8('Customer') %][%- END %]</th>
      <th class="listheading">[% 'Invoice' | $T8 %]</th>
      <th class="listheading" align="right">[% 'Amount' | $T8 %]</th>
      <th class="listheading" align="right">[% 'Open amount' | $T8 %]</th>
     </tr>
 
     [%- FOREACH invoice = INVOICES %]
-     <input type="hidden" name="bank_transfers[+].ap_id" value="[% HTML.escape(invoice.id) %]">
+     <input type="hidden" name="bank_transfers[+].[% arap %]_id" value="[% HTML.escape(invoice.id) %]">
 
      <tr class="listrow[% loop.count % 2 %]">
       <td align="center">
-       [%- IF invoice.vendor_bank_info_ok %]
+       [%- IF invoice.vc_bank_info_ok %]
         <input type="checkbox" name="bank_transfers[].selected" value="1">
        [%- END %]
       </td>
       <td>
-       [%- IF loop.first || (previous_vendorname != invoice.vendorname) %]
-        <a href="ct.pl?action=edit&db=vendor&id=[% HTML.url(invoice.vendor_id) %]&callback=[% HTML.url('sepa.pl?action=bank_transfer_add') %]">
-         [%- GET HTML.escape(invoice.vendorname);
-             SET previous_vendorname = invoice.vendorname;
-             IF !invoice.vendor_bank_info_ok;
+       [%- IF loop.first || (previous_vcname != invoice.vcname) %]
+        <a href="ct.pl?action=edit&db=[% vc %]&id=[% HTML.url(invoice.vc_id) %]&callback=[% HTML.url('sepa.pl?action=bank_transfer_add&vc=' _ vc) %]">
+         [%- GET HTML.escape(invoice.vcname);
+             SET previous_vcname = invoice.vcname;
+             IF !invoice.vc_bank_info_ok;
                GET ' <sup>(1)</sup>';
-               SET show_vendor_bank_info_footnote = '1';
+               SET show_vc_bank_info_footnote = '1';
              END; -%]
         </a>
        [%- END -%]
       </td>
 
       <td>
-       <a href="[% IF invoice.invoice %]ir[% ELSE %]ap[% END %].pl?action=edit&id=[% HTML.escape(invoice.id) %]">
+       <a href="[% IF invoice.invoice %][% iris %][% ELSE %][% arap %][% END %].pl?action=edit&id=[% HTML.escape(invoice.id) %]">
         [% HTML.escape(invoice.invnumber) %]
        </a>
       </td>
@@ -60,7 +73,7 @@
       <td align="right">[% LxERP.format_amount(invoice.invoice_amount, -2) %]</td>
       <td align="right">[% LxERP.format_amount(invoice.open_amount, -2) %]</td>
       <td align="right">[% invoice.duedate %]</td>
-      <td><input name="bank_transfers[].reference" value="[% HTML.escape(invoice.invnumber) %]"></td>
+      <td><input name="bank_transfers[].reference" value="[% HTML.escape(invoice.reference_prefix _ invoice.invnumber) %]"></td>
       <td align="right">
        <input name="bank_transfers[].amount" value="[% LxERP.format_amount(invoice.invoice_amount, -2) %]" style="text-align: right">
       </td>
    </table>
   </p>
 
-  [%- IF show_vendor_bank_info_footnote %]
+  [%- IF show_vc_bank_info_footnote %]
    <p>
-    <sup>(1)</sup> [%- 'No bank information has been entered in this vendor\'s master data entry. You cannot create bank transfers unless you enter bank information.' | $T8 %]
+    <sup>(1)</sup>
+    [%- IF is_vendor %]
+     [%- 'No bank information has been entered in this vendor\'s master data entry. You cannot create bank transfers unless you enter bank information.' | $T8 %]
+    [%- ELSE %]
+     [%- 'No bank information has been entered in this customer\'s master data entry. You cannot create bank collections unless you enter bank information.' | $T8 %]
+    [%- END %]
    </p>
   [%- END %]
 
@@ -80,6 +98,7 @@
   </p>
 
   <input type="hidden" name="action" value="dispatcher">
+  <input type="hidden" name="vc" value="[%- HTML.escape(vc) %]">
  </form>
 
  <script type="text/javascript" src="js/jquery.js"></script>
index 06bbea880b6c607cd883067445c967602608e183..0a5059a201c51b78f89a041eec7a14c63cddb0c4 100644 (file)
@@ -1,5 +1,14 @@
 [%- USE T8 %]
 [% USE HTML %][% USE LxERP %]
+[% IF vc == 'vendor' %]
+ [% SET is_vendor = 1 %]
+ [% SET arap = 'ap' %]
+ [% SET iris = 'ir' %]
+[% ELSE %]
+ [% SET is_vendor = 0 %]
+ [% SET arap = 'ar' %]
+ [% SET iris = 'is' %]
+[%- END %]
 <body>
 
  [%- IF error_message %]
@@ -9,7 +18,12 @@
  <p><div class="listtop">[% title %]</div></p>
 
  <form action="sepa.pl" method="post">
-  <p>1. [% 'Please select the source bank account for the transfers:' | $T8 %]
+  <p>1.
+   [%- IF is_vendor %]
+    [% 'Please select the source bank account for the transfers:' | $T8 %]
+   [%- ELSE %]
+    [% 'Please select the destination bank account for the collections:' | $T8 %]
+   [%- END %]
    <br>
    [%- INCLUDE generic/multibox.html
          name      = 'bank_account.id',
   </p>
 
   <p>
-   2. [% 'Please Check the bank information for each vendor:' | $T8 %]
+   2.
+   [%- IF is_vendor %]
+    [% 'Please Check the bank information for each vendor:' | $T8 %]
+   [%- ELSE %]
+    [% 'Please Check the bank information for each customer:' | $T8 %]
+   [%- END %]
    <br>
    <table>
     <tr>
-     <th class="listheading">[% 'Vendor' | $T8 %]</th>
+     <th class="listheading">[%- IF is_vendor %][% 'Vendor' | $T8 %][%- ELSE %][%- LxERP.t8('Customer') %][%- END %]</th>
      <th class="listheading">[% 'IBAN' | $T8 %]</th>
      <th class="listheading">[% 'BIC' | $T8 %]</th>
      <th class="listheading">[% 'Bank' | $T8 %]</th>
     </tr>
 
-    [%- FOREACH vbi = VENDOR_BANK_INFO %]
+    [%- FOREACH vbi = VC_BANK_INFO %]
     <tr class="listrow[% loop.count % 1 %]">
      <td>
-      <input type="hidden" name="vendor_bank_info[+].id" value="[% HTML.escape(vbi.id) %]">
-      <input type="hidden" name="vendor_bank_info[].name" value="[% HTML.escape(vbi.name) %]">
+      <input type="hidden" name="vc_bank_info[+].id" value="[% HTML.escape(vbi.id) %]">
+      <input type="hidden" name="vc_bank_info[].name" value="[% HTML.escape(vbi.name) %]">
       [% HTML.escape(vbi.name) %]
      </td>
-     <td><input name="vendor_bank_info[].iban" size="20" value="[% HTML.escape(vbi.iban) %]"></td>
-     <td><input name="vendor_bank_info[].bic" size="20" value="[% HTML.escape(vbi.bic) %]"></td>
-     <td><input name="vendor_bank_info[].bank" size="30" value="[% HTML.escape(vbi.bank) %]"></td>
+     <td><input name="vc_bank_info[].iban" size="20" value="[% HTML.escape(vbi.iban) %]"></td>
+     <td><input name="vc_bank_info[].bic" size="20" value="[% HTML.escape(vbi.bic) %]"></td>
+     <td><input name="vc_bank_info[].bank" size="30" value="[% HTML.escape(vbi.bank) %]"></td>
     </tr>
     [%- END %]
    </table>
    <br>
    <table>
     <tr>
-     <th class="listheading">[% 'Vendor' | $T8 %]</th>
+     <th class="listheading">[%- IF is_vendor %][% 'Vendor' | $T8 %][%- ELSE %][%- LxERP.t8('Customer') %][%- END %]</th>
      <th class="listheading">[% 'Invoice' | $T8 %]</th>
      <th class="listheading" align="right">[% 'Amount' | $T8 %]</th>
      <th class="listheading" align="right">[% 'Open amount' | $T8 %]</th>
      <th class="listheading">[% 'Purpose' | $T8 %]</th>
-     <th class="listheading" align="right">[% 'Bank transfer amount' | $T8 %]</th>
+     <th class="listheading" align="right">[%- IF is_vendor %][% 'Bank transfer amount' | $T8 %][%- ELSE %][%- LxERP.t8('Bank collection amount') %][%- END %]</th>
      <th class="listheading">[% 'Execution date' | $T8 %]</th>
     </tr>
 
     [%- FOREACH bank_transfer = BANK_TRANSFERS %]
-     <input type="hidden" name="bank_transfers[+].ap_id" value="[% HTML.escape(bank_transfer.id) %]">
-     <input type="hidden" name="bank_transfers[].vendor_id" value="[% HTML.escape(bank_transfer.vendor_id) %]">
+     <input type="hidden" name="bank_transfers[+].[% arap %]_id" value="[% HTML.escape(bank_transfer.id) %]">
+     <input type="hidden" name="bank_transfers[].vc_id" value="[% HTML.escape(bank_transfer.vc_id) %]">
      <input type="hidden" name="bank_transfers[].selected" value="1">
 
      <tr class="listrow[% loop.count % 2 %]">
       <td>
-       [%- IF loop.first || (previous_vendorname != bank_transfer.vendorname) %]
-        <a href="ct.pl?action=edit&db=vendor&id=[% HTML.url(bank_transfer.vendor_id) %]&callback=[% HTML.url('sepa.pl?action=bank_transfer_add') %]">
-         [%- GET HTML.escape(bank_transfer.vendorname);
-             SET previous_vendorname = bank_transfer.vendorname; -%]
+       [%- IF loop.first || (previous_vcname != bank_transfer.vcname) %]
+        <a href="ct.pl?action=edit&db=[% vc %]&id=[% HTML.url(bank_transfer.vc_id) %]&callback=[% HTML.url('sepa.pl?action=bank_transfer_add&vc=' _ vc) %]">
+         [%- GET HTML.escape(bank_transfer.vcname);
+             SET previous_vcname = bank_transfer.vcname; -%]
         </a>
        [%- END -%]
       </td>
 
       <td>
-       <a href="[% IF bank_transfer.invoice %]ir[% ELSE %]ap[% END %].pl?action=edit&id=[% HTML.escape(bank_transfer.id) %]">
+       <a href="[% IF bank_transfer.invoice %][% iris %][% ELSE %][% arap %][% END %].pl?action=edit&id=[% HTML.escape(bank_transfer.id) %]">
         [% HTML.escape(bank_transfer.invnumber) %]
        </a>
       </td>
   </p>
 
   <p>
-   <input type="submit" class="submit" name="action_bank_transfer_create" value="[% 'Create bank transfer' | $T8 %]">
+   [%- IF is_vendor %]
+    <input type="submit" class="submit" name="action_bank_transfer_create" value="[% 'Create bank transfer' | $T8 %]">
+   [%- ELSE %]
+    <input type="submit" class="submit" name="action_bank_transfer_create" value="[% 'Create bank collection' | $T8 %]">
+   [%- END %]
   </p>
 
   <input type="hidden" name="action" value="dispatcher">
+  <input type="hidden" name="vc" value="[%- HTML.escape(vc) %]">
   <input type="hidden" name="confirmation" value="1">
  </form>
 
index d71ae55b802a52befb8ac9c0355e6892fd5d9f3d..6740ba1f316c5019af4b5714f0e9d1a12989fa6c 100644 (file)
  <p>
   <ul>
    <li>
-    <a href="sepa.pl?action=bank_transfer_download_sepa_xml&id=[% HTML.url(id) %]">
+    <a href="sepa.pl?action=bank_transfer_download_sepa_xml&id=[% HTML.url(id) %]&vc=[% HTML.url(vc) %]">
      [% 'Download SEPA XML export file' | $T8 %]
     </a>
    </li>
 
    <li>
-    <a href="sepa.pl?action=bank_transfer_list&l_open=1&l_not_executed=1">
+    <a href="sepa.pl?action=bank_transfer_list&l_open=1&l_not_executed=1&vc=[% HTML.url(vc) %]">
      [% 'List open SEPA exports' | $T8 %]
     </a>
    </li>
index 28b17edf5fe7921de2c07b4fbec47489113e5caa..a534d1adae56288cdbe736ff53bc5ef85847ab59 100644 (file)
@@ -1,6 +1,15 @@
 [%- USE T8 %]
 [% USE HTML %]
 [% USE LxERP %]
+[% IF vc == 'vendor' %]
+ [% SET is_vendor = 1 %]
+ [% SET arap = 'ap' %]
+ [% SET iris = 'ir' %]
+[% ELSE %]
+ [% SET is_vendor = 0 %]
+ [% SET arap = 'ar' %]
+ [% SET iris = 'is' %]
+[%- END %]
 <body>
 
  <p><div class="listtop">[% title %]: [% HTML.escape(export.ids.join(', ')) %]</div></p>
       <th class="listheading" align="center"><input type="checkbox" id="select_all"></th>
      [%- END %]
      <th class="listheading">[% 'Invoice' | $T8 %]</th>
-     <th class="listheading">[% 'Vendor' | $T8 %]</th>
-     <th class="listheading" colspan="2">[% 'Source bank account' | $T8 %]</th>
-     <th class="listheading" colspan="2">[% 'Target bank account' | $T8 %]</th>
+     <th class="listheading">[%- IF is_vendor %][% 'Vendor' | $T8 %][%- ELSE %][%- LxERP.t8('Customer') %][%- END %]</th>
+     [%- IF is_vendor %]
+      <th class="listheading" colspan="2">[% 'Source bank account' | $T8 %]</th>
+      <th class="listheading" colspan="2">[% 'Target bank account' | $T8 %]</th>
+     [%- ELSE %]
+      <th class="listheading" colspan="2">[% 'Target bank account' | $T8 %]</th>
+      <th class="listheading" colspan="2">[% 'Source bank account' | $T8 %]</th>
+     [%- END %]
      <th class="listheading" align="right">[% 'Amount' | $T8 %]</th>
      <th class="listheading">[% 'Reference' | $T8 %]</th>
      <th class="listheading" align="right">[% 'Requested execution date' | $T8 %]</th>
        </td>
       [%- END %]
       <td>
-       <a href="[% IF item.invoice %]ir[% ELSE %]ap[% END %].pl?action=edit&type=invoice&id=[% HTML.url(item.ap_id) %]">[% HTML.escape(item.invnumber) %]</a>
+       <a href="[% IF item.invoice %][% iris %][% ELSE %][% arap %][% END %].pl?action=edit&type=invoice&id=[% IF is_vendor %][% HTML.url(item.ap_id) %][% ELSE %][% HTML.url(item.ar_id) %][% END %]">[% HTML.escape(item.invnumber) %]</a>
       </td>
-      <td>[% HTML.escape(item.vendor_name) %]</td>
+      <td>[% HTML.escape(item.vc_name) %]</td>
       <td>[% HTML.escape(item.our_iban) %]</td>
       <td>[% HTML.escape(item.our_bic) %]</td>
-      <td>[% HTML.escape(item.vendor_iban) %]</td>
-      <td>[% HTML.escape(item.vendor_bic) %]</td>
+      <td>[% HTML.escape(item.vc_iban) %]</td>
+      <td>[% HTML.escape(item.vc_bic) %]</td>
       <td align="right">[% HTML.escape(LxERP.format_amount(item.amount, 2)) %]</td>
       <td>[% HTML.escape(item.reference) %]</td>
       <td align="right">[% HTML.escape(item.requested_execution_date) %]</td>
     [%- END %]
    [%- END %]
   [%- END %]
+
+     <input type="hidden" name="vc" value="[% HTML.escape(vc) %]">
  </form>
 
 </body>
index 79f373f2cf2a5f6702317507991fb05cf7905c1a..1eab32bfb3abc985dbf0ec8774fb92d640dbc6f3 100644 (file)
@@ -4,6 +4,7 @@
 [%- IF show_buttons %]
  <input type="hidden" name="action" value="dispatcher">
  <input type="hidden" name="mode" value="multi">
+ <input type="hidden" name="vc" value="[%- HTML.escape(vc) %]">
 
  <p>
   <input type="submit" class="submit" name="action_bank_transfer_download_sepa_xml" value="[% 'SEPA XML download' | $T8 %]">
index 4d1a6dcf2807bbd04b38b47230ba00e250bbc32e..063b4eec42a4e5a244548fdbe72497ce23ff66cc 100644 (file)
@@ -6,7 +6,11 @@
 
  <form action="sepa.pl" method="post">
   <p>
-   [%- 'Do you really want to close the following SEPA exports? No payment will be recorded for bank transfers that haven\'t been marked as executed yet.' | $T8 %]
+   [%- IF vc == 'vendor' %]
+    [%- 'Do you really want to close the following SEPA exports? No payment will be recorded for bank transfers that haven\'t been marked as executed yet.' | $T8 %]
+   [%- ELSE %]
+    [%- 'Do you really want to close the following SEPA exports? No payment will be recorded for bank collections that haven\'t been marked as executed yet.' | $T8 %]
+   [%- END %]
   </p>
 
   <p>
@@ -14,7 +18,7 @@
    [%- FOREACH id = OPEN_EXPORT_IDS %]
     [%- UNLESS loop.first %], [%- END %]
     <input type="hidden" name="open_export_ids[]" value="[% HTML.escape(id) %]">
-    <a href="sepa.pl?action=bank_transfer_edit&id=[% HTML.url(id) %]">[% HTML.escape(id) %]</a>
+    <a href="sepa.pl?action=bank_transfer_edit&id=[% HTML.url(id) %]&vc=[% HTML.url(vc) %]">[% HTML.escape(id) %]</a>
    [%- END %]
   </p>
 
@@ -24,6 +28,7 @@
   </p>
 
   <input type="hidden" name="action" value="dispatcher">
+  <input type="hidden" name="vc" value="[%- HTML.escape(vc) %]">
  </form>
 
 </body>
index 306179fe5f4a8313a1c8d13c6bccd337a44f0893..bc60d8850f2072fb173f0b7b5104fffc07eab81d 100644 (file)
@@ -1,5 +1,5 @@
 [%- USE T8 %]
-[% USE HTML %]
+[% USE HTML %][% USE LxERP %]
 <body>
 
  <p><div class="listtop">[% title %]</div></p>
@@ -8,8 +8,8 @@
   <p>
    <table>
     <tr>
-     <td align="right">[% 'Vendor' | $T8 %]</td>
-     <td><input name="f_vendor"></td>
+     <td align="right">[%- IF vc == 'vendor' %][% 'Vendor' | $T8 %][%- ELSE %][%- LxERP.t8('Customer') %][%- END %]</td>
+     <td><input name="f_vc"></td>
     </tr>
 
     <tr>
@@ -86,6 +86,7 @@
 
   <p>
    <input type="hidden" name="action" value="dispatcher">
+   <input type="hidden" name="vc" value="[%- HTML.escape(vc) %]">
    <input type="submit" class="submit" name="action_bank_transfer_list" value="[% 'Continue' | $T8 %]">
   </p>
  </form>
diff --git a/templates/webpages/vk/search_invoice.html b/templates/webpages/vk/search_invoice.html
new file mode 100644 (file)
index 0000000..18ff0fe
--- /dev/null
@@ -0,0 +1,173 @@
+[%- USE T8 %]
+<body>
+
+ <form method=post name="search_invoice" action=[% script %]>
+
+  <table width=100%>
+  <tr><th class=listtop>[% title %]</th></tr>
+  <tr height="5"></tr>
+  <tr>
+   <td>
+    <table>
+     <tr>
+       <td>[% 'Main sorting' | $T8 %]</td>
+       <td colspan="3">
+        <input name="sortby" id="artikelsort" class="radio" type="radio" value="artikelsort" checked>
+        <label for="artikelsort">[% 'Artikel' | $T8 %]</label>
+        <input name="sortby" id="customersort" class="radio" type="radio" value="customersort">
+        <label for="customersort">[% 'Customer' | $T8 %]</label>
+       </td>
+      </tr>
+
+
+
+     <tr>
+      <th align=right>[% 'Customer' | $T8 %]</th>
+      <td colspan=3>
+            [%- INCLUDE 'generic/multibox.html'
+                 name          = 'customer',
+                 default       = oldcustomer,
+                 style         = 'width: 250px',
+                 DATA          = ALL_VC,
+                 id_sub        = 'vc_keys',
+                 label_key     = 'name',
+                 select        = vc_select,
+                 limit         = vclimit,
+                 show_empty    = 1,
+                 allow_textbox = 1,
+                 -%]
+      </td>
+     </tr>
+     <tr>
+      <th align=right nowrap>[% 'Department' | $T8 %]</th>
+      <td>
+            [%- INCLUDE 'generic/multibox.html'
+                 name          = 'department',
+                 style         = 'width: 250px',
+                 DATA          = ALL_DEPARTMENTS,
+                 id_key        = 'id',
+                 label_key     = 'description',
+                 show_empty    = 1,
+                 allow_textbox = 0,
+            -%]
+      </td>
+     </tr>
+     <tr>
+      <th align="right">[% 'Project Number' | $T8 %]</th>
+      <td colspan="3">
+            [%- INCLUDE 'generic/multibox.html'
+                 name          =  'project_id',
+                 style         = "width: 250px",
+                 DATA          =  ALL_PROJECTS,
+                 id_key        = 'id',
+                 label_key     = 'projectnumber',
+                 limit         = vclimit,
+                 show_empty    = 1,
+                 allow_textbox = 0,
+            -%]
+      </td>
+     </tr>
+      <tr>
+       <th align="right" nowrap>[% 'Part Number' | $T8 %]</th>
+       <td><input name="partnumber" size="20"></td>
+      </tr>
+      <tr>
+       <th align="right" nowrap>[% 'Part Description' | $T8 %]</th>
+       <td colspan="3"><input name="description" size="40"></td>
+      </tr>
+     <tr>
+      <th align=right nowrap>[% 'From' | $T8 %]</th>
+      <td>
+       <input name=transdatefrom id=transdatefrom size=11 title="[% dateformat | html %]" onBlur="check_right_date_format(this)">
+       <input type=button name=transdatefrom id="trigger1" value=[% 'button' | $T8 %]>
+      </td>
+     <th align=right>[% 'Bis' | $T8 %]</th>
+     <td>
+      <input name=transdateto id=transdateto size=11 title="[% dateformat | html %]" onBlur="check_right_date_format(this)">
+      <input type=button name=transdateto name=transdateto id="trigger2" value=[% 'button' | $T8 %]>
+     </td>
+    </tr>
+   <input type=hidden name=sort value=transdate>
+   </table>
+    </td>
+    </tr>
+    <tr>
+     <td>
+      <table>
+       <tr>
+        <th align=right nowrap>[% 'Include in Report' | $T8 %]</th>
+        <td>
+         <table width=100%>
+          <tr>
+           <td align=right><input name="l_description" class=checkbox type=checkbox value=Y checked></td>
+           <td nowrap>[% 'Description' | $T8 %]</td>
+           <td align=right><input name="l_partnumber" class=checkbox type=checkbox value=Y></td>
+           <td nowrap>[% 'Part Number' | $T8 %]</td>
+           <td align=right><input name="l_invnumber" class=checkbox type=checkbox value=Y checked></td>
+           <td nowrap>[% 'Invnumber' | $T8 %]</td>
+           <td align=right><input name="l_transdate" class=checkbox type=checkbox value="Y" checked></td>
+           <td nowrap>[% 'Invdate' | $T8 %]</td>
+          </tr>
+          <tr>
+           <td align=right><input name="l_qty" class=checkbox type=checkbox value="Y" checked></td>
+           <td nowrap>[% 'Quantity' | $T8 %]</td>
+           <td align=right><input name="l_discount" class=checkbox type=checkbox value="Y"></td>
+           <td nowrap>[% 'Discount' | $T8 %]</td>
+           <td align=right><input name="l_unit" class=checkbox type=checkbox value="Y"></td>
+           <td nowrap>[% 'Unit' | $T8 %]</td>
+          </tr>
+          <tr>
+           <td align=right><input name="l_sellprice" class=checkbox type=checkbox value=Y checked></td>
+           <td nowrap>[% 'Sales price' | $T8 %]</td>
+           <td align=right><input name="l_sellprice_total" class=checkbox type=checkbox value=Y checked></td>
+           <td nowrap>[% 'Sales price total' | $T8 %]</td>
+           <td align=right><input name="l_lastcost" class=checkbox type=checkbox value=Y checked></td>
+           <td nowrap>[% 'Purchase price' | $T8 %]</td>
+           <td align=right><input name="l_lastcost_total" class=checkbox type=checkbox value=Y checked></td>
+           <td nowrap>[% 'Purchase price total' | $T8 %]</td>
+          </tr>
+          <tr>
+           <td align=right><input name="l_marge_total" class=checkbox type=checkbox value=Y checked></td>
+           <td nowrap>[% 'Margetotal' | $T8 %]</td>
+           <td align=right><input name="l_marge_percent" class=checkbox type=checkbox value=Y checked></td>
+           <td nowrap>[% 'Margepercent' | $T8 %]</td>
+          </tr>
+          <tr>
+           <td align=right><input name="l_subtotal" class=checkbox type=checkbox value=Y checked></td>
+           <td nowrap>[% 'Subtotal' | $T8 %]</td>
+           <td align=right><input name="l_total" class=checkbox type=checkbox value="Y" checked></td>
+           <td nowrap>[% 'Total' | $T8 %]</td>
+           <td align=right><input name="l_headers" class=checkbox type=checkbox value="Y" checked></td>
+           <td nowrap>[% 'Headers' | $T8 %]</td>
+          </tr>
+          <tr>
+            <th align="right" nowrap>[% 'Decimalplaces' | $T8 %]</th>
+            <td colspan="4"><input name="decimalplaces" size="2" value="2"></td>
+          </tr>
+         </table>
+        </td>
+       </tr>
+      </table>
+     </td>
+    </tr>
+    <tr>
+     <td><hr size=3 noshade></td>
+    </tr>
+   </table>
+   <input type=hidden name=nextsub value=[% nextsub %]>
+   <br>
+   <input class=submit type=submit name=action value="[% 'Continue' | $T8 %]">
+  </form>
+ <script type="text/javascript">
+ <!--
+   Calendar.setup( { inputField : "transdatefrom", ifFormat :"[% myconfig_jsc_dateformat %]", align : "BR", button : "trigger1" });
+   Calendar.setup( { inputField : "transdateto", ifFormat :"[% myconfig_jsc_dateformat %]", align : "BL", button : "trigger2" });
+   $(document).ready(function(){
+    $('customer').focus();
+    setupDateFormat('[% dateformat | html %]','[% 'Falsches Datumsformat!' | $T8 %]');
+    setupPoints('[% numberformat | html %]','[% 'wrongformat' | $T8 %]');
+   })
+ //-->
+ </script>
+ </body>
+</html>
diff --git a/users/partshead.csv b/users/partshead.csv
deleted file mode 100644 (file)
index 53793b4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-partnumber     fvId    wgr     partsgroup      ean     model   ErsatzArt       makemodel       MarkeText       description     cat01   cat01Text       cat02   cat02Text       cat03   cat03Text       cat04   cat04Text       KzStueck        KzAL    KzAktion        KzSperre        pg_1    pg_2    listprice       lastcost        InfLagME        InfLagWE\r
diff --git a/vk.pl b/vk.pl
new file mode 120000 (symlink)
index 0000000..385000d
--- /dev/null
+++ b/vk.pl
@@ -0,0 +1 @@
+am.pl
\ No newline at end of file