Merge branch 'master' of git@vc.linet-services.de:public/lx-office-erp
authorHolger Lindemann <hli@lenny.hoch.ul>
Mon, 25 Jun 2012 16:42:07 +0000 (18:42 +0200)
committerHolger Lindemann <hli@lenny.hoch.ul>
Mon, 25 Jun 2012 16:42:07 +0000 (18:42 +0200)
15 files changed:
SL/CT.pm
SL/Controller/CsvImport/Base.pm
SL/Controller/CsvImport/Contact.pm
SL/DB/Contact.pm
SL/DB/DeliveryOrderItem.pm
SL/DB/Helper/CustomVariables.pm
SL/SEPA.pm
SL/VK.pm
bin/mozilla/ct.pl
bin/mozilla/io.pl
doc/changelog
locale/de/all
templates/webpages/ct/_contact.html
templates/webpages/ct/search_contact.html
templates/webpages/gl/search.html

index 49eb591..fabc3ca 100644 (file)
--- a/SL/CT.pm
+++ b/SL/CT.pm
@@ -367,73 +367,18 @@ sub save_customer {
   do_query( $form, $dbh, $query, @values );
 
   $query = undef;
+  my @columns = qw(cp_title cp_givenname cp_name cp_email cp_phone1 cp_phone2 cp_abteilung cp_fax
+                   cp_mobile1 cp_mobile2 cp_satphone cp_satfax cp_project cp_privatphone cp_privatemail cp_birthday cp_gender
+                   cp_street cp_zipcode cp_city);
+  @values     = map { $_ eq 'cp_gender' ? ($form->{$_} eq 'f' ? 'f' : 'm') : $form->{$_} } @columns;
+
   if ( $form->{cp_id} ) {
-    $query = qq|UPDATE contacts SET | .
-      qq|cp_title = ?,  | .
-      qq|cp_givenname = ?, | .
-      qq|cp_name = ?, | .
-      qq|cp_email = ?, | .
-      qq|cp_phone1 = ?, | .
-      qq|cp_phone2 = ?, | .
-      qq|cp_abteilung = ?, | .
-      qq|cp_fax = ?, | .
-      qq|cp_mobile1 = ?, | .
-      qq|cp_mobile2 = ?, | .
-      qq|cp_satphone = ?, | .
-      qq|cp_satfax = ?, | .
-      qq|cp_project = ?, | .
-      qq|cp_privatphone = ?, | .
-      qq|cp_privatemail = ?, | .
-      qq|cp_birthday = ?, | .
-      qq|cp_gender = ? | .
-      qq|WHERE cp_id = ?|;
-    @values = (
-      $form->{cp_title},
-      $form->{cp_givenname},
-      $form->{cp_name},
-      $form->{cp_email},
-      $form->{cp_phone1},
-      $form->{cp_phone2},
-      $form->{cp_abteilung},
-      $form->{cp_fax},
-      $form->{cp_mobile1},
-      $form->{cp_mobile2},
-      $form->{cp_satphone},
-      $form->{cp_satfax},
-      $form->{cp_project},
-      $form->{cp_privatphone},
-      $form->{cp_privatemail},
-      $form->{cp_birthday},
-      $form->{cp_gender} eq 'f' ? 'f' : 'm',
-      $form->{cp_id}
-      );
+    $query = qq|UPDATE contacts SET | . join(', ', map { "${_} = ?" } @columns) . qq| WHERE cp_id = ?|;
+    push @values, $form->{cp_id};
+
   } elsif ( $form->{cp_name} || $form->{cp_givenname} ) {
-    $query =
-      qq|INSERT INTO contacts ( cp_cv_id, cp_title, cp_givenname,  | .
-      qq|  cp_name, cp_email, cp_phone1, cp_phone2, cp_abteilung, cp_fax, cp_mobile1, | .
-      qq|  cp_mobile2, cp_satphone, cp_satfax, cp_project, cp_privatphone, cp_privatemail, | .
-      qq|  cp_birthday, cp_gender) | .
-      qq|VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|;
-    @values = (
-      $form->{id},
-      $form->{cp_title},
-      $form->{cp_givenname},
-      $form->{cp_name},
-      $form->{cp_email},
-      $form->{cp_phone1},
-      $form->{cp_phone2},
-      $form->{cp_abteilung},
-      $form->{cp_fax},
-      $form->{cp_mobile1},
-      $form->{cp_mobile2},
-      $form->{cp_satphone},
-      $form->{cp_satfax},
-      $form->{cp_project},
-      $form->{cp_privatphone},
-      $form->{cp_privatemail},
-      $form->{cp_birthday},
-      $form->{cp_gender} eq 'f' ? 'f' : 'm',
-      );
+    $query = qq|INSERT INTO contacts (| . join(', ', 'cp_cv_id', @columns) . qq|) VALUES (?, | . join(', ', ('?') x scalar(@columns)) . qq|)|;
+    unshift @values, $form->{id};
   }
   do_query( $form, $dbh, $query, @values ) if ($query);
 
@@ -1226,7 +1171,7 @@ sub search_contacts {
     'vcnumber'  => 'vcnumber, cp_name, cp_givenname',
     );
 
-  my %sortcols  = map { $_ => 1 } qw(cp_name cp_givenname cp_phone1 cp_phone2 cp_mobile1 cp_email vcname vcnumber);
+  my %sortcols  = map { $_ => 1 } qw(cp_name cp_givenname cp_phone1 cp_phone2 cp_mobile1 cp_email cp_street cp_zipcode cp_city vcname vcnumber);
 
   my $order_by  = $sortcols{$::form->{sort}} ? $::form->{sort} : 'cp_name';
   $::form->{sort} = $order_by;
index 6a66e8c..eda921f 100644 (file)
@@ -9,6 +9,7 @@ use SL::DB::Customer;
 use SL::DB::Language;
 use SL::DB::PaymentTerm;
 use SL::DB::Vendor;
+use SL::DB::Contact;
 
 use parent qw(Rose::Object);
 
index e5dadbb..5d0a1be 100644 (file)
@@ -3,6 +3,8 @@ package SL::Controller::CsvImport::Contact;
 use strict;
 
 use SL::Helper::Csv;
+use SL::DB::CustomVariable;
+use SL::DB::CustomVariableConfig;
 
 use parent qw(SL::Controller::CsvImport::Base);
 
@@ -16,6 +18,12 @@ sub init_class {
   $self->class('SL::DB::Contact');
 }
 
+sub init_all_cvar_configs {
+  my ($self) = @_;
+
+  return SL::DB::Manager::CustomVariableConfig->get_all(where => [ module => 'Contacts' ]);
+}
+
 sub check_objects {
   my ($self) = @_;
 
@@ -23,9 +31,11 @@ sub check_objects {
     $self->check_name($entry);
     $self->check_vc($entry, 'cp_cv_id');
     $self->check_gender($entry);
+    $self->handle_cvars($entry);
   }
 
   $self->add_info_columns({ header => $::locale->text('Customer/Vendor'), method => 'vc_name' });
+  $self->add_cvar_raw_data_columns;
 }
 
 sub check_name {
@@ -87,6 +97,7 @@ sub setup_displayable_columns {
   my ($self) = @_;
 
   $self->SUPER::setup_displayable_columns;
+  $self->add_cvar_columns_to_displayable_columns;
 
   $self->add_displayable_columns({ name => 'cp_abteilung',   description => $::locale->text('Department')                    },
                                  { name => 'cp_birthday',    description => $::locale->text('Birthday')                      },
index d891f07..565566a 100644 (file)
@@ -14,6 +14,8 @@ use SL::DB::Helper::CustomVariables (
 # Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
 __PACKAGE__->meta->make_manager_class;
 
+__PACKAGE__->meta->initialize;
+
 sub used {
   my ($self) = @_;
 
index e832ddb..873c0a4 100644 (file)
@@ -13,6 +13,8 @@ use SL::DB::Helper::CustomVariables (
 
 __PACKAGE__->meta->make_manager_class;
 
+__PACKAGE__->meta->initialize;
+
 # methods
 
 sub part {
index ef6a0a9..c935cba 100644 (file)
@@ -18,7 +18,7 @@ sub import {
 
   $params{module}     ||= _calc_modules_from_overloads(%params) if $params{overloads};
   $params{sub_module} ||= '';
-  $params{id}         ||= 'id';
+  $params{id}         ||= _get_primary_key_column($caller_package);
 
   $params{module} || $params{sub_module}  or croak 'need param module or sub_module';
 
@@ -51,7 +51,7 @@ sub make_cvar_accessor {
     custom_variables => {
       type         => 'one to many',
       class        => 'SL::DB::CustomVariable',
-      column_map   => { ($params{id} || 'id') => 'trans_id' },
+      column_map   => { $params{id} => 'trans_id' },
       query_args   => [ sub_module => $params{sub_module}, @module_filter ],
     }
   );
@@ -165,6 +165,17 @@ sub _calc_modules_from_overloads {
   return [ keys %modules ];
 }
 
+sub _get_primary_key_column {
+  my ($caller_package) = @_;
+  my $meta             = $caller_package->meta;
+
+  my $column_name;
+  $column_name = $meta->{primary_key}->{columns}->[0] if $meta->{primary_key} && (ref($meta->{primary_key}->{columns}) eq 'ARRAY') && (1 == scalar(@{ $meta->{primary_key}->{columns} }));
+
+  croak "Unable to retrieve primary key column name: meta information for package $caller_package not set up correctly" unless $column_name;
+
+  return $column_name;
+}
 
 1;
 
index ced75be..d2eb13f 100644 (file)
@@ -403,6 +403,12 @@ sub post_payment {
     # Update the invoice to reflect the new paid amount.
     do_statement($form, @{ $handles{update_arap} }, $orig_item->{amount}, $orig_item->{"${arap}_id"});
 
+    # Update datepaid of invoice. set_datepaid (which has some extra logic)
+    # finds the date from acc_trans, where the payment has already been
+    # recorded above, so we don't need to explicitly pass
+    # $item->{execution_date}
+    IO->set_datepaid(table => "$arap", id => $orig_item->{"${arap}_id"}, dbh => $dbh);
+
     # Update the item to reflect that it has been posted.
     do_statement($form, @{ $handles{finish_item} }, $item->{execution_date}, $item_id);
 
index 9cf8bed..55c46f2 100644 (file)
--- a/SL/VK.pm
+++ b/SL/VK.pm
@@ -77,8 +77,13 @@ sub invoice_transactions {
   # Bestandteile von Erzeugnissen herausfiltern
   $where .= " AND i.assemblyitem is not true ";
 
-  my $sortorder;
+  # filter allowed parameters for mainsort and subsort as passed by POST
+  my @databasefields = qw(description customername country partsgroup business salesman month);
+  my ($mainsort) = grep { /^$form->{mainsort}$/ } @databasefields;
+  my ($subsort) = grep { /^$form->{subsort}$/ } @databasefields;
+  die "illegal parameter for mainsort or subsort" unless $mainsort and $subsort;
 
+  my $sortorder;
   # sorting by month is a special case, we don't want to sort alphabetically by
   # month name, so we also extract a numerical month in the from YYYYMM to sort
   # by in case of month sorting
@@ -88,16 +93,15 @@ sub invoice_transactions {
   if ($form->{mainsort} eq 'month') {
     $sortorder .= "nummonth,"
   } else {
-    $sortorder .= $form->{mainsort} . ",";
+    $sortorder .= $mainsort . ",";
   };
   if ($form->{subsort} eq 'month') {
     $sortorder .= "nummonth,"
   } else {
-    $sortorder .= $form->{subsort} . ",";
+    $sortorder .= $subsort . ",";
   };
   $sortorder .= 'ar.transdate,ar.invnumber';  # Default sorting order after mainsort und subsort
 
-
   if ($form->{customer_id}) {
     $where .= " AND ar.customer_id = ?";
     push(@values, $form->{customer_id});
index 56fad89..31c70d0 100644 (file)
@@ -301,7 +301,7 @@ sub list_contacts {
   my $cvar_configs = CVar->get_configs('module' => 'Contacts');
 
   my @columns      = qw(
-    cp_id vcname vcnumber cp_name cp_givenname cp_street cp_phone1 cp_phone2
+    cp_id vcname vcnumber cp_name cp_givenname cp_street cp_zipcode cp_city cp_phone1 cp_phone2
     cp_mobile1 cp_mobile2 cp_email cp_abteilung cp_birthday cp_gender
   );
 
@@ -327,6 +327,8 @@ sub list_contacts {
     'cp_name'      => { 'text' => $::locale->text('Name'), },
     'cp_givenname' => { 'text' => $::locale->text('Given Name'), },
     'cp_street'    => { 'text' => $::locale->text('Street'), },
+    'cp_zipcode'   => { 'text' => $::locale->text('Zipcode'), },
+    'cp_city'      => { 'text' => $::locale->text('City'), },
     'cp_phone1'    => { 'text' => $::locale->text('Phone1'), },
     'cp_phone2'    => { 'text' => $::locale->text('Phone2'), },
     'cp_mobile1'   => { 'text' => $::locale->text('Mobile1'), },
index fa46e64..e25f963 100644 (file)
@@ -1535,22 +1535,31 @@ sub print_form {
     my %queued = map { s|.*/|| } split / /, $form->{queued};
 
     my $filename;
+    my $suffix = ($form->{postscript}) ? '.ps' : '.pdf';
     if ($filename = $queued{ $form->{formname} }) {
       $form->{queued} =~ s/\Q$form->{formname} $filename\E//;
       unlink $::lx_office_conf{paths}->{spool} . "/$filename";
       $filename =~ s/\..*$//g;
+      $filename .= $suffix;
+      $form->{OUT} = $::lx_office_conf{paths}->{spool} . "/$filename";
+      $form->{OUT_MODE} = '>';
     } else {
-      $filename = time;
-      $filename .= $$;
+      my $temp_fh;
+      ($temp_fh, $filename) = File::Temp::tempfile(
+        'kivitendo-spoolXXXXXX',
+        SUFFIX => "$suffix",
+        DIR => $::lx_office_conf{paths}->{spool},
+      );
+      close $temp_fh;
+      $form->{OUT} = "$filename";
+      # use >> for OUT_MODE because file is already created by File::Temp
+      $form->{OUT_MODE} = '>>';
+      # strip directory so that only filename is stored in table status
+      ($filename) = $filename =~ /^$::lx_office_conf{paths}->{spool}\/(.*)/;
     }
 
-    $filename .= ($form->{postscript}) ? '.ps' : '.pdf';
-    $form->{OUT} = $::lx_office_conf{paths}->{spool} . "/$filename";
-    $form->{OUT_MODE} = '>';
-
     # add type
     $form->{queued} .= " $form->{formname} $filename";
-
     $form->{queued} =~ s/^ //;
   }
   my $queued = $form->{queued};
index 7ee0c88..bc2f092 100644 (file)
@@ -14,6 +14,8 @@ Größere neue Features:
   konsistent bleibt und eine Fehlermeldung ausgegeben. Das Feature kann in der
   Konfiguration unter [datev_check] angeschaltet werden.
 
+- Verkaufsbericht: Sortierung um Land, Warengruppen, Kundentyp, Verkäufer und
+  Monat erweitert, sowie benutzerdefinierte Variablen eingebunden
 
 Experimentelle Features:
 
index 6a5a58e..b5047be 100644 (file)
@@ -1147,7 +1147,7 @@ $self->{texts} = {
   'Missing amount'              => 'Fehlbetrag',
   'Missing parameter #1 in call to sub #2.' => 'Fehlernder Parameter \'#1\' in Funktionsaufruf \'#2\'.',
   'Missing parameter (at least one of #1) in call to sub #2.' => 'Fehlernder Parameter (mindestens einer aus \'#1\') in Funktionsaufruf \'#2\'.',
-  'Missing qty'                 => '',
+  'Missing qty'                 => 'Fehlende Stückzahl',
   'Missing taxkeys in invoices with taxes.' => 'Fehlende Steuerschl&uuml;ssel in Rechnungen mit Steuern',
   'Missing user id!'            => 'Benutzer ID fehlt!',
   'Mitarbeiter'                 => 'Mitarbeiter',
@@ -1503,6 +1503,7 @@ $self->{texts} = {
   'Recorded Tax'                => 'Gespeicherte Steuern',
   'Recorded taxkey'             => 'Gespeicherter Steuerschlüssel',
   'Reference'                   => 'Referenz',
+  'Reference / Invoice Number'  => 'Referenz / Rechnungsnummer',
   'Reference missing!'          => 'Referenz fehlt!',
   'Release From Stock'          => 'Lagerausgang',
   'Remaining'                   => 'Rest',
@@ -1687,7 +1688,7 @@ $self->{texts} = {
   'Start the correction assistant' => 'Korrekturassistenten starten',
   'Startdate_coa'               => 'Gültig ab',
   'Starting Balance'            => 'Eröffnungsbilanzwerte',
-  'Starting with version 2.6.3 the configuration files in "config" have been consolidated.' => '',
+  'Starting with version 2.6.3 the configuration files in "config" have been consolidated.' => 'Ab Version 2.6.3 wurden die Konfiguration vereinfacht und es gibt nur noch eine Konfigurationsdatei im Verzeichnis config',
   'Statement'                   => 'Sammelrechnung',
   'Statement Balance'           => 'Sammelrechnungsbilanz',
   'Statement sent to'           => 'Sammelrechnung verschickt an',
index 1c24fe1..528ad8d 100644 (file)
@@ -9,16 +9,15 @@
       </td>
      </tr>
 
-    <tr>
-     <th align="left" nowrap>[% 'Gender' | $T8 %]</th>
-     <td>
-      <select id="cp_gender" name="cp_gender">
-       <option value="m"[% IF cp_gender == 'm' %] selected[% END %]>[% 'male' | $T8 %]</option>
-       <option value="f"[% IF cp_gender == 'f' %] selected[% END %]>[% 'female' | $T8 %]</option>
-      </select>
-     </td>
-    </tr>
-    <tr>
+     <tr>
+      <th align="left" nowrap>[% 'Gender' | $T8 %]</th>
+      <td>
+       <select id="cp_gender" name="cp_gender">
+        <option value="m"[% IF cp_gender == 'm' %] selected[% END %]>[% 'male' | $T8 %]</option>
+        <option value="f"[% IF cp_gender == 'f' %] selected[% END %]>[% 'female' | $T8 %]</option>
+       </select>
+      </td>
+     </tr>
 
      <tr>
       <th align="left" nowrap>[% 'Title' | $T8 %]</th>
       <td><input id="cp_name" name="cp_name" size="40" maxlength="75" value="[% HTML.escape(cp_name) %]"></td>
      </tr>
 
+     <tr>
+      <th align="left" nowrap>[% 'E-mail' | $T8 %]</th>
+      <td><input id="cp_email" name="cp_email" size="40" value="[% HTML.escape(cp_email) %]"></td>
+     </tr>
+
      <tr>
       <th align="left" nowrap>[% 'Phone1' | $T8 %]</th>
       <td><input id="cp_phone1" name="cp_phone1" size="40" maxlength="75" value="[% HTML.escape(cp_phone1) %]"></td>
      </tr>
 
      <tr>
-      <th align="left" nowrap>[% 'E-mail' | $T8 %]</th>
-      <td><input id="cp_email" name="cp_email" size="40" value="[% HTML.escape(cp_email) %]"></td>
+      <th align="left" nowrap>[% 'Street' | $T8 %]</th>
+      <td><input id="cp_street" name="cp_street" size="40" maxlength="75" value="[% HTML.escape(cp_street) %]"></td>
+     </tr>
+
+     <tr>
+      <th align="left" nowrap>[% 'Zip, City' | $T8 %]</th>
+      <td>
+       <input id="cp_zipcode" name="cp_zipcode" size="5" maxlength="10" value="[% HTML.escape(cp_zipcode) %]">
+       <input id="cp_city" name="cp_city" size="25" maxlength="75" value="[% HTML.escape(cp_city) %]">
+      </td>
      </tr>
 
      <tr>
index be67814..0f7c127 100644 (file)
         <input name="l.cp_givenname" id="l_cp_givenname" type="checkbox" class="checkbox" value="Y" checked>
         <label for="l_cp_givenname">[% 'Given Name' | $T8 %]</label>
        </td>
+      </tr>
+      <tr>
        <td>
         <input name="l.cp_street" id="l_cp_street" type="checkbox" class="checkbox" value="Y">
         <label for="l_cp_street">[% 'Street' | $T8 %]</label>
        </td>
+       <td>
+        <input name="l.cp_zipcode" id="l_cp_zipcode" type="checkbox" class="checkbox" value="Y">
+        <label for="l_cp_zipcode">[% 'Zipcode' | $T8 %]</label>
+       </td>
+       <td>
+        <input name="l.cp_city" id="l_cp_city" type="checkbox" class="checkbox" value="Y">
+        <label for="l_cp_city">[% 'City' | $T8 %]</label>
+       </td>
       </tr>
       <tr>
        <td>
index 6c5b7d7..ed7948d 100644 (file)
@@ -17,7 +17,7 @@
     <td>
       <table>
         <tr>
-          <th align=right>[% 'Reference' | $T8 %]</th>
+          <th align=right>[% 'Reference / Invoice Number' | $T8 %]</th>
           <td><input name=reference size=20></td>
           <th align=right>[% 'Source' | $T8 %]</th>
           <td><input name=source size=20></td>